Public API#
The top-level evo_lmm namespace contains the supported public classes and
functions. The signatures below are generated directly from the installed
package.
Evolutionary random-effects LMMs backed by raw GRGL dosage operators.
- class evo_lmm.AssociationResult(chrom, local_idx, score, beta, se, chisq, pvalue, chisq_linreg=None, pvalue_linreg=None, model_mask=None, frequencies=None, inverse_scale=nan, calibration_factor=nan)#
Bases:
objectCompact BOLT-compatible association output for one chromosome block.
betaandseare in raw diploid-dosage effect units, matching the evolutionary model’ssigma_b2scale.scoreis the calibrated inverse-variance scorex_j^T V_loco^-1 yon the BOLT-normalised test column. Entries excluded bymodel_mask(monomorphic or covariate-collinear columns) carrynanstatistics andpvalue = 1.- Parameters:
chrom (Any)
local_idx (ndarray)
score (ndarray)
beta (ndarray)
se (ndarray)
chisq (ndarray)
pvalue (ndarray)
chisq_linreg (ndarray | None)
pvalue_linreg (ndarray | None)
model_mask (ndarray | None)
frequencies (ndarray | None)
inverse_scale (float)
calibration_factor (float)
- good()#
Return the boolean mask of variants with reportable statistics.
- Return type:
ndarray
- class evo_lmm.CalibrationResult(factor, std, ratio_of_medians, median_of_ratios, selected, tried, prospective, retrospective, inverse_scale, residuals=<factory>, quadratic_form=<factory>, screen_threshold=5.0, seed=0)#
Bases:
objectProspective/retrospective calibration of the evolutionary LMM statistic.
- Parameters:
factor (float)
std (float)
ratio_of_medians (float)
median_of_ratios (float)
selected (tuple[tuple[Any, int], ...])
tried (int)
prospective (ndarray)
retrospective (ndarray)
inverse_scale (dict[Any, float])
residuals (dict[Any, ndarray])
quadratic_form (dict[Any, float])
screen_threshold (float)
seed (int)
- factor#
The applied calibration factor: the ratio of prospective to retrospective statistic sums, or the ratio of medians when the jackknife standard error exceeds
CALIBRATION_STD_LIMIT.- Type:
float
- inverse_scale#
Per-chromosome
VinvScaleFactorin raw-effect units. A tested chromosome’s calibrated inverse-variance score is(x_j^T H_loco^-1 P y) / sigma_b2 / inverse_scale[chrom].- Type:
dict[Any, float]
- residuals#
H_loco^-1 P_C yfor each left-out chromosome, reused byevo_lmm.association()so the solves are not repeated.- Type:
dict[Any, numpy.ndarray]
- class evo_lmm.ConvergenceReport(status='unknown', converged=False, iterations=0, step_se_norm=nan, step_se_tol=nan, newton_decrement=nan, score_norm=nan, accepted_step=nan, ai_condition=nan, ai_damping=nan)#
Bases:
objectHow a fit ended, in sample-size-independent terms.
Both fitters – single-component
evo_lmm.fit_reml()andevo_lmm.fit_multicomponent_reml()– judge convergence by the same rule and report it through this object, so the two are comparable.step_se_normis the criterion:max_i |step_i| / SE_iwithstep = AI^-1 scoreandSE = sqrt(diag(AI^-1))– the largest move the next undamped Newton step would make in any coordinate, in units of that coordinate’s own standard error. Convergence is declared when it is at or belowstep_se_tol.newton_decrementissqrt(score' AI^-1 score), logged alongside it. Both are dimensionless, invariant to a reparameterization of the coordinates, and order one at a fixed distance from the optimum regardless of sample size.score_normis a diagnostic, not a criterion: at a fixed statistical distance from the optimum it grows roughly likesqrt(n), so no absolute bound on it means the same thing at two sample sizes. It is reported because it is cheap and occasionally informative, never to be thresholded.statusnames the exit, and is the field to branch on:convergedstep_se_norm <= step_se_tolat an accepted iterate.converged_after_dense_finishThe criterion was met only after the exact dense finishing optimizer ran (single-component fitter).
stalled_near_toleranceEvery step halving was rejected, but the criterion was within ten times its tolerance, so the iterate is accepted as converged.
line_search_stalledThe iteration budget ran out and the final iteration’s step was rejected.
iteration_capThe iteration budget ran out with steps still being accepted.
optimizer_stalledA delegated optimizer (dense L-BFGS-B) returned without meeting the criterion, whatever its own verdict was.
unidentifiedThe criterion is met on every direction the information matrix locates, but at least one coordinate has a standard error wider than its own coordinate box, so the data do not place it anywhere. The fit is done; that coordinate’s value is not an estimate and must not be reported. A pure-null panel lands here: with no genetic variance there is no information about the frequency-shape parameter.
not_startedmax_iter=0; the reported state is the initial point.oracleNot produced by an optimizer at all – an explicitly constructed covariance, used by oracle tests.
convergedis the summarystatus inCONVERGED_STATUSES; it never distinguishes these cases on its own, which is whystatusexists.- Parameters:
status (str)
converged (bool)
iterations (int)
step_se_norm (float)
step_se_tol (float)
newton_decrement (float)
score_norm (float)
accepted_step (float)
ai_condition (float)
ai_damping (float)
- class evo_lmm.DenseREMLOracle(genotypes, frequencies, covariates=None, *, model='simplified')#
Bases:
objectConvenient exact REML oracle for tests and small dense simulations.
- Parameters:
genotypes (np.ndarray)
frequencies (np.ndarray)
covariates (np.ndarray | None)
model (str)
- evo_lmm.convergence_statistics(score, ai, *, se_limit=60.0)#
Return the scale-free convergence statistics
(step_se_norm, decrement).step_se_norm = max_i |step_i| / SE_iwithstep = AI^-1 scoreandSE_i = sqrt((AI^-1)_ii): the largest move the next undamped Newton step would make in any coordinate, measured in that coordinate’s own standard error.decrement = sqrt(score' AI^-1 score)is the Newton decrement, which approximates twice the objective decrease the step would buy.Both are dimensionless and invariant to a reparameterization of the coordinates. They also measure distance from the optimum in standard-error units, so they stay order one at a fixed statistical distance regardless of
n, whereas||score||_infat the same point grows roughly likesqrt(n). A fixed absolute score tolerance therefore demands gettingsqrt(n)times closer as data are added, which is why it is not the gate.The statistic is taken over the coordinates the information matrix locates;
unidentified_coordinates()masks the rest, and a fit carrying any of them reportsstatus="unidentified"so the value is not read as an estimate. Excluding them is not leniency: where the standard error is1e10log units, score-over-information is numerical noise divided by numerical noise, and thresholding it reports the floating-point floor rather than the fit.When no coordinate is identified the result is
inf, not zero: an iteration must never stop because its information matrix was momentarily unusable. That case is named by theunidentifiedstatus once the fit is over, not treated as convergence mid-loop. Non-finite input also returnsinf.- Parameters:
score (ndarray)
ai (ndarray)
se_limit (float)
- Return type:
tuple[float, float]
- class evo_lmm.EvolutionaryLmmOps(chromosomes, frequencies=None, covariates=None, *, sample_filter=None, model='simplified', mutation_filter=None)#
Bases:
objectMatrix-free projected raw-dosage operators for evolutionary LMMs.
- Parameters:
chromosomes (Any) – An
(N, M)dense dosage matrix, a mapping of chromosome labels to matrices/GRGs, or a sequence of matrices/(label, source)pairs.frequencies (Any) – Sample allele frequencies, supplied as one vector, one vector per chromosome, or a mapping. GRG inputs may omit this and extract them through GRAPP’s frequency traversal.
covariates (np.ndarray | None) – Fixed-effect design. An intercept is added when absent and the basis is QR-orthonormalised once.
model (str) – Coordinate interpretation for transformed
phiarrays.sample_filter (Sequence[int] | None)
mutation_filter (Mapping[Any, Sequence[int]] | None)
- classmethod from_dense(genotypes, frequencies, covariates=None, *, chrom_labels=None, model='simplified')#
Convenience constructor for dense tests and small simulations.
- Parameters:
genotypes (ndarray | Sequence[ndarray])
frequencies (ndarray | Sequence[ndarray])
covariates (ndarray | None)
chrom_labels (Sequence[Any] | None)
model (str)
- Return type:
- test_stats(chrom)#
Return prior-independent tested-genotype statistics for a chromosome.
These are the quantities the BOLT-style calibration and association formulas need: the projected raw-dosage norms, the BOLT normalisation, and the eligibility mask. They depend only on the genotypes and the covariate basis, never on the fitted evolutionary prior.
- Parameters:
chrom (Any)
- Return type:
- apply_model_x(weights, theta=None, exclude_chrom=None)#
Apply
P_C X diag(weights)to variant coefficients.weightsis normally a vector of model coefficients. Whenthetais a prior, it applies the model operatorP_C X diag(sqrt(w(theta)))to those coefficients. A raw coefficient vector or chromosome mapping may also be supplied withouttheta. This method deliberately contains no sample-standardisation or1/Mnormalization.- Parameters:
weights (ndarray | Mapping[Any, ndarray] | EvolutionaryPrior)
theta (Any)
exclude_chrom (Any)
- Return type:
ndarray
- model_scores(vector, theta=None, exclude_chrom=None)#
Return model scores, optionally for
B_theta^T = diag(sqrt(w))X^T P_C.- Parameters:
vector (ndarray)
theta (Any)
exclude_chrom (Any)
- Return type:
ndarray
- apply_k(vector, theta, exclude_chrom=None)#
Apply
K = P_C X diag(w(theta)) X^T P_C.- Parameters:
vector (ndarray)
theta (Any)
exclude_chrom (Any)
- Return type:
ndarray
- apply_dk(vector, theta, parameter, exclude_chrom=None)#
Apply a first derivative of
Kin a transformed shape coordinate.- Parameters:
vector (ndarray)
theta (Any)
parameter (str)
exclude_chrom (Any)
- Return type:
ndarray
- apply_h(vector, phi, exclude_chrom=None)#
Apply the projected shape matrix
H = K + delta I.- Parameters:
vector (ndarray)
phi (Any)
exclude_chrom (Any)
- Return type:
ndarray
- apply_dh(vector, phi, parameter, exclude_chrom=None)#
Apply a first derivative of
Hinlog_delta,log_tau, orlogit_r.- Parameters:
vector (ndarray)
phi (Any)
parameter (str)
exclude_chrom (Any)
- Return type:
ndarray
- apply_dh_matmat(values, phi, parameter, exclude_chrom=None)#
Apply a first derivative of
Hto several columns at once.This is the matrix-RHS counterpart of
apply_dh(). Keeping the columns batched is important for GRG inputs: onematmattraversal replaces one traversal per stochastic trace probe.- Parameters:
values (ndarray)
phi (Any)
parameter (str)
exclude_chrom (Any)
- Return type:
ndarray
- apply_k_matmat(values, theta, exclude_chrom=None)#
Apply
Kto batched right-hand sides without per-column traversals.- Parameters:
values (ndarray)
theta (Any)
exclude_chrom (Any)
- Return type:
ndarray
- solve_ph(rhs_columns, phi, exclude_chrom=None, *, tol=0.0005, max_iter=None, initial=None, stats=None)#
Solve projected
H z = P_C rhsfor one or many right-hand sides.initialis an optional warm start. Each column is validated against a zero start independently; a poor or invalid cached column is reset without affecting the other right-hand sides. Ifstatsis passed, it is populated with aggregate iteration and warm-start diagnostics.- Parameters:
rhs_columns (ndarray)
phi (Any)
exclude_chrom (Any)
tol (float)
max_iter (int | None)
initial (ndarray | None)
stats (dict[str, Any] | None)
- Return type:
ndarray
- test_scores(chrom, vector)#
Return BOLT-normalised test-genotype scores for one chromosome.
- Parameters:
chrom (Any)
vector (ndarray)
- Return type:
ndarray
- test_column(chrom, local_idx)#
Return one projected, BOLT-normalised test-genotype column.
- Parameters:
chrom (Any)
local_idx (int)
- Return type:
ndarray
- chromosome_frequencies(chrom)#
Return sample allele frequencies for one chromosome in operator order.
- Parameters:
chrom (Any)
- Return type:
ndarray
- local_indices(chrom)#
Return mutation identifiers for a chromosome in operator order.
- Parameters:
chrom (Any)
- Return type:
ndarray
- kernel_trace(theta, exclude_chrom=None)#
Return
tr(P_C K P_C)without constructing a dense kernel.- Parameters:
theta (Any)
exclude_chrom (Any)
- Return type:
float
- dense_kernel(theta, exclude_chrom=None)#
Materialise a kernel for a small dense input or a test oracle.
- Parameters:
theta (Any)
exclude_chrom (Any)
- Return type:
ndarray
- class evo_lmm.EvolutionaryPrior#
Bases:
objectCommon interface implemented by the two evolutionary priors.
- coordinates(delta)#
Return unconstrained
(log_delta, log_tau[, logit_r])coordinates.- Parameters:
delta (float)
- Return type:
ndarray
- class evo_lmm.FitDiagnostics(convergence, trace_estimator, trace_probes, objective=nan, initialization='default', trace_operator_queries=0, trace_standard_errors=<factory>, cg_iterations=<factory>, cg_warm_start_hits=0, cg_warm_start_rejections=0, cg_initial_residual_norms=<factory>, cg_final_residual_norms=<factory>, random_seed=None, boundary_hits=(), warnings=())#
Bases:
objectNumerical and identifiability diagnostics from a fit.
Convergence lives in
ConvergenceReportunderconvergence; the flat accessors below delegate to it so both fitters expose the same names.objectiveis the profiled REML objective or ``nan``. It is never a stand-in for something else: the stochastic paths do not evaluate a log-determinant, so they reportnanrather than a surrogate, and convergence is judged byconvergence.step_se_normin every path.- Parameters:
convergence (ConvergenceReport)
trace_estimator (str)
trace_probes (int)
objective (float)
initialization (str)
trace_operator_queries (int)
trace_standard_errors (dict[str, float])
cg_iterations (list[int])
cg_warm_start_hits (int)
cg_warm_start_rejections (int)
cg_initial_residual_norms (list[float])
cg_final_residual_norms (list[float])
random_seed (int | None)
boundary_hits (tuple[str, ...])
warnings (tuple[str, ...])
- class evo_lmm.FitResult(prior, sigma_b2, sigma_e2, delta, h2, log_likelihood, fixed_effects, projected_phenotype, ph_y, diagnostics, model, ops=None)#
Bases:
objectScientific-scale fit result for an evolutionary LMM.
- Parameters:
prior (EvolutionaryPrior)
sigma_b2 (float)
sigma_e2 (float)
delta (float)
h2 (float)
log_likelihood (float)
fixed_effects (ndarray)
projected_phenotype (ndarray)
ph_y (ndarray)
diagnostics (FitDiagnostics)
model (str)
ops (Any)
- property sigma_g2: float#
Compatibility alias; unlike GRAPP this is raw-effect
sigma_b2.
- blup()#
Return the projected genetic-value BLUP
sigma_b2 K P_V y.- Return type:
ndarray
- class evo_lmm.FullPrior(sigma_b2, tau, rho)#
Bases:
EvolutionaryPriorThe full evolutionary prior with identifiable coupling
rho^2.Only
rho^2appears in the conditional variance, so the sign ofrhois not identifiable. The public parameter accepts-1 <= rho <= 1and the optimizer works directly withr = rho^2.- Parameters:
sigma_b2 (float)
tau (float)
rho (float)
- class evo_lmm.SimplifiedPrior(sigma_b2, tau)#
Bases:
EvolutionaryPriorThe exact
rho^2 = 1evolutionary prior.- Parameters:
sigma_b2 (float) – Per-locus focal-trait effect variance on raw dosage units.
tau (float) – Non-negative
sigma_a^2 / W_Saggregate.tau=0is the frequency-independent boundary and is useful for tests and diagnostics.
- class evo_lmm.GrgSimulation(tree_sequence, grg, frequencies, effects, genetic_value, phenotype, prior, residual_variance, seed)#
Bases:
objectA simulated GRG phenotype with effects sampled from an evolutionary prior.
- Parameters:
tree_sequence (Any)
grg (Any)
frequencies (ndarray)
effects (ndarray)
genetic_value (ndarray)
phenotype (ndarray)
prior (EvolutionaryPrior)
residual_variance (float)
seed (int)
- class evo_lmm.VariantData(frequencies, local_idx, raw_norm2=None, centered_norm2=None)#
Bases:
objectCached per-variant information used by an evolutionary operator.
frequenciesare sample allele frequencies andlocal_idxare the mutation identifiers in the source chromosome.raw_norm2andcentered_norm2are optional because GRGL operators can obtain them via graph traversals when needed.- Parameters:
frequencies (ndarray)
local_idx (ndarray)
raw_norm2 (ndarray | None)
centered_norm2 (ndarray | None)
- evo_lmm.allele_frequency_q(frequencies)#
Return
q = x_hat * (1 - x_hat)for sample allele frequencies.- Parameters:
frequencies (ndarray)
- Return type:
ndarray
- evo_lmm.association(result, y=None, *, use_loco=True, calibrate=True, calibration=None, calibration_variants=30, seed=0, screen_threshold=5.0, cg_tol=0.0005)#
Compute calibrated BOLT-style association statistics per chromosome.
The mixed-model statistic uses the fitted evolutionary LOCO covariance
V_loco = sigma_b2 * (K_evo,loco + delta I)while the tested columns keep GRAPP’s independent BOLT normalisation. Withcalibrate=Truethe prospective/retrospective moment matching ofevo_lmm.calibrate_association()supplies the per-chromosome inverse scale; otherwise the uncalibrated (factor = 1) scale is used, which is only appropriate for diagnostics.betaandseare returned in raw diploid-dosage units. A single-variant linear-regression chi-square is reported alongside the mixed model statistic so inflation can be compared directly.- Parameters:
result (FitResult)
y (ndarray | None)
use_loco (bool)
calibrate (bool)
calibration (CalibrationResult | None)
calibration_variants (int)
seed (int)
screen_threshold (float)
cg_tol (float)
- Return type:
list[AssociationResult]
- evo_lmm.association_summary(results)#
Return mean chi-square and lambda_GC for the mixed model and linreg.
lambda_gcdivides the median chi-square by the median of a one-degree-of-freedom chi-square, so a calibrated null gives values near one for both statistics.- Parameters:
results (Sequence[AssociationResult])
- Return type:
dict[str, dict[str, float]]
- evo_lmm.calibrate_association(result, y=None, *, count=30, seed=0, screen_threshold=5.0, cg_tol=0.0005, stats=None)#
Calibrate the LMM statistic against the fitted evolutionary covariance.
For every selected variant
jon its own chromosomecthe retrospective and prospective statistics areretro = (N - C) * (x_j^T u_c)^2 / (||u_c||^2 * ||x_j||^2)pro = (N - C) * (x_j^T u_c)^2 / (x_j^T H_c^-1 x_j) / (y^T u_c)with
u_c = H_c^-1 P_C yandH_cthe LOCO evolutionary shape matrix. Both are invariant tosigma_b2, so the factor is a pure shape correction;sigma_b2enters only throughinverse_scale.- Parameters:
result (FitResult)
y (ndarray | None)
count (int)
seed (int)
screen_threshold (float)
cg_tol (float)
stats (dict[Any, TestVariantStats] | None)
- Return type:
- evo_lmm.select_calibration_variants(result, *, count=30, seed=0, screen_threshold=5.0, stats=None)#
Select calibration variants with BOLT’s blocked GRAMMAR pre-screen.
Eligible variants are split into
countequal blocks in chromosome order. One variant is drawn uniformly from each block and accepted when its all-chromosome GRAMMAR retrospective statistic falls belowscreen_threshold, which keeps strongly associated variants out of the calibration set. Returns the selected(chrom, local_idx)pairs and the number of candidates examined.- Parameters:
result (FitResult)
count (int)
seed (int)
screen_threshold (float)
stats (dict[Any, TestVariantStats] | None)
- Return type:
tuple[list[tuple[Any, int]], int]
- class evo_lmm.TestVariantStats(chrom, local_idx, centered_norm2, projected_norm2, test_scale, norm_scale, std_projected_norm2, model_mask)#
Bases:
objectPer-variant tested-genotype statistics for one chromosome block.
All quantities are computed after the covariate projection
P_C. Thetest_scaleis the BOLT normalisationsqrt(centered_norm2 / (n - 1))applied to raw diploid dosage columns, sonorm_scale = 1 / test_scaleconverts a raw-dosage quantity into BOLT-normalised units. Nothing here depends on the fitted evolutionary prior.- Parameters:
chrom (Any)
local_idx (ndarray)
centered_norm2 (ndarray)
projected_norm2 (ndarray)
test_scale (ndarray)
norm_scale (ndarray)
std_projected_norm2 (ndarray)
model_mask (ndarray)
- projected_norm2#
||P_C x_j||^2in raw diploid dosage units.- Type:
numpy.ndarray
- std_projected_norm2#
||P_C x_j||^2in BOLT-normalised units, i.e.projected_norm2 * norm_scale**2.- Type:
numpy.ndarray
- model_mask#
Variants eligible for association output; monomorphic and covariate-collinear columns are excluded exactly as in GRAPP.
- Type:
numpy.ndarray
- evo_lmm.dense_variant_data(genotypes, frequencies=None, *, local_idx=None)#
Build variant metadata from an
(N, M)raw dosage matrix.If frequencies are omitted, they are calculated as the mean dosage divided by ploidy two. This default is deliberately explicit in the docstring and is only intended for diploid dense test/simulation inputs.
- Parameters:
genotypes (ndarray)
frequencies (ndarray | None)
local_idx (Sequence[int] | None)
- Return type:
- evo_lmm.exact_average_information(y, H, derivatives, covariates=None)#
Return the direct quadratic-form average-information matrix.
- Parameters:
y (ndarray)
H (ndarray)
derivatives (Sequence[ndarray])
covariates (ndarray | None)
- Return type:
ndarray
- evo_lmm.exact_reml_score(y, H, derivatives, covariates=None, *, scale=1.0)#
Return exact shape scores for
V = scale * H.The scale is normally the profiled
sigma_b2. Omitting it evaluates the equivalent unit-scale score.- Parameters:
y (ndarray)
H (ndarray)
derivatives (Sequence[ndarray])
covariates (ndarray | None)
scale (float)
- Return type:
ndarray
- evo_lmm.fit_dense_reml(genotypes, frequencies, y, *, covariates=None, model='simplified', **kwargs)#
Fit the exact dense oracle in one call.
- Parameters:
genotypes (ndarray)
frequencies (ndarray)
y (ndarray)
covariates (ndarray | None)
model (str)
kwargs (Any)
- Return type:
- evo_lmm.fit_evolutionary_bolt_lmm(chrom_grgs, y, *, frequencies=None, covariates=None, model='simplified', initial=None, sample_filter=None, trace_probes=12, seed=0, max_iter=50, cg_tol=0.0005, trace_method='hutchinson', warm_start=True, initialization='default')#
Fit the CPU GRGL-backed evolutionary model across chromosomes.
- Parameters:
chrom_grgs (Sequence[tuple[Any, Any]])
y (ndarray)
frequencies (Mapping[Any, ndarray] | Sequence[ndarray] | None)
covariates (ndarray | None)
model (str)
initial (Any)
sample_filter (Sequence[int] | None)
trace_probes (int)
seed (int)
max_iter (int)
cg_tol (float)
trace_method (str)
warm_start (bool)
initialization (str)
- Return type:
- evo_lmm.fit_evolutionary_bolt(chrom_grgs, y, *, frequencies=None, covariates=None, model='simplified', initial=None, sample_filter=None, trace_probes=12, seed=0, max_iter=50, cg_tol=0.0005, trace_method='hutchinson', warm_start=True, initialization='default')#
Fit the CPU GRGL-backed evolutionary model across chromosomes.
- Parameters:
chrom_grgs (Sequence[tuple[Any, Any]])
y (ndarray)
frequencies (Mapping[Any, ndarray] | Sequence[ndarray] | None)
covariates (ndarray | None)
model (str)
initial (Any)
sample_filter (Sequence[int] | None)
trace_probes (int)
seed (int)
max_iter (int)
cg_tol (float)
trace_method (str)
warm_start (bool)
initialization (str)
- Return type:
- evo_lmm.fit_evolutionary_reml(ops, y, *, model=None, initial=None, delta=1.0, trace_probes=12, seed=0, max_iter=50, tol=1e-06, step_se_tol=0.01, cg_tol=0.0005, max_step=2.0, exact=None, trace_method='hutchinson', warm_start=True, initialization='default')#
Fit evolutionary shape parameters by profiled average-information REML.
sigma_b2is profiled asy'P_H y / (N-rank(C))andsigma_e2is derived asdelta*sigma_b2. Dense operators use exact traces by default; matrix-free operators use fixed Rademacher probes (Hutchinson) and warm-started projected CG solves.The stochastic defaults are deliberately cheap and match GRAPP’s solver budget:
trace_probes=12andcg_tol=5e-4. They are appropriate for exploratory fits and for benchmark parity, not for final reported estimates. If a larger stochastic trace budget is desired, raisetrace_probeswhile retaining the sketch solver tolerancecg_tol=5e-4; inspectFitDiagnostics.trace_standard_errorsas a diagnostic rather than treating it as a separate convergence rule.Convergence is declared when
step_se_tolboundsmax_i |step_i| / SE_i– seeconvergence_statistics(). The default1e-2means the next undamped Newton step would move no coordinate by more than one percent of its own standard error.tolkeeps its two remaining roles: the line search accepts a trial displacement below it, and it is passed asgtolto the exact dense finishing optimizer. It is no longer the convergence gate, because||score||_infgrows withnand a fixed absolute bound on it is a different requirement at every sample size.FitDiagnostics.statusnames how the fit ended;convergedalone does not distinguish the criterion being met from the finishing optimizer’s loose back-stop.- Parameters:
ops (EvolutionaryLmmOps)
y (ndarray)
model (str | None)
initial (Any)
delta (float)
trace_probes (int)
seed (int)
max_iter (int)
tol (float)
step_se_tol (float)
cg_tol (float)
max_step (float)
exact (bool | None)
trace_method (str)
warm_start (bool)
initialization (str)
- Return type:
- evo_lmm.fit_evolutionary_lmm(genotypes, y, frequencies=None, *, covariates=None, model='simplified', initial=None, sample_filter=None, trace_probes=12, seed=0, max_iter=50, cg_tol=0.0005, exact=None, trace_method='hutchinson', warm_start=True, initialization='default')#
Fit a simplified or full evolutionary LMM from dense matrices or GRGs.
Missing phenotypes are removed before constructing the operator. For GRGs, the corresponding individual sample filter is passed to GRAPP and allele frequencies are recomputed on the retained sample.
- Parameters:
genotypes (Any)
y (ndarray)
frequencies (Any)
covariates (ndarray | None)
model (str)
initial (Any)
sample_filter (Sequence[int] | None)
trace_probes (int)
seed (int)
max_iter (int)
cg_tol (float)
exact (bool | None)
trace_method (str)
warm_start (bool)
initialization (str)
- Return type:
- evo_lmm.fit_reml(ops, y, *, model=None, initial=None, delta=1.0, trace_probes=12, seed=0, max_iter=50, tol=1e-06, step_se_tol=0.01, cg_tol=0.0005, max_step=2.0, exact=None, trace_method='hutchinson', warm_start=True, initialization='default')#
Fit evolutionary shape parameters by profiled average-information REML.
sigma_b2is profiled asy'P_H y / (N-rank(C))andsigma_e2is derived asdelta*sigma_b2. Dense operators use exact traces by default; matrix-free operators use fixed Rademacher probes (Hutchinson) and warm-started projected CG solves.The stochastic defaults are deliberately cheap and match GRAPP’s solver budget:
trace_probes=12andcg_tol=5e-4. They are appropriate for exploratory fits and for benchmark parity, not for final reported estimates. If a larger stochastic trace budget is desired, raisetrace_probeswhile retaining the sketch solver tolerancecg_tol=5e-4; inspectFitDiagnostics.trace_standard_errorsas a diagnostic rather than treating it as a separate convergence rule.Convergence is declared when
step_se_tolboundsmax_i |step_i| / SE_i– seeconvergence_statistics(). The default1e-2means the next undamped Newton step would move no coordinate by more than one percent of its own standard error.tolkeeps its two remaining roles: the line search accepts a trial displacement below it, and it is passed asgtolto the exact dense finishing optimizer. It is no longer the convergence gate, because||score||_infgrows withnand a fixed absolute bound on it is a different requirement at every sample size.FitDiagnostics.statusnames how the fit ended;convergedalone does not distinguish the criterion being met from the finishing optimizer’s loose back-stop.- Parameters:
ops (EvolutionaryLmmOps)
y (ndarray)
model (str | None)
initial (Any)
delta (float)
trace_probes (int)
seed (int)
max_iter (int)
tol (float)
step_se_tol (float)
cg_tol (float)
max_step (float)
exact (bool | None)
trace_method (str)
warm_start (bool)
initialization (str)
- Return type:
- evo_lmm.exact_reml_loglikelihood(y, covariance, covariates=None, *, scale=1.0, include_constant=False)#
Evaluate the exact restricted log likelihood for a dense covariance.
covarianceis the fullVmatrix. The profiled form used by the fitter is obtained by passingscale=1and profiling that scale outside this function. A fixed intercept is used when covariates are omitted.- Parameters:
y (ndarray)
covariance (ndarray)
covariates (ndarray | None)
scale (float)
include_constant (bool)
- Return type:
float
- evo_lmm.profiled_average_information(y, H, derivatives, covariates=None, *, scale=1.0)#
Return the shape AI after eliminating the profiled scale coordinate.
The Schur complement is formed from the full coordinate vector
(log_sigma_b2, shape...)withH_scale = H.scaleis the current profiledsigma_b2.- Parameters:
y (ndarray)
H (ndarray)
derivatives (Sequence[ndarray])
covariates (ndarray | None)
scale (float)
- Return type:
ndarray
- evo_lmm.haseman_elston_initialization(ops, y, prior, *, probes=12, seed=0)#
Estimate
(sigma_b2, sigma_e2, delta)by projected HE moments.The moment solution is intentionally only an initializer. Exact dense traces are used for dense operators; spherical XTrace estimates are used for GRG operators.
- Parameters:
ops (EvolutionaryLmmOps)
y (ndarray)
prior (EvolutionaryPrior)
probes (int)
seed (int)
- Return type:
tuple[float, float, float]
- evo_lmm.grg_variant_data(grg, *, frequencies=None, sample_filter=None, mutation_filter=None)#
Build cached metadata for one GRG chromosome.
GRGL retains mutation identifiers even when a mutation filter is supplied; the returned
local_idxpreserves those identifiers fortest_column.- Parameters:
grg (Any)
frequencies (ndarray | None)
sample_filter (Sequence[int] | None)
mutation_filter (Sequence[int] | None)
- Return type:
- evo_lmm.loco_solve(result, y, exclude_chrom)#
Solve the fitted projected LOCO shape system for one chromosome.
- Parameters:
result (FitResult)
y (ndarray)
exclude_chrom (Any)
- Return type:
ndarray
- evo_lmm.loco_solutions(result, y=None)#
Return one projected
P_H ysolution per chromosome exclusion.- Parameters:
result (FitResult)
y (ndarray | None)
- Return type:
dict[Any, ndarray]
- evo_lmm.predict_blup(result)#
Return projected genetic-value BLUPs.
- Parameters:
result (FitResult)
- Return type:
ndarray
- evo_lmm.prior_from_coordinates(model, coordinates, *, sigma_b2=1.0)#
Construct a unit/profiled prior and
deltafrom optimizer coordinates.The returned prior has the supplied
sigma_b2and coordinates are(log_delta, log_tau[, logit_r]). Exact boundary values are supported by allowing infinite transformed coordinates.- Parameters:
model (str)
coordinates (ndarray)
sigma_b2 (float)
- Return type:
tuple[EvolutionaryPrior, float]
- evo_lmm.prior_from_parameters(model, *, sigma_b2, tau, rho=1.0)#
Create a prior from scientific parameters with an explicit model name.
- Parameters:
model (str)
sigma_b2 (float)
tau (float)
rho (float)
- Return type:
- evo_lmm.restricted_log_likelihood(y, covariance, covariates=None, *, scale=1.0, include_constant=False)#
Evaluate the exact restricted log likelihood for a dense covariance.
covarianceis the fullVmatrix. The profiled form used by the fitter is obtained by passingscale=1and profiling that scale outside this function. A fixed intercept is used when covariates are omitted.- Parameters:
y (ndarray)
covariance (ndarray)
covariates (ndarray | None)
scale (float)
include_constant (bool)
- Return type:
float
- evo_lmm.sample_allele_frequencies(grg, *, sample_filter=None, adjust_missing=True)#
Extract sample allele frequencies from a GRGL-backed chromosome.
sample_filteris expressed in individual indices, matching GRAPP’s raw genotype operators. Missing alleles are excluded from the denominator by default, so the result remains a sample frequency rather than an imputed dosage frequency.- Parameters:
grg (Any)
sample_filter (Sequence[int] | None)
adjust_missing (bool)
- Return type:
ndarray
- evo_lmm.simulate_grg_lmm(prior, *, n_individuals=24, sequence_length=100000.0, population_size=1000.0, recombination_rate=1e-08, mutation_rate=2e-07, residual_variance=0.4, seed=7)#
Simulate a diploid tree sequence, convert it to a GRG, and draw a trait.
The returned
effectsare raw-dosage SNP effects sampled independently asNormal(0, prior.effect_variances(frequencies)). The genetic value is computed by the GRG-backed raw operator and projected off the intercept, matching the fitting boundary used byfit_evolutionary_bolt_lmm().The temporary
.treesfile is removed after GRGL conversion. The GRG object and original in-memory tree sequence remain available in the result.- Parameters:
prior (EvolutionaryPrior)
n_individuals (int)
sequence_length (float)
population_size (float)
recombination_rate (float)
mutation_rate (float)
residual_variance (float)
seed (int)
- Return type:
- class evo_lmm.MultiComponentFit(prior, sigma_e2, h2, convergence, ops, objective=nan, ai_covariance=None, standard_errors=None, trace_method='hutchinson', trace_probes=0, cg_tol=nan, trace_standard_error=nan, phenotype=None, warnings=(), initialization='default', mom_raw_component_scales=None, mom_truncated=None)#
Bases:
objectProfiled REML result for the partitioned simplified model.
Convergence is reported through
evo_lmm.ConvergenceReport, the same object the single-component fitter uses, so the two fitters are judged by one criterion and read the same way. The flat accessors below delegate to it.objectiveis the profiled REML objective or ``nan``. The AI path never evaluates a log-determinant, so it reportsnanrather than a surrogate; an earlier revision put0.5*||score||^2in this slot, which was neither a likelihood nor the convergence criterion. Only the exact dense method returns a real objective here.warningsreports eachtau_cin a regime where it is unidentified. It is a report only: a boundary hit does not changestatusorconverged.- Parameters:
prior (MultiComponentPrior)
sigma_e2 (float)
h2 (float)
convergence (ConvergenceReport)
ops (MultiComponentOps)
objective (float)
ai_covariance (ndarray | None)
standard_errors (dict[str, float] | None)
trace_method (str)
trace_probes (int)
cg_tol (float)
trace_standard_error (float)
phenotype (ndarray | None)
warnings (tuple[str, ...])
initialization (str)
mom_raw_component_scales (ndarray | None)
mom_truncated (ndarray | None)
- class evo_lmm.MultiComponentOps(components)#
Bases:
objectSum of independently partitioned projected raw-dosage component operators.
- Parameters:
components (Mapping[Any, EvolutionaryLmmOps])
- project(values)#
Project vectors or matrices off the shared covariate basis.
- Parameters:
values (ndarray)
- Return type:
ndarray
- classmethod from_operators(components)#
Construct a partition from already-adapted dense or GRGL operators.
- Parameters:
components (Mapping[Any, EvolutionaryLmmOps])
- Return type:
- kernel_trace(prior)#
Return
tr(P_C K P_C)without materialising a dense kernel.- Parameters:
prior (MultiComponentPrior)
- Return type:
float
- apply_k(values, prior)#
Apply the summed partitioned kernel to one or many vectors.
- Parameters:
values (ndarray)
prior (MultiComponentPrior)
- Return type:
ndarray
- derivative_kernels(prior)#
Return analytic derivatives in the same coordinate order as the prior.
- Parameters:
prior (MultiComponentPrior)
- Return type:
dict[str, ndarray]
- apply_dh_matmat(values, prior, parameter)#
Apply a component derivative to batched vectors (dense/GRGL path).
- Parameters:
values (ndarray)
prior (MultiComponentPrior)
parameter (str)
- Return type:
ndarray
- apply_component_derivatives_matmat(values, prior)#
Apply all component derivatives to shared batched right-hand sides.
The projection and right-hand-side batch are shared across the returned derivatives; GRGL-backed component operators retain their
matmattraversal rather than falling back to one traversal per probe.- Parameters:
values (ndarray)
prior (MultiComponentPrior)
- Return type:
dict[str, ndarray]
- apply_shape_matmat(values, prior)#
Apply
H = I + sum_c K_cto batched projected vectors.- Parameters:
values (ndarray)
prior (MultiComponentPrior)
- Return type:
ndarray
- class evo_lmm.MultiComponentPrior(labels, components)#
Bases:
objectOne simplified prior per annotation category.
coordinatesare ordered(log_sigma_b2_c, log_tau_c)pairs. Atau_cof zero is represented by-infin transformed coordinates.- Parameters:
labels (tuple[Any, ...])
components (tuple[SimplifiedPrior, ...])
- classmethod flat(labels, scales=None)#
Return the exact M0 boundary with all
tau_c = 0.- Parameters:
labels (Sequence[Any])
scales (Sequence[float] | None)
- Return type:
Return M1’s shared-
tauidentifiability-crutch specification.- Parameters:
tau (float)
- Return type:
- evo_lmm.fit_multicomponent_reml(ops, y, *, initial=None, max_iter=200, method='ai', trace_method='hutchinson', trace_probes=12, seed=0, cg_tol=0.0005, tol=1e-06, step_se_tol=0.01, max_step=2.0, fit_tau=True, initialization='default')#
Fit by profiled REML.
The residual scale
sigma_e2is profiled; component scales are searched as ratios to that scale in log coordinates. The objective is REML, and the reported componentsigma_b2values are returned on the scientific scale after profiling.tolis the score-norm convergence tolerance; the default matches the single-component fitter. It is no longer the convergence gate: convergence is declared whenstep_se_tolboundsmax_i |step_i| / SE_i, the same scale-free statistic the single-component fitter uses, andtolonly accepts a vanishing line-search displacement.fit_tau=Falseholds everytau_cat its value ininitialand searches only the|c|scale coordinates. That is the pooled-shape mode used for per-gene fitting, where the shapes are estimated once across genes and must not be re-estimated per gene.initialization="he"applies the joint projected Haseman–Elston(|c|+1)moment system to the component scale coordinates. The current category-specifictau_cvalues are retained: HE is linear in the covariance components conditional on those evolutionary weights and cannot identify the nonlinear shape coordinates by itself. Raw moment scales and negative-scale flags are retained on the returned fit for the required no-truncation audit; invalid or non-positive values fall back to the requested/default scale for optimisation.- Parameters:
ops (MultiComponentOps)
y (ndarray)
initial (MultiComponentPrior | ndarray | None)
max_iter (int)
method (str)
trace_method (str)
trace_probes (int)
seed (int)
cg_tol (float)
tol (float)
step_se_tol (float)
max_step (float)
fit_tau (bool)
initialization (str)
- Return type:
- evo_lmm.profiled_reml_objective(ops, y, prior)#
Evaluate the exact dense profiled-REML objective for a fixed prior.
Returns
(objective, sigma_e2)forV = sigma_e2 * (I + K). This is the small-dense reference used to verify the M0/M1/M2 nesting ladder.- Parameters:
ops (MultiComponentOps)
y (ndarray)
prior (MultiComponentPrior)
- Return type:
tuple[float, float]
- class evo_lmm.CollapsedVariants(genotypes, frequencies, source_indices)#
Bases:
objectResult of optional MAC-threshold burden construction.
- Parameters:
genotypes (dict[Any, ndarray])
frequencies (dict[Any, ndarray])
source_indices (dict[Any, tuple[tuple[int, ...], ...]])
- class evo_lmm.MoMResult(component_scales, residual_variance, raw_component_scales, truncated, system, trace_standard_errors=None)#
Bases:
objectJoint method-of-moments estimates and the negative-estimate audit.
- Parameters:
component_scales (ndarray)
residual_variance (float)
raw_component_scales (ndarray)
truncated (ndarray)
system (ndarray)
trace_standard_errors (dict[str, float] | None)
- evo_lmm.collapse_mac(genotypes, *, ploidy=2, mac_threshold=10.0)#
Collapse variants with MAC below
mac_thresholdper category.Filtering and collapsing occur before frequency recomputation. The collapsed column is a dosage burden and its frequency is its sample mean divided by
ploidy * n.- Parameters:
genotypes (Mapping[Any, ndarray])
ploidy (int)
mac_threshold (float)
- Return type:
- evo_lmm.flat_prior(labels, scales=None)#
Return named M0: a flat per-category prior with
tau_c = 0.- Parameters:
labels (tuple[Any, ...])
scales (Mapping[Any, float] | None)
- Return type:
- evo_lmm.joint_mom_initialization(ops, y, prior, *, trace_method='exact', trace_probes=12, seed=0)#
Solve the
(|c|+1)projected Haseman–Elston moment system.The returned
raw_component_scalesare never truncated. Thecomponent_scalesfield applies the RareEffect boundary rule for an explicitly requested baseline comparison.- Parameters:
ops (MultiComponentOps)
y (ndarray)
prior (MultiComponentPrior)
trace_method (str)
trace_probes (int)
seed (int)
- Return type:
- evo_lmm.fit_rare_effect_baseline(ops, y, *, max_iter=100)#
Fit the named flat baseline marginally and apply the MoM-ratio rule.
Each category is fitted independently by exact restricted (REML) profiling at the
tau=0boundary. The joint adjustment is then computed from the partitioned moment system; no evolutionary weighting is introduced.- Parameters:
ops (MultiComponentOps)
y (ndarray)
max_iter (int)
- Return type:
- class evo_lmm.RareEffectBaselineResult(marginal_scales, marginal_mom_scales, joint_mom_scales, adjusted_scales, negative_mom_fallback)#
Bases:
objectMarginal per-category estimates plus the MoM-ratio adjustment.
marginal_scalesare restricted (REML) marginal estimates: the objective infit_rare_effect_baseline()carries theslogdet(B' V^-1 B)term. Whether RareEffect’s published pipeline uses ML or REML here is not verified in this repository, so do not describe this field as reproducing an ML convention.- Parameters:
marginal_scales (ndarray)
marginal_mom_scales (ndarray)
joint_mom_scales (ndarray)
adjusted_scales (ndarray)
negative_mom_fallback (ndarray)
- evo_lmm.rare_effect_mom_ratio(marginal_scales, marginal_mom_scales, joint_mom_scales)#
Apply RareEffect’s marginal-ML × joint-MoM/marginal-MoM adjustment.
A non-positive marginal or joint MoM estimate triggers the published unadjusted-marginal fallback rather than silently truncating the result.
- Parameters:
marginal_scales (ndarray)
marginal_mom_scales (ndarray)
joint_mom_scales (ndarray)
- Return type:
- class evo_lmm.HeritabilityEstimates(rare_effect: 'float', evolutionary: 'float', rare_genetic_variance: 'float', evolutionary_genetic_variance: 'float')#
Bases:
object- Parameters:
rare_effect (float)
evolutionary (float)
rare_genetic_variance (float)
evolutionary_genetic_variance (float)
- class evo_lmm.GeneComponentReport(gene, pooled_tau, sigma_b2_by_category)#
Bases:
objectGene-level empirical-Bayes report with pooled category shapes.
- Parameters:
gene (Any)
pooled_tau (dict[Any, float])
sigma_b2_by_category (dict[Any, float])
- class evo_lmm.FitReport(heritability, heritability_se, component_standard_errors, maf_decomposition, tau_profiles=None)#
Bases:
objectIntegrated estimand report with covariance-derived uncertainty.
- Parameters:
heritability (HeritabilityEstimates)
heritability_se (float)
component_standard_errors (dict[str, float])
maf_decomposition (dict[Any, ndarray] | None)
tau_profiles (dict[Any, ProfileLikelihood] | None)
- class evo_lmm.ProfileLikelihood(tau, objective, lower, upper)#
Bases:
objectOne-dimensional profile likelihood on a scientific parameter scale.
- Parameters:
tau (ndarray)
objective (ndarray)
lower (float)
upper (float)
- evo_lmm.boundary_lrt_pvalue(statistic, added_boundaries=1)#
Mixture-null p-value for independent non-negative boundary coordinates.
- Parameters:
statistic (float)
added_boundaries (int)
- Return type:
float
- evo_lmm.delta_method_se(function, estimate, covariance, step=1e-05)#
Finite-difference delta-method standard error from an AI covariance.
- Parameters:
function (Callable[[ndarray], float])
estimate (ndarray)
covariance (ndarray)
step (float)
- Return type:
float
- evo_lmm.genic_variance_by_maf(ops, prior, bins)#
Decompose projected genic variance by MAF bin and category.
- Parameters:
ops (MultiComponentOps)
prior (MultiComponentPrior)
bins (Sequence[float])
- Return type:
dict[Any, ndarray]
- evo_lmm.heritability_conventions(ops, prior, sigma_e2)#
Return RareEffect’s uncentered-
nand evo-lmm’s projected-dh².- Parameters:
ops (MultiComponentOps)
prior (MultiComponentPrior)
sigma_e2 (float)
- Return type:
- evo_lmm.gene_component_report(gene, pooled_tau, sigma_b2_by_category)#
Construct the pooled-shape/per-gene-scale reporting unit.
- Parameters:
gene (Any)
pooled_tau (dict[Any, float])
sigma_b2_by_category (dict[Any, float])
- Return type:
- evo_lmm.fit_genes(genes, phenotype, pooled_tau, *, max_iter=100, trace_method='hutchinson', trace_probes=12)#
Fit per-gene scales with the category shapes pooled across genes.
pooled_tauis held fixed for every gene (fit_tau=False); it is a pooled estimate, not a per-gene starting point. Only the|c|scale coordinates are searched, so the reportedpooled_tauis the shape the per-gene scales were actually conditioned on.- Parameters:
genes (dict[Any, MultiComponentOps])
phenotype (ndarray)
pooled_tau (dict[Any, float])
max_iter (int)
trace_method (str)
trace_probes (int)
- Return type:
dict[Any, GeneComponentReport]
- evo_lmm.fit_report(fit, *, maf_bins=None)#
Convert a fit into both estimands plus delta-method h² uncertainty.
- Parameters:
fit (MultiComponentFit)
maf_bins (Sequence[float] | None)
- Return type:
- evo_lmm.fit_tau_profiles(fit, tau_grids)#
Profile each category’s
tau_cwith other fitted parameters fixed.- Parameters:
fit (MultiComponentFit)
tau_grids (dict[Any, Sequence[float]])
- Return type:
dict[Any, ProfileLikelihood]
- evo_lmm.fit_parameter_profiles(fit, parameter_grids)#
Profile scientific-scale
sigma_b2[label]andtau[label]grids.- Parameters:
fit (MultiComponentFit)
parameter_grids (dict[str, Sequence[float]])
- Return type:
dict[str, ProfileLikelihood]
- evo_lmm.profile_tau(tau_values, objective, *, confidence=0.95)#
Evaluate a tau profile and use the likelihood-ratio cutoff for bounds.
- Parameters:
tau_values (Sequence[float])
objective (Callable[[float], float])
confidence (float)
- Return type:
Priors#
- class evo_lmm.SimplifiedPrior(sigma_b2, tau)
Bases:
EvolutionaryPriorThe exact
rho^2 = 1evolutionary prior.- Parameters:
sigma_b2 (float) – Per-locus focal-trait effect variance on raw dosage units.
tau (float) – Non-negative
sigma_a^2 / W_Saggregate.tau=0is the frequency-independent boundary and is useful for tests and diagnostics.
- class evo_lmm.FullPrior(sigma_b2, tau, rho)
Bases:
EvolutionaryPriorThe full evolutionary prior with identifiable coupling
rho^2.Only
rho^2appears in the conditional variance, so the sign ofrhois not identifiable. The public parameter accepts-1 <= rho <= 1and the optimizer works directly withr = rho^2.- Parameters:
sigma_b2 (float)
tau (float)
rho (float)
Operators and data boundaries#
- class evo_lmm.EvolutionaryLmmOps(chromosomes, frequencies=None, covariates=None, *, sample_filter=None, model='simplified', mutation_filter=None)
Bases:
objectMatrix-free projected raw-dosage operators for evolutionary LMMs.
- Parameters:
chromosomes (Any) – An
(N, M)dense dosage matrix, a mapping of chromosome labels to matrices/GRGs, or a sequence of matrices/(label, source)pairs.frequencies (Any) – Sample allele frequencies, supplied as one vector, one vector per chromosome, or a mapping. GRG inputs may omit this and extract them through GRAPP’s frequency traversal.
covariates (np.ndarray | None) – Fixed-effect design. An intercept is added when absent and the basis is QR-orthonormalised once.
model (str) – Coordinate interpretation for transformed
phiarrays.sample_filter (Sequence[int] | None)
mutation_filter (Mapping[Any, Sequence[int]] | None)
- classmethod from_dense(genotypes, frequencies, covariates=None, *, chrom_labels=None, model='simplified')
Convenience constructor for dense tests and small simulations.
- Parameters:
genotypes (ndarray | Sequence[ndarray])
frequencies (ndarray | Sequence[ndarray])
covariates (ndarray | None)
chrom_labels (Sequence[Any] | None)
model (str)
- Return type:
- test_stats(chrom)
Return prior-independent tested-genotype statistics for a chromosome.
These are the quantities the BOLT-style calibration and association formulas need: the projected raw-dosage norms, the BOLT normalisation, and the eligibility mask. They depend only on the genotypes and the covariate basis, never on the fitted evolutionary prior.
- Parameters:
chrom (Any)
- Return type:
- apply_model_x(weights, theta=None, exclude_chrom=None)
Apply
P_C X diag(weights)to variant coefficients.weightsis normally a vector of model coefficients. Whenthetais a prior, it applies the model operatorP_C X diag(sqrt(w(theta)))to those coefficients. A raw coefficient vector or chromosome mapping may also be supplied withouttheta. This method deliberately contains no sample-standardisation or1/Mnormalization.- Parameters:
weights (ndarray | Mapping[Any, ndarray] | EvolutionaryPrior)
theta (Any)
exclude_chrom (Any)
- Return type:
ndarray
- model_scores(vector, theta=None, exclude_chrom=None)
Return model scores, optionally for
B_theta^T = diag(sqrt(w))X^T P_C.- Parameters:
vector (ndarray)
theta (Any)
exclude_chrom (Any)
- Return type:
ndarray
- apply_k(vector, theta, exclude_chrom=None)
Apply
K = P_C X diag(w(theta)) X^T P_C.- Parameters:
vector (ndarray)
theta (Any)
exclude_chrom (Any)
- Return type:
ndarray
- apply_dk(vector, theta, parameter, exclude_chrom=None)
Apply a first derivative of
Kin a transformed shape coordinate.- Parameters:
vector (ndarray)
theta (Any)
parameter (str)
exclude_chrom (Any)
- Return type:
ndarray
- apply_h(vector, phi, exclude_chrom=None)
Apply the projected shape matrix
H = K + delta I.- Parameters:
vector (ndarray)
phi (Any)
exclude_chrom (Any)
- Return type:
ndarray
- apply_dh(vector, phi, parameter, exclude_chrom=None)
Apply a first derivative of
Hinlog_delta,log_tau, orlogit_r.- Parameters:
vector (ndarray)
phi (Any)
parameter (str)
exclude_chrom (Any)
- Return type:
ndarray
- apply_dh_matmat(values, phi, parameter, exclude_chrom=None)
Apply a first derivative of
Hto several columns at once.This is the matrix-RHS counterpart of
apply_dh(). Keeping the columns batched is important for GRG inputs: onematmattraversal replaces one traversal per stochastic trace probe.- Parameters:
values (ndarray)
phi (Any)
parameter (str)
exclude_chrom (Any)
- Return type:
ndarray
- apply_k_matmat(values, theta, exclude_chrom=None)
Apply
Kto batched right-hand sides without per-column traversals.- Parameters:
values (ndarray)
theta (Any)
exclude_chrom (Any)
- Return type:
ndarray
- solve_ph(rhs_columns, phi, exclude_chrom=None, *, tol=0.0005, max_iter=None, initial=None, stats=None)
Solve projected
H z = P_C rhsfor one or many right-hand sides.initialis an optional warm start. Each column is validated against a zero start independently; a poor or invalid cached column is reset without affecting the other right-hand sides. Ifstatsis passed, it is populated with aggregate iteration and warm-start diagnostics.- Parameters:
rhs_columns (ndarray)
phi (Any)
exclude_chrom (Any)
tol (float)
max_iter (int | None)
initial (ndarray | None)
stats (dict[str, Any] | None)
- Return type:
ndarray
- test_scores(chrom, vector)
Return BOLT-normalised test-genotype scores for one chromosome.
- Parameters:
chrom (Any)
vector (ndarray)
- Return type:
ndarray
- test_column(chrom, local_idx)
Return one projected, BOLT-normalised test-genotype column.
- Parameters:
chrom (Any)
local_idx (int)
- Return type:
ndarray
- chromosome_frequencies(chrom)
Return sample allele frequencies for one chromosome in operator order.
- Parameters:
chrom (Any)
- Return type:
ndarray
- local_indices(chrom)
Return mutation identifiers for a chromosome in operator order.
- Parameters:
chrom (Any)
- Return type:
ndarray
- kernel_trace(theta, exclude_chrom=None)
Return
tr(P_C K P_C)without constructing a dense kernel.- Parameters:
theta (Any)
exclude_chrom (Any)
- Return type:
float
- dense_kernel(theta, exclude_chrom=None)
Materialise a kernel for a small dense input or a test oracle.
- Parameters:
theta (Any)
exclude_chrom (Any)
- Return type:
ndarray
- class evo_lmm.VariantData(frequencies, local_idx, raw_norm2=None, centered_norm2=None)
Bases:
objectCached per-variant information used by an evolutionary operator.
frequenciesare sample allele frequencies andlocal_idxare the mutation identifiers in the source chromosome.raw_norm2andcentered_norm2are optional because GRGL operators can obtain them via graph traversals when needed.- Parameters:
frequencies (ndarray)
local_idx (ndarray)
raw_norm2 (ndarray | None)
centered_norm2 (ndarray | None)
Fitting results#
- class evo_lmm.FitResult(prior, sigma_b2, sigma_e2, delta, h2, log_likelihood, fixed_effects, projected_phenotype, ph_y, diagnostics, model, ops=None)
Bases:
objectScientific-scale fit result for an evolutionary LMM.
- Parameters:
prior (EvolutionaryPrior)
sigma_b2 (float)
sigma_e2 (float)
delta (float)
h2 (float)
log_likelihood (float)
fixed_effects (ndarray)
projected_phenotype (ndarray)
ph_y (ndarray)
diagnostics (FitDiagnostics)
model (str)
ops (Any)
- property sigma_g2: float
Compatibility alias; unlike GRAPP this is raw-effect
sigma_b2.
- blup()
Return the projected genetic-value BLUP
sigma_b2 K P_V y.- Return type:
ndarray
- class evo_lmm.FitDiagnostics(convergence, trace_estimator, trace_probes, objective=nan, initialization='default', trace_operator_queries=0, trace_standard_errors=<factory>, cg_iterations=<factory>, cg_warm_start_hits=0, cg_warm_start_rejections=0, cg_initial_residual_norms=<factory>, cg_final_residual_norms=<factory>, random_seed=None, boundary_hits=(), warnings=())
Bases:
objectNumerical and identifiability diagnostics from a fit.
Convergence lives in
ConvergenceReportunderconvergence; the flat accessors below delegate to it so both fitters expose the same names.objectiveis the profiled REML objective or ``nan``. It is never a stand-in for something else: the stochastic paths do not evaluate a log-determinant, so they reportnanrather than a surrogate, and convergence is judged byconvergence.step_se_normin every path.- Parameters:
convergence (ConvergenceReport)
trace_estimator (str)
trace_probes (int)
objective (float)
initialization (str)
trace_operator_queries (int)
trace_standard_errors (dict[str, float])
cg_iterations (list[int])
cg_warm_start_hits (int)
cg_warm_start_rejections (int)
cg_initial_residual_norms (list[float])
cg_final_residual_norms (list[float])
random_seed (int | None)
boundary_hits (tuple[str, ...])
warnings (tuple[str, ...])
- class evo_lmm.AssociationResult(chrom, local_idx, score, beta, se, chisq, pvalue, chisq_linreg=None, pvalue_linreg=None, model_mask=None, frequencies=None, inverse_scale=nan, calibration_factor=nan)
Bases:
objectCompact BOLT-compatible association output for one chromosome block.
betaandseare in raw diploid-dosage effect units, matching the evolutionary model’ssigma_b2scale.scoreis the calibrated inverse-variance scorex_j^T V_loco^-1 yon the BOLT-normalised test column. Entries excluded bymodel_mask(monomorphic or covariate-collinear columns) carrynanstatistics andpvalue = 1.- Parameters:
chrom (Any)
local_idx (ndarray)
score (ndarray)
beta (ndarray)
se (ndarray)
chisq (ndarray)
pvalue (ndarray)
chisq_linreg (ndarray | None)
pvalue_linreg (ndarray | None)
model_mask (ndarray | None)
frequencies (ndarray | None)
inverse_scale (float)
calibration_factor (float)
- good()
Return the boolean mask of variants with reportable statistics.
- Return type:
ndarray
Association and calibration#
- class evo_lmm.CalibrationResult(factor, std, ratio_of_medians, median_of_ratios, selected, tried, prospective, retrospective, inverse_scale, residuals=<factory>, quadratic_form=<factory>, screen_threshold=5.0, seed=0)
Bases:
objectProspective/retrospective calibration of the evolutionary LMM statistic.
- Parameters:
factor (float)
std (float)
ratio_of_medians (float)
median_of_ratios (float)
selected (tuple[tuple[Any, int], ...])
tried (int)
prospective (ndarray)
retrospective (ndarray)
inverse_scale (dict[Any, float])
residuals (dict[Any, ndarray])
quadratic_form (dict[Any, float])
screen_threshold (float)
seed (int)
- factor
The applied calibration factor: the ratio of prospective to retrospective statistic sums, or the ratio of medians when the jackknife standard error exceeds
CALIBRATION_STD_LIMIT.- Type:
float
- inverse_scale
Per-chromosome
VinvScaleFactorin raw-effect units. A tested chromosome’s calibrated inverse-variance score is(x_j^T H_loco^-1 P y) / sigma_b2 / inverse_scale[chrom].- Type:
dict[Any, float]
- residuals
H_loco^-1 P_C yfor each left-out chromosome, reused byevo_lmm.association()so the solves are not repeated.- Type:
dict[Any, numpy.ndarray]
- class evo_lmm.TestVariantStats(chrom, local_idx, centered_norm2, projected_norm2, test_scale, norm_scale, std_projected_norm2, model_mask)
Bases:
objectPer-variant tested-genotype statistics for one chromosome block.
All quantities are computed after the covariate projection
P_C. Thetest_scaleis the BOLT normalisationsqrt(centered_norm2 / (n - 1))applied to raw diploid dosage columns, sonorm_scale = 1 / test_scaleconverts a raw-dosage quantity into BOLT-normalised units. Nothing here depends on the fitted evolutionary prior.- Parameters:
chrom (Any)
local_idx (ndarray)
centered_norm2 (ndarray)
projected_norm2 (ndarray)
test_scale (ndarray)
norm_scale (ndarray)
std_projected_norm2 (ndarray)
model_mask (ndarray)
- projected_norm2
||P_C x_j||^2in raw diploid dosage units.- Type:
numpy.ndarray
- std_projected_norm2
||P_C x_j||^2in BOLT-normalised units, i.e.projected_norm2 * norm_scale**2.- Type:
numpy.ndarray
- model_mask
Variants eligible for association output; monomorphic and covariate-collinear columns are excluded exactly as in GRAPP.
- Type:
numpy.ndarray
- evo_lmm.calibrate_association(result, y=None, *, count=30, seed=0, screen_threshold=5.0, cg_tol=0.0005, stats=None)
Calibrate the LMM statistic against the fitted evolutionary covariance.
For every selected variant
jon its own chromosomecthe retrospective and prospective statistics areretro = (N - C) * (x_j^T u_c)^2 / (||u_c||^2 * ||x_j||^2)pro = (N - C) * (x_j^T u_c)^2 / (x_j^T H_c^-1 x_j) / (y^T u_c)with
u_c = H_c^-1 P_C yandH_cthe LOCO evolutionary shape matrix. Both are invariant tosigma_b2, so the factor is a pure shape correction;sigma_b2enters only throughinverse_scale.- Parameters:
result (FitResult)
y (ndarray | None)
count (int)
seed (int)
screen_threshold (float)
cg_tol (float)
stats (dict[Any, TestVariantStats] | None)
- Return type:
- evo_lmm.select_calibration_variants(result, *, count=30, seed=0, screen_threshold=5.0, stats=None)
Select calibration variants with BOLT’s blocked GRAMMAR pre-screen.
Eligible variants are split into
countequal blocks in chromosome order. One variant is drawn uniformly from each block and accepted when its all-chromosome GRAMMAR retrospective statistic falls belowscreen_threshold, which keeps strongly associated variants out of the calibration set. Returns the selected(chrom, local_idx)pairs and the number of candidates examined.- Parameters:
result (FitResult)
count (int)
seed (int)
screen_threshold (float)
stats (dict[Any, TestVariantStats] | None)
- Return type:
tuple[list[tuple[Any, int]], int]
- evo_lmm.association(result, y=None, *, use_loco=True, calibrate=True, calibration=None, calibration_variants=30, seed=0, screen_threshold=5.0, cg_tol=0.0005)
Compute calibrated BOLT-style association statistics per chromosome.
The mixed-model statistic uses the fitted evolutionary LOCO covariance
V_loco = sigma_b2 * (K_evo,loco + delta I)while the tested columns keep GRAPP’s independent BOLT normalisation. Withcalibrate=Truethe prospective/retrospective moment matching ofevo_lmm.calibrate_association()supplies the per-chromosome inverse scale; otherwise the uncalibrated (factor = 1) scale is used, which is only appropriate for diagnostics.betaandseare returned in raw diploid-dosage units. A single-variant linear-regression chi-square is reported alongside the mixed model statistic so inflation can be compared directly.- Parameters:
result (FitResult)
y (ndarray | None)
use_loco (bool)
calibrate (bool)
calibration (CalibrationResult | None)
calibration_variants (int)
seed (int)
screen_threshold (float)
cg_tol (float)
- Return type:
list[AssociationResult]
- evo_lmm.association_summary(results)
Return mean chi-square and lambda_GC for the mixed model and linreg.
lambda_gcdivides the median chi-square by the median of a one-degree-of-freedom chi-square, so a calibrated null gives values near one for both statistics.- Parameters:
results (Sequence[AssociationResult])
- Return type:
dict[str, dict[str, float]]