1+ import numpy as np
2+ import pytest
3+ from spotpython .utils .sampling import mmphi_intensive_update
4+
5+ def test_mmphi_intensive_update_basic ():
6+ # 2 points in 2D
7+ X = np .array ([[0.0 , 0.0 ], [1.0 , 0.0 ]])
8+ new_point = np .array ([0.0 , 1.0 ])
9+ # Initial distances and multiplicities (only one pair: distance 1.0)
10+ d = np .array ([1.0 ])
11+ J = np .array ([1 ])
12+ q = 2.0
13+ p = 2.0
14+
15+ intensive_phiq , updated_J , updated_d = mmphi_intensive_update (X , new_point , J , d , q , p )
16+
17+ # There are now 3 points, so 3 pairs: (0,1), (0,2), (1,2)
18+ # Distances: (0,1): 1.0, (0,2): 1.0, (1,2): sqrt(2)
19+ expected_d = np .array ([1.0 , np .sqrt (2 )])
20+ expected_J = np .array ([2 , 1 ])
21+ assert np .allclose (np .sort (updated_d ), np .sort (expected_d ))
22+ assert np .sum (updated_J ) == 3 # 3 pairs
23+
24+ # Check the value is finite and positive
25+ assert intensive_phiq > 0
26+ assert np .isfinite (intensive_phiq )
27+
28+ def test_mmphi_intensive_update_single_point_raises ():
29+ X = np .empty ((0 , 2 ))
30+ new_point = np .array ([0.0 , 0.0 ])
31+ d = np .array ([])
32+ J = np .array ([])
33+ with pytest .raises (ValueError ):
34+ mmphi_intensive_update (X , new_point , J , d )
35+
36+ def test_mmphi_intensive_update_duplicate_distances ():
37+ """
38+ Test mmphi_intensive_update with duplicate distances.
39+ """
40+ X = np .array ([[0.0 ], [1.0 ], [2.0 ]])
41+ new_point = np .array ([3.0 ])
42+ d = np .array ([1.0 , 2.0 ])
43+ J = np .array ([2 , 1 ])
44+ q = 2.0
45+ p = 2.0
46+
47+ intensive_phiq , updated_J , updated_d = mmphi_intensive_update (X , new_point , J , d , q , p )
48+
49+ # Expected distances and counts
50+ expected_d = np .array ([1.0 , 2.0 , 3.0 ])
51+ expected_J = np .array ([3 , 2 , 1 ])
52+
53+ assert np .allclose (np .sort (updated_d ), np .sort (expected_d ))
54+ assert np .array_equal (updated_J , expected_J )
55+ assert np .sum (updated_J ) == 6 # 4 points, 6 pairs
56+
57+ # Check the value is finite and positive
58+ assert intensive_phiq > 0
59+ assert np .isfinite (intensive_phiq )
60+
61+ def test_mmphi_intensive_update_nondefault_q_p ():
62+ """
63+ Test mmphi_intensive_update with non-default values of q and p.
64+ """
65+ X = np .array ([[0.0 , 0.0 ], [1.0 , 1.0 ]])
66+ new_point = np .array ([0.0 , 2.0 ])
67+ d = np .array ([np .sqrt (2 )]) # Existing distances should remain unchanged
68+ J = np .array ([1 ]) # Existing counts should remain unchanged
69+ q = 1.0
70+ p = 1.0
71+
72+ intensive_phiq , updated_J , updated_d = mmphi_intensive_update (X , new_point , J , d , q , p )
73+
74+ # Expected distances and counts
75+ # Combine original distances with new distances calculated using Manhattan distance
76+ new_distances = np .array ([np .sum (np .abs (X [0 ] - new_point )), np .sum (np .abs (X [1 ] - new_point ))])
77+ all_distances = np .concatenate ((d , new_distances ))
78+ expected_d , expected_J = np .unique (all_distances , return_counts = True )
79+
80+ assert np .allclose (np .sort (updated_d ), np .sort (expected_d ))
81+ assert np .array_equal (updated_J , expected_J )
82+ assert np .sum (updated_J ) == len (all_distances ) # Total number of pairs
83+
84+ # Check the value is finite and positive
85+ assert intensive_phiq > 0
86+ assert np .isfinite (intensive_phiq )
0 commit comments