Skip to content

Commit c230243

Browse files
committed
apply intrinsic method added and more math annotations
1 parent 08d9079 commit c230243

File tree

2 files changed

+42
-27
lines changed

2 files changed

+42
-27
lines changed

src/gstools/cokriging/base.py

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ class CollocatedCokriging(Krige):
2727
2828
Both variants assume the cross-covariance follows:
2929
30-
C_YZ(h) = ρ_YZ(0) · √(C_Z(h) · C_Y(h))
30+
.. math::
31+
C_{YZ}(h) = \\rho_{YZ}(0) \\cdot \\sqrt{C_Z(h) \\cdot C_Y(h)}
3132
32-
where ρ_YZ(0) is the cross-correlation at zero lag. This assumption
33+
where :math:`\\rho_{YZ}(0)` is the cross-correlation at zero lag. This assumption
3334
requires that primary and secondary variables have similar spatial
3435
correlation structures. Violations of MM1 can lead to suboptimal
3536
estimates and unreliable variance.
@@ -38,11 +39,11 @@ class CollocatedCokriging(Krige):
3839
3940
- **Simple Collocated** ("simple"):
4041
Uses only collocated secondary at estimation point. Simpler but
41-
may show variance inflation (σ²_SCCK > σ²_SK).
42+
may show variance inflation :math:`\\sigma^2_{\\text{SCCK}} > \\sigma^2_{\\text{SK}}`.
4243
4344
- **Intrinsic Collocated** ("intrinsic"):
4445
Uses collocated secondary plus secondary at all primary locations.
45-
Provides accurate variance: σ²_ICCK = (1-ρ₀²)·σ²_SK ≤ σ²_SK.
46+
Provides accurate variance: :math:`\\sigma^2_{\\text{ICCK}} = (1-\\rho_0^2) \\cdot \\sigma^2_{\\text{SK}} \\leq \\sigma^2_{\\text{SK}}`.
4647
4748
Parameters
4849
----------
@@ -235,27 +236,13 @@ def __call__(self, pos=None, secondary_data=None, **kwargs):
235236
sk_field, sk_var = super().__call__(pos=pos, **kwargs_with_var)
236237
secondary_data = np.asarray(secondary_data, dtype=np.double)
237238

239+
# apply algorithm-specific post-processing
238240
if self.algorithm == "simple":
239241
cokriging_field, cokriging_var = self._apply_simple_collocated(
240242
sk_field, sk_var, secondary_data, user_return_var)
241243
elif self.algorithm == "intrinsic":
242-
# apply collocated secondary contribution
243-
collocated_contribution = self._lambda_Y0 * (
244-
secondary_data - self.secondary_mean)
245-
cokriging_field = sk_field + collocated_contribution
246-
247-
# compute intrinsic variance
248-
if user_return_var:
249-
C_Z0, C_Y0, C_YZ0 = self._compute_covariances()
250-
if C_Y0 * C_Z0 < 1e-15:
251-
rho_squared = 0.0
252-
else:
253-
rho_squared = (C_YZ0**2) / (C_Y0 * C_Z0)
254-
icck_var = (1.0 - rho_squared) * sk_var
255-
icck_var = np.maximum(0.0, icck_var)
256-
cokriging_var = icck_var
257-
else:
258-
cokriging_var = None
244+
cokriging_field, cokriging_var = self._apply_intrinsic_collocated(
245+
sk_field, sk_var, secondary_data, user_return_var)
259246
else:
260247
raise ValueError(f"Unknown algorithm: {self.algorithm}")
261248

@@ -292,6 +279,34 @@ def _apply_simple_collocated(self, sk_field, sk_var, secondary_data, return_var)
292279
scck_variance = None
293280
return scck_field, scck_variance
294281

282+
def _apply_intrinsic_collocated(self, sk_field, sk_var, secondary_data, return_var):
283+
"""
284+
Apply intrinsic collocated cokriging.
285+
286+
Adds the collocated secondary contribution at estimation locations
287+
and computes ICCK variance.
288+
289+
Note: The secondary-at-primary contribution is already added during
290+
the kriging solve in _summate().
291+
"""
292+
# apply collocated secondary contribution
293+
collocated_contribution = self._lambda_Y0 * (
294+
secondary_data - self.secondary_mean)
295+
icck_field = sk_field + collocated_contribution
296+
297+
# compute intrinsic variance
298+
if return_var:
299+
C_Z0, C_Y0, C_YZ0 = self._compute_covariances()
300+
if C_Y0 * C_Z0 < 1e-15:
301+
rho_squared = 0.0
302+
else:
303+
rho_squared = (C_YZ0**2) / (C_Y0 * C_Z0)
304+
icck_var = (1.0 - rho_squared) * sk_var
305+
icck_var = np.maximum(0.0, icck_var)
306+
else:
307+
icck_var = None
308+
return icck_field, icck_var
309+
295310
def _summate(self, field, krige_var, c_slice, k_vec, return_var):
296311
"""Apply intrinsic collocated cokriging during kriging solve."""
297312
if self.algorithm == "simple":

src/gstools/cokriging/methods.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,11 @@ class SimpleCollocated(CollocatedCokriging):
7676
secondary_var : :class:`float`
7777
Variance of the secondary variable. Must be positive.
7878
mean : :class:`float`, optional
79-
Mean value for simple kriging (primary variable mean m_Z). Default: 0.0
79+
Mean value for simple kriging (primary variable mean :math:`m_Z`). Default: 0.0
8080
secondary_mean : :class:`float`, optional
81-
Mean value of the secondary variable (m_Y).
81+
Mean value of the secondary variable (:math:`m_Y`).
8282
Required for simple collocated cokriging to properly handle
83-
the anomaly-space formulation: Y(u) - m_Y.
83+
the anomaly-space formulation: :math:`Y(u) - m_Y`.
8484
Default: 0.0
8585
normalizer : :any:`None` or :any:`Normalizer`, optional
8686
Normalizer to be applied to the input data to gain normality.
@@ -242,11 +242,11 @@ class IntrinsicCollocated(CollocatedCokriging):
242242
secondary_var : :class:`float`
243243
Variance of the secondary variable. Must be positive.
244244
mean : :class:`float`, optional
245-
Mean value for simple kriging (primary variable mean m_Z). Default: 0.0
245+
Mean value for simple kriging (primary variable mean :math:`m_Z`). Default: 0.0
246246
secondary_mean : :class:`float`, optional
247-
Mean value of the secondary variable (m_Y).
247+
Mean value of the secondary variable (:math:`m_Y`).
248248
Required for intrinsic collocated cokriging to properly handle
249-
the anomaly-space formulation: Y(u) - m_Y.
249+
the anomaly-space formulation: :math:`Y(u) - m_Y`.
250250
Default: 0.0
251251
normalizer : :any:`None` or :any:`Normalizer`, optional
252252
Normalizer to be applied to the input data to gain normality.

0 commit comments

Comments
 (0)