21
21
from pytuq .utils .mindex import get_mi
22
22
from pytuq .lreg .lreg import lsq
23
23
from pytuq .lreg .anl import anl
24
+ from pytuq .lreg .bcs import bcs
24
25
25
26
26
27
class PCE :
@@ -33,12 +34,13 @@ class PCE:
33
34
pctype (list[str]): Type of PC polynomial used.
34
35
outdim (int): Physical dimensionality, i.e. # of output variables.
35
36
lreg (lreg object): Linear regression object used for fitting the model.
37
+ mindex (int np.ndarray): Multiindex array carrying the powers to which the basis functions will be raised to within the PC terms.
36
38
regression_method (str): Method used for linear regression. ex] anl, opt, lsq
37
39
_x_train (np.ndarray): Input training data
38
40
_y_train (np.ndarray): Output training data, corresponding to x_train
39
41
"""
40
42
41
- def __init__ (self , pce_dim , pce_order , pce_type , ** kwargs ):
43
+ def __init__ (self , pce_dim , pce_order , pce_type , verbose = 0 , ** kwargs ):
42
44
r"""Initializes a Polynomial Chaos Random Variable (PCRV) with, at minimum:
43
45
stochastic dimensionality, order, and polynomial chaos (PC) type.
44
46
@@ -48,6 +50,7 @@ def __init__(self, pce_dim, pce_order, pce_type, **kwargs):
48
50
pce_order (int): Order of the PC expansion.
49
51
pce_type (str or list): PC type. Either a list of :math:`s` strings (one per stochastic dimension),
50
52
or a single string for all dimensions. Supported types include 'LU' (Legendre) and 'HG' (Hermite-Gaussian).
53
+ verbose (int): Output verbosity. Higher values print out more information. Default of 0
51
54
pce_outdim (int, optional): Physical dimensionality :math:`s` of the PC random variable/vector.
52
55
Default of 1 indicates a scalar-valued output.
53
56
mi (list or np.ndarray, optional): List of :math:`d` multiindex arrays, each of size :math:`(K_i,s)` for :math:`i=1, \dots, d`.
@@ -66,18 +69,24 @@ def __init__(self, pce_dim, pce_order, pce_type, **kwargs):
66
69
self .order = pce_order
67
70
self .pctype = pce_type # Choose from options: 'LU', 'HG', or mix of ['HG', 'LU']
68
71
self .outdim = kwargs .get ('pce_outdim' , 1 ) # Scalar valued output
72
+ self .verbose = verbose
69
73
70
74
self .lreg = None
71
75
self ._x_train = None
72
76
self ._y_train = None
73
77
self .regression_method = None
74
78
79
+ # Get the original multiindex, before possible modification in build
80
+ self .mindex = kwargs .get ('mi' , get_mi (self .order , self .sdim ))
81
+
75
82
self .pcrv = PCRV (self .outdim , self .sdim , self .pctype ,
76
- mi = kwargs . get ( 'mi' , get_mi ( self .order , self . sdim )) ,
77
- cfs = kwargs .get ('cfs' ))
83
+ mi = self .mindex ,
84
+ cfs = kwargs .get ('cfs' ))
78
85
79
- print (self .pcrv , end = '\n \n ' )
80
- # self.pcrv.printInfo() # Useful for vector valued functions
86
+ if self .verbose > 0 :
87
+ print ("Constructed PC Surrogate with the following attributes:" )
88
+ print (self .pcrv , end = '\n \n ' )
89
+ # self.pcrv.printInfo()
81
90
82
91
def set_training_data (self , x_train , y_train ):
83
92
r"""Sets the training data with validation.
@@ -127,11 +136,14 @@ def build(self, **kwargs):
127
136
- prior_var (float): Available for regression type 'anl', method 'full'.
128
137
129
138
Returns:
130
- np.ndarray: Coefficients for matrix
139
+ np.ndarray: PC coefficients
131
140
"""
132
141
if self ._x_train is None or self ._y_train is None :
133
142
raise RuntimeError ("Training data must be set using set_training_data() before calling build()." )
134
143
144
+ # Reset the multiindex and coefficients
145
+ self .pcrv .setMiCfs (self .mindex , cfs = None )
146
+
135
147
regression = kwargs .get ('regression' , 'lsq' )
136
148
137
149
if regression == 'lsq' :
@@ -142,11 +154,15 @@ def build(self, **kwargs):
142
154
self .lreg = anl (method = 'vi' , datavar = kwargs .get ('datavar' ), cov_nugget = kwargs .get ('cov_nugget' , 0.0 ))
143
155
else :
144
156
self .lreg = anl (datavar = kwargs .get ('datavar' ), prior_var = kwargs .get ('prior_var' ), cov_nugget = kwargs .get ('cov_nugget' , 0.0 ))
157
+ elif regression == 'bcs' :
158
+ self .lreg = bcs (eta = kwargs .get ('eta' , 1.e-8 ), datavar_init = kwargs .get ('datavar_init' ))
145
159
else :
146
160
raise ValueError (f"Regression method '{ regression } ' is not recognized and/or supported yet." )
147
161
148
162
self .regression_method = type (self .lreg ).__name__
149
- print ("Regression method:" , self .regression_method )
163
+
164
+ if self .verbose > 0 :
165
+ print ("Regression method:" , self .regression_method )
150
166
151
167
def basisevaluator (x , pars ):
152
168
self .pcrv , = pars
@@ -155,6 +171,10 @@ def basisevaluator(x, pars):
155
171
self .lreg .setBasisEvaluator (basisevaluator , (self .pcrv ,))
156
172
self .lreg .fit (self ._x_train , self ._y_train )
157
173
174
+ # Update the multi-index and coefficients retained by BCS as attributes of pcrv object
175
+ if regression == 'bcs' :
176
+ self .pcrv .setMiCfs ([self .mindex [self .lreg .used ,:]], [self .lreg .cf ])
177
+
158
178
return self .lreg .cf
159
179
160
180
def evaluate (self , x_eval , ** kwargs ):
@@ -166,7 +186,7 @@ def evaluate(self, x_eval, **kwargs):
166
186
data_variance (bool, optional): Whether to compute posterior-predictive (i.e. add data variance) or not.
167
187
168
188
Returns:
169
- dictionary: Dictionary of predicted y-values, along with standard deviation, covariance, and variance of predictions if applicable.
189
+ dict: Values for predicted y-values, standard deviation, covariance, and variance of predictions ( if applicable) as np.ndarrays.
170
190
"""
171
191
# If single output (scalar-valued function), standard deviation and variance are calculated,
172
192
# but not covariance.
0 commit comments