fvgp 4.2.10__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
fvgp/.editorconfig ADDED
@@ -0,0 +1,21 @@
1
+ # http://editorconfig.org
2
+
3
+ root = true
4
+
5
+ [*]
6
+ indent_style = space
7
+ indent_size = 4
8
+ trim_trailing_whitespace = true
9
+ insert_final_newline = true
10
+ charset = utf-8
11
+ end_of_line = lf
12
+
13
+ [*.bat]
14
+ indent_style = tab
15
+ end_of_line = crlf
16
+
17
+ [LICENSE]
18
+ insert_final_newline = false
19
+
20
+ [Makefile]
21
+ indent_style = tab
@@ -0,0 +1,15 @@
1
+ * fvGP version:
2
+ * Python version:
3
+ * Operating System:
4
+
5
+ ### Description
6
+
7
+ Describe what you were trying to get done.
8
+ Tell us what happened, what went wrong, and what you expected to happen.
9
+
10
+ ### What I Did
11
+
12
+ ```
13
+ Paste the command(s) you ran and the output.
14
+ If there was a crash, please include the traceback here.
15
+ ```
fvgp/.gitignore ADDED
@@ -0,0 +1,105 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ env/
12
+ build/
13
+ develop-eggs/
14
+ dist/
15
+ downloads/
16
+ eggs/
17
+ .eggs/
18
+ lib/
19
+ lib64/
20
+ parts/
21
+ sdist/
22
+ var/
23
+ wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+
28
+ # PyInstaller
29
+ # Usually these files are written by a python script from a template
30
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
31
+ *.manifest
32
+ *.spec
33
+
34
+ # Installer logs
35
+ pip-log.txt
36
+ pip-delete-this-directory.txt
37
+
38
+ # Unit test / coverage reports
39
+ htmlcov/
40
+ .tox/
41
+ .coverage
42
+ .coverage.*
43
+ .cache
44
+ nosetests.xml
45
+ coverage.xml
46
+ *.cover
47
+ .hypothesis/
48
+ .pytest_cache/
49
+
50
+ # Translations
51
+ *.mo
52
+ *.pot
53
+
54
+ # Django stuff:
55
+ *.log
56
+ local_settings.py
57
+
58
+ # Flask stuff:
59
+ instance/
60
+ .webassets-cache
61
+
62
+ # Scrapy stuff:
63
+ .scrapy
64
+
65
+ # Sphinx documentation
66
+ docs/_build/
67
+
68
+ # PyBuilder
69
+ target/
70
+
71
+ # Jupyter Notebook
72
+ .ipynb_checkpoints
73
+
74
+ # pyenv
75
+ .python-version
76
+
77
+ # celery beat schedule file
78
+ celerybeat-schedule
79
+
80
+ # SageMath parsed files
81
+ *.sage.py
82
+
83
+ # dotenv
84
+ .env
85
+
86
+ # virtualenv
87
+ .venv
88
+ venv/
89
+ ENV/
90
+
91
+ # Spyder project settings
92
+ .spyderproject
93
+ .spyproject
94
+
95
+ # Rope project settings
96
+ .ropeproject
97
+
98
+ # mkdocs documentation
99
+ /site
100
+
101
+ # mypy
102
+ .mypy_cache/
103
+
104
+ # IDE settings
105
+ .vscode/
fvgp/.travis.yml ADDED
@@ -0,0 +1,14 @@
1
+ # Config file for automatic testing at travis-ci.com
2
+
3
+ language: python
4
+ python:
5
+ - 3.10
6
+ - 3.9
7
+
8
+ # Command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors
9
+ install: pip install -U tox-travis
10
+
11
+ # Command to run tests, e.g. python setup.py test
12
+ script: tox
13
+
14
+
fvgp/__init__.py ADDED
@@ -0,0 +1,20 @@
1
+ """Top-level package for fvGP."""
2
+
3
+ __author__ = """Marcus Michael Noack"""
4
+ __email__ = 'MarcusNoack@lbl.gov'
5
+
6
+ try:
7
+ from ._version import __version__
8
+ except (ImportError, ModuleNotFoundError) as ex:
9
+ raise RuntimeError('Running fvgp from source code requires installation. If you would like an editable source '
10
+ 'install, use "pip install -e ." to perform and editable installation.') from ex
11
+
12
+ from loguru import logger
13
+ import sys
14
+ from .gp import GP
15
+ from .fvgp import fvGP
16
+ from .gpMCMC import gpMCMC
17
+
18
+ __all__ = ['GP', 'fvGP']
19
+
20
+ logger.disable('fvgp')
fvgp/_version.py ADDED
@@ -0,0 +1,16 @@
1
+ # file generated by setuptools_scm
2
+ # don't change, don't track in version control
3
+ TYPE_CHECKING = False
4
+ if TYPE_CHECKING:
5
+ from typing import Tuple, Union
6
+ VERSION_TUPLE = Tuple[Union[int, str], ...]
7
+ else:
8
+ VERSION_TUPLE = object
9
+
10
+ version: str
11
+ __version__: str
12
+ __version_tuple__: VERSION_TUPLE
13
+ version_tuple: VERSION_TUPLE
14
+
15
+ __version__ = version = '4.2.10'
16
+ __version_tuple__ = version_tuple = (4, 2, 10)
@@ -0,0 +1,35 @@
1
+ import torch
2
+ from torch import nn
3
+
4
+
5
+ class Network(nn.Module): # pragma: no cover
6
+ def __init__(self, dim, layer_width):
7
+ super().__init__()
8
+ # Inputs to hidden layer linear transformation
9
+ self.layer1 = nn.Linear(dim, layer_width)
10
+ self.layer2 = nn.Linear(layer_width, layer_width)
11
+ self.layer3 = nn.Linear(layer_width, dim)
12
+ self.number_of_hps = int(2. * dim * layer_width + layer_width ** 2 + 2. * layer_width + dim)
13
+
14
+ def forward(self, x):
15
+ x = torch.Tensor(x)
16
+ x = torch.nn.functional.relu(self.layer1(x))
17
+ x = torch.nn.functional.relu(self.layer2(x))
18
+ x = torch.nn.functional.relu(self.layer3(x))
19
+ return x.detach().numpy()
20
+
21
+ def set_weights(self, w1, w2, w3):
22
+ with torch.no_grad(): self.layer1.weight = nn.Parameter(torch.from_numpy(w1).float())
23
+ with torch.no_grad(): self.layer2.weight = nn.Parameter(torch.from_numpy(w2).float())
24
+ with torch.no_grad(): self.layer3.weight = nn.Parameter(torch.from_numpy(w3).float())
25
+
26
+ def set_biases(self, b1, b2, b3):
27
+ with torch.no_grad(): self.layer1.bias = nn.Parameter(torch.from_numpy(b1).float())
28
+ with torch.no_grad(): self.layer2.bias = nn.Parameter(torch.from_numpy(b2).float())
29
+ with torch.no_grad(): self.layer3.bias = nn.Parameter(torch.from_numpy(b3).float())
30
+
31
+ def get_weights(self):
32
+ return self.layer1.weight, self.layer2.weight, self.layer3.weight
33
+
34
+ def get_biases(self):
35
+ return self.layer1.bias, self.layer2.bias, self.layer3.bias
fvgp/fvgp.py ADDED
@@ -0,0 +1,413 @@
1
+ #!/usr/bin/env python
2
+ import numpy as np
3
+ from .gp import GP
4
+
5
+
6
+ class fvGP(GP):
7
+ """
8
+ This class provides all the tools for a multi-task Gaussian Process (GP).
9
+ This class allows for full HPC support for training. After initialization, this
10
+ class provides all the methods described for the GP class.
11
+
12
+ V ... number of input points
13
+
14
+ Di... input space dimensionality
15
+
16
+ Do... output space dimensionality
17
+
18
+ No... number of outputs
19
+
20
+ N ... arbitrary integers (N1, N2,...)
21
+
22
+
23
+ The main logic of fvGP is that any multi-task GP is just a single-task GP
24
+ over a Cartesian product space of input and output space, as long as the kernel
25
+ is flexible enough, so prepare to work on your kernel. This is the best
26
+ way to give the user optimal control and power. In the
27
+ prior-mean function, noise function, and kernel function definition, you will
28
+ see that the input `x` is defined over this combined space.
29
+ For example, if your input space is a Euclidean 2d space and your output
30
+ is labelled [0,1], the input to the mean, kernel, and noise function might be
31
+
32
+ x =
33
+
34
+ [[0.2, 0.3,0],[0.9,0.6,0],
35
+
36
+ [0.2, 0.3,1],[0.9,0.6,1]]
37
+
38
+ This has to be understood and taken into account when customizing fvGP for multi-task
39
+ use. The examples will provide deeper insight.
40
+
41
+ Parameters
42
+ ----------
43
+ x_data : np.ndarray
44
+ The input point positions. Shape (V x D), where D is the `input_space_dim`.
45
+ y_data : np.ndarray
46
+ The values of the data points. Shape (V,No).
47
+ init_hyperparameters : np.ndarray, optional
48
+ Vector of hyperparameters used by the GP initially.
49
+ This class provides methods to train hyperparameters.
50
+ The default is an array that specifies the right number of
51
+ initial hyperparameters for the default kernel, which is
52
+ a deep kernel with two layers of width
53
+ fvgp.fvGP.gp_deep_kernel_layer_width. If you specify
54
+ another kernel, please provide
55
+ init_hyperparameters.
56
+ output_positions : np.ndarray, optional
57
+ A 2-D numpy array of shape (U x output_number), so that for each measurement position, the outputs
58
+ are clearly defined by their positions in the output space. The default is
59
+ np.array([[0,1,2,3,...,output_number - 1],[0,1,2,3,...,output_number - 1],...]).
60
+ noise_variances : np.ndarray, optional
61
+ An numpy array defining the uncertainties/noise in the data
62
+ `y_data` in form of a point-wise variance. Shape y_data.shape.
63
+ Note: if no noise_variances are provided here, the gp_noise_function
64
+ callable will be used; if the callable is not provided, the noise variances
65
+ will be set to `abs(np.mean(y_data) / 100.0`. If
66
+ noise covariances are required, also make use of the gp_noise_function.
67
+ compute_device : str, optional
68
+ One of "cpu" or "gpu", determines how linear system solves are run. The default is "cpu".
69
+ For "gpu", pytorch has to be installed manually.
70
+ If gp2Scale is enabled but no kernel is provided, the choice of the compute_device
71
+ becomes much more important. In that case, the default kernel will be computed on
72
+ the cpu or the gpu which will significantly change the compute time depending on the compute
73
+ architecture.
74
+ gp_kernel_function : Callable, optional
75
+ A symmetric positive semi-definite covariance function (a kernel)
76
+ that calculates the covariance between
77
+ data points. It is a function of the form k(x1,x2,hyperparameters, obj).
78
+ The input x1 is a N1 x Di+Do array of positions, x2 is a N2 x Di+Do
79
+ array of positions, the hyperparameters argument
80
+ is a 1d array of length N depending on how many hyperparameters are initialized, and
81
+ obj is an `fvgp.GP` instance. The default is a deep kernel with 2 hidden layers and
82
+ a width of fvgp.fvGP.gp_deep_kernel_layer_width.
83
+ gp_kernel_function_grad : Callable, optional
84
+ A function that calculates the derivative of the `gp_kernel_function` with respect to the hyperparameters.
85
+ If provided, it will be used for local training (optimization) and can speed up the calculations.
86
+ It accepts as input x1 (a N1 x Di+Do array of positions),
87
+ x2 (a N2 x Di+Do array of positions),
88
+ hyperparameters, and a
89
+ `fvgp.GP` instance. The default is a finite difference calculation.
90
+ If 'ram_economy' is True, the function's input is x1, x2, direction (int), hyperparameters (numpy array), and a
91
+ `fvgp.GP` instance, and the output
92
+ is a numpy array of shape (len(hps) x N).
93
+ If 'ram economy' is False,the function's input is x1, x2, hyperparameters, and a
94
+ `fvgp.GP` instance. The output is
95
+ a numpy array of shape (len(hyperparameters) x N1 x N2). See 'ram_economy'.
96
+ gp_mean_function : Callable, optional
97
+ A function that evaluates the prior mean at a set of input position. It accepts as input
98
+ an array of positions (of shape N1 x Di+Do), hyperparameters
99
+ and a `fvgp.GP` instance. The return value is a 1d array of length N1. If None is provided,
100
+ `fvgp.GP._default_mean_function` is used.
101
+ gp_mean_function_grad : Callable, optional
102
+ A function that evaluates the gradient of the ``gp_mean_function'' at a set of input positions with respect to
103
+ the hyperparameters. It accepts as input an array of positions (of size N1 x Di+Do), hyperparameters
104
+ and a `fvgp.GP` instance. The return value is a 2d array of shape (len(hyperparameters) x N1). If None is
105
+ provided, either zeros are returned since the default mean function does not depend on hyperparameters, or a
106
+ finite-difference approximation is used if ``gp_mean_function'' is provided.
107
+ gp_noise_function : Callable optional
108
+ The noise function is a callable f(x,hyperparameters,obj) that returns a
109
+ positive symmetric definite matrix of shape(len(x),len(x)).
110
+ The input x is a numpy array of shape (N x Di+Do). The hyperparameter array is the same
111
+ that is communicated to mean and kernel functions. The obj is a fvgp.fvGP instance.
112
+ gp_noise_function_grad : Callable, optional
113
+ A function that evaluates the gradient of the ``gp_noise_function'' at an input position with respect
114
+ to the hyperparameters. It accepts as input an array of positions (of size N x Di+Do),
115
+ hyperparameters (a 1d array of length D+1 for the default kernel)
116
+ and a `fvgp.GP` instance. The return value is a 3-D array of shape
117
+ (len(hyperparameters) x N x N). If None is provided, either
118
+ zeros are returned since the default noise function does not depend on hyperparameters.
119
+ If ``gp_noise_function'' is provided but no gradient function,
120
+ a finite-difference approximation will be used.
121
+ The same rules regarding ram economy as for the kernel definition apply here.
122
+ gp2Scale: bool, optional
123
+ Turns on gp2Scale. This will distribute the covariance computations across multiple workers.
124
+ This is an advanced feature for HPC GPs up to 10
125
+ million datapoints. If gp2Scale is used, the default kernel is an anisotropic Wendland
126
+ kernel which is compactly supported. The noise function will have
127
+ to return a scipy.sparse matrix instead of a numpy array. There are a few more things
128
+ to consider (read on); this is an advanced option.
129
+ If no kernel is provided, the compute_device option should be revisited. The kernel will
130
+ use the specified device to compute covariances.
131
+ The default is False.
132
+ gp2Scale_dask_client : dask.distributed.Client, optional
133
+ A dask client for gp2Scale to distribute covariance computations over. Has to contain at least 3 workers.
134
+ On HPC architecture, this client is provided by the jobscript. Please have a look at the examples.
135
+ A local client is used as default.
136
+ gp2Scale_batch_size : int, optional
137
+ Matrix batch size for distributed computing in gp2Scale. The default is 10000.
138
+ calc_inv : bool, optional
139
+ If True, the algorithm calculates and stores the inverse of the covariance
140
+ matrix after each training or update of the dataset or hyperparameters,
141
+ which makes computing the posterior covariance faster (5-10 times).
142
+ For larger problems (>2000 data points), the use of inversion should be avoided due
143
+ to computational instability and costs. The default is
144
+ False. Note, the training will always use Cholesky or LU decomposition instead of the
145
+ inverse for stability reasons. Storing the inverse is
146
+ a good option when the dataset is not too large and the posterior covariance is heavily used.
147
+ ram_economy : bool, optional
148
+ Only of interest if the gradient and/or Hessian of the marginal log_likelihood
149
+ is/are used for the training.
150
+ If True, components of the derivative of the marginal log-likelihood are calculated
151
+ subsequently, leading to a slow-down
152
+ but much less RAM usage. If the derivative of the kernel (or noise function) with
153
+ respect to the hyperparameters (gp_kernel_function_grad) is
154
+ going to be provided, it has to be tailored: for ram_economy=True it should be of
155
+ the form f(x1[, x2], direction, hyperparameters, obj)
156
+ and return a 2d numpy array of shape len(x1) x len(x2).
157
+ If ram_economy=False, the function should be of the form f(x1[, x2,] hyperparameters, obj)
158
+ and return a numpy array of shape
159
+ H x len(x1) x len(x2), where H is the number of hyperparameters. CAUTION:
160
+ This array will be stored and is very large.
161
+ args : any, optional
162
+ args will be a class attribute and therefore available to kernel, noise and prior mean functions.
163
+ info : bool, optional
164
+ Provides a way how to see the progress of gp2Scale, Default is False
165
+
166
+ Attributes
167
+ ----------
168
+ x_data : np.ndarray
169
+ Datapoint positions
170
+ y_data : np.ndarray
171
+ Datapoint values
172
+ fvgp_x_data : np.ndarray
173
+ Datapoint positions as seen by fvgp
174
+ fvgp_y_data : np.ndarray
175
+ Datapoint values as seen by fvgp
176
+ noise_variances : np.ndarray
177
+ Datapoint observation (co)variances.
178
+ prior.hyperparameters : np.ndarray
179
+ Current hyperparameters in use.
180
+ prior.K : np.ndarray
181
+ Current prior covariance matrix of the GP
182
+ prior.m : np.ndarray
183
+ Current prior mean vector.
184
+ marginal_density.KVinv : np.ndarray
185
+ If enabled, the inverse of the prior covariance + nose matrix V
186
+ inv(K+V)
187
+ marginal_density.KVlogdet : float
188
+ logdet(K+V)
189
+ likelihood.V : np.ndarray
190
+ the noise covariance matrix
191
+
192
+
193
+ This class inherits all capabilities from :py:class:`fvgp.GP`.
194
+ Check there for a full list of capabilities. Here are the most important.
195
+
196
+ Base-GP Methods:
197
+
198
+ :py:meth:`fvgp.GP.train`
199
+
200
+ :py:meth:`fvgp.GP.train_async`
201
+
202
+ :py:meth:`fvgp.GP.stop_training`
203
+
204
+ :py:meth:`fvgp.GP.kill_training`
205
+
206
+ :py:meth:`fvgp.GP.update_hyperparameters`
207
+
208
+ :py:meth:`fvgp.GP.set_hyperparameters`
209
+
210
+ :py:meth:`fvgp.GP.get_hyperparameters`
211
+
212
+ Posterior Evaluations:
213
+
214
+ :py:meth:`fvgp.GP.posterior_mean`
215
+
216
+ :py:meth:`fvgp.GP.posterior_covariance`
217
+
218
+ :py:meth:`fvgp.GP.posterior_mean_grad`
219
+
220
+ :py:meth:`fvgp.GP.posterior_covariance_grad`
221
+
222
+ :py:meth:`fvgp.GP.joint_gp_prior`
223
+
224
+ :py:meth:`fvgp.GP.joint_gp_prior_grad`
225
+
226
+ :py:meth:`fvgp.GP.gp_entropy`
227
+
228
+ :py:meth:`fvgp.GP.gp_entropy_grad`
229
+
230
+ :py:meth:`fvgp.GP.gp_kl_div`
231
+
232
+ :py:meth:`fvgp.GP.gp_kl_div_grad`
233
+
234
+ :py:meth:`fvgp.GP.gp_mutual_information`
235
+
236
+ :py:meth:`fvgp.GP.gp_total_correlation`
237
+
238
+ :py:meth:`fvgp.GP.gp_relative_information_entropy`
239
+
240
+ :py:meth:`fvgp.GP.gp_relative_information_entropy_set`
241
+
242
+ :py:meth:`fvgp.GP.posterior_probability`
243
+
244
+ :py:meth:`fvgp.GP.posterior_probability_grad`
245
+
246
+ Validation Methods:
247
+
248
+ :py:meth:`fvgp.GP.crps`
249
+
250
+ :py:meth:`fvgp.GP.rmse`
251
+
252
+ :py:meth:`fvgp.GP.make_2d_x_pred`
253
+
254
+ :py:meth:`fvgp.GP.make_1d_x_pred`
255
+
256
+ :py:meth:`fvgp.GP.log_likelihood`
257
+
258
+ :py:meth:`fvgp.GP.test_log_likelihood_gradient`
259
+ """
260
+
261
+ def __init__(
262
+ self,
263
+ x_data,
264
+ y_data,
265
+ init_hyperparameters=None,
266
+ output_positions=None,
267
+ noise_variances=None,
268
+ compute_device="cpu",
269
+ gp_kernel_function=None,
270
+ gp_kernel_function_grad=None,
271
+ gp_noise_function=None,
272
+ gp_noise_function_grad=None,
273
+ gp_mean_function=None,
274
+ gp_mean_function_grad=None,
275
+ gp2Scale=False,
276
+ gp2Scale_dask_client=None,
277
+ gp2Scale_batch_size=10000,
278
+ calc_inv=False,
279
+ ram_economy=False,
280
+ args=None,
281
+ info=False,
282
+ ):
283
+
284
+ if isinstance(x_data, np.ndarray):
285
+ assert np.ndim(x_data) == 2
286
+ self.input_space_dim = x_data.shape[1]
287
+ else: self.input_space_dim = 1
288
+
289
+ self.output_num = y_data.shape[1]
290
+ output_space_dim = 1
291
+ ###check the output dims
292
+
293
+ if np.ndim(y_data) == 1:
294
+ raise ValueError("The output number is 1, you can use GP for single-task GPs")
295
+ if output_space_dim == 1 and isinstance(output_positions, np.ndarray) is False:
296
+ self.output_positions = self._compute_standard_output_positions(len(x_data))
297
+ else:
298
+ self.output_positions = output_positions
299
+
300
+ assert isinstance(self.output_positions, np.ndarray) and np.ndim(self.output_positions) == 2
301
+ self.index_set_dim = self.input_space_dim + output_space_dim
302
+ ####transform the space
303
+ self.fvgp_x_data = x_data
304
+ self.fvgp_y_data = y_data
305
+ self.fvgp_noise_variances = noise_variances
306
+ x_data, y_data, noise_variances = self._transform_index_set(x_data, y_data, noise_variances,
307
+ self.output_positions)
308
+
309
+ ####init GP
310
+ super().__init__(
311
+ x_data,
312
+ y_data,
313
+ init_hyperparameters=init_hyperparameters,
314
+ noise_variances=noise_variances,
315
+ compute_device=compute_device,
316
+ gp_kernel_function=gp_kernel_function,
317
+ gp_kernel_function_grad=gp_kernel_function_grad,
318
+ gp_mean_function=gp_mean_function,
319
+ gp_mean_function_grad=gp_mean_function_grad,
320
+ gp_noise_function=gp_noise_function,
321
+ gp_noise_function_grad=gp_noise_function_grad,
322
+ gp2Scale=gp2Scale,
323
+ gp2Scale_dask_client=gp2Scale_dask_client,
324
+ gp2Scale_batch_size=gp2Scale_batch_size,
325
+ calc_inv=calc_inv,
326
+ ram_economy=ram_economy,
327
+ args=args,
328
+ info=info)
329
+
330
+ def update_gp_data(
331
+ self,
332
+ x_new,
333
+ y_new,
334
+ noise_variances_new=None,
335
+ append=True,
336
+ output_positions_new=None,
337
+ ):
338
+
339
+ """
340
+ This function updates the data in the gp object instance.
341
+ The data will NOT be appended but overwritten!
342
+ Please provide the full updated data set.
343
+
344
+ Parameters
345
+ ----------
346
+ x_new : np.ndarray
347
+ The point positions. Shape (V x D), where D is the `input_space_dim`.
348
+ y_new : np.ndarray
349
+ The values of the data points. Shape (V,1) or (V).
350
+ noise_variances_new : np.ndarray, optional
351
+ An numpy array defining the uncertainties in the data `y_data` in form of a point-wise variance.
352
+ Shape (len(y_data), 1) or (len(y_data)).
353
+ Note: if no variances are provided here, the noise_covariance
354
+ callable will be used; if the callable is not provided the noise variances
355
+ will be set to `abs(np.mean(y_data)) / 100.0`. If you provided a noise function,
356
+ the noise_variances_new will be ignored.
357
+ append : bool, optional
358
+ Indication whether to append to or overwrite the existing dataset. Default = True.
359
+ In the default case, data will be appended.
360
+ output_positions_new : np.ndarray, optional
361
+ A 3-D numpy array of shape (U x output_number x output_dim), so that
362
+ for each measurement position, the outputs
363
+ are clearly defined by their positions in the output space.
364
+ The default is np.array([[0,1,2,3,...,output_number - 1],[0,1,2,3,...,output_number - 1],...]).
365
+ """
366
+
367
+ ##########################################
368
+ #######prepare value positions############
369
+ ##########################################
370
+ if not isinstance(output_positions_new, np.ndarray):
371
+ output_positions_new = self._compute_standard_output_positions(len(x_new))
372
+ ######################################
373
+ #####transform to index set###########
374
+ ######################################
375
+ x_data, y_data, noise_variances = self._transform_index_set(x_new, y_new, noise_variances_new,
376
+ output_positions_new)
377
+ super().update_gp_data(x_data, y_data, noise_variances, append=append)
378
+ self.output_positions = np.row_stack([self.output_positions, output_positions_new])
379
+
380
+ ################################################################################################
381
+ def _compute_standard_output_positions(self, point_number):
382
+ value_pos = np.zeros((point_number, self.output_num))
383
+ for j in range(self.output_num):
384
+ value_pos[:, j] = j
385
+ return value_pos
386
+
387
+ ################################################################################################
388
+ def _transform_index_set(self, x_data, y_data, noise_variances, output_positions):
389
+ point_number = len(x_data)
390
+ assert isinstance(x_data, np.ndarray) or isinstance(x_data, list)
391
+ if isinstance(x_data, np.ndarray):
392
+ new_points = np.zeros((point_number * self.output_num, self.index_set_dim))
393
+ else:
394
+ new_points = [0.] * point_number * self.output_num
395
+ new_values = np.zeros((point_number * self.output_num))
396
+ if noise_variances is not None:
397
+ new_variances = np.zeros((point_number * self.output_num))
398
+ else:
399
+ new_variances = None
400
+ for i in range(self.output_num):
401
+ if isinstance(x_data, np.ndarray):
402
+ new_points[i * point_number: (i + 1) * point_number] = np.column_stack([x_data, output_positions[:, i]])
403
+ if isinstance(x_data, list):
404
+ for j in range(len(x_data)):
405
+ new_points[i * point_number + j] = [x_data[j], output_positions[j, i]]
406
+ new_values[i * point_number: (i + 1) * point_number] = y_data[:, i]
407
+ if noise_variances is not None:
408
+ new_variances[i * point_number: (i + 1) * point_number] = noise_variances[:, i]
409
+
410
+ return new_points, new_values, new_variances
411
+
412
+ ################################################################################################
413
+