def generate_krig(init_samp, n_krigsamp, nvar, problem): # Kriging Sample t1 = time.time() init_krigsamp = mcpopgen(type="lognormal", ndim=nvar, n_order=1, n_coeff=5, stddev=0.2, mean=1) ykrig = evaluate(init_krigsamp, type=problem) t2 = time.time() print("50 samp eval", t2 - t1) # Evaluate Kriging Sample and calculate PoF real init_samp_G = evaluate(init_samp, type=problem) total_samp = np.hstack((init_samp, init_samp_G)).transpose() positive_samp = total_samp[:, total_samp[nvar] >= 0] positive_samp = positive_samp.transpose() nsamp = np.size(init_samp, 0) npos = np.size(positive_samp, 0) Pfreal = 1 - npos / nsamp lb = np.floor(np.min(init_samp)) * np.ones(shape=[nvar]) ub = np.ceil(np.max(init_samp)) * np.ones(shape=[nvar]) # Set Kriging Info KrigInfo = initkriginfo("single") KrigInfo["X"] = init_krigsamp KrigInfo["y"] = ykrig KrigInfo["nvar"] = nvar KrigInfo["nsamp"] = n_krigsamp KrigInfo["nrestart"] = 5 KrigInfo["ub"] = ub KrigInfo["lb"] = lb KrigInfo["nkernel"] = len(KrigInfo["kernel"]) KrigInfo["n_princomp"] = 4 KrigInfo["optimizer"] = "lbfgsb" #trainkrig t = time.time() krigobj = KPLS(KrigInfo, standardization=True, standtype='default', normy=False, trainvar=False) krigobj.train(parallel=False) loocverr, _ = krigobj.loocvcalc() elapsed = time.time() - t print("elapsed time for train Kriging model: ", elapsed, "s") print("LOOCV error of Kriging model: ", loocverr, "%") return krigobj, Pfreal
def generate_krig(init_samp, krigsamp, nvar, problem): # Monte Carlo Sampling t1 = time.time() init_krigsamp = krigsamp n_krigsamp = np.size(krigsamp, 0) ykrig = evaluate(init_krigsamp, type=problem) t2 = time.time() init_samp_G = evaluate(init_samp, type=problem) total_samp = np.hstack((init_samp, init_samp_G)).transpose() positive_samp = total_samp[:, total_samp[nvar] >= 0] positive_samp = positive_samp.transpose() nsamp = np.size(init_samp, 0) npos = np.size(positive_samp, 0) Pfreal = 1 - npos / nsamp lb = np.floor(np.min(init_samp)) * np.ones(shape=[nvar]) ub = np.ceil(np.max(init_samp)) * np.ones(shape=[nvar]) # Set Kriging Info KrigInfo = initkriginfo("single") KrigInfo["X"] = init_krigsamp KrigInfo["y"] = ykrig KrigInfo["nvar"] = nvar KrigInfo["nsamp"] = n_krigsamp KrigInfo["nrestart"] = 5 KrigInfo["ub"] = ub KrigInfo["lb"] = lb KrigInfo["nkernel"] = len(KrigInfo["kernel"]) KrigInfo["optimizer"] = "lbfgsb" #trainkrig t = time.time() krigobj = Kriging(KrigInfo, standardization=True, standtype='default', normy=False, trainvar=False) krigobj.train(parallel=False) loocverr, _ = krigobj.loocvcalc() elapsed = time.time() - t print("elapsed time for train Kriging model: ", elapsed, "s") print("LOOCV error of Kriging model: ", loocverr, "%") return krigobj, Pfreal
def calc_ft_order(self, first=True, total=False): """ Calculate first and total order Sobol Indices Return: s1 (numpy array): 1st order sobol indices. """ s1 = np.zeros(self.nvar) st = np.zeros(self.nvar) for ii in range(self.nvar): C_i = deepcopy(self.B) C_i[:, ii] = self.A[:, ii] # Use Kriging to predict Monte-Carlo if self.krigobj is not None: nsamp = np.size(C_i, axis=0) yci = np.zeros(shape=[nsamp, 1]) if nsamp <= 10000: yci = self.krigobj.predict(C_i, ['pred']) else: run_times = int(np.ceil(nsamp / 10000)) for i in range(run_times): start = i * 10000 stop = (i + 1) * 10000 if i != (run_times - 1): yci[start:stop, :] = self.krigobj.predict( C_i[start:stop, :], ['pred']) else: yci[start:, :] = self.krigobj.predict( C_i[start:, :], ['pred']) elif self.krigobj is None and self.problem is not None: if not callable(self.problem): yci = evaluate(C_i, self.problem) else: yci = self.problem(C_i) if first: s1[ii] = ((1 / self.n) * np.sum(self.ya * yci) - self.fo_2) / self.denom if total: st[ii] = 1 - (( (1 / self.n) * np.sum(self.yb * yci) - self.fo_2) / self.denom) return [s1, st]
def generate_krig(init_samp, n_krigsamp, nvar, problem, n_cpu): init_krigsamp = mcpopgen(type="lognormal", ndim=nvar, n_order=1, n_coeff=5, stddev=0.2, mean=1) print("Evaluating Kriging Sample") ykrig = evaluate(init_krigsamp, type=problem) print(np.count_nonzero(ykrig <= 0)) lb = (np.min(init_samp, axis=0)) ub = (np.max(init_samp, axis=0)) Pfreal = None # Set Kriging Info KrigInfo = initkriginfo(1) KrigInfo["X"] = init_krigsamp KrigInfo["y"] = ykrig KrigInfo["nvar"] = nvar KrigInfo["nsamp"] = n_krigsamp KrigInfo["nrestart"] = 5 KrigInfo["ub"] = ub KrigInfo["lb"] = lb KrigInfo["nkernel"] = len(KrigInfo["kernel"]) KrigInfo["n_princomp"] = 4 KrigInfo["optimizer"] = "lbfgsb" #trainkrig drm = None t = time.time() krigobj = KPLS(KrigInfo, standardization=True, standtype='default', normy=False, trainvar=False) krigobj.train(n_cpu=n_cpu) loocverr, _ = krigobj.loocvcalc() elapsed = time.time() - t print("elapsed time to train Kriging model: ", elapsed, "s") print("LOOCV error of Kriging model: ", loocverr, "%") return krigobj, loocverr, drm
def calc_second_order(self, s1): """ Calculate second order indices :return: """ s2 = dict() for ii in range(self.nvar - 1): for jj in range(ii + 1, self.nvar): C_ij = deepcopy(self.B) C_ij[:, ii] = self.A[:, ii] C_ij[:, jj] = self.A[:, jj] # Use Kriging to predict Monte-Carlo if self.krigobj is not None: nsamp = np.size(C_ij, axis=0) yci = np.zeros(shape=[nsamp, 1]) if nsamp <= 10000: yci = self.krigobj.predict(C_ij, ['pred']) else: run_times = int(np.ceil(nsamp / 10000)) for i in range(run_times): start = i * 10000 stop = (i + 1) * 10000 if i != (run_times - 1): yci[start:stop, :] = self.krigobj.predict( C_ij[start:stop, :], ['pred']) else: yci[start:, :] = self.krigobj.predict( C_ij[start:, :], ['pred']) elif self.krigobj is None and self.problem is not None: if not callable(self.problem): yci = evaluate(C_ij, self.problem) else: yci = self.problem(C_ij) vij = ((1 / self.n) * np.sum(self.ya * yci) - self.fo_2) key = "x" + str(ii + 1) + "-x" + str(jj + 1) s2[key] = (vij / self.denom) - s1[ii] - s1[jj] return s2
def pred(krigobj, init_samp, problem, drmmodel=None): nsamp = np.size(init_samp, axis=0) Gx = np.zeros(shape=[nsamp, 1]) if nsamp < 10000: Gx = krigobj.predict(init_samp, ['pred']) else: run_times = int(np.ceil(nsamp / 10000)) for i in range(run_times): start = i * 10000 stop = (i + 1) * 10000 if i != (run_times - 1): Gx[start:stop, :] = krigobj.predict(init_samp[start:stop, :], ['pred'], drmmodel=drmmodel) else: Gx[start:, :] = krigobj.predict(init_samp[start:, :], ['pred'], drmmodel=drmmodel) init_samp_G = evaluate(init_samp, type=problem) subs = np.transpose((init_samp_G - Gx)) subs1 = np.transpose((init_samp_G - Gx) / init_samp_G) RMSE = np.sqrt(np.sum(subs**2) / nsamp) RMSRE = np.sqrt(np.sum(subs1**2) / nsamp) MAPE = 100 * np.sum(abs(subs1)) / nsamp print("RMSE = ", RMSE) print("MAPE = ", MAPE, "%") print("==============================") print("UQ") mean1 = np.mean(Gx) stdev1 = np.std(Gx) mean2 = np.mean(init_samp_G) stdev2 = np.std(init_samp_G) print("model\tmean\tstdev") print("real:\t", mean2, "\t", stdev2) print("pred:\t", mean1, "\t", stdev1) print("==============================")
def run(self, autoupdate=True, disp=True, savedatato=None, logging=False, saveimageto=None, plotdatapos=None, plotdataneg=None, loggingAPIkey=None, logname=None, logworkspace=None): """ Run AKMCS analysis Args: autoupdate (bool): Perform automatic update on design space or not. Default to True. disp (bool): Display progress or not. Default to True. savedatato (str): Filename to save update data. e.g.: 'filename.csv' Return: None """ #logging if logging: if loggingAPIkey is None or logname is None or logworkspace is None: raise ValueError('Logging is turned on, APIkey, project and workspace must be specified.') self.logging = Experiment(api_key=loggingAPIkey, project_name=logname, workspace=logworkspace) if savedatato is not None: self.logging.set_name(savedatato) else: pass else: pass # Calculate Gx and SigmaG # Split init_samp to avoid memory error krig_initsamp = self.krigobj.KrigInfo['X'] t1 = time.time() if self.nsamp < 10000: self.Gx,self.sigmaG = self.krigobj.predict(self.init_samp, ['pred','s']) else: run_times = int(np.ceil(self.nsamp/10000)) for i in range(run_times): start = i * 10000 stop = (i+1) * 10000 if i != (run_times - 1): self.Gx[start:stop, :], self.sigmaG[:,start:stop] = \ self.krigobj.predict(self.init_samp[start:stop, :], ['pred','s']) else: self.Gx[start:, :], self.sigmaG[:,start:] = \ self.krigobj.predict(self.init_samp[start:, :], ['pred','s']) t2 = time.time() # Calculate probability of failure self.Pf = self.pfcalc() # Calculate learning function U self.lfucalc() self.stopcrit() self.updateX = np.array([self.xnew]) self.minUiter = np.array([self.minU]) if disp: print(f"Done iter no: 0, Pf: {self.Pf}, minU: {self.minU}") # Update samples automatically while autoupdate: labeladded = False for i in range(self.maxupdate): # Evaluate new samples and append into Kriging object information t = time.time() ynew = evaluate(self.xnew, type=self.akmcsInfo['problem']) self.krigobj.KrigInfo['y'] = np.vstack((self.krigobj.KrigInfo['y'],ynew)) self.krigobj.KrigInfo['X'] = np.vstack((self.krigobj.KrigInfo['X'], self.xnew)) self.krigobj.KrigInfo['nsamp'] += 1 # standardize model and train updated kriging model t3 = time.time() self.krigobj.standardize() self.krigobj.train(disp=False) t4 = time.time() # Calculate Gx and SigmaG # Split init_samp to avoid memory error if self.nsamp < 10000: self.Gx, self.sigmaG = self.krigobj.predict(self.init_samp, ['pred', 's']) else: run_times = int(np.ceil(self.nsamp / 10000)) for ii in range(run_times): start = ii * 10000 stop = (ii + 1) * 10000 if ii != (run_times - 1): self.Gx[start:stop, :], self.sigmaG[:, start:stop] = \ self.krigobj.predict(self.init_samp[start:stop, :], ['pred', 's']) else: self.Gx[start:, :], self.sigmaG[:, start:] = \ self.krigobj.predict(self.init_samp[start:, :], ['pred', 's']) t5 = time.time() # Calculate Pf, COV and LFU self.Pf = self.pfcalc() self.cov = self.covpf() self.lfucalc() self.stopcrit() t6 = time.time() # Update variables self.updateX = np.vstack((self.updateX,self.xnew)) self.minUiter = np.vstack((self.minUiter,self.minU)) elapsed = time.time() - t if disp: print(f"iter no: {i+1}, Pf: {self.Pf}, stopcrit: {self.stop_criteria}, time(s): {elapsed}, " f"ynew: {ynew}") if logging: self.logging.log_parameter('krigtype',self.krigobj.KrigInfo['type']) outdict = {"Prob_fail":self.Pf, "stopcrit":self.stop_criteria, "time(s)":elapsed } self.logging.log_metrics(outdict,step=i+1) if savedatato is not None: temparray = np.array([i,self.Pf,self.stop_criteria,elapsed]) if i == 0: totaldata = temparray[:] else: totaldata = np.vstack((totaldata,temparray)) filename = savedatato np.savetxt(filename, totaldata, delimiter=',', header='iter,Pf,stopcrit,time(s)') else: pass if saveimageto is not None: imagefile = saveimageto + str(i) + ".PNG" title = "Pf = " + str(self.Pf) plt.figure(0, figsize=[10, 9]) if not labeladded: plt.scatter(plotdatapos[:, 0], plotdatapos[:, 1], c='yellow', label='Feasible') plt.scatter(plotdataneg[:, 0], plotdataneg[:, 1], c='cyan', label='Infeasible') plt.scatter(krig_initsamp[:, 0], krig_initsamp[:, 1], c='red', label='Initial Kriging Population') plt.scatter(self.updateX[:, 0], self.updateX[:, 1], s=75, c='black', marker='x', label='Update') labeladded = True else: plt.scatter(plotdatapos[:, 0], plotdatapos[:, 1], c='yellow') plt.scatter(plotdataneg[:, 0], plotdataneg[:, 1], c='cyan') plt.scatter(krig_initsamp[:, 0], krig_initsamp[:, 1], c='red') plt.scatter(self.updateX[:, 0], self.updateX[:, 1], s=75, c='black', marker='x') plt.xlabel('X1', fontsize=18) plt.ylabel('X2', fontsize=18) plt.tick_params(axis='both', which='both', labelsize=16) plt.legend(loc=1, prop={'size': 15}) plt.title(title,fontdict={'fontsize':20}) plt.savefig(imagefile, format='png') else: pass # Break condition if self.stop_criteria <= 0.05 and i >= 15: break else: pass print(f"COV: {self.cov}") if self.cov <= 0.05: break else: pass break # temporary break for debugging, delete/comment this line later
def run( self, autoupdate=True, disp=True, savedatato=None, logging=False, saveimageto=None, plotdatapos=None, plotdataneg=None, loggingAPIkey=None, logname=None, logworkspace=None, ): """ Run AKMCS analysis Args: autoupdate (bool): Perform automatic update on design space or not. Default to True. disp (bool): Display progress or not. Default to True. savedatato (str): Filename to save update data. e.g.: 'filename.csv' Return: None """ # logging if logging: # disable logging print("Logging feature is currently disabled.") pass else: pass # Calculate Gx and SigmaG # Split init_samp to avoid memory error krig_initsamp = self.krigobj.KrigInfo["X"] t1 = time.time() run_times = int(np.ceil(self.nsamp / 10000)) for i in range(run_times): start = i * 10000 if i != (run_times - 1): stop = (i + 1) * 10000 else: stop = self.nsamp init_samp = self.init_samp[start:stop, :] gx, sigmag = self.krigobj.predict(init_samp, ["pred", "s"]) self.Gx[start:stop, :] = gx self.sigmaG[start:stop, :] = sigmag t2 = time.time() # Calculate probability of failure self.Pf = self.pfcalc() # Calculate learning function U self.lfucalc() self.stopcrit() self.updateX = np.array([self.xnew]) self.minUiter = np.array([self.minU]) if disp: print(f"Done iter no: 0, Pf: {self.Pf}, minU: {self.minU}") # Update samples automatically while autoupdate: labeladded = False for i_update in range(self.maxupdate): # Evaluate new samples and append into Kriging object information t = time.time() ynew = evaluate(self.xnew, type=self.akmcsInfo["problem"]) self.krigobj.KrigInfo["y"] = np.vstack( (self.krigobj.KrigInfo["y"], ynew)) self.krigobj.KrigInfo["X"] = np.vstack( (self.krigobj.KrigInfo["X"], self.xnew)) self.krigobj.KrigInfo["nsamp"] += 1 # standardize model and train updated kriging model t3 = time.time() self.krigobj.standardize() self.krigobj.train(disp=False) t4 = time.time() # Calculate Gx and SigmaG # Split init_samp to avoid memory error run_times = int(np.ceil(self.nsamp / 10000)) for ii in range(run_times): start = ii * 10000 if ii != (run_times - 1): stop = (ii + 1) * 10000 else: stop = self.nsamp init_samp = self.init_samp[start:stop, :] gx, sigmag = self.krigobj.predict(init_samp, ["pred", "s"]) self.Gx[start:stop, :] = gx self.sigmaG[start:stop, :] = sigmag t5 = time.time() # Calculate Pf, COV and LFU self.Pf = self.pfcalc() self.cov = self.covpf() self.lfucalc() self.stopcrit() t6 = time.time() # Update variables self.updateX = np.vstack((self.updateX, self.xnew)) self.minUiter = np.vstack((self.minUiter, self.minU)) elapsed = time.time() - t if disp: print(f"iter no: {i_update+1}, Pf: {self.Pf}, " f"stopcrit: {self.stop_criteria}, " f"time(s): {elapsed}, ynew: {ynew}") if logging: self.logging.log_parameter("krigtype", self.krigobj.KrigInfo["type"]) outdict = { "Prob_fail": self.Pf, "stopcrit": self.stop_criteria, "time(s)": elapsed, } self.logging.log_metrics(outdict, step=i_update + 1) if savedatato is not None: temparray = np.array( [i_update, self.Pf, self.stop_criteria, elapsed]) if i_update == 0: totaldata = temparray[:] else: totaldata = np.vstack((totaldata, temparray)) filename = savedatato np.savetxt( filename, totaldata, delimiter=",", header="iter,Pf,stopcrit,time(s)", ) else: pass if saveimageto is not None: imagefile = saveimageto + str(i_update) + ".PNG" title = "Pf = " + str(self.Pf) plt.figure(0, figsize=[10, 9]) if not labeladded: plt.scatter( plotdatapos[:, 0], plotdatapos[:, 1], c="yellow", label="Feasible", ) plt.scatter( plotdataneg[:, 0], plotdataneg[:, 1], c="cyan", label="Infeasible", ) plt.scatter( krig_initsamp[:, 0], krig_initsamp[:, 1], c="red", label="Initial Kriging Population", ) plt.scatter( self.updateX[:, 0], self.updateX[:, 1], s=75, c="black", marker="x", label="Update", ) labeladded = True else: plt.scatter(plotdatapos[:, 0], plotdatapos[:, 1], c="yellow") plt.scatter(plotdataneg[:, 0], plotdataneg[:, 1], c="cyan") plt.scatter(krig_initsamp[:, 0], krig_initsamp[:, 1], c="red") plt.scatter( self.updateX[:, 0], self.updateX[:, 1], s=75, c="black", marker="x", ) plt.xlabel("X1", fontsize=18) plt.ylabel("X2", fontsize=18) plt.tick_params(axis="both", which="both", labelsize=16) plt.legend(loc=1, prop={"size": 15}) plt.title(title, fontdict={"fontsize": 20}) plt.savefig(imagefile, format="png") else: pass # Break condition if self.stop_criteria <= 0.05 and i_update >= 15: break else: pass print(f"COV: {self.cov}") if self.cov <= 0.05: break else: pass break # temporary break for debugging, delete/comment this line later
return xtotal if __name__ == '__main__': nvar = 2 n_krigsamp = 25 problem = 'styblinski' filename = "akmcs2d.csv" figloc = 'akmcsupdate' init_samp = mcpopgen(type='normal', ndim=nvar, n_order=6, n_coeff=1, stddev=1.5) ysamp = evaluate(init_samp, problem) krigsamp = mcpopgen(type='normal', ndim=nvar, n_order=1, n_coeff=2.5, stddev=1.5) pos_MC = init_samp[ysamp.flatten() > 0, :] neg_MC = init_samp[ysamp.flatten() <= 0, :] krigobj, Pfreal = generate_krig(init_samp, krigsamp, nvar, problem) xtotal = run_akmcs(krigobj, init_samp, problem, filename, figloc, pos_MC, neg_MC) print(Pfreal) updateX = xtotal[n_krigsamp:, :]
def analyze(self, first=True, total=False, second=False): """ Run sensitivity analysis Args: first (bool): calculate first order or not total (bool): calculate total order or not Return: indices (dictionary): dictionary containing the sobol indices """ if self.krigobj is not None: nsamp = np.size(self.A, axis=0) self.ya = np.zeros(shape=[nsamp, 1]) if nsamp <= 10000: self.ya = self.krigobj.predict(self.A, ['pred']) else: run_times = int(np.ceil(nsamp / 10000)) for i in range(run_times): start = i * 10000 stop = (i + 1) * 10000 if i != (run_times - 1): self.ya[start:stop, :] = self.krigobj.predict( self.A[start:stop, :], ['pred']) else: self.ya[start:, :] = self.krigobj.predict( self.A[start:, :], ['pred']) self.yb = np.zeros(shape=[nsamp, 1]) if nsamp <= 10000: self.yb = self.krigobj.predict(self.B, ['pred']) else: run_times = int(np.ceil(nsamp / 10000)) for i in range(run_times): start = i * 10000 stop = (i + 1) * 10000 if i != (run_times - 1): self.yb[start:stop, :] = self.krigobj.predict( self.B[start:stop, :], ['pred']) else: self.yb[start:, :] = self.krigobj.predict( self.B[start:, :], ['pred']) elif self.krigobj is None and self.problem is not None: if not callable(self.problem): self.ya = evaluate(self.A, self.problem) self.yb = evaluate(self.B, self.problem) else: self.ya = self.problem(self.A) self.yb = self.problem(self.B) else: raise ValueError("Either krigobj or problem must be not None") self.fo_2 = (np.sum(self.ya) / self.n)**2 self.denom = (np.sum(self.ya**2) / self.n) - self.fo_2 indices = dict() if first is True or total is True: indices["first"], indices["total"] = self.calc_ft_order( first, total) if second is True: indices["second"] = self.calc_second_order(indices["first"]) elif second is True and first is False: indices["first"], indices["total"] = self.calc_ft_order(True, True) indices["second"] = self.calc_second_order(indices["first"]) else: pass return indices