Skip to content

Commit eee94f9

Browse files
0.29.22
sampling fixed
1 parent 3321394 commit eee94f9

3 files changed

Lines changed: 26 additions & 11 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
77

88
[project]
99
name = "spotpython"
10-
version = "0.29.21"
10+
version = "0.29.22"
1111
authors = [
1212
{ name="T. Bartz-Beielstein", email="tbb@bartzundbartz.de" }
1313
]

src/spotpython/utils/sampling.py

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -883,7 +883,7 @@ def subset(X: np.ndarray, ns: int) -> Tuple[np.ndarray, np.ndarray]:
883883
return Xs, Xr
884884

885885

886-
def mmphi_intensive(X: np.ndarray, q: Optional[float] = 2.0, p: Optional[float] = 2.0) -> float:
886+
def mmphi_intensive(X: np.ndarray, q: Optional[float] = 2.0, p: Optional[float] = 2.0) -> tuple[float, np.ndarray, np.ndarray]:
887887
"""
888888
Calculates a size-invariant Morris-Mitchell criterion.
889889
@@ -902,8 +902,11 @@ def mmphi_intensive(X: np.ndarray, q: Optional[float] = 2.0, p: Optional[float]
902902
Defaults to 2.0.
903903
904904
Returns:
905-
float:
906-
The size-invariant space-fillingness metric. Smaller is better.
905+
tuple[float, np.ndarray, np.ndarray]:
906+
A tuple containing:
907+
- intensive_phiq: The intensive space-fillingness metric.
908+
- J: Multiplicities of distances.
909+
- d: Unique distances.
907910
908911
Examples:
909912
>>> import numpy as np
@@ -915,7 +918,7 @@ def mmphi_intensive(X: np.ndarray, q: Optional[float] = 2.0, p: Optional[float]
915918
... [1.0, 1.0]
916919
... ])
917920
>>> # Calculate the intensive space-fillingness metric with q=2, using Euclidean distances (p=2)
918-
>>> quality = mmphi_intensive(X, q=2, p=2)
921+
>>> quality, J, d = mmphi_intensive(X, q=2, p=2)
919922
>>> print(quality)
920923
"""
921924
# Ensure there are no duplicate points
@@ -926,14 +929,14 @@ def mmphi_intensive(X: np.ndarray, q: Optional[float] = 2.0, p: Optional[float]
926929

927930
# The criterion is not well-defined for fewer than 2 points.
928931
if n_points < 2:
929-
return np.inf
932+
return np.inf, 0, 0
930933

931934
# Get the unique distances and their multiplicities
932935
J, d = jd(X, p=p)
933936

934937
# If all points are identical, the design is infinitely bad.
935938
if d.size == 0:
936-
return np.inf
939+
return np.inf, J, d
937940

938941
# Calculate the number of unique pairs of points
939942
M = n_points * (n_points - 1) / 2
@@ -950,7 +953,7 @@ def mmphi_intensive(X: np.ndarray, q: Optional[float] = 2.0, p: Optional[float]
950953
except Exception:
951954
return np.inf
952955

953-
return intensive_phiq
956+
return intensive_phiq, J, d
954957

955958

956959
def mmphi_intensive_update(X: np.ndarray, new_point: np.ndarray, J: np.ndarray, d: np.ndarray, q: float = 2.0, p: float = 2.0) -> tuple[float, np.ndarray, np.ndarray]:
@@ -967,6 +970,18 @@ def mmphi_intensive_update(X: np.ndarray, new_point: np.ndarray, J: np.ndarray,
967970
968971
Returns:
969972
tuple[float, np.ndarray, np.ndarray]: Updated intensive_phiq, updated_J, updated_d.
973+
974+
Examples:
975+
>>> import numpy as np
976+
>>> from spotpython.utils.sampling import mmphi_intensive_update
977+
>>> # Existing design with 3 points in 2D
978+
>>> X = np.array([[0.0, 0.0], [0.5, 0.5], [1.0, 1.0]])
979+
>>> phiq, J, d = mmphi_intensive(X, q=2, p=2)
980+
>>> # New point to add
981+
>>> new_point = np.array([0.1, 0.1])
982+
>>> # Update the intensive criterion
983+
>>> updated_phiq, updated_J, updated_d = mmphi_intensive_update(X, new_point, J, d, q=2, p=2)
984+
970985
"""
971986
n_points = X.shape[0]
972987
if n_points < 1:

test/test_sampling_mmphi_intensive.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def real_jd(X, p=2.0):
2929
vals, counts = np.unique(np.round(dists, 8), return_counts=True)
3030
return counts, vals
3131
monkeypatch.setattr(sampling, "jd", real_jd)
32-
val = mmphi_intensive(X, q=2.0, p=2.0)
32+
val, J, d = mmphi_intensive(X, q=2.0, p=2.0)
3333
assert np.isscalar(val)
3434
assert val > 0
3535
if orig_jd:
@@ -39,11 +39,11 @@ def test_mmphi_intensive_duplicates(monkeypatch):
3939
# All points identical: should return np.inf
4040
X = np.ones((4, 2))
4141
monkeypatch.setattr(sampling, "jd", lambda X, p=2.0: (np.array([]), np.array([])))
42-
val = mmphi_intensive(X)
42+
val, J, d = mmphi_intensive(X)
4343
assert val == np.inf
4444

4545
def test_mmphi_intensive_too_few_points():
4646
# Only one point: should return np.inf
4747
X = np.array([[0.5, 0.5]])
48-
val = mmphi_intensive(X)
48+
val, J, d = mmphi_intensive(X)
4949
assert val == np.inf

0 commit comments

Comments
 (0)