@@ -330,7 +330,7 @@ def L(self) -> pt.TensorVariable:
330
330
def L (self , value : TensorLike ):
331
331
self ._L = pt .as_tensor_variable (value )
332
332
333
- def prior_linearized (self , Xs : TensorLike ):
333
+ def prior_linearized (self , X : TensorLike ):
334
334
"""Linearized version of the HSGP. Returns the Laplace eigenfunctions and the square root
335
335
of the power spectral density needed to create the GP.
336
336
@@ -343,7 +343,7 @@ def prior_linearized(self, Xs: TensorLike):
343
343
344
344
Parameters
345
345
----------
346
- Xs : array-like
346
+ X : array-like
347
347
Function input values.
348
348
349
349
Returns
@@ -371,9 +371,9 @@ def prior_linearized(self, Xs: TensorLike):
371
371
# L = [10] means the approximation is valid from Xs = [-10, 10]
372
372
gp = pm.gp.HSGP(m=[200], L=[10], cov_func=cov_func)
373
373
374
+ # Set X as Data so it can be mutated later, and then pass it to the GP
374
375
X = pm.Data("X", X)
375
- # Pass X to the GP
376
- phi, sqrt_psd = gp.prior_linearized(Xs=X)
376
+ phi, sqrt_psd = gp.prior_linearized(X=X)
377
377
378
378
# Specify standard normal prior in the coefficients, the number of which
379
379
# is given by the number of basis vectors, saved in `n_basis_vectors`.
@@ -403,8 +403,8 @@ def prior_linearized(self, Xs: TensorLike):
403
403
# Important: fix the computation of the midpoint of X.
404
404
# If X is mutated later, the training midpoint will be subtracted, not the testing one.
405
405
if self ._X_center is None :
406
- self ._X_center = (pt .max (Xs , axis = 0 ) + pt .min (Xs , axis = 0 )).eval () / 2
407
- Xs = Xs - self ._X_center # center for accurate computation
406
+ self ._X_center = (pt .max (X , axis = 0 ) + pt .min (X , axis = 0 )).eval () / 2
407
+ Xs = X - self ._X_center # center for accurate computation
408
408
409
409
# Index Xs using input_dim and active_dims of covariance function
410
410
Xs , _ = self .cov_func ._slice (Xs )
@@ -600,7 +600,7 @@ def __init__(
600
600
601
601
super ().__init__ (mean_func = mean_func , cov_func = cov_func )
602
602
603
- def prior_linearized (self , Xs : TensorLike ):
603
+ def prior_linearized (self , X : TensorLike ):
604
604
"""Linearized version of the approximation. Returns the cosine and sine bases and coefficients
605
605
of the expansion needed to create the GP.
606
606
@@ -615,8 +615,8 @@ def prior_linearized(self, Xs: TensorLike):
615
615
616
616
Parameters
617
617
----------
618
- Xs : array-like
619
- Function input values. Assumes they have been mean subtracted or centered at zero.
618
+ X : array-like
619
+ Function input values.
620
620
621
621
Returns
622
622
-------
@@ -640,15 +640,9 @@ def prior_linearized(self, Xs: TensorLike):
640
640
# m=200 means 200 basis vectors
641
641
gp = pm.gp.HSGPPeriodic(m=200, scale=scale, cov_func=cov_func)
642
642
643
- # Order is important. First calculate the mean, then make X a shared variable,
644
- # then subtract the mean. When X is mutated later, the correct mean will be
645
- # subtracted.
646
- X_mean = np.mean(X, axis=0)
647
- X = pm.MutableData("X", X)
648
- Xs = X - X_mean
649
-
650
- # Pass the zero-subtracted Xs in to the GP
651
- (phi_cos, phi_sin), psd = gp.prior_linearized(Xs=Xs)
643
+ # Set X as Data so it can be mutated later, and then pass it to the GP
644
+ X = pm.Data("X", X)
645
+ (phi_cos, phi_sin), psd = gp.prior_linearized(X=X)
652
646
653
647
# Specify standard normal prior in the coefficients. The number of which
654
648
# is twice the number of basis vectors minus one.
@@ -675,6 +669,13 @@ def prior_linearized(self, Xs: TensorLike):
675
669
with model:
676
670
ppc = pm.sample_posterior_predictive(idata, var_names=["f"])
677
671
"""
672
+ # Important: fix the computation of the midpoint of X.
673
+ # If X is mutated later, the training midpoint will be subtracted, not the testing one.
674
+ if self ._X_center is None :
675
+ self ._X_center = (pt .max (Xs , axis = 0 ) + pt .min (Xs , axis = 0 )).eval () / 2
676
+ Xs = Xs - self ._X_center # center for accurate computation
677
+
678
+ # Index Xs using input_dim and active_dims of covariance function
678
679
Xs , _ = self .cov_func ._slice (Xs )
679
680
680
681
phi_cos , phi_sin = calc_basis_periodic (Xs , self .cov_func .period , self ._m , tl = pt )
@@ -697,9 +698,7 @@ def prior(self, name: str, X: TensorLike, dims: str | None = None): # type: ign
697
698
dims: None
698
699
Dimension name for the GP random variable.
699
700
"""
700
- self ._X_mean = pt .mean (X , axis = 0 )
701
-
702
- (phi_cos , phi_sin ), psd = self .prior_linearized (X - self ._X_mean )
701
+ (phi_cos , phi_sin ), psd = self .prior_linearized (X )
703
702
704
703
m = self ._m
705
704
self ._beta = pm .Normal (f"{ name } _hsgp_coeffs_" , size = (m * 2 - 1 ))
0 commit comments