Skip to content

Commit b67bd77

Browse files
0.34.7
1 parent 2250b58 commit b67bd77

7 files changed

Lines changed: 291 additions & 4 deletions

File tree

notebooks/00_spotPython_tests.ipynb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15154,6 +15154,21 @@
1515415154
"plt.show()"
1515515155
]
1515615156
},
15157+
{
15158+
"cell_type": "code",
15159+
"execution_count": 3,
15160+
"metadata": {},
15161+
"outputs": [],
15162+
"source": [
15163+
"from spotpython.utils.compare import selectNew\n",
15164+
"import numpy as np\n",
15165+
"A = np.array([[1,2,3],[4,5,7]])\n",
15166+
"X = np.array([[1,2,3],[4,5,6]])\n",
15167+
"B, ind = selectNew(A, X)\n",
15168+
"assert B.shape[0] == 1\n",
15169+
"assert np.equal(ind, np.array([False, True])).all()"
15170+
]
15171+
},
1515715172
{
1515815173
"cell_type": "code",
1515915174
"execution_count": null,
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# SPOT Kriging in 2 Dimensions: Nyström Approximation vs. Exact (Rosenbrock Function)\n",
8+
"\n",
9+
"This notebook demonstrates how to use the `Spot` class from `spotpython` with and without the Nyström approximation for Kriging surrogates on the 2-dimensional Rosenbrock function.\n",
10+
"\n",
11+
"We use a maximum of 100 function evaluations."
12+
]
13+
},
14+
{
15+
"cell_type": "code",
16+
"execution_count": null,
17+
"metadata": {},
18+
"outputs": [],
19+
"source": [
20+
"import numpy as np\n",
21+
"from spotpython.fun.objectivefunctions import Analytical\n",
22+
"from spotpython.spot import Spot\n",
23+
"from spotpython.utils.init import fun_control_init, design_control_init, surrogate_control_init"
24+
]
25+
},
26+
{
27+
"cell_type": "markdown",
28+
"metadata": {},
29+
"source": [
30+
"## Define the Rosenbrock Function"
31+
]
32+
},
33+
{
34+
"cell_type": "code",
35+
"execution_count": null,
36+
"metadata": {},
37+
"outputs": [],
38+
"source": [
39+
"# do not change, these are given by the organizers\n",
40+
"dim = 6\n",
41+
"lower = np.full(dim, -2)\n",
42+
"upper = np.full(dim, 2)\n",
43+
"fun = Analytical().fun_rosenbrock\n",
44+
"fun_evals = 100"
45+
]
46+
},
47+
{
48+
"cell_type": "markdown",
49+
"metadata": {},
50+
"source": [
51+
"## Set up SPOT Controls"
52+
]
53+
},
54+
{
55+
"cell_type": "markdown",
56+
"metadata": {},
57+
"source": [
58+
"## Aquisition Random and Regression and y as Infill Criterion"
59+
]
60+
},
61+
{
62+
"cell_type": "code",
63+
"execution_count": null,
64+
"metadata": {},
65+
"outputs": [],
66+
"source": [
67+
"init_size = 12\n",
68+
"use_nystrom = False\n",
69+
"method = \"regression\"\n",
70+
"infill_criterion = \"ei\"\n",
71+
"tolerance_x = 1e-6 # minimum distance in x for accepting new points\n",
72+
"seed = 321\n",
73+
"max_surrogate_points = 24\n",
74+
"min_Lambda = -6\n",
75+
"max_Lambda = 1\n",
76+
"min_theta = -3\n",
77+
"max_theta = 2\n",
78+
"isotropic = False\n",
79+
"optim_p = True\n",
80+
"min_success_rate = 0.10 # percent\n",
81+
"acquisition_failure_strategy = \"random\""
82+
]
83+
},
84+
{
85+
"cell_type": "code",
86+
"execution_count": null,
87+
"metadata": {},
88+
"outputs": [],
89+
"source": [
90+
"fun_control = fun_control_init(\n",
91+
" lower=lower,\n",
92+
" upper=upper,\n",
93+
" fun_evals=fun_evals,\n",
94+
" max_time=60,\n",
95+
" seed=seed,\n",
96+
" show_progress=True,\n",
97+
" infill_criterion=infill_criterion,\n",
98+
" min_success_rate=min_success_rate,\n",
99+
" tolerance_x=tolerance_x,\n",
100+
" TENSORBOARD_CLEAN=True,\n",
101+
" tensorboard_log=True,\n",
102+
" acquisition_failure_strategy=acquisition_failure_strategy,\n",
103+
")\n",
104+
"design_control = design_control_init(init_size=init_size)\n",
105+
"surrogate_control_exact = surrogate_control_init(use_nystrom=use_nystrom, \n",
106+
" optim_p=optim_p,\n",
107+
" method=method, max_surrogate_points=max_surrogate_points, min_Lambda=min_Lambda, max_Lambda=max_Lambda, min_theta=min_theta, max_theta=max_theta, isotropic=isotropic)\n",
108+
"spot_exact_random = Spot(\n",
109+
" fun=fun,\n",
110+
" fun_control=fun_control,\n",
111+
" design_control=design_control,\n",
112+
" surrogate_control=surrogate_control_exact\n",
113+
" )\n",
114+
"spot_exact_random.run()\n",
115+
"spot_exact_random.plot_progress(log_y=True, title=\"spotpython: Random Kriging\")"
116+
]
117+
},
118+
{
119+
"cell_type": "markdown",
120+
"metadata": {},
121+
"source": [
122+
"## Aquisition MM and Regression and y as Infill Criterion"
123+
]
124+
},
125+
{
126+
"cell_type": "code",
127+
"execution_count": null,
128+
"metadata": {},
129+
"outputs": [],
130+
"source": [
131+
"acquisition_failure_strategy = \"mm\""
132+
]
133+
},
134+
{
135+
"cell_type": "code",
136+
"execution_count": null,
137+
"metadata": {},
138+
"outputs": [],
139+
"source": [
140+
"fun_control = fun_control_init(\n",
141+
" lower=lower,\n",
142+
" upper=upper,\n",
143+
" fun_evals=fun_evals,\n",
144+
" max_time=60,\n",
145+
" seed=seed,\n",
146+
" show_progress=True,\n",
147+
" infill_criterion=infill_criterion,\n",
148+
" min_success_rate=min_success_rate,\n",
149+
" tolerance_x=tolerance_x,\n",
150+
" TENSORBOARD_CLEAN=True,\n",
151+
" tensorboard_log=True,\n",
152+
" acquisition_failure_strategy=acquisition_failure_strategy,\n",
153+
")\n",
154+
"design_control = design_control_init(init_size=init_size)\n",
155+
"surrogate_control_exact = surrogate_control_init(use_nystrom=use_nystrom, optim_p=optim_p, method=method, max_surrogate_points=max_surrogate_points, min_Lambda=min_Lambda, max_Lambda=max_Lambda, min_theta=min_theta, max_theta=max_theta, isotropic=isotropic)\n",
156+
"spot_exact_mm = Spot(\n",
157+
" fun=fun,\n",
158+
" fun_control=fun_control,\n",
159+
" design_control=design_control,\n",
160+
" surrogate_control=surrogate_control_exact\n",
161+
")\n",
162+
"spot_exact_mm.run()\n",
163+
"spot_exact_mm.plot_progress(log_y=True, title=\"spotpython: Morris-Mitchell Kriging.\")"
164+
]
165+
},
166+
{
167+
"cell_type": "markdown",
168+
"metadata": {},
169+
"source": [
170+
"## Compare Minimum Found"
171+
]
172+
},
173+
{
174+
"cell_type": "code",
175+
"execution_count": null,
176+
"metadata": {},
177+
"outputs": [],
178+
"source": [
179+
"print(f\"[2D] spotpython Kriging Random:\\n min y = {spot_exact_random.min_y:.4f} at x = {spot_exact_random.min_X}\")\n",
180+
"print(f\"[2D] spotpython Kriging Morris-Mitchell:\\n min y = {spot_exact_mm.min_y:.4f} at x = {spot_exact_mm.min_X}\")"
181+
]
182+
},
183+
{
184+
"cell_type": "code",
185+
"execution_count": null,
186+
"metadata": {},
187+
"outputs": [],
188+
"source": [
189+
"spot_exact_random.plot_important_hyperparameter_contour(max_imp=3)\n"
190+
]
191+
},
192+
{
193+
"cell_type": "code",
194+
"execution_count": null,
195+
"metadata": {},
196+
"outputs": [],
197+
"source": [
198+
"spot_exact_mm.plot_important_hyperparameter_contour(max_imp=3)"
199+
]
200+
}
201+
],
202+
"metadata": {
203+
"kernelspec": {
204+
"display_name": "spot313",
205+
"language": "python",
206+
"name": "python3"
207+
},
208+
"language_info": {
209+
"codemirror_mode": {
210+
"name": "ipython",
211+
"version": 3
212+
},
213+
"file_extension": ".py",
214+
"mimetype": "text/x-python",
215+
"name": "python",
216+
"nbconvert_exporter": "python",
217+
"pygments_lexer": "ipython3",
218+
"version": "3.13.7"
219+
}
220+
},
221+
"nbformat": 4,
222+
"nbformat_minor": 2
223+
}

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.34.6"
10+
version = "0.34.7"
1111
authors = [
1212
{ name="T. Bartz-Beielstein", email="tbb@bartzundbartz.de" }
1313
]

src/spotpython/spot/spot.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ def __init__(
215215
self.success_rate = 0.0
216216
self.success_counter = 0
217217
self.window_size = 100
218-
self.min_success_rate = 0.01
218+
self.min_success_rate = 0.0
219219
# small value:
220220
self.eps = sqrt(spacing(1))
221221

@@ -373,6 +373,7 @@ def _set_additional_attributes(self) -> None:
373373
self.n_points = self.fun_control["n_points"]
374374
self.progress_file = self.fun_control["progress_file"]
375375
self.tkagg = self.fun_control["tkagg"]
376+
self.min_success_rate = self.fun_control["min_success_rate"]
376377
# self.success_counter = 0
377378
if self.tkagg:
378379
matplotlib.use("TkAgg")
@@ -1714,7 +1715,7 @@ def update_design(self) -> None:
17141715
# the last window_size evaluations:
17151716
self._update_success_rate(y_new=y0)
17161717
# Append New Solutions (only if they are not nan):
1717-
if (y0.shape[0] > 0) and (self._get_success_rate() >= self.min_success_rate):
1718+
if y0.shape[0] > 0:
17181719
self.X = np.append(self.X, X0, axis=0)
17191720
self.y = np.append(self.y, y0)
17201721
else:

src/spotpython/utils/init.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ def fun_control_init(
6464
max_surrogate_points=30,
6565
metric_sklearn=None,
6666
metric_sklearn_name=None,
67+
min_success_rate=0.0,
6768
noise=False,
6869
n_points=1,
6970
n_samples=None,
@@ -228,6 +229,10 @@ def fun_control_init(
228229
The metric object from the scikit-learn library. Default is None.
229230
metric_sklearn_name (str):
230231
The name of the metric object from the scikit-learn library. Default is None.
232+
min_success_rate (float):
233+
The minimum success rate for the Spot optimization to continue.
234+
If the success rate falls below this value, a random point is proposed based on the acquisition_failure_strategy.
235+
Default is 0.0.
231236
noise (bool):
232237
Whether the objective function is noiy or not. Default is False.
233238
Affects the repeat of the function evaluations.
@@ -395,6 +400,7 @@ def fun_control_init(
395400
'metric_sklearn_name': None,
396401
'metric_torch': None,
397402
'metric_params': {},
403+
'min_success_rate': 0.0,
398404
'model_dict': {},
399405
'noise': False,
400406
'n_points': 1,
@@ -489,6 +495,7 @@ def fun_control_init(
489495
"metric_sklearn_name": metric_sklearn_name,
490496
"metric_torch": None,
491497
"metric_params": {},
498+
"min_success_rate": min_success_rate,
492499
"model_dict": {},
493500
"noise": noise,
494501
"n_points": n_points,

test/test_select_new_x.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import numpy as np
2+
import pytest
3+
from spotpython.utils.compare import selectNew
4+
5+
def test_selectNew_all_known():
6+
A = np.array([[1, 2, 3], [4, 5, 6]])
7+
X = np.array([[1, 2, 3], [4, 5, 6]])
8+
B, ind = selectNew(A, X)
9+
assert B.shape[0] == 0
10+
assert np.all(ind == np.array([False, False]))
11+
12+
def test_selectNew_one_new():
13+
A = np.array([[1, 2, 3], [4, 5, 7]])
14+
X = np.array([[1, 2, 3], [4, 5, 6]])
15+
B, ind = selectNew(A, X)
16+
assert B.shape[0] == 1
17+
assert np.all(ind == np.array([False, True]))
18+
assert np.all(B == np.array([[4, 5, 7]]))
19+
20+
def test_selectNew_all_new():
21+
A = np.array([[7, 8, 9], [10, 11, 12]])
22+
X = np.array([[1, 2, 3], [4, 5, 6]])
23+
B, ind = selectNew(A, X)
24+
assert B.shape[0] == 2
25+
assert np.all(ind == np.array([True, True]))
26+
assert np.all(B == A)
27+
28+
def test_selectNew_with_tolerance():
29+
A = np.array([[1.0, 2.0, 3.0], [4.01, 5.0, 6.0]])
30+
X = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
31+
B, ind = selectNew(A, X, tolerance=0.05)
32+
assert B.shape[0] == 0
33+
assert np.all(ind == np.array([False, False]))
34+
35+
def test_selectNew_with_tolerance_one_new():
36+
A = np.array([[1.0, 2.0, 3.0], [4.1, 5.0, 6.0]])
37+
X = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
38+
B, ind = selectNew(A, X, tolerance=0.05)
39+
assert B.shape[0] == 1
40+
assert np.all(ind == np.array([False, True]))
41+
assert np.allclose(B, np.array([[4.1, 5.0, 6.0]]))

test/test_update_success_rate.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
@pytest.fixture
66
def spot_instance():
77
# Minimal Spot instance with required attributes
8-
fun_control = {"lower": np.array([-1, -1]), "upper": np.array([1, 1]), "var_type": ["num", "num"], "fun_evals": 10, "fun_repeats": 1, "max_time": 1e6, "noise": False, "tolerance_x": 0, "ocba_delta": 0, "log_level": 50, "show_models": False, "show_progress": False, "infill_criterion": "ei", "n_points": 1, "seed": 1, "progress_file": None, "tkagg": False, "verbosity": 0, "acquisition_failure_strategy": "random", "fun_mo2so": None, "penalty_NA": 0, "PREFIX": "test", "tensorboard_log": False, "spot_tensorboard_path": None, "save_experiment": False, "db_dict_name": None, "save_result": False, "var_name": ["x0", "x1"]}
8+
fun_control = {"lower": np.array([-1, -1]), "upper": np.array([1, 1]), "var_type": ["num", "num"], "fun_evals": 10, "fun_repeats": 1, "max_time": 1e6, "noise": False, "tolerance_x": 0, "ocba_delta": 0, "log_level": 50, "show_models": False, "show_progress": False, "infill_criterion": "ei", "n_points": 1, "seed": 1, "progress_file": None, "tkagg": False, "verbosity": 0, "acquisition_failure_strategy": "random", "fun_mo2so": None, "penalty_NA": 0, "PREFIX": "test", "tensorboard_log": False, "spot_tensorboard_path": None, "save_experiment": False, "db_dict_name": None, "save_result": False, "var_name": ["x0", "x1"], "min_success_rate": 0.0}
99
design_control = {"init_size": 5, "repeats": 1}
1010
from spotpython.utils.init import surrogate_control_init, optimizer_control_init
1111
surrogate_control = surrogate_control_init()

0 commit comments

Comments
 (0)