Skip to content

Commit

Permalink
bug fixed and new license agreement
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcusMNoack committed Mar 14, 2024
1 parent e3e505b commit 6658e82
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 60 deletions.
9 changes: 7 additions & 2 deletions LEGAL.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
gpCAM Copyright (c) 2021, The Regents of the University of California,
****************************

gpCAM Copyright (c) 2024, The Regents of the University of California,
through Lawrence Berkeley National Laboratory (subject to receipt of
any required approvals from the U.S. Dept. of Energy). All rights reserved.

Expand All @@ -11,4 +13,7 @@ of Energy and the U.S. Government consequently retains certain rights. As
such, the U.S. Government has been granted for itself and others acting on
its behalf a paid-up, nonexclusive, irrevocable, worldwide license in the
Software to reproduce, distribute copies to the public, prepare derivative
works, and perform publicly and display publicly, and to permit others to do so.
works, and perform publicly and display publicly, and to permit others to do so.


***************************
4 changes: 2 additions & 2 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

GPL v3 License

gpCAM Copyright (c) 2021, The Regents of the University of California,
gpCAM Copyright (c) 2024, The Regents of the University of California,
through Lawrence Berkeley National Laboratory (subject to receipt of
any required approvals from the U.S. Dept. of Energy). All rights reserved.

Expand All @@ -24,7 +24,7 @@ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
Expand Down
16 changes: 4 additions & 12 deletions gpcam/autonomous_experimenter.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ class AutonomousExperimenterGP:
The default is a random draw from a uniform distribution
within hyperparameter_bounds, with a shape appropriate
for the default kernel (D + 1), which is an anisotropic Matern
kernel with automatic relevance determination (ARD). If sparse_node or gp2Scale is
kernel with automatic relevance determination (ARD). If gp2Scale is
enabled, the default kernel changes to the anisotropic Wendland kernel.
hyperparameter_bounds : np.ndarray, optional
A 2d numpy array of shape (N x 2), where N is the number of needed hyperparameters.
The default is None, in which case the hyperparameter_bounds are estimated from the domain size
and the initial y_data. If normalize_y is True or the data changes significantly,
and the initial y_data. If the data changes significantly,
the hyperparameters and the bounds should be changed/retrained. Initial hyperparameters and bounds
can also be set in the train calls. The default only works for the default kernels.
instrument_function : Callable, optional
Expand Down Expand Up @@ -191,11 +191,9 @@ def __init__(self,
store_inv=False,
training_dask_client=None,
acq_func_opt_dask_client=None,
sparse_mode=False,
gp2Scale=False,
gp2Scale_dask_client=None,
gp2Scale_batch_size=10000,
normalize_y=False,
ram_economy=True,
info=False,
args=None
Expand Down Expand Up @@ -259,11 +257,9 @@ def __init__(self,
gp_noise_function_grad=None,
gp_mean_function=prior_mean_function,
gp_mean_function_grad=None,
sparse_mode=sparse_mode,
gp2Scale=gp2Scale,
gp2Scale_dask_client=gp2Scale_dask_client,
gp2Scale_batch_size=gp2Scale_batch_size,
normalize_y=normalize_y,
store_inv=store_inv,
ram_economy=ram_economy,
args=args,
Expand Down Expand Up @@ -686,12 +682,12 @@ class AutonomousExperimenterFvGP(AutonomousExperimenterGP):
The default is a random draw from a uniform distribution
within hyperparameter_bounds, with a shape appropriate
for the default kernel (D + 1), which is an anisotropic Matern
kernel with automatic relevance determination (ARD). If sparse_node or gp2Scale is
kernel with automatic relevance determination (ARD). If gp2Scale is
enabled, the default kernel changes to the anisotropic Wendland kernel.
hyperparameter_bounds : np.ndarray, optional
A 2d numpy array of shape (N x 2), where N is the number of needed hyperparameters.
The default is None, in which case the hyperparameter_bounds are estimated from the domain size
and the initial y_data. If normalize_y is True or the data changes significantly,
and the initial y_data. If the data changes significantly,
the hyperparameters and the bounds should be changed/retrained. Initial hyperparameters and bounds
can also be set in the train calls. The default only works for the default kernels.
instrument_function : Callable, optional
Expand Down Expand Up @@ -833,11 +829,9 @@ def __init__(self,
store_inv=False,
training_dask_client=None,
acq_func_opt_dask_client=None,
sparse_mode=False,
gp2Scale=False,
gp2Scale_dask_client=None,
gp2Scale_batch_size=10000,
normalize_y=False,
ram_economy=True,
info=False,
args=None
Expand Down Expand Up @@ -899,11 +893,9 @@ def __init__(self,
gp_noise_function_grad=None,
gp_mean_function=prior_mean_function,
gp_mean_function_grad=None,
sparse_mode=sparse_mode,
gp2Scale=gp2Scale,
gp2Scale_dask_client=gp2Scale_dask_client,
gp2Scale_batch_size=gp2Scale_batch_size,
normalize_y=normalize_y,
store_inv=store_inv,
ram_economy=ram_economy,
args=args,
Expand Down
55 changes: 18 additions & 37 deletions gpcam/gp_optimizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,12 @@ class GPOptimizer(GP):
The default is a random draw from a uniform distribution
within hyperparameter_bounds, with a shape appropriate
for the default kernel (D + 1), which is an anisotropic Matern
kernel with automatic relevance determination (ARD). If sparse_node or gp2Scale is
kernel with automatic relevance determination (ARD). If gp2Scale is
enabled, the default kernel changes to the anisotropic Wendland kernel.
hyperparameter_bounds : np.ndarray, optional
A 2d numpy array of shape (N x 2), where N is the number of needed hyperparameters.
The default is None, in which case the hyperparameter_bounds are estimated from the domain size
and the initial y_data. If normalize_y is True or the data changes significantly,
and the initial y_data. If the data changes significantly,
the hyperparameters and the bounds should be changed/retrained. Initial hyperparameters and bounds
can also be set in the train calls. The default only works for the default kernels.
noise_variances : np.ndarray, optional
Expand Down Expand Up @@ -210,17 +210,6 @@ class GPOptimizer(GP):
hyperparameters. If `gp_noise_function` is provided but no gradient function,
a finite-difference approximation will be used.
The same rules regarding ram economy as for the kernel definition apply here.
normalize_y : bool, optional
If True, the data values `y_data` will be normalized to max(y_data) = 1, min(y_data) = 0.
The default is False.
Variances will be updated accordingly.
sparse_mode : bool, optional
When sparse_mode is enabled, the algorithm will use a user-defined kernel
function or, if that's not provided, an anisotropic Wendland kernel
and check for sparsity in the prior covariance. If sparsity is present,
sparse operations will be used to speed up computations.
Caution: the covariance is still stored at first in a dense format.
For more extreme scaling, check out the gp2Scale option.
gp2Scale: bool, optional
Turns on gp2Scale. This will distribute the covariance computations across multiple workers.
This is an advanced feature for HPC GPs up to 10
Expand Down Expand Up @@ -320,11 +309,9 @@ def __init__(
gp_noise_function_grad=None,
gp_mean_function=None,
gp_mean_function_grad=None,
sparse_mode=False,
gp2Scale=False,
gp2Scale_dask_client=None,
gp2Scale_batch_size=10000,
normalize_y=False,
store_inv=True,
ram_economy=False,
args=None,
Expand Down Expand Up @@ -354,11 +341,9 @@ def __init__(
gp_noise_function_grad=gp_noise_function_grad,
gp_mean_function=gp_mean_function,
gp_mean_function_grad=gp_mean_function_grad,
sparse_mode=sparse_mode,
gp2Scale=gp2Scale,
gp2Scale_dask_client=gp2Scale_dask_client,
gp2Scale_batch_size=gp2Scale_batch_size,
normalize_y=normalize_y,
store_inv=store_inv,
ram_economy=ram_economy,
args=args,
Expand Down Expand Up @@ -420,7 +405,7 @@ def evaluate_acquisition_function(self, x, acquisition_function="variance", orig
logger.error("Evaluating the acquisition function was not successful.")
raise Exception("Evaluating the acquisition function was not successful.", ex)

def tell(self, x, y, noise_variances=None):
def tell(self, x, y, noise_variances=None, overwrite=True):
"""
This function can tell() the gp_optimizer class
the data that was collected. The data will instantly be used to update the gp data.
Expand All @@ -436,8 +421,10 @@ def tell(self, x, y, noise_variances=None):
noise_variances : np.ndarray, optional
Point value variances (of shape U x 1 or U) to be communicated to the Gaussian Process.
If not provided, the GP will 1% of the y values as variances.
overwrite : bool, optional
The default is True. Indicates if all previous data should be overwritten.
"""
super().update_gp_data(x, y, noise_variances=noise_variances)
super().update_gp_data(x, y, noise_variances=noise_variances, overwrite=overwrite)

##############################################################
def train(
Expand Down Expand Up @@ -786,6 +773,8 @@ def ask(self,
logger.info("bounds:\n{}", bounds)
logger.info("acq func: {}", acquisition_function)

assert isinstance(vectorized, bool)

#check for bounds or candidate set
if bounds is not None and candidates is not None:
raise Exception("Bounds and candidates provided. Only one should be given.")
Expand All @@ -803,6 +792,8 @@ def ask(self,
bounds = new_optimization_bounds
if acquisition_function != "total correlation" and acquisition_function != "relative information entropy":
acquisition_function = "total correlation"
warnings.warn("You specified n>1 and method != 'hgdl' in ask(). The acquisition function \
has therefore been changed to 'total correlation'")

if acquisition_function == "total correlation" or acquisition_function == "relative information entropy":
vectorized = False
Expand Down Expand Up @@ -997,17 +988,6 @@ class fvGPOptimizer(fvGP):
If `gp_noise_function` is provided but no gradient function,
a finite-difference approximation will be used.
The same rules regarding ram economy as for the kernel definition apply here.
normalize_y : bool, optional
If True, the data values `y_data` will be normalized to max(y_data) = 1, min(y_data) = 0.
The default is False.
Variances will be updated accordingly.
sparse_mode : bool, optional
When sparse_mode is enabled, the algorithm will use a user-defined kernel function or,
if that's not provided, an anisotropic Wendland kernel
and check for sparsity in the prior covariance. If sparsity is present,
sparse operations will be used to speed up computations.
Caution: the covariance is still stored at first in a dense format. For more extreme scaling,
check out the gp2Scale option.
gp2Scale: bool, optional
Turns on gp2Scale. This will distribute the covariance computations across multiple workers.
This is an advanced feature for HPC GPs up to 10
Expand All @@ -1033,7 +1013,7 @@ class fvGPOptimizer(fvGP):
True. Note, the training will always use Cholesky or LU decomposition instead of the inverse
for stability reasons. Storing the inverse is
a good option when the dataset is not too large and the posterior covariance is heavily used.
If sparse_mode or gp2Scale is used, store_inv will be set to False.
If gp2Scale is used, store_inv will be set to False.
ram_economy : bool, optional
Only of interest if the gradient and/or Hessian of the marginal log_likelihood
is/are used for the training.
Expand Down Expand Up @@ -1115,11 +1095,9 @@ def __init__(
gp_noise_function_grad=None,
gp_mean_function=None,
gp_mean_function_grad=None,
sparse_mode=False,
gp2Scale=False,
gp2Scale_dask_client=None,
gp2Scale_batch_size=10000,
normalize_y=False,
store_inv=True,
ram_economy=False,
args=None,
Expand Down Expand Up @@ -1159,11 +1137,9 @@ def __init__(
gp_noise_function_grad=gp_noise_function_grad,
gp_mean_function=gp_mean_function,
gp_mean_function_grad=gp_mean_function_grad,
sparse_mode=sparse_mode,
gp2Scale=gp2Scale,
gp2Scale_dask_client=gp2Scale_dask_client,
gp2Scale_batch_size=gp2Scale_batch_size,
normalize_y=normalize_y,
store_inv=store_inv,
ram_economy=ram_economy,
args=args,
Expand Down Expand Up @@ -1230,7 +1206,7 @@ def evaluate_acquisition_function(self, x, x_out, acquisition_function="variance
raise Exception("Evaluating the acquisition function was not successful.", ex)

############################################################################
def tell(self, x, y, noise_variances=None, output_positions=None):
def tell(self, x, y, noise_variances=None, output_positions=None, overwrite=True):
"""
This function can tell() the gp_optimizer class
the data that was collected. The data will instantly be used to update the GP data.
Expand All @@ -1251,8 +1227,11 @@ def tell(self, x, y, noise_variances=None, output_positions=None):
are clearly defined by their positions in the output space.
The default is np.array([[0],[1],[2],[3],...,[output_number - 1]]) for each
point in the input space. The default is only permissible if output_dim is 1.
overwrite : bool, optional
The default is True. Indicates if all previous data should be overwritten.
"""
super().update_gp_data(x, y, noise_variances=noise_variances, output_positions=output_positions)
super().update_gp_data(x, y, noise_variances=noise_variances,
output_positions=output_positions, overwrite=overwrite)

##############################################################
def train(self,
Expand Down Expand Up @@ -1611,6 +1590,8 @@ def ask(self,
bounds = new_optimization_bounds
if acquisition_function != "total correlation" and acquisition_function != "relative information entropy":
acquisition_function = "total correlation"
warnings.warn("You specified n>1 and method != 'hgdl' in ask(). The acquisition function \
has therefore been changed to 'total correlation'")
if acquisition_function == "total correlation" or acquisition_function == "relative information entropy":
vectorized = False
if method != "global": vectorized = False
Expand Down
4 changes: 3 additions & 1 deletion gpcam/surrogate_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def find_acquisition_function_maxima(gp, acquisition_function,
x_out=None,
dask_client=None,
info=False):

if candidates is None and optimization_bounds is None:
raise Exception("optimization bounds or candidates have to be provided")
bounds = optimization_bounds
Expand Down Expand Up @@ -179,7 +180,7 @@ def evaluate_acquisition_function(x, gp=None, acquisition_function=None, origin=
##########################################################
if isinstance(x, np.ndarray) and np.ndim(x) == 1: x = x.reshape(-1, gp.input_dim)
if x_out is not None and np.ndim(x_out) != 2: raise Exception(
"x_out in evaluate_acquisition_function has to be a 2d umpy array.")
"x_out in evaluate_acquisition_function has to be a 2d numpy array.")

if cost_function is not None and origin is not None:
cost_eval = cost_function(origin, x, cost_function_parameters)
Expand Down Expand Up @@ -288,6 +289,7 @@ def differential_evolution(func,
constraints=(),
disp=False,
vectorized=True):

res = devo(partial(acq_function_vectorization_wrapper, func=func, vectorized=vectorized), bounds, tol=tol, x0=x0,
maxiter=max_iter, popsize=popsize, polish=False, disp=disp, constraints=constraints,
vectorized=vectorized)
Expand Down
8 changes: 4 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
wheel
numpy == 1.23.5
scipy == 1.11.2
scipy == 1.12.0
matplotlib
pandas
ophyd
dask >= 2021.6.2
distributed >= 2021.6.2
dask == 2024.1.0
distributed == 2024.1.0
zmq
fvgp == 4.1.1
fvgp == 4.1.2
plotly
notebook
loguru
4 changes: 2 additions & 2 deletions tests/test_gpCAM.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ def test_fvae(self):
my_ae.kill_training()

#...and run. That's it. You successfully executed an autonomous experiment.
my_ae.go(N = 20)
my_ae.go(N = 10)



Expand All @@ -163,7 +163,7 @@ def test_acq_funcs(self):
from gpcam.gp_optimizer import GPOptimizer

#initialize some data
x_data = np.random.uniform(size = (100,3))
x_data = np.random.uniform(size = (10,3))
y_data = np.sin(np.linalg.norm(x_data, axis = 1))


Expand Down

0 comments on commit 6658e82

Please sign in to comment.