@@ -301,11 +301,12 @@ def fit(self, outputs=None, linear_dims=None, continuous_dims=None, continuous_l
301301
302302 return self
303303
304- def _make_continuous_cov (self , continuous_cov_func , D_in , idx_s , n_s , ℓ_μ , ℓ_σ , stabilize = True , eps = 1e-6 ):
304+ def _make_continuous_cov (self , continuous_cov_func , D_in , idx_s , n_s , ℓ_μ , ℓ_σ , ARD = True , stabilize = True , eps = 1e-6 ):
305305
306306 def continuous_cov (suffix ):
307- # ℓ = pm.InverseGamma(f'ℓ_{suffix}', mu=ℓ_μ, sigma=ℓ_σ, shape=n_s)
308- ℓ = pm .Gamma (f'ℓ_{ suffix } ' , alpha = 2 , beta = 1 )
307+ shape = n_s if ARD else 1
308+ # ℓ = pm.InverseGamma(f'ℓ_{suffix}', mu=ℓ_μ, sigma=ℓ_σ, shape=shape)
309+ ℓ = pm .Gamma (f'ℓ_{ suffix } ' , alpha = 2 , beta = 1 , shape = shape )
309310 η = pm .Gamma (f'η_{ suffix } ' , alpha = 2 , beta = 1 )
310311 cov = η ** 2 * continuous_cov_func (input_dim = D_in , active_dims = idx_s , ls = ℓ )
311312 if stabilize :
@@ -336,7 +337,8 @@ def coreg_cov(suffix, D_out, idx):
336337 # TODO: add full probabilistic model description to docstring
337338 # TODO: allow dimension-specific continuous kernel specification
338339 # TODO: allow single multi-dimensional continuous kernel rather than independent kernels per dimension
339- def build_model (self , seed = None , continuous_kernel = 'ExpQuad' , heteroskedastic_inputs = False , heteroskedastic_outputs = True , sparse = False , n_u = 100 ):
340+ def build_model (self , seed = None , continuous_kernel = 'ExpQuad' , heteroskedastic_inputs = False ,
341+ heteroskedastic_outputs = True , sparse = False , n_u = 100 , ARD = True ):
340342 r"""Compile a marginalized pymc3 model for the GP.
341343
342344 Each dimension in :attr:`continuous_dims` is combined in an ExpQuad kernel with a principled
@@ -361,6 +363,10 @@ def build_model(self, seed=None, continuous_kernel='ExpQuad', heteroskedastic_in
361363 Whether to use a `sparse approximation`_ to the GP.
362364 n_u: int, default 100
363365 Number of inducing points to use for the sparse approximation, if required.
366+ ARD: bool, default True
367+ Whether to use "Automatic Relevance Determination" in the continuous kernel. If _True_, each continuous
368+ dimension receives its own lengthscale; otherwise a single lengthscale is used for all continuous
369+ dimensions.
364370
365371 Returns
366372 -------
@@ -392,7 +398,7 @@ def build_model(self, seed=None, continuous_kernel='ExpQuad', heteroskedastic_in
392398 'n_u' : n_u ,
393399 }
394400
395- gp_dict = self ._construct_kernels (X , continuous_kernel , seed , sparse , latent = False )
401+ gp_dict = self ._construct_kernels (X , continuous_kernel , seed , sparse , latent = False , ARD = ARD )
396402
397403 with self .model :
398404
@@ -474,7 +480,7 @@ def _prepare_lengthscales(self, X):
474480 ℓ_μ , ℓ_σ = [stat for stat in np .array ([get_ℓ_prior (dim ) for dim in X_s .T ]).T ]
475481 return ℓ_μ , ℓ_σ
476482
477- def _construct_kernels (self , X , continuous_kernel , seed , sparse , latent , stabilize = True , eps = 1e-6 ):
483+ def _construct_kernels (self , X , continuous_kernel , seed , sparse , latent , ARD = True , stabilize = True , eps = 1e-6 ):
478484
479485 continuous_kernels = ['ExpQuad' , 'RatQuad' , 'Matern32' , 'Matern52' , 'Exponential' , 'Cosine' ]
480486 assert_in ('Continuous kernel' , continuous_kernel , continuous_kernels )
@@ -487,7 +493,7 @@ def _construct_kernels(self, X, continuous_kernel, seed, sparse, latent, stabili
487493 ℓ_μ , ℓ_σ = self ._prepare_lengthscales (X )
488494
489495 continuous_cov = self ._make_continuous_cov (continuous_cov_func , D_in , idxs ['s' ], ns ['s' ], ℓ_μ , ℓ_σ ,
490- stabilize = stabilize , eps = eps )
496+ ARD = ARD , stabilize = stabilize , eps = eps )
491497 linear_cov = self ._make_linear_cov (D_in , idxs ['l' ], ns ['l' ])
492498 coreg_cov = self ._make_coreg_cov (D_in , seed )
493499
@@ -547,7 +553,7 @@ def _construct_kernels(self, X, continuous_kernel, seed, sparse, latent, stabili
547553 self .gp_dict = gp_dict
548554 return gp_dict
549555
550- def build_latent (self , seed = None , continuous_kernel = 'ExpQuad' , prior_name = 'latent_prior' , eps = 1e-6 ):
556+ def build_latent (self , seed = None , continuous_kernel = 'ExpQuad' , prior_name = 'latent_prior' , ARD = True , eps = 1e-6 ):
551557
552558 if self .additive :
553559 raise NotImplementedError ('Additive/latent GPs are not yet implemented' )
@@ -562,7 +568,8 @@ def build_latent(self, seed=None, continuous_kernel='ExpQuad', prior_name='laten
562568 self .sparse = False
563569 self .latent = True
564570
565- gp_dict = self ._construct_kernels (X , continuous_kernel , seed , sparse = False , latent = True , stabilize = True , eps = eps )
571+ gp_dict = self ._construct_kernels (X , continuous_kernel , seed , sparse = False , latent = True , ARD = ARD ,
572+ stabilize = True , eps = eps )
566573
567574 with self .model :
568575 self .prior = gp_dict ['total' ].prior (prior_name , X = X )
0 commit comments