apbase.cross_variogram

Cross-variogram fitting and secondary-variable screening for cokriging.

Runs before apbase.cokriging: fits a generic cross-variogram model between any two variables, and screens candidate secondary variables against a primary via a Fisher z-test (significance) and a Cauchy-Schwarz check (admissibility).

class apbase.cross_variogram.CovariateReport(rho, p_value, admissible_fraction, n_pairs, decision, status, model_params)

Bases: object

Screening outcome for one candidate secondary variable.

Parameters:
  • rho (float)

  • p_value (float)

  • admissible_fraction (float)

  • n_pairs (int)

  • decision (bool)

  • status (str)

  • model_params (dict[str, float | int | str] | None)

rho: float
p_value: float
admissible_fraction: float
n_pairs: int
decision: bool
status: str
model_params: dict[str, float | int | str] | None
class apbase.cross_variogram.CrossVariogram(*, n_lags=50, max_pairs=100000, max_distance=0.0, max_colocation_dist=None)

Bases: object

Fit an empirical cross-variogram model between two variables.

Symmetric in a/b – no fixed primary/secondary role. Used by screen_secondary_variables() and by CoKriging’s ICM/LMC fit for every variable pair.

a and b may be sampled at different coordinates: the native fit pairs them via nearest-neighbor join, accepting a match within max_colocation_dist.

Parameters:
  • n_lags (int) – Same meaning as Variogram, applied to the paired sample.

  • max_pairs (int) – Same meaning as Variogram, applied to the paired sample.

  • max_distance (float) – Same meaning as Variogram, applied to the paired sample.

  • max_colocation_dist (float | None) – Maximum distance accepted by the nearest-neighbor join. None requires an exact coincidence.

Examples

>>> import numpy as np
>>> from apbase.cross_variogram import CrossVariogram
>>> xa = np.ascontiguousarray([0.0, 10.0, 0.0, 10.0, 5.0])
>>> ya = np.ascontiguousarray([0.0, 0.0, 10.0, 10.0, 5.0])
>>> za = np.ascontiguousarray([5.0, 7.0, 8.0, 10.0, 6.5])
>>> zb = np.ascontiguousarray([1.2, 1.6, 1.7, 2.1, 1.4])
>>> cross = CrossVariogram(n_lags=4).fit(xa, ya, za, xa, ya, zb)
>>> cross.rho > 0.0
True
property n_lags: int

Number of lag bins used by the native fitter.

Returns:

Lag bin count.

Return type:

int

property max_pairs: int

Maximum sampled colocated point pairs.

Returns:

Pair sampling cap; 0 means all eligible pairs subject to the native ceiling.

Return type:

int

property max_distance: float

Maximum pair distance considered by the fitter.

Returns:

Distance cutoff in coordinate units; 0.0 uses the native default extent.

Return type:

float

property max_colocation_dist: float | None

Maximum nearest-neighbor distance accepted for colocating samples.

Returns:

Distance tolerance, or None for exact coordinate coincidence.

Return type:

float or None

property n_threads: int

OpenMP thread count used by native cross-variogram routines.

Returns:

Current value resolved from apbase.config.

Return type:

int

classmethod from_data(xa, ya, za, xb, yb, zb, **kwargs)

Create and fit a cross-variogram from source data.

Parameters:
  • xa (array_like) – First variable coordinates and values.

  • ya (array_like) – First variable coordinates and values.

  • za (array_like) – First variable coordinates and values.

  • xb (array_like) – Second variable coordinates and values.

  • yb (array_like) – Second variable coordinates and values.

  • zb (array_like) – Second variable coordinates and values.

  • **kwargs – Keyword arguments forwarded to CrossVariogram.

Returns:

Fitted cross-variogram.

Return type:

CrossVariogram

property is_fitted: bool

Whether a cross-variogram fit is available.

Returns:

True after fit() succeeds.

Return type:

bool

property model_values: ndarray

[model_id, nugget, partial_sill, range, sse].

nugget/partial_sill may be negative for a negatively-correlated pair – unlike an auto-variogram, a cross-variogram is not required to be a valid direct covariance on its own. Available whenever the fit found at least 3 populated lag bins, even if the winning model later turns out invalid for model_params/evaluate() (e.g. range collapsing to 0) – see n_pairs to check whether the colocated sample was even large enough to attempt a fit.

Returns:

Native cross-variogram model vector.

Return type:

numpy.ndarray

Type:

Native model vector

property model_params: dict[str, float | int | str]

Readable parameters for the selected cross-variogram model.

Raises the same way Variogram does when the fit degenerated (e.g. too few colocated pairs to populate 3 lag bins). Callers that need to handle a degenerate fit without raising (like screen_secondary_variables()) should check n_pairs before reading this.

Returns:

Model id/name, nugget, partial sill, sill, range, and SSE.

Return type:

dict

property rho: float

Pearson correlation over the paired colocated sample.

Returns:

Correlation coefficient.

Return type:

float

property n_pairs: int

Number of colocated pairs found by the nearest-neighbor join.

Returns:

Count of paired finite samples.

Return type:

int

fit(xa, ya, za, xb, yb, zb)

Fit the cross-variogram model between a and b.

Parameters:
  • xa (array_like) – First variable coordinates and values.

  • ya (array_like) – First variable coordinates and values.

  • za (array_like) – First variable coordinates and values.

  • xb (array_like) – Second variable coordinates and values.

  • yb (array_like) – Second variable coordinates and values.

  • zb (array_like) – Second variable coordinates and values.

Returns:

Fitted cross-variogram. Non-finite rows are ignored separately on each variable before colocated pairing.

Return type:

CrossVariogram

Raises:

ValueError – If either variable has invalid sizes or no finite rows.

Notes

Rows where xa/ya/za (or xb/yb/zb) are NaN or infinite are ignored on their respective side before pairing.

evaluate(distance)

Evaluate the fitted cross-semivariance at one or more distances.

Parameters:

distance (array_like) – Distances in the same coordinate units used during fitting.

Returns:

Cross-semivariance values with the same shape as distance.

Return type:

numpy.ndarray

class apbase.cross_variogram.ScreeningResult(selected, report)

Bases: object

Result of screen_secondary_variables().

Parameters:
  • selected (dict[str, tuple[ArrayLike, ArrayLike, ArrayLike]])

  • report (dict[str, CovariateReport])

selected: dict[str, tuple[ArrayLike, ArrayLike, ArrayLike]]
report: dict[str, CovariateReport]
apbase.cross_variogram.screen_secondary_variables(x0, y0, z0, candidates, *, alpha=0.05, correction='bonferroni', min_abs_rho=0.3, max_violation_fraction=0.1, max_colocation_dist=None, n_lags=50, max_pairs=100000, max_distance=0.0)

Test each candidate secondary variable for admissible use in cokriging.

Runs, per candidate: a Fisher z-test on the primary<->candidate correlation (Fisher1921) and a Cauchy-Schwarz admissibility check on the fitted cross-variogram (Journel1978, Myers1982). A candidate is kept only if both the correlation is significant (and practically relevant, via min_abs_rho) and the cross-variogram is admissible.

Parameters:
  • x0 (ArrayLike) – Primary variable source coordinates and values.

  • y0 (ArrayLike) – Primary variable source coordinates and values.

  • z0 (ArrayLike) – Primary variable source coordinates and values.

  • candidates (dict[str, tuple[ArrayLike, ArrayLike, ArrayLike]]) – Mapping of candidate name to (x, y, z) source arrays.

  • alpha (float) – Significance level for the Fisher z-test, per candidate before correction.

  • correction (Literal['bonferroni', 'none']) – "bonferroni" (default when len(candidates) > 1) divides alpha by the candidate count to control the family-wise false-positive rate; "none" tests each candidate at alpha directly.

  • min_abs_rho (float) – Practical-significance threshold: a candidate is rejected even with a significant p-value if |rho| < min_abs_rho.

  • max_violation_fraction (float) – Maximum fraction of evaluated lags allowed to violate the Cauchy-Schwarz bound before a candidate is rejected as inadmissible.

  • max_colocation_dist (float | None) – Passed through to CrossVariogram for the primary<->candidate pairing. None requires an exact coincidence.

  • n_lags (int) – Passed through to both the primary/candidate Variogram fits and the CrossVariogram fit.

  • max_pairs (int) – Passed through to both the primary/candidate Variogram fits and the CrossVariogram fit.

  • max_distance (float) – Passed through to both the primary/candidate Variogram fits and the CrossVariogram fit.

Returns:

selected: subset of candidates that passed both tests, ready for CoKriging(...).fit(x0, y0, z0, secondaries=result.selected). report: per-candidate diagnostics (rho, p-value, admissible fraction, decision, status) for every candidate, kept or not.

Return type:

ScreeningResult

Notes

A candidate rejected for “insufficient sample” (fewer than 4 colocated pairs) or an invalid fitted model is recorded in report with decision=False and the reason in status – it does not raise.

Examples

>>> result = screen_secondary_variables(x0, y0, z0, {"ndvi": (xn, yn, zn)})
>>> result.selected
{'ndvi': (xn, yn, zn)}