Skip to content

Commit c2590f1

Browse files
0.31.10
1 parent 38500ec commit c2590f1

6 files changed

Lines changed: 188 additions & 286 deletions

File tree

notebooks/00_spotPython_tests.ipynb

Lines changed: 136 additions & 164 deletions
Large diffs are not rendered by default.

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

src/spotpython/fun/objectivefunctions.py

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def __init__(self, offset: float = 0.0, sigma=0.0, seed: int = 126, fun_control=
4949
self.fun_control["seed"] = self.seed
5050

5151
def __repr__(self) -> str:
52-
return f"analytical(offset={self.offset}, sigma={self.sigma}, seed={self.seed})"
52+
return f"Analytical(offset={self.offset}, sigma={self.sigma}, seed={self.seed})"
5353

5454
def _prepare_input_data(self, X, fun_control):
5555
if fun_control is not None:
@@ -67,17 +67,17 @@ def _add_noise(self, y: List[float]) -> np.ndarray:
6767
containing the noisy data.
6868
6969
Args:
70-
self (analytical): analytical class object.
70+
self (Analytical): Analytical class object.
7171
y (List[float]): Input data.
7272
7373
Returns:
7474
np.ndarray: Noisy data.
7575
7676
Examples:
77-
>>> from spotpython.fun.objectivefunctions import analytical
77+
>>> from spotpython.fun.objectivefunctions import Analytical
7878
import numpy as np
7979
y = np.array([1, 2, 3, 4, 5])
80-
fun = analytical(sigma=1.0, seed=123)
80+
fun = Analytical(sigma=1.0, seed=123)
8181
fun._add_noise(y)
8282
array([0.01087865, 1.63221335, 4.28792526, 4.19397442, 5.9202309 ])
8383
@@ -117,10 +117,10 @@ def fun_branin_factor(self, X: np.ndarray, fun_control: Optional[Dict] = None) -
117117
np.ndarray: A 1D numpy array with shape (n,) containing the calculated values.
118118
119119
Examples:
120-
>>> from spotpython.fun.objectivefunctions import analytical
120+
>>> from spotpython.fun.objectivefunctions import Analytical
121121
import numpy as np
122122
X = np.array([[0, 0, 0], [0, 0, 1], [0, 0, 2]])
123-
fun = analytical()
123+
fun = Analytical()
124124
fun.fun_branin_factor(X)
125125
array([55.60211264, 65.60211264, 45.60211264])
126126
"""
@@ -230,10 +230,10 @@ def fun_sphere(self, X: np.ndarray, fun_control: Optional[Dict] = None) -> np.nd
230230
np.ndarray: A 1D numpy array with shape (n,) containing the calculated values.
231231
232232
Examples:
233-
>>> from spotpython.fun.objectivefunctions import analytical
233+
>>> from spotpython.fun.objectivefunctions import Analytical
234234
>>> import numpy as np
235235
>>> X = np.array([[1, 2, 3], [4, 5, 6]])
236-
>>> fun = analytical()
236+
>>> fun = Analytical()
237237
>>> fun.fun_sphere(X)
238238
array([14., 77.])
239239
@@ -256,10 +256,10 @@ def fun_cubed(self, X: np.ndarray, fun_control: Optional[Dict] = None) -> np.nda
256256
np.ndarray: A 1D numpy array with shape (n,) containing the calculated values.
257257
258258
Examples:
259-
>>> from spotpython.fun.objectivefunctions import analytical
259+
>>> from spotpython.fun.objectivefunctions import Analytical
260260
>>> import numpy as np
261261
>>> X = np.array([[1, 2, 3], [4, 5, 6], [-1, -1, -1]])
262-
>>> fun = analytical()
262+
>>> fun = Analytical()
263263
>>> fun.fun_cubed(X)
264264
array([ 36., 405., -3.])
265265
"""
@@ -283,10 +283,10 @@ def fun_forrester(self, X: np.ndarray, fun_control: Optional[Dict] = None) -> np
283283
np.ndarray: A 1D numpy array with shape (n,) containing the calculated values.
284284
285285
Examples:
286-
>>> from spotpython.fun.objectivefunctions import analytical
286+
>>> from spotpython.fun.objectivefunctions import Analytical
287287
>>> import numpy as np
288288
>>> X = np.array([[1, 2, 3], [4, 5, 6]])
289-
>>> fun = analytical()
289+
>>> fun = Analytical()
290290
>>> fun.fun_forrester(X)
291291
array([ 0. , 11.99999999])
292292
"""
@@ -324,13 +324,13 @@ def fun_branin(self, X: np.ndarray, fun_control: Optional[Dict] = None) -> np.nd
324324
np.ndarray: A 1D numpy array with shape (n,) containing the calculated values.
325325
326326
Examples:
327-
>>> from spotpython.fun.objectivefunctions import analytical
327+
>>> from spotpython.fun.objectivefunctions import Analytical
328328
pi = np.pi
329329
X = np.array([[0,0],
330330
[-pi, 12.275],
331331
[pi, 2.275],
332332
[9.42478, 2.475]])
333-
fun = analytical()
333+
fun = Analytical()
334334
fun.fun_branin(X)
335335
array([55.60211264, 0.39788736, 0.39788736, 0.39788736])
336336
@@ -362,10 +362,10 @@ def fun_branin_modified(self, X: np.ndarray, fun_control: Optional[Dict] = None)
362362
np.ndarray: A 1D numpy array with shape (n,) containing the calculated values.
363363
364364
Examples:
365-
>>> from spotpython.fun.objectivefunctions import analytical
365+
>>> from spotpython.fun.objectivefunctions import Analytical
366366
>>> import numpy as np
367367
>>> X = np.array([[1, 2, 3], [4, 5, 6]])
368-
>>> fun = analytical()
368+
>>> fun = Analytical()
369369
>>> fun.fun_branin_modified(X)
370370
array([ 0. , 11.99999999])
371371
@@ -398,10 +398,10 @@ def fun_sin_cos(self, X, fun_control=None):
398398
(np.ndarray): A 1D numpy array with shape (n,) containing the calculated values.
399399
400400
Examples:
401-
>>> from spotpython.fun.objectivefunctions import analytical
401+
>>> from spotpython.fun.objectivefunctions import Analytical
402402
>>> import numpy as np
403403
>>> X = np.array([[1, 2, 3], [4, 5, 6]])
404-
>>> fun = analytical()
404+
>>> fun = Analytical()
405405
>>> fun.fun_sin_cos(X)
406406
array([-1. , -0.41614684])
407407
"""
@@ -425,10 +425,10 @@ def fun_runge(self, X: np.ndarray, fun_control: Optional[Dict] = None) -> np.nda
425425
np.ndarray: A 1D numpy array with shape (n,) containing the calculated values.
426426
427427
Examples:
428-
>>> from spotpython.fun.objectivefunctions import analytical
428+
>>> from spotpython.fun.objectivefunctions import Analytical
429429
>>> import numpy as np
430430
>>> X = np.array([[1, 2, 3], [4, 5, 6]])
431-
>>> fun = analytical()
431+
>>> fun = Analytical()
432432
>>> fun.fun_runge(X)
433433
array([0.0625 , 0.015625 , 0.00390625])
434434
@@ -493,10 +493,10 @@ def fun_wingwt_to_nat(self, X: np.ndarray, fun_control: Optional[Dict] = None) -
493493
A 1D numpy array with shape (n,) containing the calculated wing weight values.
494494
495495
Examples:
496-
>>> from spotpython.fun.objectivefunctions import analytical
496+
>>> from spotpython.fun.objectivefunctions import Analytical
497497
>>> import numpy as np
498498
>>> X = np.array([np.zeros(10), np.ones(10)])
499-
>>> fun = analytical()
499+
>>> fun = Analytical()
500500
>>> fun.fun_wingwt(X)
501501
array([158.28245046, 409.33182691])
502502
"""
@@ -575,10 +575,10 @@ def fun_wingwt(self, X: np.ndarray, fun_control: Optional[Dict] = None) -> np.nd
575575
A 1D numpy array with shape (n,) containing the calculated wing weight values.
576576
577577
Examples:
578-
>>> from spotpython.fun.objectivefunctions import analytical
578+
>>> from spotpython.fun.objectivefunctions import Analytical
579579
>>> import numpy as np
580580
>>> X = np.array([np.zeros(10), np.ones(10)])
581-
>>> fun = analytical()
581+
>>> fun = Analytical()
582582
>>> fun.fun_wingwt(X)
583583
array([158.28245046, 409.33182691])
584584
"""
@@ -612,10 +612,10 @@ def fun_xsin(self, X: np.ndarray, fun_control: Optional[Dict] = None) -> np.ndar
612612
np.ndarray: A 1D numpy array with shape (n,) containing the calculated values.
613613
614614
Examples:
615-
>>> from spotpython.fun.objectivefunctions import analytical
615+
>>> from spotpython.fun.objectivefunctions import Analytical
616616
>>> import numpy as np
617617
>>> X = np.array([[1, 2, 3, 4, 5, 6, 7, 8, 9], [4, 5, 6, 7, 8, 9, 10, 11, 12]])
618-
>>> fun = analytical()
618+
>>> fun = Analytical()
619619
>>> fun.fun_xsin(X)
620620
array([0.84147098, 0.90929743, 0.14112001])
621621
@@ -634,10 +634,10 @@ def fun_rosen(self, X: np.ndarray, fun_control: Optional[Dict] = None) -> np.nda
634634
np.ndarray: A 1D numpy array with shape (n,) containing the calculated values.
635635
636636
Examples:
637-
>>> from spotpython.fun.objectivefunctions import analytical
637+
>>> from spotpython.fun.objectivefunctions import Analytical
638638
>>> import numpy as np
639639
>>> X = np.array([[1, 2,], [4, 5 ]])
640-
>>> fun = analytical()
640+
>>> fun = Analytical()
641641
>>> fun.fun_rosen(X)
642642
array([24, 0])
643643
"""
@@ -660,10 +660,10 @@ def fun_random_error(self, X: np.ndarray, fun_control: Optional[Dict] = None) ->
660660
np.ndarray: A 1D numpy array with shape (n,) containing the calculated values.
661661
662662
Examples:
663-
>>> from spotpython.fun.objectivefunctions import analytical
663+
>>> from spotpython.fun.objectivefunctions import Analytical
664664
>>> import numpy as np
665665
>>> X = np.array([[1, 2,], [4, 5 ]])
666-
>>> fun = analytical()
666+
>>> fun = Analytical()
667667
>>> fun.fun_random_error(X)
668668
array([24, 0])
669669

src/spotpython/spot/spot.py

Lines changed: 3 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
from typing import Callable
5252
from spotpython.utils.numpy2json import NumpyEncoder
5353
from spotpython.utils.file import load_result
54-
from spotpython.surrogate.plot import plot_3d_contour, plotkd
54+
from spotpython.surrogate.plot import plotkd
5555

5656
# Setting up the backend to use QtAgg
5757
# matplotlib.use("TkAgg")
@@ -2528,84 +2528,9 @@ def plot_contour(
25282528
cmap="jet",
25292529
) -> None:
25302530
"""
2531-
Plot the contour and 3D surface for any pair of dimensions of the surrogate model.
2532-
This method visualizes the surrogate model's predictions over a grid for two selected dimensions.
2533-
It creates both a filled contour plot and a 3D surface plot, allowing users to inspect the surrogate's
2534-
response surface. The remaining dimensions are fixed to either their minimum or maximum values, depending
2535-
on the `use_min` and `use_max` flags.
2531+
Plot a contour plot of the surrogate model for two hyperparameters.
25362532
"""
2537-
plotkd(model=self.surrogate, X=self.X, y=self.y, i=i, j=j, num=n_grid)
2538-
2539-
def plot_contour_old(
2540-
self,
2541-
i=0,
2542-
j=1,
2543-
min_z=None,
2544-
max_z=None,
2545-
show=True,
2546-
title=None,
2547-
filename=None,
2548-
n_grid=50,
2549-
contour_levels=10,
2550-
dpi=200,
2551-
figsize=(12, 5),
2552-
use_min=False,
2553-
use_max=True,
2554-
tkagg=False,
2555-
cmap="jet",
2556-
) -> None:
2557-
"""
2558-
Plot the contour and 3D surface for any pair of dimensions of the surrogate model.
2559-
This method visualizes the surrogate model's predictions over a grid for two selected dimensions.
2560-
It creates both a filled contour plot and a 3D surface plot, allowing users to inspect the surrogate's
2561-
response surface. The remaining dimensions are fixed to either their minimum or maximum values, depending
2562-
on the `use_min` and `use_max` flags.
2563-
2564-
Args:
2565-
i (int, optional): Index of the first dimension to plot. Default is 0.
2566-
j (int, optional): Index of the second dimension to plot. Default is 1.
2567-
min_z (float, optional): Minimum value for the color scale (z-axis). If None, determined automatically.
2568-
max_z (float, optional): Maximum value for the color scale (z-axis). If None, determined automatically.
2569-
show (bool, optional): Whether to display the plot interactively. Default is True.
2570-
filename (str, optional): If provided, saves the plot to this file. Default is None.
2571-
n_grid (int, optional): Number of grid points per dimension. Default is 50.
2572-
contour_levels (int, optional): Number of contour levels. Default is 10.
2573-
dpi (int, optional): Dots per inch for saved figure. Default is 200.
2574-
title (str, optional): Title for the plot. Default is None.
2575-
figsize (tuple, optional): Figure size in inches (width, height). Default is (12, 6).
2576-
use_min (bool, optional): If True, fix hidden dimensions to their minimum values. Default is False.
2577-
use_max (bool, optional): If True, fix hidden dimensions to their maximum values. Default is True.
2578-
tkagg (bool, optional): If True, use TkAgg backend for matplotlib. Default is False.
2579-
cmap (str, optional): Colormap to use for the contour plot. Default is "jet".
2580-
2581-
Returns:
2582-
None
2583-
"""
2584-
X, Y, Z = self.prepare_plot(
2585-
i=i,
2586-
j=j,
2587-
n_grid=n_grid,
2588-
use_min=use_min,
2589-
use_max=use_max,
2590-
)
2591-
plot_3d_contour(
2592-
X=X,
2593-
Y=Y,
2594-
Z=Z,
2595-
vmin=min_z if min_z is not None else np.min(Z),
2596-
vmax=max_z if max_z is not None else np.max(Z),
2597-
var_name=self.var_name,
2598-
i=i,
2599-
j=j,
2600-
show=show,
2601-
filename=filename,
2602-
contour_levels=contour_levels,
2603-
dpi=dpi,
2604-
title=title,
2605-
figsize=figsize,
2606-
tkagg=tkagg,
2607-
cmap=cmap,
2608-
)
2533+
plotkd(model=self.surrogate, X=self.X, y=self.y, i=i, j=j, num=n_grid, var_type=self.var_type)
26092534

26102535
def plot_important_hyperparameter_contour(
26112536
self,

src/spotpython/surrogate/kriging.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@
55
from sklearn.base import BaseEstimator, RegressorMixin
66
from scipy.special import erf
77
import matplotlib.pyplot as plt
8-
from numpy import linspace, meshgrid, array, append
9-
import pylab
10-
from numpy import ravel
8+
from numpy import linspace, append
119
from scipy.spatial.distance import cdist, pdist, squareform
1210
from spotpython.surrogate.plot import plotkd
1311

@@ -789,8 +787,6 @@ def plot(self, i: int = 0, j: int = 1, show: Optional[bool] = True) -> None:
789787
S.surrogate.plot()
790788
"""
791789
if self.k == 1:
792-
# TODO: Improve plot (add conf. interval etc.)
793-
fig = pylab.figure(figsize=(9, 6))
794790
n_grid = 100
795791
x = linspace(self.min_X[0], self.max_X[0], num=n_grid)
796792
y = self.predict(x)
@@ -799,4 +795,4 @@ def plot(self, i: int = 0, j: int = 1, show: Optional[bool] = True) -> None:
799795
if show:
800796
plt.show()
801797
else:
802-
plotkd(model=self, X=self.X_, y=self.y_, i=i, j=j, show=show)
798+
plotkd(model=self, X=self.X_, y=self.y_, i=i, j=j, show=show, var_type=self.var_type)

src/spotpython/surrogate/plot.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,7 @@ def plot1d(model, X: np.ndarray, y: np.ndarray, show: Optional[bool] = True) ->
5656

5757

5858
def generate_mesh_grid(
59-
X: Optional[np.ndarray] = None,
60-
i: int = 0,
61-
j: int = 1,
62-
num: int = 100,
63-
lower: Optional[np.ndarray] = None,
64-
upper: Optional[np.ndarray] = None,
59+
X: Optional[np.ndarray] = None, i: int = 0, j: int = 1, num: int = 100, lower: Optional[np.ndarray] = None, upper: Optional[np.ndarray] = None, var_type: Optional[List[str]] = None
6560
):
6661
"""
6762
Generate a mesh grid for two selected dimensions, filling remaining dimensions with their mean values
@@ -74,6 +69,7 @@ def generate_mesh_grid(
7469
num (int): Number of grid points per dimension.
7570
lower (np.ndarray, optional): Lower bounds for each dimension (shape (k,)).
7671
upper (np.ndarray, optional): Upper bounds for each dimension (shape (k,)).
72+
var_type (list of str, optional): List of variable types for each dimension. Can be either "num", "int", or "factor".
7773
7874
Returns:
7975
X_i (np.ndarray): Meshgrid for the i-th dimension.
@@ -95,6 +91,17 @@ def generate_mesh_grid(
9591
x_i = linspace(lower[i], upper[i], num=num)
9692
x_j = linspace(lower[j], upper[j], num=num)
9793

94+
# Masked rounding (using floor) for integer or factor variables
95+
if var_type is not None:
96+
# For x_i
97+
if hasattr(x_i, "__len__"):
98+
mask_i = np.array([var_type[i] != "num"] * len(x_i))
99+
x_i = np.where(mask_i, np.floor(x_i), x_i)
100+
# For x_j
101+
if hasattr(x_j, "__len__"):
102+
mask_j = np.array([var_type[j] != "num"] * len(x_j))
103+
x_j = np.where(mask_j, np.floor(x_j), x_j)
104+
98105
X_i, X_j = meshgrid(x_i, x_j)
99106
grid_points = np.zeros((X_i.size, k))
100107
grid_points[:, i] = X_i.ravel()
@@ -334,6 +341,7 @@ def plotkd(
334341
eps: float = 1e-4,
335342
max_error: float = 1e-3,
336343
var_names: Optional[List[str]] = None,
344+
var_type: Optional[List[str]] = None,
337345
cmap: str = "jet",
338346
num: int = 100,
339347
vmin: Optional[float] = None,
@@ -354,6 +362,7 @@ def plotkd(
354362
eps (float): Tolerance for coloring points based on prediction error. Default is 1e-4.
355363
max_error (float): Maximum error for color scaling. Default is 1e-3.
356364
var_names (list of str, optional): List of variable names for axis labeling. If None, generic labels are used.
365+
var_type (list of str, optional): List of variable types for each dimension. Can be either "num", "int", or "factor".
357366
cmap (str): Colormap for the surface and contour plots. Default is "jet".
358367
num (int): Number of grid points per dimension for the mesh grid. Default is 100.
359368
vmin (float, optional): Minimum value for the color scale. If None, determined from predictions.
@@ -375,7 +384,7 @@ def plotkd(
375384
"""
376385
k = X.shape[1]
377386
check_ij(i, j, k)
378-
X_i, X_j, grid_points = generate_mesh_grid(X, i, j, num)
387+
X_i, X_j, grid_points = generate_mesh_grid(X, i, j, num, var_type=var_type)
379388

380389
# Predict the values and standard deviations
381390
y_pred, y_std = model.predict(grid_points, return_std=True)

0 commit comments

Comments
 (0)