Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
09c08d3
first version of Simplecollocated CoKriging with markov Model 1
n0228a Aug 25, 2025
6548b05
Merge branch 'GeoStat-Framework:main' into main
n0228a Aug 25, 2025
d76da40
Add collocated cokriging implementation (SCCK and ICCK)
n0228a Sep 21, 2025
399ab57
Implement simple SCCK (Simple Collocated Cokriging)
n0228a Sep 21, 2025
482214b
Finished SCCK, example shows variance inflation problem in SCCK
n0228a Sep 26, 2025
39dde82
Merge pull request #1 from n0228a/feature/collocated-cokriging
n0228a Sep 26, 2025
2a4ff26
deleted debugging test prints
n0228a Sep 26, 2025
d621f7f
Implement ICCK (Intrinsic Collocated Cokriging) with comprehensive te…
n0228a Sep 27, 2025
58afebd
Refactor cokriging: Unified CollocatedCokriging base class
n0228a Sep 27, 2025
aeb55e8
fixed variance calculation and cokriging tests with examples
n0228a Oct 6, 2025
6bf2e88
small fixes
n0228a Oct 6, 2025
e310d4c
renaming of variables and consolidating test file
n0228a Oct 7, 2025
53e8ad3
cleaned up examples and fixed import in init.py
n0228a Oct 7, 2025
e591031
updated cokriging tests to only test additional capabilities
n0228a Oct 8, 2025
0ffb9fd
small description fixes and fixed example design
n0228a Oct 8, 2025
0ff71a3
Update test_cokriging.py
n0228a Oct 8, 2025
08d9079
update init with cokrige and documentation with math environment
n0228a Oct 16, 2025
c230243
apply intrinsic method added and more math annotations
n0228a Oct 16, 2025
8371c80
fixed formula for mm1
n0228a Oct 16, 2025
5b5b3eb
fix math
n0228a Oct 16, 2025
4142adc
Refactor: Add Correlogram architecture for extensible cokriging
n0228a Oct 17, 2025
f921e58
docs: Add comprehensive correlogram architecture documentation
n0228a Oct 17, 2025
ad846ec
deleted
n0228a Oct 28, 2025
77ab419
linter fixes
n0228a Oct 28, 2025
871834d
Delete CORRELOGRAM_ARCHITECTURE.md
n0228a Oct 28, 2025
eca9e70
Merge pull request #2 from n0228a/feature/correlogram-architecture
n0228a Oct 28, 2025
686880b
Revert "Feature/correlogram architecture"
n0228a Oct 28, 2025
acdab79
Merge pull request #3 from n0228a/revert-2-feature/correlogram-archit…
n0228a Oct 28, 2025
a1d2d89
fixed old code and removed comments
n0228a Oct 28, 2025
919dc9b
fix documentation and API in tests
n0228a Oct 30, 2025
7d043b3
Merge feature/correlogram-architecture: Add Correlogram architecture …
n0228a Oct 30, 2025
60953e0
Complete merge: Add missing __init__.py exports and example updates
n0228a Oct 30, 2025
49a2ec7
ruff formatting
n0228a Nov 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions examples/05_kriging/10_simple_collocated_cokriging.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
r"""
Simple Collocated Cokriging
----------------------------

Simple collocated cokriging uses secondary data at the estimation location
to improve the primary variable estimate.

This example demonstrates the new correlogram-based API using MarkovModel1,
which encapsulates the Markov Model I (MM1) cross-covariance structure.

Example
^^^^^^^

Here we compare Simple Kriging with Simple Collocated Cokriging using the
new MarkovModel1 correlogram.
"""

import matplotlib.pyplot as plt
import numpy as np

from gstools import Gaussian, MarkovModel1, krige
from gstools.cokriging import SimpleCollocated

# condtions
np.random.seed(4)
cond_pos = np.array([0.5, 2.1, 3.8, 6.2, 13.5])
cond_val = np.array([0.8, 1.2, 1.8, 2.1, 1.4])
gridx = np.linspace(0.0, 15.0, 151)
model = Gaussian(dim=1, var=0.5, len_scale=2.0)

###############################################################################
# Generate correlated secondary data

sec_pos = np.linspace(0, 15, 31)
primary_trend = np.interp(sec_pos, cond_pos, cond_val)
gap_feature = -1.6 * np.exp(-(((sec_pos - 10.0) / 2.0) ** 2))
gap_feature2 = -0.95 * np.exp(-(((sec_pos - 4.0) / 2.0) ** 2))
sec_val = 0.99 * primary_trend + gap_feature + gap_feature2

sec_grid = np.interp(gridx, sec_pos, sec_val)
sec_at_primary = np.interp(cond_pos, sec_pos, sec_val)

###############################################################################
# Simple Kriging and Simple Collocated Cokriging

sk = krige.Simple(model, cond_pos=cond_pos, cond_val=cond_val, mean=1.0)
sk_field, sk_var = sk(gridx, return_var=True)

# Compute cross-correlation from data
cross_corr = np.corrcoef(cond_val, sec_at_primary)[0, 1]

# Create MarkovModel1 correlogram (NEW API)
correlogram = MarkovModel1(
primary_model=model,
cross_corr=cross_corr,
secondary_var=np.var(sec_val),
primary_mean=1.0,
secondary_mean=np.mean(sec_val),
)

# Simple Collocated Cokriging with new API
scck = SimpleCollocated(correlogram, cond_pos=cond_pos, cond_val=cond_val)
scck_field, scck_var = scck(gridx, secondary_data=sec_grid, return_var=True)

###############################################################################

fig, ax = plt.subplots(1, 2, figsize=(10, 3.5))

ax[0].scatter(cond_pos, cond_val, color="red", label="Primary data")
ax[0].scatter(
cond_pos,
sec_at_primary,
color="blue",
marker="s",
label="Secondary at primary",
)
ax[0].plot(sec_pos, sec_val, "b-", alpha=0.6, label="Secondary data")
ax[0].legend()

ax[1].plot(gridx, sk_field, label="Simple Kriging")
ax[1].plot(gridx, scck_field, label="Simple Collocated Cokriging")
ax[1].scatter(cond_pos, cond_val, color="k", zorder=10, label="Conditions")
ax[1].legend()

plt.tight_layout()
plt.show()
95 changes: 95 additions & 0 deletions examples/05_kriging/11_intrinsic_collocated_cokriging.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
r"""
Intrinsic Collocated Cokriging
-------------------------------

Intrinsic Collocated Cokriging (ICCK) improves variance estimation
compared to Simple Collocated Cokriging.

This example demonstrates the new correlogram-based API using MarkovModel1.

The variance formula is:

.. math:: \sigma^2_{ICCK} = (1 - \rho_0^2) \cdot \sigma^2_{SK}

Example
^^^^^^^

Here we compare Simple Kriging with Intrinsic Collocated Cokriging using the
new MarkovModel1 correlogram.
"""

import matplotlib.pyplot as plt
import numpy as np

from gstools import Gaussian, MarkovModel1, krige
from gstools.cokriging import IntrinsicCollocated

# condtions
np.random.seed(4)
cond_pos = np.array([0.5, 2.1, 3.8, 6.2, 13.5])
cond_val = np.array([0.8, 1.2, 1.8, 2.1, 1.4])
gridx = np.linspace(0.0, 15.0, 151)
model = Gaussian(dim=1, var=0.5, len_scale=2.0)

###############################################################################
# Generate correlated secondary data

sec_pos = np.linspace(0, 15, 31)
primary_trend = np.interp(sec_pos, cond_pos, cond_val)
gap_feature = -1.6 * np.exp(-(((sec_pos - 10.0) / 2.0) ** 2))
gap_feature2 = -0.95 * np.exp(-(((sec_pos - 4.0) / 2.0) ** 2))
sec_val = 0.99 * primary_trend + gap_feature + gap_feature2

sec_grid = np.interp(gridx, sec_pos, sec_val)
sec_at_primary = np.interp(cond_pos, sec_pos, sec_val)

###############################################################################
# Simple Kriging and Intrinsic Collocated Cokriging

sk = krige.Simple(model, cond_pos=cond_pos, cond_val=cond_val, mean=1.0)
sk_field, sk_var = sk(gridx, return_var=True)

# Compute cross-correlation from data
cross_corr = np.corrcoef(cond_val, sec_at_primary)[0, 1]

# Create MarkovModel1 correlogram (NEW API)
correlogram = MarkovModel1(
primary_model=model,
cross_corr=cross_corr,
secondary_var=np.var(sec_val),
primary_mean=1.0,
secondary_mean=np.mean(sec_val),
)

# Intrinsic Collocated Cokriging with new API
icck = IntrinsicCollocated(
correlogram,
cond_pos=cond_pos,
cond_val=cond_val,
secondary_cond_pos=cond_pos,
secondary_cond_val=sec_at_primary,
)
icck_field, icck_var = icck(gridx, secondary_data=sec_grid, return_var=True)

###############################################################################

fig, ax = plt.subplots(1, 2, figsize=(10, 3.5))

ax[0].scatter(cond_pos, cond_val, color="red", label="Primary data")
ax[0].scatter(
cond_pos,
sec_at_primary,
color="blue",
marker="s",
label="Secondary at primary",
)
ax[0].plot(sec_pos, sec_val, "b-", alpha=0.6, label="Secondary data")
ax[0].legend()

ax[1].plot(gridx, sk_field, label="Simple Kriging")
ax[1].plot(gridx, icck_field, label="Intrinsic Collocated Cokriging")
ax[1].scatter(cond_pos, cond_val, color="k", zorder=10, label="Conditions")
ax[1].legend()

plt.tight_layout()
plt.show()
33 changes: 31 additions & 2 deletions src/gstools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
field
variogram
krige
cokriging
random
tools
transform
Expand All @@ -36,6 +37,17 @@
.. autosummary::
Krige

Cokriging
^^^^^^^^^
Collocated cokriging methods for multivariate estimation

.. currentmodule:: gstools.cokriging

.. autosummary::
SimpleCollocated
IntrinsicCollocated
MarkovModel1

Spatial Random Field
^^^^^^^^^^^^^^^^^^^^
Classes for (conditioned) random field generation
Expand Down Expand Up @@ -134,17 +146,23 @@
"""

# Hooray!
from gstools import (
from gstools import ( # noqa: I001
config,
covmodel,
field,
krige,
cokriging,
normalizer,
random,
tools,
transform,
variogram,
)
from gstools.cokriging import (
IntrinsicCollocated,
MarkovModel1,
SimpleCollocated,
)
from gstools.covmodel import (
Circular,
CovModel,
Expand Down Expand Up @@ -199,7 +217,15 @@
__version__ = "0.0.0.dev0"

__all__ = ["__version__"]
__all__ += ["covmodel", "field", "variogram", "krige", "random", "tools"]
__all__ += [
"covmodel",
"field",
"variogram",
"krige",
"cokriging",
"random",
"tools",
]
__all__ += ["transform", "normalizer", "config"]
__all__ += [
"CovModel",
Expand Down Expand Up @@ -234,6 +260,9 @@

__all__ += [
"Krige",
"SimpleCollocated",
"IntrinsicCollocated",
"MarkovModel1",
"SRF",
"CondSRF",
"PGS",
Expand Down
36 changes: 36 additions & 0 deletions src/gstools/cokriging/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""
GStools subpackage providing cokriging.

.. currentmodule:: gstools.cokriging

Cokriging Classes
^^^^^^^^^^^^^^^^^

.. autosummary::
:toctree:

CollocatedCokriging
SimpleCollocated
IntrinsicCollocated

Correlogram Models
^^^^^^^^^^^^^^^^^^

.. autosummary::
:toctree:

Correlogram
MarkovModel1
"""

from gstools.cokriging.base import CollocatedCokriging
from gstools.cokriging.correlogram import Correlogram, MarkovModel1
from gstools.cokriging.methods import IntrinsicCollocated, SimpleCollocated

__all__ = [
"CollocatedCokriging",
"SimpleCollocated",
"IntrinsicCollocated",
"Correlogram",
"MarkovModel1",
]
Loading
Loading