def cnstrct_nonGQ_1d(self): """ Constructs a PCE over a 1D parameter space using 'Regression' method with arbitrary truncation `K=LMax` to compute the PCE coefficients for arbitrarily chosen parameter samples. Args: `fVal`: 1D numpy array of size `n` Simulator's response values at `n` training samples `pceDict['distType']`: List of length 1, =[distType1], where distType1:string specifies the distribution type of the parameter based on the gPCE rule `xi`: 2D numpy array of size (n,1) Training parameter samples over the mapped space `pceDict['LMax']`: int Maximum order of the PCE. `LMax` is required since `'pceSolveMethod'=='Regression'`. """ nQ = len(self.fVal) # number of quadratures (collocation samples) K = self.LMax # truncation in the PCE distType_ = self.distType[0] if self.verbose: print('...... Number of terms in PCE, K= ', K) nData = len(self.fVal) # number of observations if self.verbose: print('...... Number of Data point, n= ', nData) # (2) Find the coefficients in the expansion:Only Regression method can be used. A = np.zeros((nData, K)) sum2 = [] # auxiliary GQ rule for computing gamma_k xi_aux, w_aux = self.gqPtsWts(K + 1, distType_) fac_ = self._gqInteg_fac(distType_) for k in range(K): psi_aux = self.basis(k, xi_aux, distType_) for j in range(nData): A[j, k] = self.basis(k, self.xi[j], distType_) sum2.append(np.sum((psi_aux[:K + 1])**2. * w_aux[:K + 1] * fac_)) # Find the PCE coeffs by Linear Regression fCoef = linAlg.myLinearRegress(A, self.fVal) # (3) Find the mean and variance of f(q) estimated by PCE fMean = fCoef[0] fVar = np.sum(fCoef[1:]**2. * sum2[1:]) self.coefs = fCoef self.fMean = fMean self.fVar = fVar
def cnstrct_nonGQTP_pd(self): R""" Constructs a PCE over a pD parameter space (p>1), for the following settings: * `'truncMethod'`: `'TO'` or `'TP'` * `'pceSolveMethod'`: `'Regression'` (only allowed method) * This method is used for any combination of `'sampleType'` and `'truncMethod'` but `'GQ'`+`'TP'` """ p=self.p distType=self.distType xiGrid=self.xi if self.verbose: print('... A gPCE for a %d-D parameter space is constructed.' %p) print('...... PCE truncation method: %s' %self.truncMethod) print('...... Method of computing PCE coefficients: %s' %self.pceSolveMethod) if self.truncMethod=='TO': LMax=self.LMax #max order of polynomial in each direction if self.verbose: print(' with LMax=%d as the max polynomial order in each direction.' %LMax) if self.pceSolveMethod!='Regression': raise ValueError("only Regression method can be used for PCE with Total Order truncation method.") #(1) Preliminaries #Number of terms in PCE if self.truncMethod=='TO': K=int(mt.factorial(LMax+p)/(mt.factorial(LMax)*mt.factorial(p))) Nmax=(LMax+1)**p kOrderList=[LMax+1]*p elif self.truncMethod=='TP': #'TP' needs nQList K=np.prod(np.asarray(self.nQList)) Nmax=K kOrderList=self.nQList # Quadrature rule only to compute \gamma_k xiAux=[] wAux=[] fac=[] for i in range(p): xi_,w_=self.gqPtsWts(self.nQList[i],distType[i]) xiAux.append(xi_) wAux.append(w_) fac.append(self._gqInteg_fac(distType[i])) # Index set kSet=[] #index set for the constructed PCE kGlob=np.arange(Nmax) #Global index kLoc=kGlob.reshape(kOrderList,order='F') #Local index for i in range(Nmax): k_=np.where(kLoc==kGlob[i]) kSet_=[] for j in range(p): kSet_.append(k_[j][0]) if (self.truncMethod=='TO' and sum(kSet_)<=LMax) or self.truncMethod=='TP': kSet.append(kSet_) if self.verbose: print('...... Number of terms in PCE, K= ',K) nData=len(self.fVal) #number of observations if self.verbose: print('...... Number of Data point, n= ',nData) #(2) Find the coefficients in the expansion:Only Regression method can be used. A=np.zeros((nData,K)) sum2=[] for k in range(K): psi_k_=self.basis(kSet[k][0],xiAux[0],distType[0]) sum2_=np.sum(psi_k_**2*wAux[0])*fac[0] aij_=self.basis(kSet[k][0],xiGrid[:,0],distType[0]) for i in range(1,p): aij_*=self.basis(kSet[k][i],xiGrid[:,i],distType[i]) psi_k_=self.basis(kSet[k][i],xiAux[i],distType[i]) sum2_*=np.sum(psi_k_**2*wAux[i])*fac[i] A[:,k]=aij_ sum2.append(sum2_) #Find the PCE coeffs by Linear Regression fCoef=linAlg.myLinearRegress(A,self.fVal) #(3) Find the mean and variance of f(q) as estimated by PCE fMean=fCoef[0] fVar=0.0 for k in range(1,K): fVar+=fCoef[k]*fCoef[k]*sum2[k] self.coefs=fCoef self.fMean=fMean self.fVar=fVar self.kSet=kSet
def cnstrct_GQTP_pd(self): R""" Constructs a PCE over a pD parameter space (p>1) using the following settings: * `'sampType':'GQ'` (Gauss-Quadrature nodes) * `'truncMethod': 'TP'` (Tensor-product) * `'pceSolveMethod':'Projection'` or 'Regression' """ if self.verbose: print('... A gPCE for a %d-D parameter space is constructed.'%self.p) print('...... Samples in each direction are Gauss Quadrature nodes (User should check this!).') print('...... PCE truncation method: TP') print('...... Method of computing PCE coefficients: %s' %self.pceSolveMethod) distType=self.distType p=self.p #(1) Quadrature rule xi=[] w=[] fac=[] K=1 for i in range(p): xi_,w_=self.gqPtsWts(self.nQList[i],distType[i]) xi.append(xi_) w.append(w_) K*=self.nQList[i] fac.append(self._gqInteg_fac(distType[i])) if self.verbose: print('...... Number of terms in PCE, K= ',K) nData=len(self.fVal) #number of observations if self.verbose: print('...... Number of Data point, n= ',nData) if K!=nData: raise ValueError("K=%d is not equal to nData=%d"%(K,nData)) #(2) Index set kSet=[] #index set for the constructed PCE kGlob=np.arange(K) #Global index kLoc=kGlob.reshape(self.nQList,order='F') #Local index for i in range(K): k_=np.where(kLoc==kGlob[i]) kSet_=[] for j in range(p): kSet_.append(k_[j][0]) kSet.append(kSet_) #(3) Find the coefficients in the expansion #By default, Projection method is used (assuming samples are Gauss-Quadrature points) fCoef=np.zeros(K) sum2=[] fVal_=self.fVal.reshape(self.nQList,order='F').T #global to local index for k in range(K): psi_k=[] for j in range(p): psi_k.append(self.basis(kSet[k][j],xi[j],distType[j])) sum1 =np.matmul(fVal_,(psi_k[0]*w[0]))*fac[0] sum2_=np.sum(psi_k[0]**2*w[0])*fac[0] for i in range(1,p): num_=(psi_k[i]*w[i]) sum1=np.matmul(sum1,num_)*fac[i] sum2_*=np.sum(psi_k[i]**2*w[i])*fac[i] fCoef[k]=sum1/sum2_ sum2.append(sum2_) #(3b) Compute fCoef via Regression if self.pceDict['pceSolveMethod']=='Regression': xiGrid=reshaper.vecs2grid(xi) A=np.zeros((nData,K)) for k in range(K): aij_=self.basis(kSet[k][0],xiGrid[:,0],distType[0]) for i in range(1,p): aij_*=self.basis(kSet[k][i],xiGrid[:,i],distType[i]) A[:,k]=aij_ fCoef=linAlg.myLinearRegress(A,self.fVal) #This is a uniquely determined system #(4) Find the mean and variance of f(q) as estimated by PCE fMean=fCoef[0] fVar=np.sum(fCoef[1:]**2.*sum2[1:]) self.coefs=fCoef self.fMean=fMean self.fVar=fVar self.kSet=kSet