fvgp 4.2.2__tar.gz → 4.2.3__tar.gz

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.
Files changed (40) hide show
  1. {fvgp-4.2.2/fvgp.egg-info → fvgp-4.2.3}/PKG-INFO +1 -1
  2. {fvgp-4.2.2 → fvgp-4.2.3}/fvgp/_version.py +3 -3
  3. {fvgp-4.2.2 → fvgp-4.2.3}/fvgp/fvgp.py +3 -8
  4. {fvgp-4.2.2 → fvgp-4.2.3}/fvgp/gp.py +50 -110
  5. {fvgp-4.2.2 → fvgp-4.2.3}/fvgp/gpMCMC.py +8 -7
  6. {fvgp-4.2.2 → fvgp-4.2.3}/fvgp/gp_marginal_density.py +4 -6
  7. {fvgp-4.2.2 → fvgp-4.2.3}/fvgp/gp_posterior.py +50 -52
  8. {fvgp-4.2.2 → fvgp-4.2.3/fvgp.egg-info}/PKG-INFO +1 -1
  9. {fvgp-4.2.2 → fvgp-4.2.3}/tests/test_fvgp.py +18 -3
  10. {fvgp-4.2.2 → fvgp-4.2.3}/AUTHORS.rst +0 -0
  11. {fvgp-4.2.2 → fvgp-4.2.3}/CONTRIBUTING.rst +0 -0
  12. {fvgp-4.2.2 → fvgp-4.2.3}/COPYING +0 -0
  13. {fvgp-4.2.2 → fvgp-4.2.3}/HISTORY.rst +0 -0
  14. {fvgp-4.2.2 → fvgp-4.2.3}/LICENSE +0 -0
  15. {fvgp-4.2.2 → fvgp-4.2.3}/MANIFEST.in +0 -0
  16. {fvgp-4.2.2 → fvgp-4.2.3}/README.md +0 -0
  17. {fvgp-4.2.2 → fvgp-4.2.3}/docs/Makefile +0 -0
  18. {fvgp-4.2.2 → fvgp-4.2.3}/docs/make.bat +0 -0
  19. {fvgp-4.2.2 → fvgp-4.2.3}/docs/source/_static/landing.png +0 -0
  20. {fvgp-4.2.2 → fvgp-4.2.3}/docs/source/conf.py +0 -0
  21. {fvgp-4.2.2 → fvgp-4.2.3}/fvgp/__init__.py +0 -0
  22. {fvgp-4.2.2 → fvgp-4.2.3}/fvgp/deep_kernel_network.py +0 -0
  23. {fvgp-4.2.2 → fvgp-4.2.3}/fvgp/gp_data.py +0 -0
  24. {fvgp-4.2.2 → fvgp-4.2.3}/fvgp/gp_kernels.py +0 -0
  25. {fvgp-4.2.2 → fvgp-4.2.3}/fvgp/gp_likelihood.py +0 -0
  26. {fvgp-4.2.2 → fvgp-4.2.3}/fvgp/gp_lin_alg.py +0 -0
  27. {fvgp-4.2.2 → fvgp-4.2.3}/fvgp/gp_prior.py +0 -0
  28. {fvgp-4.2.2 → fvgp-4.2.3}/fvgp/gp_training.py +0 -0
  29. {fvgp-4.2.2 → fvgp-4.2.3}/fvgp/mcmc.py +0 -0
  30. {fvgp-4.2.2 → fvgp-4.2.3}/fvgp.egg-info/SOURCES.txt +0 -0
  31. {fvgp-4.2.2 → fvgp-4.2.3}/fvgp.egg-info/dependency_links.txt +0 -0
  32. {fvgp-4.2.2 → fvgp-4.2.3}/fvgp.egg-info/entry_points.txt +0 -0
  33. {fvgp-4.2.2 → fvgp-4.2.3}/fvgp.egg-info/not-zip-safe +0 -0
  34. {fvgp-4.2.2 → fvgp-4.2.3}/fvgp.egg-info/requires.txt +0 -0
  35. {fvgp-4.2.2 → fvgp-4.2.3}/fvgp.egg-info/top_level.txt +0 -0
  36. {fvgp-4.2.2 → fvgp-4.2.3}/setup.cfg +0 -0
  37. {fvgp-4.2.2 → fvgp-4.2.3}/setup.py +0 -0
  38. {fvgp-4.2.2 → fvgp-4.2.3}/tests/__init__.py +0 -0
  39. {fvgp-4.2.2 → fvgp-4.2.3}/tests/latest_hps.npy +0 -0
  40. {fvgp-4.2.2 → fvgp-4.2.3}/versioneer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fvgp
3
- Version: 4.2.2
3
+ Version: 4.2.3
4
4
  Summary: Python package for highly flexible function-valued Gaussian processes (fvGP)
5
5
  Home-page: https://github.com/MarcusMichaelNoack/fvgp
6
6
  Author: Marcus Michael Noack
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2024-05-31T14:47:35-0700",
11
+ "date": "2024-06-04T16:02:02-0700",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "c7d74e2e459b81c40049a2af64298d8d63111af3",
15
- "version": "4.2.2"
14
+ "full-revisionid": "ecd6703d29e227a0204fc15bb6f03aef33fc31ff",
15
+ "version": "4.2.3"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -147,11 +147,6 @@ class fvGP(GP):
147
147
  False. Note, the training will always use Cholesky or LU decomposition instead of the
148
148
  inverse for stability reasons. Storing the inverse is
149
149
  a good option when the dataset is not too large and the posterior covariance is heavily used.
150
- online : bool, optional
151
- A new setting that allows optimization for online applications. Default=False. If True,
152
- calc_inv will be set to true, and the inverse and the logdet() of full dataset will only be computed
153
- once in the beginning and after that only updated. This leads to a significant speedup because
154
- the most costly aspects of a GP are entirely avoided.
155
150
  ram_economy : bool, optional
156
151
  Only of interest if the gradient and/or Hessian of the marginal log_likelihood
157
152
  is/are used for the training.
@@ -216,13 +211,14 @@ class fvGP(GP):
216
211
  gp2Scale_dask_client=None,
217
212
  gp2Scale_batch_size=10000,
218
213
  calc_inv=False,
219
- online=False,
220
214
  ram_economy=False,
221
215
  args=None,
222
216
  info=False,
223
217
  ):
224
218
 
225
- if isinstance(x_data, np.ndarray): self.orig_input_space_dim = x_data.shape[1]
219
+ if isinstance(x_data, np.ndarray):
220
+ assert np.ndim(x_data) == 2
221
+ self.orig_input_space_dim = x_data.shape[1]
226
222
  else: self.orig_input_space_dim = 1
227
223
 
228
224
  self.output_num = y_data.shape[1]
@@ -262,7 +258,6 @@ class fvGP(GP):
262
258
  gp2Scale_dask_client=gp2Scale_dask_client,
263
259
  gp2Scale_batch_size=gp2Scale_batch_size,
264
260
  calc_inv=calc_inv,
265
- online=online,
266
261
  ram_economy=ram_economy,
267
262
  args=args,
268
263
  info=info)
@@ -18,8 +18,8 @@ import sys
18
18
  # neither minres nor random logdet are doing a good job in gp2Scale,
19
19
  # cg is better but we might need a preconditioner , maybe a large LU?
20
20
  # the mcmc in default mode should not need proposal distributions explicitly
21
- # reshape posteriors if x_out
22
- # when are we really using gpu vs cpu as compute_device
21
+ # reshape posteriors if x_out is given
22
+ # variational inference in fvgp
23
23
 
24
24
 
25
25
  class GP:
@@ -143,14 +143,6 @@ class GP:
143
143
  False. Note, the training will always use Cholesky or LU decomposition instead of the
144
144
  inverse for stability reasons. Storing the inverse is
145
145
  a good option when the dataset is not too large and the posterior covariance is heavily used.
146
- online : bool, optional
147
- A new setting that allows optimization for online applications. Default=False. If True,
148
- the inverse (if calc_inv is True), or the Cholesky factors (if calc_inv is False) and the logdet()
149
- will only be computed
150
- once in the beginning and after that only updated. This leads to a significant speedup because
151
- the most costly aspects of a GP are entirely avoided. A good indicator whether `online` is a good choice is
152
- the `append` option in the gp update. You always append data, never overwrite, online should be True
153
- to save some time.
154
146
  ram_economy : bool, optional
155
147
  Only of interest if the gradient and/or Hessian of the marginal log_likelihood is/are used for the training.
156
148
  If True, components of the derivative of the marginal log-likelihood are
@@ -210,7 +202,6 @@ class GP:
210
202
  gp2Scale_dask_client=None,
211
203
  gp2Scale_batch_size=10000,
212
204
  calc_inv=False,
213
- online=False,
214
205
  ram_economy=False,
215
206
  args=None,
216
207
  info=False
@@ -222,6 +213,8 @@ class GP:
222
213
  logger.remove()
223
214
  logger.enable("fvgp")
224
215
  logger.add(sys.stdout, filter="fvgp", level="INFO")
216
+ else:
217
+ logger.disable("fvgp")
225
218
  self.calc_inv = calc_inv
226
219
  self.gp2Scale = gp2Scale
227
220
  self.gp2Scale_dask_client = gp2Scale_dask_client
@@ -300,7 +293,6 @@ class GP:
300
293
  self.data,
301
294
  self.prior,
302
295
  self.likelihood,
303
- online=online,
304
296
  calc_inv=calc_inv,
305
297
  info=info,
306
298
  gp2Scale=gp2Scale,
@@ -369,7 +361,7 @@ class GP:
369
361
  self.prior.hyperparameters)
370
362
 
371
363
  # update marginal density
372
- self.marginal_density.update_data()
364
+ self.marginal_density.update_data(append)
373
365
  ##########################################
374
366
  self.x_data = self.data.x_data
375
367
  self.y_data = self.data.y_data
@@ -771,9 +763,9 @@ class GP:
771
763
  a constraint during training. The default is None which means the initialized or trained hyperparameters
772
764
  are used.
773
765
  x_out : np.ndarray, optional
774
- Output coordinates in case of multitask GP use; a numpy array of size (N x L),
775
- where N is the number of output points,
776
- and L is the dimensionality of the output space (most often 1).
766
+ Output coordinates in case of multitask GP use; a numpy array of size (N),
767
+ where N is the number evaluation points in the output direction.
768
+ Usually this is np.ndarray([0,1,2,...]).
777
769
 
778
770
  Return
779
771
  ------
@@ -796,9 +788,9 @@ class GP:
796
788
  a constraint during training. The default is None which means the initialized or trained hyperparameters
797
789
  are used.
798
790
  x_out : np.ndarray, optional
799
- Output coordinates in case of multitask GP use; a numpy array of size (N x L),
800
- where N is the number of output points,
801
- and L is the dimensionality of the output space.
791
+ Output coordinates in case of multitask GP use; a numpy array of size (N),
792
+ where N is the number evaluation points in the output direction.
793
+ Usually this is np.ndarray([0,1,2,...]).
802
794
  direction : int, optional
803
795
  Direction of derivative, If None (default) the whole gradient will be computed.
804
796
 
@@ -820,9 +812,9 @@ class GP:
820
812
  A numpy array of shape (V x D), interpreted as an array of input point positions or a list for
821
813
  GPs on non-Euclidean input spaces.
822
814
  x_out : np.ndarray, optional
823
- Output coordinates in case of multitask GP use; a numpy array of size (N x L),
824
- where N is the number of output points,
825
- and L is the dimensionality of the output space.
815
+ Output coordinates in case of multitask GP use; a numpy array of size (N),
816
+ where N is the number evaluation points in the output direction.
817
+ Usually this is np.ndarray([0,1,2,...]).
826
818
  variance_only : bool, optional
827
819
  If True the computation of the posterior covariance matrix is avoided which can save compute time.
828
820
  In that case the return will only provide the variance at the input points.
@@ -847,9 +839,9 @@ class GP:
847
839
  A numpy array of shape (V x D), interpreted as an array of input point positions or a list for
848
840
  GPs on non-Euclidean input spaces.
849
841
  x_out : np.ndarray, optional
850
- Output coordinates in case of multitask GP use; a numpy array of size (N x L),
851
- where N is the number of output points,
852
- and L is the dimensionality of the output space.
842
+ Output coordinates in case of multitask GP use; a numpy array of size (N),
843
+ where N is the number evaluation points in the output direction.
844
+ Usually this is np.ndarray([0,1,2,...]).
853
845
  direction : int, optional
854
846
  Direction of derivative, If None (default) the whole gradient will be computed.
855
847
 
@@ -870,9 +862,9 @@ class GP:
870
862
  A numpy array of shape (V x D), interpreted as an array of input point positions or a list for
871
863
  GPs on non-Euclidean input spaces.
872
864
  x_out : np.ndarray, optional
873
- Output coordinates in case of multitask GP use; a numpy array of size (N x L),
874
- where N is the number of output points,
875
- and L is the dimensionality of the output space.
865
+ Output coordinates in case of multitask GP use; a numpy array of size (N),
866
+ where N is the number evaluation points in the output direction.
867
+ Usually this is np.ndarray([0,1,2,...]).
876
868
 
877
869
  Return
878
870
  ------
@@ -894,9 +886,9 @@ class GP:
894
886
  direction : int
895
887
  Direction of derivative.
896
888
  x_out : np.ndarray, optional
897
- Output coordinates in case of multitask GP use; a numpy array of size (N x L),
898
- where N is the number of output points,
899
- and L is the dimensionality of the output space.
889
+ Output coordinates in case of multitask GP use; a numpy array of size (N),
890
+ where N is the number evaluation points in the output direction.
891
+ Usually this is np.ndarray([0,1,2,...]).
900
892
 
901
893
  Return
902
894
  ------
@@ -954,9 +946,9 @@ class GP:
954
946
  direction : int
955
947
  Direction of derivative.
956
948
  x_out : np.ndarray, optional
957
- Output coordinates in case of multitask GP use; a numpy array of size (N x L),
958
- where N is the number of output points,
959
- and L is the dimensionality of the output space.
949
+ Output coordinates in case of multitask GP use; a numpy array of size (N),
950
+ where N is the number evaluation points in the output direction.
951
+ Usually this is np.ndarray([0,1,2,...]).
960
952
 
961
953
  Return
962
954
  ------
@@ -1012,9 +1004,9 @@ class GP:
1012
1004
  comp_cov : np.ndarray
1013
1005
  Comparison covariance matrix for KL divergence. shape(comp_cov) = (len(x_pred),len(x_pred))
1014
1006
  x_out : np.ndarray, optional
1015
- Output coordinates in case of multitask GP use; a numpy array of size (N x L),
1016
- where N is the number of output points,
1017
- and L is the dimensionality of the output space.
1007
+ Output coordinates in case of multitask GP use; a numpy array of size (N),
1008
+ where N is the number evaluation points in the output direction.
1009
+ Usually this is np.ndarray([0,1,2,...]).
1018
1010
 
1019
1011
  Return
1020
1012
  -------
@@ -1039,9 +1031,9 @@ class GP:
1039
1031
  direction: int
1040
1032
  The direction in which the gradient will be computed.
1041
1033
  x_out : np.ndarray, optional
1042
- Output coordinates in case of multitask GP use; a numpy array of size (N x L),
1043
- where N is the number of output points,
1044
- and L is the dimensionality of the output space.
1034
+ Output coordinates in case of multitask GP use; a numpy array of size (N),
1035
+ where N is the number evaluation points in the output direction.
1036
+ Usually this is np.ndarray([0,1,2,...]).
1045
1037
 
1046
1038
  Return
1047
1039
  ------
@@ -1084,9 +1076,9 @@ class GP:
1084
1076
  A numpy array of shape (V x D), interpreted as an array of input point positions or a list for
1085
1077
  GPs on non-Euclidean input spaces.
1086
1078
  x_out : np.ndarray, optional
1087
- Output coordinates in case of multitask GP use; a numpy array of size (N x L),
1088
- where N is the number of output points,
1089
- and L is the dimensionality of the output space.
1079
+ Output coordinates in case of multitask GP use; a numpy array of size (N),
1080
+ where N is the number evaluation points in the output direction.
1081
+ Usually this is np.ndarray([0,1,2,...]).
1090
1082
 
1091
1083
  Return
1092
1084
  -------
@@ -1111,9 +1103,9 @@ class GP:
1111
1103
  A numpy array of shape (V x D), interpreted as an array of input point positions or a list for
1112
1104
  GPs on non-Euclidean input spaces.
1113
1105
  x_out : np.ndarray, optional
1114
- Output coordinates in case of multitask GP use; a numpy array of size (N x L),
1115
- where N is the number of output points,
1116
- and L is the dimensionality of the output space.
1106
+ Output coordinates in case of multitask GP use; a numpy array of size (N),
1107
+ where N is the number evaluation points in the output direction.
1108
+ Usually this is np.ndarray([0,1,2,...]).
1117
1109
 
1118
1110
  Return
1119
1111
  -------
@@ -1136,9 +1128,9 @@ class GP:
1136
1128
  A numpy array of shape (V x D), interpreted as an array of input point positions or a list for
1137
1129
  GPs on non-Euclidean input spaces.
1138
1130
  x_out : np.ndarray, optional
1139
- Output coordinates in case of multitask GP use; a numpy array of size (N x L),
1140
- where N is the number of output points,
1141
- and L is the dimensionality of the output space.
1131
+ Output coordinates in case of multitask GP use; a numpy array of size (N),
1132
+ where N is the number evaluation points in the output direction.
1133
+ Usually this is np.ndarray([0,1,2,...]).
1142
1134
 
1143
1135
  Return
1144
1136
  -------
@@ -1163,9 +1155,9 @@ class GP:
1163
1155
  A numpy array of shape (V x D), interpreted as an array of input point positions or a list for
1164
1156
  GPs on non-Euclidean input spaces.
1165
1157
  x_out : np.ndarray, optional
1166
- Output coordinates in case of multitask GP use; a numpy array of size (N x L),
1167
- where N is the number of output points,
1168
- and L is the dimensionality of the output space.
1158
+ Output coordinates in case of multitask GP use; a numpy array of size (N),
1159
+ where N is the number evaluation points in the output direction.
1160
+ Usually this is np.ndarray([0,1,2,...]).
1169
1161
 
1170
1162
  Return
1171
1163
  -------
@@ -1190,9 +1182,9 @@ class GP:
1190
1182
  comp_cov: np.nparray
1191
1183
  Covariance matrix, in R^{len(x_pred) times len(x_pred)}
1192
1184
  x_out : np.ndarray, optional
1193
- Output coordinates in case of multitask GP use; a numpy array of size (N x L),
1194
- where N is the number of output points,
1195
- and L is the dimensionality of the output space.
1185
+ Output coordinates in case of multitask GP use; a numpy array of size (N),
1186
+ where N is the number evaluation points in the output direction.
1187
+ Usually this is np.ndarray([0,1,2,...]).
1196
1188
 
1197
1189
  Return
1198
1190
  -------
@@ -1218,9 +1210,9 @@ class GP:
1218
1210
  direction : int
1219
1211
  The direction to compute the gradient in.
1220
1212
  x_out : np.ndarray, optional
1221
- Output coordinates in case of multitask GP use; a numpy array of size (N x L),
1222
- where N is the number of output points,
1223
- and L is the dimensionality of the output space.
1213
+ Output coordinates in case of multitask GP use; a numpy array of size (N),
1214
+ where N is the number evaluation points in the output direction.
1215
+ Usually this is np.ndarray([0,1,2,...]).
1224
1216
 
1225
1217
  Return
1226
1218
  -------
@@ -1229,58 +1221,6 @@ class GP:
1229
1221
  given the GP posterior at a given point.
1230
1222
  """
1231
1223
  return self.posterior.posterior_probability_grad(x_pred, comp_mean, comp_cov, direction, x_out=x_out)
1232
-
1233
- ##################################################################################
1234
- ##################################################################################
1235
- ##################################################################################
1236
- ##################################################################################
1237
- ######################Compute#Covariance#Matrix###################################
1238
- ##################################################################################
1239
- ##################################################################################
1240
- def _normalize(self, data):
1241
- min_d = np.min(data)
1242
- max_d = np.max(data)
1243
- data = (data - min_d) / (max_d - min_d)
1244
- return data, min_d, max_d
1245
-
1246
- def normalize_y_data(self, y_data):
1247
- """
1248
- Function to normalize the y_data.
1249
- The user is responsible to normalize the noise accordingly.
1250
- This function will not update the object instance.
1251
-
1252
- Parameters
1253
- ----------
1254
- y_data : np.ndarray
1255
- Numpy array of shape (U).
1256
- """
1257
- return self._normalize(y_data)
1258
-
1259
- def _normalize_x_data(self, x_data):
1260
- n_x = np.empty(x_data.shape)
1261
- x_min = np.empty((len(x_data)))
1262
- x_max = np.empty((len(x_data)))
1263
- for i in range(len(self.x_data[0])):
1264
- n_x[:, i], x_min[i], x_max[i] = self._normalize(x_data[:, i])
1265
- return n_x, x_min, x_max
1266
-
1267
- def _normalize_x_pred(self, x_pred, x_min, x_max):
1268
- new_x_pred = np.empty(x_pred.shape)
1269
- for i in range(len(x_pred[0])):
1270
- new_x_pred[:, i] = (x_pred[:, i] - x_min[i]) / (x_max[i] - x_min[i])
1271
- return new_x_pred
1272
-
1273
- def _cartesian_product_noneuclid(self, x, y):
1274
- """
1275
- Input x,y have to be 2d numpy arrays
1276
- The return is the cartesian product of the two sets
1277
- """
1278
- res = []
1279
- for i in range(len(y)):
1280
- for j in range(len(x)):
1281
- res.append([x[j], y[i]])
1282
- return res
1283
-
1284
1224
  ####################################################################################
1285
1225
  ####################################################################################
1286
1226
  #######################VALIDATION###################################################
@@ -102,7 +102,7 @@ class gpMCMC:
102
102
  x0 : np.ndarray
103
103
  Starting point of the mcmc.
104
104
  info : bool
105
- Whether to print information is the mcmc runs (use logger).
105
+ Whether to print information about the mcmc iterations (using logger).
106
106
  break_condition : callable or string or None
107
107
  A break condition that specified when the mcmc is terminated. If None,
108
108
  mcmc will run until `n_updates` is reached. If callable will get the mcmc object instance as
@@ -194,8 +194,7 @@ class gpMCMC:
194
194
  assert callable(obj.prop_dist)
195
195
 
196
196
  # get proposed x (x_star)
197
- x_star[obj.indices] = obj.prop_dist(x_old[obj.indices].copy(), obj)
198
-
197
+ x_star[obj.indices] = obj.prop_dist(x_old[obj.indices].copy(), x_old, obj)
199
198
  # evaluate prior(x_star)
200
199
  prior_evaluation_x_star = self.prior_function(x_star, self.args)
201
200
  jump_trace = 0.
@@ -207,7 +206,7 @@ class gpMCMC:
207
206
  metr_ratio = np.exp(prior_evaluation_x_star + likelihood_star -
208
207
  prior_eval - likelihood)
209
208
  if np.isnan(metr_ratio): metr_ratio = 0.
210
- if metr_ratio > np.random.uniform(0, 1, 1):
209
+ if metr_ratio > np.random.uniform(0, 1, 1) or obj.auto_accept:
211
210
  x = x_star
212
211
  prior_eval = prior_evaluation_x_star
213
212
  likelihood = likelihood_star
@@ -224,7 +223,8 @@ class gpMCMC:
224
223
 
225
224
  ###############################################################
226
225
  class ProposalDistribution:
227
- def __init__(self, prop_dist,
226
+ def __init__(self,
227
+ prop_dist,
228
228
  indices,
229
229
  init_prop_Sigma=None,
230
230
  adapt_callable=None,
@@ -232,6 +232,7 @@ class ProposalDistribution:
232
232
  c_0=10,
233
233
  c_1=.8,
234
234
  K=10,
235
+ auto_accept=False,
235
236
  adapt_cov=True,
236
237
  prop_args=None):
237
238
  """
@@ -272,6 +273,7 @@ class ProposalDistribution:
272
273
  self.c_0 = c_0
273
274
  self.c_1 = c_1
274
275
  self.K = K
276
+ self.auto_accept = auto_accept
275
277
  self.adapt_cov = adapt_cov
276
278
  dim = len(indices)
277
279
  self.jump_trace = []
@@ -296,8 +298,7 @@ class ProposalDistribution:
296
298
  self.prop_args["prop_Sigma"] = init_prop_Sigma
297
299
  self.prop_args["sigma_m"] = 2.4 ** 2 / dim
298
300
 
299
- #########################################################
300
-
301
+ #########################################################
301
302
  def _adapt(self, end, mcmc_obj):
302
303
  K = self.K
303
304
  if (end % K) == 0:
@@ -11,7 +11,6 @@ class GPMarginalDensity:
11
11
  data_obj,
12
12
  prior_obj,
13
13
  likelihood_obj,
14
- online=False,
15
14
  calc_inv=False,
16
15
  info=False,
17
16
  gp2Scale=False,
@@ -21,15 +20,13 @@ class GPMarginalDensity:
21
20
  self.prior_obj = prior_obj
22
21
  self.likelihood_obj = likelihood_obj
23
22
  self.calc_inv = calc_inv
24
- self.online = online
25
23
  self.info = info
26
24
  self.y_data = data_obj.y_data
27
25
  self.gp2Scale = gp2Scale
28
26
  self.compute_device = compute_device
29
27
  if self.gp2Scale:
30
- self.online = False
31
28
  self.calc_inv = False
32
- warnings.warn("gp2Scale use forbids calc_inv=True or online=True. Both have been set to False")
29
+ warnings.warn("gp2Scale use forbids calc_inv=True; it has been set to False")
33
30
  self.KVlinalg = KVlinalg(info, compute_device)
34
31
  K, V, m = self._get_KVm()
35
32
  if self.gp2Scale: mode = self._set_gp2Scale_mode(K)
@@ -39,11 +36,12 @@ class GPMarginalDensity:
39
36
  self.KVinvY = self._set_KVinvY(K, V, m, mode)
40
37
 
41
38
  ##################################################################
42
- def update_data(self):
39
+ def update_data(self, append):
43
40
  """Update the marginal PDF when the data has changed in data likelihood or prior objects"""
44
41
  self.y_data = self.data_obj.y_data
45
42
  K, V, m = self._get_KVm()
46
- self.KVinvY = self._update_KVinvY(K, V, m)
43
+ if append: self.KVinvY = self._update_KVinvY(K, V, m)
44
+ else: self.KVinvY = self._set_KVinvY(K, V, m, self.KVlinalg.mode)
47
45
 
48
46
  def update_hyperparameters(self):
49
47
  """Update the marginal PDF when if hyperparameters have changed"""
@@ -1,31 +1,9 @@
1
1
  import numpy as np
2
- from .gp_lin_alg import solve
3
2
  from loguru import logger
4
- import warnings
5
3
  from scipy.sparse import issparse
6
4
  from .gp_lin_alg import *
7
5
 
8
6
 
9
- def cartesian_product(x, y):
10
- """
11
- Input x,y have to be 2d numpy arrays
12
- The return is the cartesian product of the two sets
13
- """
14
- res = []
15
- if isinstance(x, list) or isinstance(y, list):
16
- for i in range(len(y)):
17
- for j in range(len(x)):
18
- res.append((y[i], x[j]))
19
- return res
20
- elif isinstance(x, np.ndarray) and isinstance(y, np.ndarray):
21
- for i in range(len(y)):
22
- for j in range(len(x)):
23
- res.append(np.append(x[j], y[i]))
24
- return np.array(res)
25
- else:
26
- raise Exception("Cartesian product out of options")
27
-
28
-
29
7
  class GPposterior:
30
8
  def __init__(self,
31
9
  data_obj,
@@ -53,13 +31,15 @@ class GPposterior:
53
31
  hyperparameters = self.prior_obj.hyperparameters
54
32
 
55
33
  self._perform_input_checks(x_pred, x_out)
34
+ x_orig = x_pred.copy()
56
35
  if x_out is not None: x_pred = self.cartesian_product(x_pred, x_out)
57
36
 
58
37
  k = self.kernel(x_data, x_pred, hyperparameters, self)
59
38
  A = k.T @ KVinvY
60
39
  posterior_mean = self.mean_function(x_pred, hyperparameters, self) + A
40
+ if x_out is not None: posterior_mean = posterior_mean.reshape(len(x_orig), len(x_out), order='F')
61
41
 
62
- return {"x": x_pred,
42
+ return {"x": x_orig,
63
43
  "f(x)": posterior_mean}
64
44
 
65
45
  def posterior_mean_grad(self, x_pred, hyperparameters=None, x_out=None, direction=None):
@@ -75,6 +55,7 @@ class GPposterior:
75
55
  hyperparameters = self.prior_obj.hyperparameters
76
56
 
77
57
  self._perform_input_checks(x_pred, x_out)
58
+ x_orig = x_pred.copy()
78
59
  if x_out is not None: x_pred = self.cartesian_product(x_pred, x_out)
79
60
 
80
61
  f = self.mean_function(x_pred, hyperparameters, self)
@@ -83,20 +64,23 @@ class GPposterior:
83
64
  x1 = np.array(x_pred)
84
65
  x1[:, direction] = x1[:, direction] + eps
85
66
  mean_der = (self.mean_function(x1, hyperparameters, self) - f) / eps
86
- k = self.kernel(x_data, x_pred, hyperparameters, self)
67
+ #k = self.kernel(x_data, x_pred, hyperparameters, self)
87
68
  k_g = self.d_kernel_dx(x_pred, x_data, direction, hyperparameters)
88
69
  posterior_mean_grad = mean_der + (k_g @ KVinvY)
70
+ if x_out is not None: posterior_mean_grad = posterior_mean_grad.reshape(len(x_orig), len(x_out), order='F')
89
71
  else:
90
- posterior_mean_grad = np.zeros(x_pred.shape)
91
- for direction in range(len(x_pred[0])):
72
+ posterior_mean_grad = np.zeros((len(x_pred), x_orig.shape[1]))
73
+ for direction in range(len(x_orig[0])):
92
74
  x1 = np.array(x_pred)
93
75
  x1[:, direction] = x1[:, direction] + eps
94
76
  mean_der = (self.mean_function(x1, hyperparameters, self) - f) / eps
95
77
  k_g = self.d_kernel_dx(x_pred, x_data, direction, hyperparameters)
96
78
  posterior_mean_grad[:, direction] = mean_der + (k_g @ KVinvY)
97
79
  direction = "ALL"
80
+ if x_out is not None:
81
+ posterior_mean_grad = posterior_mean_grad.reshape(len(x_orig), len(x_orig[0]), len(x_out), order='F')
98
82
 
99
- return {"x": x_pred,
83
+ return {"x": x_orig,
100
84
  "direction": direction,
101
85
  "df/dx": posterior_mean_grad}
102
86
 
@@ -105,6 +89,7 @@ class GPposterior:
105
89
  x_data = self.data_obj.x_data.copy()
106
90
 
107
91
  self._perform_input_checks(x_pred, x_out)
92
+ x_orig = x_pred.copy()
108
93
  if x_out is not None: x_pred = self.cartesian_product(x_pred, x_out)
109
94
 
110
95
  k = self.kernel(x_data, x_pred, self.prior_obj.hyperparameters, self)
@@ -140,35 +125,45 @@ class GPposterior:
140
125
  else:
141
126
  warnings.warn("Noise could not be added, you did not provide a noise callable at initialization")
142
127
 
143
- return {"x": x_pred,
128
+ if x_out is not None:
129
+ v = v.reshape(len(x_orig), len(x_out), order='F')
130
+ if S is not None: S = S.reshape(len(x_orig), len(x_orig), len(x_out), len(x_out), order='F')
131
+
132
+ return {"x": x_orig,
144
133
  "v(x)": v,
145
134
  "S": S}
146
135
 
147
136
  def posterior_covariance_grad(self, x_pred, x_out=None, direction=None):
148
137
  x_data = self.data_obj.x_data.copy()
149
138
  self._perform_input_checks(x_pred, x_out)
139
+ x_orig = x_pred.copy()
150
140
  if x_out is not None: x_pred = self.cartesian_product(x_pred, x_out)
151
141
 
152
142
  k = self.kernel(x_data, x_pred, self.prior_obj.hyperparameters, self)
153
143
  k_covariance_prod = self.marginal_density_obj.KVlinalg.solve(k)
154
144
  if direction is not None:
155
145
  k_g = self.d_kernel_dx(x_pred, x_data, direction, self.prior_obj.hyperparameters).T
156
- kk = self.kernel(x_pred, x_pred, self.prior_obj.hyperparameters, self)
146
+ #kk = self.kernel(x_pred, x_pred, self.prior_obj.hyperparameters, self)
157
147
  x1 = np.array(x_pred)
158
148
  x2 = np.array(x_pred)
159
149
  eps = 1e-6
160
150
  x1[:, direction] = x1[:, direction] + eps
161
151
  kk_g = (self.kernel(x1, x1, self.prior_obj.hyperparameters, self) -
162
152
  self.kernel(x2, x2, self.prior_obj.hyperparameters, self)) / eps
163
- a = kk_g - (2.0 * k_g.T @ k_covariance_prod)
164
- return {"x": x_pred,
165
- "dv/dx": np.diag(a),
166
- "dS/dx": a}
153
+ dSdx = kk_g - (2.0 * k_g.T @ k_covariance_prod)
154
+ #print(dSdx.shape)
155
+ a = np.diag(dSdx)
156
+ if x_out is not None:
157
+ a = a.reshape(len(x_orig), len(x_out), order='F')
158
+ dSdx = dSdx.reshape(len(x_orig), len(x_orig), len(x_out), len(x_out), order='F')
159
+ return {"x": x_orig,
160
+ "dv/dx": a,
161
+ "dS/dx": dSdx}
167
162
  else:
168
- grad_v = np.zeros((len(x_pred), len(x_pred[0])))
169
- for direction in range(len(x_pred[0])):
163
+ grad_v = np.zeros((len(x_pred), len(x_orig[0])))
164
+ for direction in range(len(x_orig[0])):
170
165
  k_g = self.d_kernel_dx(x_pred, x_data, direction, self.prior_obj.hyperparameters).T
171
- kk = self.kernel(x_pred, x_pred, self.prior_obj.hyperparameters, self)
166
+ #kk = self.kernel(x_pred, x_pred, self.prior_obj.hyperparameters, self)
172
167
  x1 = np.array(x_pred)
173
168
  x2 = np.array(x_pred)
174
169
  eps = 1e-6
@@ -176,7 +171,10 @@ class GPposterior:
176
171
  kk_g = (self.kernel(x1, x1, self.prior_obj.hyperparameters, self) -
177
172
  self.kernel(x2, x2, self.prior_obj.hyperparameters, self)) / eps
178
173
  grad_v[:, direction] = np.diag(kk_g - (2.0 * k_g.T @ k_covariance_prod))
179
- return {"x": x_pred,
174
+
175
+ if x_out is not None: grad_v = grad_v.reshape(len(x_orig), len(x_orig[0]), len(x_out), order='F')
176
+
177
+ return {"x": x_orig,
180
178
  "dv/dx": grad_v}
181
179
 
182
180
  ###########################################################################
@@ -192,6 +190,7 @@ class GPposterior:
192
190
  post_mean = self.mean_function(x_pred, self.prior_obj.hyperparameters, self)
193
191
  joint_gp_prior_mean = np.append(prior_mean_vec, post_mean)
194
192
  joint_gp_prior_cov = np.block([[K, k], [k.T, kk]])
193
+
195
194
  return {"x": x_pred,
196
195
  "K": K + np.identity(len(K)) * 1e-9,
197
196
  "k": k,
@@ -219,10 +218,9 @@ class GPposterior:
219
218
  self.prior_obj.hyperparameters,
220
219
  self)) / (2.0 * eps)
221
220
  # post_mean = self.mean_function(x_pred, self.prior_obj.hyperparameters, self)
222
- mean_der = (self.mean_function(x1, self.prior_obj.hyperparameters, self) - self.mean_function(x2,
223
- self.prior_obj.hyperparameters,
224
- self)) / (
225
- 2.0 * eps)
221
+ mean_der = ((self.mean_function(x1, self.prior_obj.hyperparameters, self) -
222
+ self.mean_function(x2, self.prior_obj.hyperparameters,self)) /
223
+ (2.0 * eps))
226
224
  full_gp_prior_mean_grad = np.append(np.zeros(prior_mean_vec.shape), mean_der)
227
225
  prior_cov_grad = np.zeros(K.shape)
228
226
  return {"x": x_pred,
@@ -345,53 +343,53 @@ class GPposterior:
345
343
  def gp_mutual_information(self, x_pred, x_out=None):
346
344
  x_data, K = self.data_obj.x_data.copy(), self.prior_obj.K.copy() + (np.identity(len(self.prior_obj.K)) * 1e-9)
347
345
  self._perform_input_checks(x_pred, x_out)
346
+ x_orig = x_pred.copy()
348
347
  if x_out is not None: x_pred = self.cartesian_product(x_pred, x_out)
349
348
 
350
349
  k = self.kernel(x_data, x_pred, self.prior_obj.hyperparameters, self)
351
350
  kk = self.kernel(x_pred, x_pred, self.prior_obj.hyperparameters, self) + (np.identity(len(x_pred)) * 1e-9)
352
351
 
353
- joint_covariance = \
354
- np.asarray(np.block([[K, k],
355
- [k.T, kk]]))
356
- return {"x": x_pred,
352
+ joint_covariance = np.block([[K, k],[k.T, kk]])
353
+ return {"x": x_orig,
357
354
  "mutual information": self.mutual_information(joint_covariance, kk, K)}
358
355
 
359
356
  ###########################################################################
360
357
  def gp_total_correlation(self, x_pred, x_out=None):
361
358
  x_data, K = self.data_obj.x_data.copy(), self.prior_obj.K.copy() + (np.identity(len(self.prior_obj.K)) * 1e-9)
362
359
  self._perform_input_checks(x_pred, x_out)
360
+ x_orig = x_pred.copy()
363
361
  if x_out is not None: x_pred = self.cartesian_product(x_pred, x_out)
364
362
 
365
363
  k = self.kernel(x_data, x_pred, self.prior_obj.hyperparameters, self)
366
364
  kk = self.kernel(x_pred, x_pred, self.prior_obj.hyperparameters, self) + (np.identity(len(x_pred)) * 1e-9)
367
- joint_covariance = np.asarray(np.block([[K, k],
368
- [k.T, kk]]))
365
+ joint_covariance = np.block([[K, k],[k.T, kk]])
369
366
 
370
- prod_covariance = np.asarray(np.block([[K, k * 0.],
371
- [k.T * 0., kk * np.identity(len(kk))]]))
367
+ prod_covariance = np.block([[K, k * 0.],[k.T * 0., kk * np.identity(len(kk))]])
372
368
 
373
- return {"x": x_pred,
369
+ return {"x": x_orig,
374
370
  "total correlation": self.kl_div(np.zeros((len(joint_covariance))), np.zeros((len(joint_covariance))),
375
371
  joint_covariance, prod_covariance)}
376
372
 
377
373
  ###########################################################################
378
374
  def gp_relative_information_entropy(self, x_pred, x_out=None):
379
375
  self._perform_input_checks(x_pred, x_out)
376
+ x_orig = x_pred.copy()
380
377
  if x_out is not None: x_pred = self.cartesian_product(x_pred, x_out)
381
378
  kk = self.kernel(x_pred, x_pred, self.prior_obj.hyperparameters, self) + (np.identity(len(x_pred)) * 1e-9)
382
379
  post_cov = self.posterior_covariance(x_pred, x_out=None)["S"] + (np.identity(len(x_pred)) * 1e-9)
383
- return {"x": x_pred,
380
+ return {"x": x_orig,
384
381
  "RIE": self.kl_div(np.zeros((len(x_pred))), np.zeros((len(x_pred))), kk, post_cov)}
385
382
 
386
383
  ###########################################################################
387
384
  def gp_relative_information_entropy_set(self, x_pred, x_out=None):
388
385
  self._perform_input_checks(x_pred, x_out)
386
+ x_orig = x_pred.copy()
389
387
  if x_out is not None: x_pred = self.cartesian_product(x_pred, x_out)
390
388
  RIE = np.zeros((len(x_pred)))
391
389
  for i in range(len(x_pred)):
392
390
  RIE[i] = self.gp_relative_information_entropy(x_pred[i].reshape(1, len(x_pred[i])), x_out=None)["RIE"]
393
391
 
394
- return {"x": x_pred,
392
+ return {"x": x_orig,
395
393
  "RIE": RIE}
396
394
 
397
395
  ###########################################################################
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fvgp
3
- Version: 4.2.2
3
+ Version: 4.2.3
4
4
  Summary: Python package for highly flexible function-valued Gaussian processes (fvGP)
5
5
  Home-page: https://github.com/MarcusMichaelNoack/fvgp
6
6
  Author: Marcus Michael Noack
@@ -22,7 +22,7 @@ from distributed.utils_test import gen_cluster, client, loop, cluster_fixture, l
22
22
  from fvgp.gp_kernels import *
23
23
  from fvgp.gp_lin_alg import *
24
24
  from scipy import sparse
25
-
25
+ from fvgp.gp_kernels import *
26
26
 
27
27
 
28
28
 
@@ -69,13 +69,25 @@ def test_lin_alg():
69
69
 
70
70
 
71
71
  def test_single_task_init_basic():
72
+ def kernel(x1,x2,hps,obj):
73
+ d = get_distance_matrix(x1,x2)
74
+ return hps[0] * matern_kernel_diff1(d,3.)
75
+ def noise(x,hps,obj):
76
+ return np.identity(len(x))
72
77
  my_gp1 = GP(x_data, y_data, init_hyperparameters = np.array([1, 1, 1, 1, 1, 1]), compute_device = 'cpu', info = True)
78
+ my_gp1 = GP(x_data, y_data, init_hyperparameters = np.array([1, 1, 1, 1, 1, 1]), gp_kernel_function = kernel,
79
+ gp_noise_function=noise, compute_device = 'cpu', info = True, ram_economy=True)
80
+ my_gp1.marginal_density.neg_log_likelihood_hessian(hyperparameters=my_gp1.get_hyperparameters())
81
+ my_gp1 = GP(x_data, y_data, init_hyperparameters = np.array([1, 1, 1, 1, 1, 1]), gp_kernel_function = kernel,
82
+ gp_noise_function=noise, compute_device = 'cpu', info = True, ram_economy=False)
83
+ my_gp1.marginal_density.neg_log_likelihood_hessian(hyperparameters=my_gp1.get_hyperparameters())
73
84
  my_gp1 = GP(x_data, y_data, info = True)
74
85
  my_gp1 = GP(x_data, y_data, init_hyperparameters = np.array([1, 1, 1, 1, 1, 1]))
75
86
  my_gp1 = GP(x_data, y_data, init_hyperparameters = np.array([1, 1, 1, 1, 1, 1]), calc_inv = False, info = True)
76
87
  my_gp1 = GP(x_data, y_data, init_hyperparameters = np.array([1, 1, 1, 1, 1, 1]), args = {'a':2.})
77
88
  my_gp1.update_gp_data(x_data, y_data, append = True)
78
89
  my_gp1.update_gp_data(x_data, y_data, append = False)
90
+
79
91
 
80
92
  my_gp1 = GP(x_data, y_data, noise_variances = np.zeros(y_data.shape) + 0.01,init_hyperparameters = np.array([1, 1, 1, 1, 1, 1]), args = {'a':2.})
81
93
  my_gp1.update_gp_data(x_data, y_data, noise_variances_new = np.zeros(y_data.shape) + 0.01, append = True)
@@ -102,6 +114,7 @@ def test_single_task_init_basic():
102
114
  my_gp1.rmse(x_data[0:2] + 1., np.array([1.,2.]))
103
115
  my_gp1.make_2d_x_pred(np.array([1.,2.]),np.array([3.,4]))
104
116
  my_gp1.make_1d_x_pred(np.array([1.,2.]))
117
+ my_gp1._get_default_hyperparameter_bounds()
105
118
 
106
119
 
107
120
  def test_single_task_init_advanced():
@@ -205,7 +218,9 @@ def test_multi_task():
205
218
  my_fvgp.update_gp_data(x_data, y_data, append = False)
206
219
  my_fvgp.train(hyperparameter_bounds=np.array([[0.01,1],[0.01,10]]),
207
220
  method = "global", pop_size = 10, tolerance = 0.001, max_iter = 2)
208
- my_fvgp.posterior_mean(np.random.rand(10,5), x_out = np.zeros((1)))["f(x)"]
221
+ my_fvgp.posterior_mean(np.random.rand(10,5), x_out = np.array([0,1]))["f(x)"]
222
+ my_fvgp.posterior_mean_grad(np.random.rand(10,5), x_out = np.array([0,1]))["df/dx"]
223
+ my_fvgp.posterior_covariance(np.random.rand(10,5), x_out = np.array([0,1]))["v(x)"]
209
224
 
210
225
 
211
226
 
@@ -240,7 +255,7 @@ def test_gp2Scale(client):
240
255
  init_s = (np.diag(hps_bounds[:,1]-hps_bounds[:,0])/100.)**2
241
256
 
242
257
  from fvgp import gpMCMC
243
- def proposal_distribution(x0, obj):
258
+ def proposal_distribution(x0, hps, obj):
244
259
  cov = obj.prop_args["prop_Sigma"]
245
260
  proposal_hps = np.zeros((len(x0)))
246
261
  proposal_hps = np.random.multivariate_normal(
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes