def expandBoundsDDB_FB(self): """ Description: Expands the search space with the full Bayesian implementation of our DDB method """ print('Attempting to expand search space with DDB-FB method') alpha=self.alpha beta=self.beta bound_samples=100 # Number of radius sample to fit the log-logistic distribution # Find y^+ and x^+ ymax=np.max(self.Y) # Generate test radii max_loc=np.argmax(self.Y) xmax=self.X[max_loc] test_bound=np.zeros(self.scalebounds.shape) bound_dist=np.zeros(bound_samples) bound_center=xmax test_bound[:,1]=bound_center+0.5 test_bound[:,0]=bound_center-0.5 max_radius=np.max(np.array([np.max(max_bound_size-test_bound[:,1]),np.max(test_bound[:,0])])) step=max_radius/bound_samples packing_number=np.zeros(bound_samples) # Generate a Thompson sample maxima to estimate internal maxima TS=AcquisitionFunction.ThompsonSampling(self.gp) tsb_x,tsb_y=acq_max_global(TS, self.gp, bounds=self.scalebounds) # Generate Gumbel samples to estimate the external maxima for i in range(0,bound_samples): bound_length=test_bound[:,1]-test_bound[:,0] volume=np.power(max_bound_size,self.dim)-np.prod(bound_length) packing_number[i]=round(volume/(5*self.gp.lengthscale)) mu=stats.norm.ppf(1.0-1.0/packing_number[i]) sigma=stats.norm.ppf(1.0-(1.0/packing_number[i])*np.exp(-1.0))-stats.norm.ppf(1.0-(1.0/(packing_number[i]))) bound_dist[i]=np.exp(-np.exp(-(-tsb_y-mu)/sigma)) test_bound[:,1]=test_bound[:,1]+step test_bound[:,0]=test_bound[:,0]-step bound_dist[np.isnan(bound_dist)]=1 # Fit the log-logistic paramaters to the Gumbel samples xfit=np.arange(0,max_radius,max_radius/100) popt,pcov=optimize.curve_fit(self.sufficientBoundPDF,xfit[0:100],bound_dist,bounds=np.array([[5,1.1],[20,5]])) print("popt={}".format(popt)) b=ymax/popt[0] a=popt[1] print("b={}, ymax={}".format(b,ymax)) # Sample for the optimal radius for d in range(0,self.dim): gamma=np.random.gamma(shape=alpha,scale=1/beta,size=100) loglog=stats.fisk.pdf(gamma,ymax/b,scale=a) scaled_weights=loglog/np.sum(loglog) multi=np.random.multinomial(1,scaled_weights) r_index=np.argmax(multi) print("Radius of {} selected".format(gamma[r_index])) self.scalebounds[d,1]=xmax[d]+gamma[r_index] self.scalebounds[d,0]=xmax[d]-gamma[r_index] print("seach space extended to {} with DDB".format(self.scalebounds))
def expandBoundsDDB_MAP(self): """ Description: Expands the search space with the MAP implementation of our DDB method """ print('Attempting to expand search space with DDB-MAP method') alpha=self.alpha beta=self.beta bound_samples=100 # Number of radius sample to fit the log-logistic distribution # Find y^+ and x^+ ymax=np.max(self.Y) # Generate test radii max_loc=np.argmax(self.Y) xmax=self.X[max_loc] test_bound=np.zeros(self.scalebounds.shape) bound_dist=np.zeros(bound_samples) bound_center=xmax test_bound[:,1]=bound_center+0.5 test_bound[:,0]=bound_center-0.5 max_radius=np.max(np.array([np.max(max_bound_size-test_bound[:,1]),np.max(test_bound[:,0])])) step=max_radius/bound_samples packing_number=np.zeros(bound_samples) # Generate a Thompson sample maxima to estimate internal maxima TS=AcquisitionFunction.ThompsonSampling(self.gp) tsb_x,tsb_y=acq_max_global(TS, self.gp, bounds=self.scalebounds) # Generate Gumbel samples to estimate the external maxima for i in range(0,bound_samples): bound_length=test_bound[:,1]-test_bound[:,0] volume=np.power(max_bound_size,self.dim)-np.prod(bound_length) packing_number[i]=round(volume/(5*self.gp.lengthscale)) mu=stats.norm.ppf(1.0-1.0/packing_number[i]) sigma=stats.norm.ppf(1.0-(1.0/packing_number[i])*np.exp(-1.0))-stats.norm.ppf(1.0-(1.0/(packing_number[i]))) bound_dist[i]=np.exp(-np.exp(-(-tsb_y-mu)/sigma)) test_bound[:,1]=test_bound[:,1]+step test_bound[:,0]=test_bound[:,0]-step bound_dist[np.isnan(bound_dist)]=1 # Fit the log-logistic paramaters to the Gumbel samples xfit=np.arange(0,max_radius,max_radius/100) popt,pcov=optimize.curve_fit(self.sufficientBoundPDF,xfit[0:100],bound_dist,bounds=np.array([[5,1.1],[20,5]])) print("popt={}".format(popt)) b=ymax/popt[0] a=popt[1] print("b={}, ymax={}".format(b,ymax)) # Find the gamma and log-logistic modes to determine the optimisation bound c=ymax/b loglog_mode=a*np.power((c-1.0)/(c+1.0),(1/c)) gamma_mode=(alpha-1)/beta opt_bound=np.ones([2]) opt_bound[0]=min(loglog_mode,gamma_mode) opt_bound[1]=max(loglog_mode,gamma_mode) bound_range=(opt_bound[1]-opt_bound[0]) # Find MAP Estimate of radius r for d in range(0,self.dim): r_max=0 p_max=0 for x0 in np.arange(opt_bound[0],opt_bound[1],bound_range/10): res=optimize.minimize(lambda x: self.radiusPDF(x,alpha,beta,b,ymax,a),x0=x0, bounds=np.array([opt_bound]), method='L-BFGS-B') if -res.fun>p_max: r_max=res.x p_max=-res.fun if r_max>opt_bound[1]: r_max=opt_bound[1] xplot=np.arange(0,10,0.01) yplot=-self.radiusPDF(xplot,alpha,beta,b,ymax,a) max_loc=np.argmax(yplot) print("optimal radius of {} with unscaled probability of {}".format(r_max,p_max)) self.scalebounds[d,1]=xmax[d]+r_max self.scalebounds[d,0]=xmax[d]-r_max print("seach space extended to {} with DDB".format(self.scalebounds))