def redraw_fn(f, axes): img = imread(img_files[f]) x1, y1, w1, h1 = track_gt[f] x2, y2, w2, h2 = tuple(sample[f].tolist()) x1 = int(x1 - w1 / 2) x2 = int(x2 - w2 / 2) y1 = int(y1 - h1 / 2) y2 = int(y2 - h2 / 2) if not redraw_fn.initialized: im = axes.imshow(img, animated=True) bb1 = Rectangle( (x1, y1), w1, h1, fill=False, # remove background edgecolor="red", gid='gt') bb2 = Rectangle( (x2, y2), w2, h2, fill=False, # remove background edgecolor="blue", gid='sample') t1 = axes.text(0, 0, '[{} {}]'.format(x1, y1), bbox=dict(facecolor='red', alpha=0.5)) t2 = axes.text(300, 0, '[{} {}]'.format(x2, y2), bbox=dict(facecolor='blue', alpha=0.5)) axes.add_patch(bb1) axes.add_patch(bb2) redraw_fn.im = im redraw_fn.bb1 = bb1 redraw_fn.bb2 = bb2 redraw_fn.t1 = t1 redraw_fn.t2 = t2 redraw_fn.initialized = True else: redraw_fn.im.set_array(img) redraw_fn.bb1.set_xy((x1, y1)) redraw_fn.bb1.set_width(w1) redraw_fn.bb1.set_height(h1) redraw_fn.t1.set_text('[{} {}]'.format(x1, y1)) redraw_fn.bb2.set_xy((x2, y2)) redraw_fn.bb2.set_width(w2) redraw_fn.bb2.set_height(h2) redraw_fn.t2.set_text('[{} {}]'.format(x2, y2))
def redraw_fn(f, axes): img = imread(img_files[f]) x, y, w, h = tuple(bbox[f, :]) w = w - x h = h - y frame = frames[f] vis = viss[f] if not redraw_fn.initialized: im = axes.imshow(img, animated=True) bb = Rectangle( (x, y), w, h, fill=False, # remove background edgecolor="red") t1 = axes.text(0, 0, '[f:{} vis:{:1.2f}]'.format(frame, vis), bbox=dict(facecolor='red', alpha=0.5)) axes.add_patch(bb) redraw_fn.im = im redraw_fn.bb1 = bb redraw_fn.t1 = t1 redraw_fn.initialized = True else: redraw_fn.im.set_array(img) redraw_fn.bb1.set_xy((x, y)) redraw_fn.bb1.set_width(w) redraw_fn.bb1.set_height(h) redraw_fn.t1.set_text('[f:{} vis:{:1.2f}]'.format(frame, vis))
def create_bbox(bbox, color): return Rectangle( (bbox[0], bbox[1]), bbox[2], bbox[3], fill=False, # remove background\n", edgecolor=color)
def redraw_fn(f, ax): img = imgs[f] box = boxs[f] x, y, w, h = box if not redraw_fn.initialized: redraw_fn.img_handle = ax.imshow(img) box_artist = Rectangle((x, y), w, h, fill=False, # remove background lw=2, edgecolor="red") ax.add_patch(box_artist) redraw_fn.box_handle = box_artist redraw_fn.last_time = time.time() redraw_fn.text_handle = ax.text(0., 1 - 0.05, 'Resolution {}x{}, FPS: {:.2f}'.format(img.shape[1], img.shape[0], 0), transform=ax.transAxes, color='yellow', size=12) redraw_fn.initialized = True else: redraw_fn.img_handle.set_array(img) redraw_fn.box_handle.set_xy((x, y)) redraw_fn.box_handle.set_width(w) redraw_fn.box_handle.set_height(h) current_time = time.time() redraw_fn.text_handle.set_text('Resolution {}x{}, FPS: {:.2f}'.format(img.shape[1], img.shape[0], 1 / (current_time - redraw_fn.last_time))) redraw_fn.last_time = current_time
def make_placement_plot(nodes, pl, scl, dest): # Read bookshelf files parse_bookshelf_scl(scl) node_dict = dict() parse_bookshelf_nodes(nodes, node_dict) parse_bookshelf_pl(pl, node_dict) fig = plt.figure() # Figure ax = fig.add_subplot(1, 1, 1) # AxesSubplot patches = set() for k, v in node_dict.items(): llx, lly = v.llx, v.lly w, h = v.width, v.height patches.add(Rectangle((llx, lly), w, h)) print("Adding collection.") ax.add_collection(PatchCollection(patches, alpha=0.4)) print("Done.") fig.show() ax.set_xlim([0, 1000]) ax.set_ylim([0, 1000]) fig.savefig('test.png')
def plotobs(self, ax, scale=1): '''plot all obstacles''' obstacles = scale * np.array(self.obstacles) if self.dim == 2: for box in obstacles: l = box[2] - box[0] w = box[3] - box[1] box_plt = Rectangle((box[0], box[1]), l, w, color='k', zorder=1) ax.add_patch(box_plt) elif self.dim == 3: for box in obstacles: X, Y, Z = cuboid_data(box) ax.plot_surface(X, Y, Z, rstride=1, cstride=1, color=(0.1, 0.15, 0.3, 0.2), zorder=1) else: print('can not plot for given dimensions')
def square(r, c, size=1, facecolor='k', edgecolor='0.7', linewidth=None): from matplotlib.pyplot import Rectangle # r and c must be swapped: row -> y axis, col -> x axis return Rectangle((c, r), size, size, facecolor=facecolor, edgecolor=edgecolor, linewidth=linewidth)
def bound_words(fig, bounds, hold=True): ax = fig.gca() for bound in bounds: _, x, y, width, height = bound ax.add_artist( Rectangle((x, y), width, height, fill=False, edgecolor='k')) if hold: show()
def redraw_fn(idx, axes): idx += 1 img = imread(img_files[idx]) x_gt, y_gt, w_gt, h_gt = vot_rect(bboxes_gt[idx]) b_seq = bbox_seq[idx - 1].split(',') b_seq = map(float, b_seq) overlap = float(overlap_seq[idx - 1]) objectness = float(objectness_seq[idx - 1]) if not redraw_fn.initialized: # import pdb; pdb.set_trace() axes, axes_p = axes redraw_fn.im_p = axes_p.imshow(imread(plot_png)) redraw_fn.im = axes.imshow(img) redraw_fn.bb1 = Rectangle((x_gt, y_gt), w_gt, h_gt, fill=False, edgecolor='red', linewidth=5) redraw_fn.bb2 = Rectangle((b_seq[0], b_seq[1]), b_seq[2], b_seq[3], fill=False, edgecolor='blue', linewidth=5) axes.add_patch(redraw_fn.bb2) axes.add_patch(redraw_fn.bb1) redraw_fn.text1 = axes.text(0.03, 0.97, '{}: {}'.format(seq, idx+1), fontdict={'size':10,}, ha='left', va='top', bbox={'facecolor':'yellow', 'alpha':0.7}, transform=axes.transAxes) redraw_fn.text2 = axes.text(0.03, 0.92, 'olap: {:.2f}'.format(overlap), fontdict={'size':10,}, ha='left', va='top', bbox={'facecolor':'blue', 'alpha':0.7}, transform=axes.transAxes) redraw_fn.text3 = axes.text(0.03, 0.87, 'obj: {:.2f}'.format(objectness), fontdict={'size':10,}, ha='left', va='top', bbox={'facecolor':'red', 'alpha':0.7}, transform=axes.transAxes) redraw_fn.text1_p = axes_p.text(0.03, 0.97, '{}: {}'.format(seq, idx+1), fontdict={'size':10,}, ha='left', va='top', bbox={'facecolor':'yellow', 'alpha':0.7}, transform=axes_p.transAxes) redraw_fn.text2_p = axes_p.text(0.03, 0.92, 'olap: {:.2f}'.format(overlap), fontdict={'size':10,}, ha='left', va='top', bbox={'facecolor':'blue', 'alpha':0.7}, transform=axes_p.transAxes) redraw_fn.text3_p = axes_p.text(0.03, 0.87, 'obj: {:.2f}'.format(objectness), fontdict={'size':10,}, ha='left', va='top', bbox={'facecolor':'red', 'alpha':0.7}, transform=axes_p.transAxes) redraw_fn.initialized = True else: # import pdb; pdb.set_trace() redraw_fn.im.set_array(img) # redraw_fn.im_p.set_array(imread(plot_png)) set_bbox(redraw_fn.bb1, vot_rect(bboxes_gt[idx])) set_bbox(redraw_fn.bb2, b_seq) redraw_fn.text1.set_text('{}: {}'.format(seq, idx+1)) redraw_fn.text2.set_text('olap: {:.2f}'.format(overlap)) redraw_fn.text3.set_text('obj: {:.2f}'.format(objectness)) redraw_fn.text1_p.set_text('{}: {}'.format(seq, idx+1)) redraw_fn.text2_p.set_text('olap: {:.2f}'.format(overlap)) redraw_fn.text3_p.set_text('obj: {:.2f}'.format(objectness))
def make_plot(language, xs, ys): settings = dict(xmin=0, xmax=5, ymin=0, ymax=0.6, magmin=0.05, magmax=0.5, coercivitymin=1.5, coercivitymax=4) colour_main = "#ffffff" colour_highlight = "#ffffff" pyplot.gcf().set_size_inches(80 / 25.4, 58 / 25.4) pyplot.xlabel(r"$B_{\mathrm{cr}} / B_\mathrm{c}$") pyplot.ylabel(r"$M_{\mathrm{rs}} / M_{\mathrm{s}}$") pyplot.xlim(settings["xmin"], settings["xmax"]) pyplot.ylim(settings["ymin"], settings["ymax"]) pyplot.gca().add_patch( Rectangle((0, 0), settings["xmax"], settings["ymax"], fc=colour_main)) pyplot.gca().add_patch( Rectangle((settings["coercivitymin"], settings["magmin"]), settings["coercivitymax"] - settings["coercivitymin"], settings["magmax"] - settings["magmin"], fc=colour_highlight)) pyplot.annotate("SD", (0.05, 0.53)) pyplot.annotate("PSD", (1.60, 0.42)) pyplot.annotate({"it": "PD", "en": "MD"}[language], (4.1, 0.01)) pyplot.hlines([settings["magmin"], settings["magmax"]], 0., 5.) pyplot.vlines([settings["coercivitymin"], settings["coercivitymax"]], 0.0, 0.6) pyplot.subplots_adjust(left=0.15, bottom=0.18, right=0.97, top=0.96) pyplot.plot(xs, ys, "o", color="none", mew=0.6, ms=4.0, mec="black", mfc="none", alpha=0.6) pyplot.savefig(os.path.join("..", "script-output", "fig-day-plot.pdf"), transparent=True)
def draw_mesh_boundary(mesh: Mesh, ax): width = mesh.x_range[1] - mesh.x_range[0] height = mesh.y_range[1] - mesh.y_range[0] r = Rectangle((-width / 2, -height / 2), width, height, fill=False, linewidth=0.5, edgecolor='black', linestyle='--', zorder=20) ax.add_artist(r)
def generate_plot(circuit): x_coords = [c.x for c in circuit.terminals] y_coords = [c.y for c in circuit.terminals] x_min, y_min = min(x_coords), min(y_coords) x_max, y_max = max(x_coords), max(y_coords) #--------------------------------------- # Make placement plot #--------------------------------------- from matplotlib.pyplot import Rectangle from matplotlib.collections import PatchCollection fig = plt.figure() fig.set_size_inches(10, 10) ax = fig.add_subplot(1, 1, 1) # Plot the placement patches = set() for comb in circuit.combs: patches.add(Rectangle((comb.x, comb.y), comb.w, comb.h)) ax.add_collection( PatchCollection(patches, facecolor='#147DFF', edgecolor='dimgrey', lw=0.25)) patches = set() for latch in circuit.latches: patches.add(Rectangle((latch.x, latch.y), latch.w, latch.h)) ax.add_collection( PatchCollection(patches, facecolor='#969696', edgecolor='dimgrey', lw=0.25)) # ax.set_xlim([0, x_max]) # ax.set_ylim([0, y_max]) ax.autoscale() fig.savefig('foo2.png', dpi=200)
def draw_cell_boundary(ax, width, height, x_offset=0, y_offset=0, color=(0.8, 0.8, 0.8)): r = Rectangle((-width / 2 + x_offset, -height / 2 + y_offset), width, height, fill=False, linewidth=1, edgecolor=color, linestyle='--') ax.plot(x_offset, y_offset, 'b+', color=color) ax.add_artist(r) return r
def extended_hinton(ax, V, C, vmax=None, cmin=None, cmax=None, cmap=None, matrix_style=False, alpha=1, enforce_box=False): if cmap is None: cmap = cm.jet if vmax is None: vmax = np.amax(np.abs(V)) if cmax is None: cmax = np.amax(C) if cmin is None: cmin = np.amin(C) cnorm = Normalize(vmin=cmin, vmax=cmax, clip=True) cmapable = ScalarMappable(norm=cnorm, cmap=cmap) if matrix_style: V, C = V.T, C.T ax.patch.set_facecolor([0, 0, 0, 0]) for (x, y), w in np.ndenumerate(V): s = C[x, y] color = cmap(cnorm(s)) # cmap(s / cmax) size = np.abs(w / vmax) rect = Rectangle([x - size / 2, y - size / 2], size, size, facecolor=color, edgecolor=color, alpha=alpha) ret = ax.add_patch(rect) if enforce_box: ax.axis('tight') try: ax.set_aspect('equal', 'box') except: pass #ax.autoscale_view() #ax.invert_yaxis() return cnorm
def drawPlot(self): ion() self.fig = plt.figure() # draw cart self.axes = self.fig.add_subplot(111, aspect='equal') self.box = Rectangle(xy=(self.cart_location - self.cartwidth / 2.0, -self.cartheight), width=self.cartwidth, height=self.cartheight) self.axes.add_artist(self.box) self.box.set_clip_box(self.axes.bbox) # draw pole self.pole = Line2D([self.cart_location, self.cart_location + np.sin(self.pole_angle)], [0, np.cos(self.pole_angle)], linewidth=3, color='black') self.axes.add_artist(self.pole) self.pole.set_clip_box(self.axes.bbox) # set axes limits self.axes.set_xlim(-10, 10) self.axes.set_ylim(-0.5, 2)
def render_batch_sample_predictions(positives, batch_sample, color=("g", "b", "purple")): images = batch_sample.to("cpu").detach( ) if batch_sample.device.type == "cuda" else batch_sample.detach() # config artist assign n_row, n_col, figsize = [2, 4, (15, 7.5)] if len(images) == 8 else [2, 2, (8, 8)] fig, axis = figure_preproduction(n_row, n_col, figsize) for i, (mods, positive) in enumerate(zip(images, positives)): ax = axis[divmod(i, n_col)] ax.imshow(mods[1], cmap="gray") for x, y, w, h, lbl in positive: ax.add_patch( Rectangle((x - w / 2, y - h / 2), w, h, fill=False, color=color[int(lbl)])) plt.show()
def make_color_legend_rects(colors, labels=None): """ Make list of rectangles and labels for making legends. Parameters ---------- colors : pandas.Series or list Pandas series whose values are colors and index is labels. Alternatively, you can provide a list with colors and provide the labels as a list. labels : list If colors is a list, this should be the list of corresponding labels. Returns ------- out : pd.Series Pandas series whose values are matplotlib rectangles and whose index are the legend labels for those rectangles. You can add each of these rectangles to your axis using ax.add_patch(r) for r in out then create a legend whose labels are out.values and whose labels are legend_rects.index: for r in legend_rects: ax.add_patch(r) lgd = ax.legend(legend_rects.values, labels=legend_rects.index) """ from matplotlib.pyplot import Rectangle if labels: d = dict(zip(labels, colors)) se = pd.Series(d) else: se = colors rects = [] for i in se.index: r = Rectangle((0, 0), 0, 0, fc=se[i]) rects.append(r) out = pd.Series(rects, index=se.index) return out
def redraw_fn(idx, axes): idx += 1 img = imread(img_files[idx]) if not redraw_fn.initialized: redraw_fn.im = axes.imshow(img) if args.r is not None: x, y, w, h = bbox_seq_dict[args.r][idx] redraw_fn.bb1 = Rectangle((x, y), w, h, fill=False, edgecolor='red', alpha=0.7, linewidth=3) axes.add_patch(redraw_fn.bb1) if args.g is not None: x, y, w, h = bbox_seq_dict[args.g][idx] redraw_fn.bb2 = Rectangle((x, y), w, h, fill=False, edgecolor='green', alpha=0.7, linewidth=3) axes.add_patch(redraw_fn.bb2) if args.b is not None: x, y, w, h = bbox_seq_dict[args.b][idx] redraw_fn.bb3 = Rectangle((x, y), w, h, fill=False, edgecolor='blue', alpha=0.7, linewidth=3) axes.add_patch(redraw_fn.bb3) if args.y is not None: x, y, w, h = bbox_seq_dict[args.y][idx] redraw_fn.bb4 = Rectangle((x, y), w, h, fill=False, edgecolor='yellow', alpha=0.7, linewidth=3) axes.add_patch(redraw_fn.bb4) redraw_fn.text1 = axes.text(0.03, 0.97, '{}: {}'.format(seq, idx + 1), fontdict={ 'size': 10, }, ha='left', va='top', bbox={ 'facecolor': 'yellow', 'alpha': 0.7 }, transform=axes.transAxes) redraw_fn.initialized = True else: redraw_fn.im.set_array(img) if args.r is not None: set_bbox(redraw_fn.bb1, bbox_seq_dict[args.r][idx]) if args.g is not None: set_bbox(redraw_fn.bb2, bbox_seq_dict[args.g][idx]) if args.b is not None: set_bbox(redraw_fn.bb3, bbox_seq_dict[args.b][idx]) if args.y is not None: set_bbox(redraw_fn.bb4, bbox_seq_dict[args.y][idx]) redraw_fn.text1.set_text('{}: {}'.format(seq, idx + 1))
def show_locomotion(motor_diameter, wheel_diameter, motor_shift, pcb_thick, module, pinion_z, gear_z): pinion_reference_diameter = module * pinion_z gear_reference_diameter = module * gear_z gear_external_diameter = module * (gear_z + 2) ax = plt.gca() ax.cla() # Motor and pinion motor_height = wheel_diameter / 2. + motor_shift motor = Circle( (0, motor_height), radius=motor_diameter / 2., color='black', linewidth=0, ) pinion = Circle( (0, motor_height), radius=pinion_reference_diameter / 2., color='yellow', linewidth=0, ) ax.add_artist(motor) ax.add_artist(pinion) # PCB height = motor_height - motor_diameter / 2. - pcb_thick width = motor_diameter + 2 * wheel_diameter pcb = Rectangle( (-width / 2., height), width=width, height=pcb_thick, color='green', linewidth=0, ) ax.add_artist(pcb) # Gears and wheels wheel_shift = (pinion_reference_diameter + gear_reference_diameter) / 2. alpha = asin(motor_shift / wheel_shift) wheel_shift = wheel_shift * cos(alpha) height = wheel_diameter / 2. gear0 = Circle( (-wheel_shift, height), radius=gear_reference_diameter / 2., color='gray', linewidth=0, ) gear1 = Circle( (wheel_shift, height), radius=gear_reference_diameter / 2., color='gray', linewidth=0, ) wheel0 = Circle((-wheel_shift, height), radius=wheel_diameter / 2., color='blue', linewidth=0, alpha=0.5) wheel1 = Circle((wheel_shift, height), radius=wheel_diameter / 2., color='blue', linewidth=0, alpha=0.5) ax.add_artist(gear0) ax.add_artist(gear1) ax.add_artist(wheel0) ax.add_artist(wheel1) # Change plot limits to fit everything x_limit = pinion_reference_diameter + wheel_diameter y_limit = max(wheel_diameter, motor_height + motor_diameter / 2.) ax.set_xlim((-x_limit, x_limit)) ax.set_ylim((0, y_limit)) ax.set_aspect('equal') # Calculate free space between the PCB and the floor pcb_floor_space = min(motor_height - motor_diameter / 2. - pcb_thick, motor_height - motor_diameter / 2.) wheel_wheel_space = 2 * wheel_shift - wheel_diameter gear_wheel_space = (wheel_diameter - gear_external_diameter) / 2. ax.set_title('''PCB to floor: %.2f mm Between wheels: %.2f mm Gear (external diameter) to wheel: %.2f mm''' % (pcb_floor_space, wheel_wheel_space, gear_wheel_space)) plt.show()
cds=so2_cds_uncorr, velo=PLUME_VELO, pix_dists=pix_dists_line, cds_err=calib.err(), pix_dists_err=pix_dist_err) # IMPORTANT STUFF FINISHED (below follow some plots) ax2 = plot_retrieval_points_into_image(so2_img_corr) pcs_line.plot_line_on_grid(ax=ax2, ls="-", color="g") ax2.legend(loc="best", framealpha=0.5, fancybox=True, fontsize=20) ax2.set_title("Dilution corrected AA image", fontsize=12) ax2.get_xaxis().set_ticks([]) ax2.get_yaxis().set_ticks([]) x0, y0, w, h = pyplis.helpers.roi2rect(AMBIENT_ROI) ax2.add_patch(Rectangle((x0, y0), w, h, fc="none", ec="c")) fig, ax3 = subplots(1, 1) ax3.plot(so2_cds_uncorr, ls="-", color="#ff33e3", label=r"Uncorr: $\Phi_{SO2}=$%.2f (+/- %.2f) kg/s" % (phi_uncorr / 1000.0, phi_uncorr_err / 1000.0)) ax3.plot(so2_cds_corr, "-g", lw=3, label=r"Corr: $\Phi_{SO2}=$%.2f (+/- %.2f) kg/s" % (phi_corr / 1000.0, phi_corr_err / 1000.0)) ax3.set_title("Cross section profile", fontsize=12) ax3.legend(loc="best", framealpha=0.5, fancybox=True, fontsize=12) ax3.set_xlim([0, len(pix_dists_line)]) ax3.set_ylim([0, 5e18]) ax3.set_ylabel(r"$S_{SO2}$ [cm$^{-2}$]", fontsize=14) ax3.set_xlabel("PCS", fontsize=14)
def runpar(f, g, H, Lg, Lh, l, u, bound, circle, A=None, b=None, E=None, d=None, Tol=1e-2, Heur=0, TolType='r', Vis=0, nsize=12, SD=1, qpsolver='cvxopt'): # Optional Inputs # Tolerance # Heuristic lattice (0 - off, 1 - on) # Tolerance type (r - relative, a - absolute) # Visualisation (0 - off, 1 - on) # Step Debugging (0 - off, 1 - on) # Node Size # QP Solver (cvxopt, quadprog, nag) # MPI from mpi4py import MPI # MPI comm comm = MPI.COMM_WORLD rank = comm.Get_rank() # Number of processors numprocs = comm.Get_size() # Print node names for each processors print('Processor %i is on node %s') % (rank,str(MPI.Get_processor_name())) # Create local groups for load balacing on each node from numpy import ceil nodes = [[0]] bins = int(ceil(numprocs/nsize)) for i in range(bins): nodes.append([]) for p in range(1,numprocs): nodes[(p % bins)+1].append(p) print nodes # Get D D = len(l) if(D > 25): raise RuntimeError('Hashing for greater than 25D not yet implemented.') # Balance Test def balance_test(lst): for p1 in reversed(range(0,len(lst))): for p2 in range(0,p1): if( abs(lst[p1]-lst[p2])/(max(min(lst[p1],lst[p2]),1)) > 0.1): return True return False if(Heur == 0): ksp = 3**D kspi = ksp else: # Load relevant normalised lattice from numpy import loadtxt, array, sqrt if(D == 2): lat = array([[0., 0.], [1., 0.], [-1., 0.], [0.5, sqrt(3.)/2.], [-0.5, sqrt(3.)/2.], [0.5, -sqrt(3.)/2.], [-0.5, -sqrt(3.)/2.]]) elif(D == 3): lat = loadtxt('d3') elif(D == 4): lat = loadtxt('d4') elif(D == 5): lat = loadtxt('d5') elif(D == 6): lat = loadtxt('e6') elif(D == 7): lat = loadtxt('e7') elif(D == 8): lat = loadtxt('e8') else: raise RuntimeError('A lattice for '+str(D)+' Dimensions has yet to be provided.') # Get kissing number + 1 ksp = lat.shape[0] kspi = 2**D # Master Process if(rank == 0): # Necessary functions from itertools import product from numpy import array, sqrt, empty, zeros, inf, hstack, isinf, argmin, argmax, all,ones, identity, vstack, dot from numpy.linalg import norm from math import floor from time import time # Import cvxopt solver from cvxopt import matrix from cvxopt.solvers import qp, options # Set tolerance options options['show_progress'] = False options['abstol'] = 1e-9 options['reltol'] = 1e-8 options['feastol'] = 1e-9 # Initialise empty arrays if A is None: A = empty((0,D)) b = empty(0) if E is None: E = empty((0,D)) d = empty(0) # Check if circle has feasible point def mfeasible(c, lfather=None, ufather=None): #box containing the ball c.lReduced = c.xc - c.r * ones(D) c.uReduced = c.xc + c.r * ones(D) # check if the sub-ball is in the domain reduced of the father def checkAndUpdateBound(): # intersection between the box of the ball and the box reduced of the father for i in range(0,D): if c.lReduced[i]<lfather[i]: c.lReduced[i]=lfather[i] if c.uReduced[i]>ufather[i]: c.uReduced[i]=ufather[i] checkAndUpdateBound() # Solve QP to check feasibility sol = qp(matrix(2*identity(D)),matrix(-2*c.xc),matrix(vstack([-1*identity(D),identity(D),A])),matrix(hstack([-l,u,b])),matrix(E),matrix(d)) mxopt = array(sol['x']).flatten() mr = sol['primal objective'] mr = mr + dot(c.xc,c.xc) # Check if point lies inside domain if(mr <= (c.r**2)): mf = 1 else: mf = 0 mxopt = None return mf, mxopt # Timer timer = time() r = norm(u-l)/2 # Radius xc = (u+l)/2 # Centre cn = circle(xc,r) mfeas, cxopt = mfeasible(cn,l,u) # Upper bound ubound = f(cxopt) #lower bound and reduced domain _, l, u = bound(cn,Lg,Lh,f,g,H,D,A,b,E,d,ubound,True) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # 0.c # Split ball if(Heur == 0): # Split circle into more circles inc = r/sqrt(D) # Increment rn = r/2 # New radius # Create square spoke configuration spk = array([p for p in product([-inc,0,inc], repeat=D)]) else: # Split circle into more circles inc = r # Increment rn = r/2 # New radius # Scale configuration spk = inc*lat # Array to distribute amongst processes darray = empty((kspi,D+1)) boundarray = empty(2*D) boundarray = hstack([l,u]) reqidsend = [] reqboundsend = [] # Create surrounding circles for i in range(0,kspi): # Create centre xcn = xc + spk[i,:] # Add to distribution list darray[i,:] = hstack([array([rn]),xcn]) # 0.c # Distribute data evenly amongst processes ihi = 0 trem = kspi prem = numprocs-1 for p in range(0,numprocs-1): tproc = int(round(trem/prem)) ilo = ihi + 1 ihi = ihi + tproc print('Master sending data elements [%i:%i] to processor %i') % (ilo-1,ihi,p+1) comm.Ssend(array([ihi-ilo+1],dtype='i'), dest=p+1, tag=9) # send array size reqidsend.append(comm.Issend(darray[ilo-1:ihi,:], dest=p+1, tag=10)) # send data array (Isend?) reqboundsend.append(comm.Issend(boundarray, dest=p+1, tag=6)) prem = prem - 1 trem = trem - tproc # Initial communication setup lclists = [1 for i in range(1,numprocs)] zerolist = [0 for i in range(1,numprocs)] confd = empty(1,dtype='i') reqbrecv = [] reqbsend = [] rarr = empty((numprocs-1,2)) reqdreq = [MPI.REQUEST_NULL for i in range(1,numprocs)] reqconf = [MPI.REQUEST_NULL for i in range(1,numprocs)] reqdreqn = [MPI.REQUEST_NULL for i in range(1,numprocs)] reqconfn = [MPI.REQUEST_NULL for i in range(1,numprocs)] # Initial local upper bound U = inf # 0.d-e # Initial rlist, xclist and comm setup rlist = [] xclist = [] rxcndat = empty((numprocs-1,2),dtype='i') dwait = 0 reqxcndat = [] reqxcnrecv = [MPI.REQUEST_NULL for i in range(1,numprocs)] reqxcnsend = [MPI.REQUEST_NULL for i in range(1,numprocs)] # Loop counter #itr = 0 # Asynchronously receive U and len(clist) for p in range(0,numprocs-1): # New Receive reqbrecv.append(comm.Irecv(rarr[p], source=p+1, tag=2)) # Send U reqbsend.append(comm.Issend(array([U]), dest=p+1, tag=3)) # Make sure data has been sent print('Master waiting for initial data sends to complete...') for p in range(0,numprocs-1): reqidsend[p].Wait() reqboundsend[p].Wait() print('done.') # Asynchronously receive xcn from all workers for p in range(0,numprocs-1): reqxcndat.append(comm.Irecv(rxcndat[p], source=p+1, tag=12)) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # 1. #and(rad > 1e-15) #and((time()-timer) < 3000) while((lclists != zerolist)and(not(all(rxcndat == 0)))): # Update iteration count #itr = itr + 1 # 1.a # Asynchronously receive U and len(clist) for p in range(0,numprocs-1): if(reqbrecv[p].Test()): # Update U and len(clist) if(rarr[p,0] < U): U = rarr[p,0] lclists[p] = rarr[p,1] # New Receive reqbrecv[p] = comm.Irecv(rarr[p], source=p+1, tag=2) # 1.b # Asynchronously send U = min(p in {1,...,P}) Up # where Up = rarr[p] for p in range(0,numprocs-1): # If previous communication has finished start new if(reqbsend[p].Test()): # Send U reqbsend[p] = comm.Issend(array([U]), dest=p+1, tag=3) # 1.c # If data check requested, process accordingly # If all data sizes received and previous sends have completed if(MPI.Request.Testall(reqxcndat))and(MPI.Request.Testall(reqxcnsend)): # If not waiting to receive data if(dwait == 0): print('Data check from all processors received.') # If any of the processors has ran out of work, ensure it is skipped plist = [] for p in range(0,numprocs-1): if(rxcndat[p,1] == 0): reqxcnrecv[p] = MPI.REQUEST_NULL else: plist.append(p) # Set up arrays to store data rxcn = [None for p in range(0,numprocs-1)] for p in plist: rxcn[p] = empty(rxcndat[p,0],dtype='i') # Receive data from all workers for p in plist: reqxcnrecv[p] = comm.Irecv(rxcn[p], source=p+1, tag=14) # Waiting for data dwait = 1 # If data from all workers received if(MPI.Request.Testall(reqxcnrecv)): # Arrays to send nc = [None for p in range(0,numprocs-1)] # Perform data check for all workers for p in plist: # If radius already in list if rxcndat[p,1] in rlist: # Check if xcns already exist ridx = rlist.index(rxcndat[p,1]) nc[p] = array(map(int,[a in xclist[ridx] for a in rxcn[p]]),dtype='i') # Add any new xcns to xclist xclist[ridx]+=[rxcn[p][i] for i in range(0,len(nc[p])) if nc[p][i]==0] # Else add radius and xcns to respective lists else: rlist.append(rxcndat[p,1]) xclist.append(list(rxcn[p])) nc[p] = zeros(rxcndat[p,0],dtype='i') # Send result of check back (Isend?) reqxcnsend[p] = comm.Issend(nc[p], dest=p+1, tag=14) print('Data check returned to processor %i.') % (p+1) # Post new receives for all processors for p in range(0,numprocs-1): # Ansynchronously receive xcn reqxcndat[p] = comm.Irecv(rxcndat[p], source=p+1, tag=12) # Not waiting for data dwait = 0 #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # 1.d # Load Balancing spread across nodes # Take snapshot of load slist = lclists[:] # Get load on each node lnode = [] for node in nodes: # Master proc, skip if(len(node)==1): pass # Actual Node with workers else: # Create list blist = [] for n in node: blist.append(slist[n-1]) # Get load per node lnode.append(blist) # Get total load per node tload = [sum(lnode[i]) for i in range(len(lnode))] # Iteration counter it = 0 while((balance_test(tload))and(it < numprocs)): # Subtract smallest load ml = min(tload) tload = map(lambda x: x-ml, tload) # Find amount to redistribute load = int(floor(sum(tload)/len(lnode))) # Find nodes with smallest & largest load minn = argmin(tload) maxn = argmax(tload) # Calculate node load to send nload = min(tload[maxn],max(load-tload[minn],0)) # Find procs with smallest & largest load on max/min nodes lminp = argmin(lnode[minn]) lmaxp = argmax(lnode[maxn]) # Get proc number gminp = nodes[minn+1][lminp] gmaxp = nodes[maxn+1][lmaxp] # Calculate actual load to send lfrac = 3 aload = min(int(lnode[maxn][lmaxp]/lfrac),max(nload-lnode[minn][lminp],0)) # Fraction of processors on node dfrac = len(nodes[minn+1]) # Send load from largest to smallest if previous send has completed and aload/dfrac > 0 if((reqdreqn[gmaxp-1].Test())and(reqconfn[gmaxp-1].Test())and(int(aload/dfrac) > 0)): # Send load from largest to smallest print('Intercomm: Master allocating %i subproblems from processor %i to node %i processors ') % (aload,gmaxp,minn+1), print nodes[minn+1][0:] # Send data allocation request reqdreqn[gmaxp-1] = comm.Issend(array([minn+1,aload],dtype='i'), dest=gmaxp, tag=24) print('Intercomm: Data allocation request sent asynchronously.') # Wait for confirmation of data send reqconfn[gmaxp-1] = comm.Irecv(confd, source=gmaxp, tag=26) # Update load per node for i in range(len(nodes[minn+1])): lnode[minn][i]+= min(int(aload/dfrac),lnode[maxn][lmaxp]) lnode[maxn][lmaxp] -= min(aload,lnode[maxn][lmaxp]) # Update tload tload = [sum(lnode[i]) for i in range(len(lnode))] # Iteration counter it += 1 # 1.e # Load Balancing on each node # For each node (excl master) for node in nodes: # Master proc, skip if(len(node)==1): pass # Actual Node with workers else: # Copy list blist = [] for n in node: blist.append(lclists[n-1]) # Subtract smallest load ml = min(blist) blist = map(lambda x: x-ml, blist) # Find load amount to redistribute load = int(floor(sum(blist)/len(blist))) # Iteration counter biter = 0 while((balance_test(blist))and(biter < len(blist))): # Find procs with smallest & largest load minp = argmin(blist) maxp = argmax(blist) # Convert to global proc numbers gminp = node[minp] gmaxp = node[maxp] # Calculate actual load to send aload = max(load-int(blist[minp]),0) # If previous send has completed and aload > 0 if((reqdreq[gmaxp-1].Test())and(reqconf[gmaxp-1].Test())and(aload > 0)): # Send load from largest to smallest print('Master allocating %i subproblems from processor %i to processor %i') % (aload,gmaxp,gminp) # Send data allocation request reqdreq[gmaxp-1] = comm.Issend(array([gminp,aload],dtype='i'), dest=gmaxp, tag=0) print('Data allocation request sent asynchronously.') # Wait for confirmation of data send reqconf[gmaxp-1] = comm.Irecv(confd, source=gmaxp, tag=22) # Update blist blist[minp] += min(aload,blist[maxp]) blist[maxp] -= min(aload,blist[maxp]) # Update iteration counter biter += 1 #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # 2 # If all finished, send kill signals print('Master sending kill signals...') for p in range(0,numprocs-1): comm.Ssend(array([1],dtype='i'), dest=p+1, tag=4) # Kill any pending data checks (Isend?) for p in range(0,numprocs-1): reqxcnsend[p] = comm.Issend(array([0],dtype='i'), dest=p+1, tag=14) # Clean up redundant messages for p in range(0,numprocs-1): #reqbsend[p].Cancel() reqbrecv[p].Cancel() #reqdreq[p].Cancel() #reqbsend[p].Free() reqbrecv[p].Free() #reqdreq[p].Free() # 3 # Receive xopt from all processors reqe = [] earr = empty((numprocs-1,D)) U = inf for p in range(0,numprocs-1): # New Receive #print('Master posting asynchronous receive of final data from processor %i') % (p+1) reqe.append(comm.Irecv(earr[p], source=p+1, tag=5)) #print('posted.') for p in range(0,numprocs-1): print('Master waiting to receive final data from processor %i') % (p+1) reqe[p].Wait() print('Final data from processor %i received') % (p+1) # Find xopt with smallest U if(not(any(isinf(earr[p])))): if(f(earr[p]) < U): xopt = earr[p] U = f(xopt) #xopt = empty(D) # How do you count iterations? itr = None # Output end result print('Minimum value of %f at (') % U, #f(xopt), for i in range(0,D-1): print('%f,') % xopt[i], print('%f)') % xopt[D-1] print('found with'), if(TolType == 'a'): print('absolute'), else: print('relative'), print('tolerance %f.') % Tol tol = Tol xs = xopt fxs = U #f(xopt) print('Elapsed time %f seconds.') % (time()-timer) return xs, fxs, tol, itr # Worker processes else: # import necessary functions from heapq import heappush, heappop from numpy import array, sqrt, dot, identity, hstack, vstack, inf, empty, ones, zeros, tile, roll, all from numpy.linalg import norm from itertools import product from sys import float_info from math import floor, ceil from time import time # Vector Hash function: http://stackoverflow.com/questions/5928725/hashing-2d-3d-and-nd-vectors #htsize = 499 # Hash Table size res = 1e-5 # Resolution # Twenty five arbitrarily chosen 8-digit primes primes = [73856093, 19349663, 83492791, 15485863, 86028121, 32452843, 67867967, 49979687, 86028157, 13769629, 95189161, 29223841, 83972821, 39271703, 79186817, 47286739, 98767549, 14139199, 64244023, 18551173, 55621541, 10920859, 53615137, 24405817, 43176253] # Pick up scattered list rsize = array([0],dtype='i') comm.Recv(rsize, source=0, tag=9) rarray = empty((rsize[0],D+1)) boundarray = empty(2*D) comm.Recv(rarray, source=0, tag=10) comm.Recv(boundarray, source=0, tag=6) print('Processor %i received initial data') % rank lr = boundarray[0:D] ur = boundarray[D:2*D] # Hash function def hashnd(x): result = 0 for i in range(0,D): result = result ^ (int(floor(x[i]/res))*primes[i]) return result # Hash radius def hashrn(r): return int(r*1e8) # Initialise empty arrays if A is None: A = empty((0,D)) b = empty(0) if E is None: E = empty((0,D)) d = empty(0) # QuadProg++ solver (fast!) if(qpsolver == 'quadprog'): # Import QuadProg++ solver from PyQuadProg import PyQuadProg # Check if circle has feasible point def mfeasible(c): # Solve QP to check feasibility sol = PyQuadProg(2*identity(D),-2*c.xc,E.transpose(),-1*d,vstack([identity(D),-1*identity(D),-1*A]).transpose(),hstack([-l,u,b])) mxopt = sol.x.getArray() mr = dot(mxopt,mxopt) + dot(mxopt,-2*c.xc) + dot(c.xc,c.xc) # Check if point lies inside domain if(mr < (c.r**2)): mf = 1 else: mf = 0 mxopt = None return mf, mxopt # CVXOPT QP solver (slow) elif(qpsolver == 'cvxopt'): # Import cvxopt solver from cvxopt import matrix from cvxopt.solvers import qp, options # Set tolerance options options['show_progress'] = False options['abstol'] = 1e-9 options['reltol'] = 1e-8 options['feastol'] = 1e-9 # Check if circle has feasible point def mfeasible(c, lfather=None, ufather=None): #box containing the ball c.lReduced = c.xc - c.r * ones(D) c.uReduced = c.xc + c.r * ones(D) # check if the sub-ball is in the domain reduced of the father def checkAndUpdateBound(): check=1 for i in range(0,D): # check the intersection between the subball and the reduction of the father's ball # if there isn't intersection, then discard the subball (check = 0) if c.lReduced[i]>ufather[i] or c.uReduced[i]<lfather[i]: check=0 break # intersection of the subball with the orginal domain (reduced at first step) if c.lReduced[i]<lr[i]: c.lReduced[i]=lr[i] if c.uReduced[i]>ur[i]: c.uReduced[i]=ur[i] return check check=1 if lfather is not None and ufather is not None: check = checkAndUpdateBound() if check==1: # Solve QP to check feasibility sol = qp(matrix(2*identity(D)),matrix(-2*c.xc),matrix(vstack([-1*identity(D),identity(D),A])),matrix(hstack([-lr,ur,b])),matrix(E),matrix(d)) mxopt = array(sol['x']).flatten() mr = sol['primal objective'] mr = mr + dot(c.xc,c.xc) # Check if point lies inside domain if(mr <= (c.r**2)): mf = 1 else: mf = 0 mxopt = None else: mf = 0 mxopt = None return mf, mxopt # NAG QP solver (fast!) elif(qpsolver == 'nag'): # Import QP Solver from qpsolver_lincon import qpsolver_lincon # Check if circle has feasible point def mfeasible(c): # Solve QP to check feasibility mxopt = c.xc.copy() mr = qpsolver_lincon(2*identity(D),-2*c.xc,hstack([l,-inf,d]),hstack([u,b,d]),mxopt,vstack([A,E]),D,A.shape[0]+E.shape[0]) mr = mr + dot(c.xc,c.xc) # Check if point lies inside domain if(mr < (c.r**2)): mf = 1 else: mf = 0 mxopt = None return mf, mxopt # Visualisation if(Vis == 1): from matplotlib.pyplot import figure, Rectangle, Circle, gca, show, title, axis, draw from colorsys import hsv_to_rgb from random import random # Draw bound constraints [l,u] fig = figure('Processor '+str(rank)) gca().add_patch(Rectangle((l[0],l[1]), u[0]-l[0], u[1]-l[1], fill=False)) axis([l[0]-1,u[0]+1,l[1]-1,u[1]+1]) title('Processor '+str(rank)) show(block=False) # Circle drawing procedure def drawc(c): # Draw circle colured according to partition gca().add_patch(Circle((c.xc[0],c.xc[1]), radius=c.r , color=hsv_to_rgb(random(),1,1), fill=False)) axis('equal') draw() # Priority queue clist = [] # list of entries arranged in a heap # Add a new task def add_task(task): heappush(clist, (task.lbound, task)) # Remove and return the lowest priority task. Raise KeyError if empty. def pop_task(): while clist: return heappop(clist) raise KeyError('Pop from an empty priority queue!') # Remove and return (in an mpi transfer array) the n lowest priority tasks def npop_task(n): carray = empty((n,(3*D)+2)) for i in range(0,n): celm = pop_task() carray[i,0:D+2] = hstack([array([celm[0],celm[1].r]),celm[1].xc]) carray[i,D+2:2*D+2] = celm[1].lReduced carray[i,2*D+2:3*D+2] = celm[1].uReduced return carray # Initial local upper bound U = inf # Bound communication setup rarr = empty(1) karr = empty(1,dtype='i') kill = 0 dwait = 0 dwaits = 0 reqdsend = MPI.REQUEST_NULL reqdsizesend = MPI.REQUEST_NULL reqconf = MPI.REQUEST_NULL reqnsend = MPI.REQUEST_NULL dwaitn = 0 dwaitsn = 0 reqdsendn = [MPI.REQUEST_NULL for i in range(1,numprocs)] reqdsizesendn = [MPI.REQUEST_NULL for i in range(1,numprocs)] reqconfn = MPI.REQUEST_NULL # 1.b-c # Bound intial list and convert to priority queue for k in range(0,rsize): # Create circle cn = circle(rarray[k,1:D+1],rarray[k,0]) # Check if circle is feasible mfeas, cxopt = mfeasible(cn,lr,ur) # If circle has a feasible point (i.e. it's feasible) if(mfeas != 0): # Upper bound ubound = f(cxopt) # Update U and xopt if(ubound < U): U = ubound xopt = cxopt # Bound circle cn.lbound, cn.lReduced, cn.uReduced = bound(cn,Lg,Lh,f,g,H,D,A,b,E,d,U,True,cn.r*2) # Add to priority queue add_task(cn) # Visualise if(Vis ==1): drawc(cn) initialRadius = cn.r*2 # 1.d # Asynchronously send U and len(clist) reqbsend = comm.Issend(array([U,len(clist)]), dest=0, tag=2) # 1.e # Asynchronously receive U reqbrecv = comm.Irecv(rarr, source=0, tag=3) # Debug Output if (SD == 1): #if(rank == 0): print('Time: %f') % (time()), print('Processor %i Number of elements: %i') % (rank,len(clist)) print('U: %f') % U #print('L: %f') % L #print('Circle radius: %e') % rad print('----------------------------') # Intial data request rq_proc_load = empty(2,dtype='i') rq_proc_loadn = empty(2,dtype='i') reqd = comm.Irecv(rq_proc_load, source=0, tag=0) reqdn = comm.Irecv(rq_proc_loadn, source=0, tag=24) # Initial kill signal request reqk = comm.Irecv(karr, source=0, tag=4) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # 2 optimality = False while(kill == 0): # Set tolerance if((TolType == 'r')and(abs(U) > float_info.epsilon)): cutoff = U - Tol*abs(U) else: cutoff = U - Tol # Prune list i = 0 while(i < len(clist)): if(clist[i][0] > cutoff): del clist[i] i=i-1 i = i+1 # If there is work left to do if(len(clist) != 0): # Get circle with smallest lbound L, cslb = pop_task() if(Heur == 0): # Split circle into more circles inc = cslb.r/sqrt(D) # Increment rn = cslb.r/2 # New radius xc = cslb.xc # Centre # Create square spoke configuration spk = array([p for p in product([-inc,0,inc], repeat=D)]) # Move centre to start of spoke array spk = roll(spk,int(ceil(ksp/2)),axis=0) else: # Split circle into more circles inc = cslb.r # Increment rn = cslb.r/2 # New radius xc = cslb.xc # Centre # Scale configuration spk = inc*lat # Create surrounding circles # Create centre nc = zeros(ksp) xcn = tile(xc,(ksp,1)) + spk # Check if circles exists locally for k in range(0,len(clist)): for i in range(0,ksp): if(all(xcn[i,:] == clist[k][1].xc)): nc[i] = 1 # Check if circles exists globally # Remove local duplicates dxcn = [] hdxcn = [] for i in range(0,ksp): if(nc[i] == 0): dxcn.append(xcn[i,:]) hdxcn.append(hashnd(xcn[i,:])) xcn = array(dxcn) hxcn = array(hdxcn,dtype='i') del dxcn[:] del hdxcn[:] # Send data asynchronously #print('Processor %i sending data check to master processor.') % rank comm.Send(array([len(hxcn),hashrn(rn)],dtype='i'), dest=0, tag=12) # send array size _ = comm.Issend(hxcn, dest=0, tag=14) # send data array (Isend?) #print('Data check sent. Awaiting response.') # Receive data asynchronously nc = empty(len(hxcn),dtype='i') reqdcheck = comm.Irecv(nc, source=0, tag=14) #print('Data check completed successfully.') # Start bounding balls lcn = [] lmfeas = [] lcxopt = [] lubound = [] for i in range(0,len(xcn)): # Create circle lcn.append(circle(xcn[i,:],rn)) mfeas, cxopt = mfeasible(lcn[i],cslb.lReduced,cslb.uReduced) lmfeas.append(mfeas) lcxopt.append(cxopt) # Bound if feasible if(mfeas != 0): # Lower bound lcn[i].lbound, lcn[i].lReduced, lcn[i].uReduced = bound(lcn[i],Lg,Lh,f,g,H,D,A,b,E,d,U,optimality,initialRadius) # Upper bound lubound.append(f(cxopt)) else: # Don't need upper bound lubound.append(None) if(reqdcheck.Test()): # Test if data check received break else: print('Processor %i started waiting for data check.') % rank wtimer = time() # Time wait time reqdcheck.Wait() # Wait for data check print('Processor %i spent %f seconds waiting for data check from master.') % (rank,time()-wtimer) # Finish bounding for j in range(0,len(xcn)): # If circle doesn't already exist somewhere if(nc[j] == 0): # If circle already bounded if(j <= i): # And circle feasible if(lmfeas[j] != 0): # Update U and xopt if(lubound[j] < U): U = lubound[j] xopt = lcxopt[j] # Add to priority queue add_task(lcn[j]) # Visualise if(Vis ==1): drawc(lcn[j]) else: # Create circle cn = circle(xcn[j,:],rn) mfeas, cxopt = mfeasible(cn,cslb.lReduced,cslb.uReduced) # If circle has a feasible point (i.e. it's feasible) if(mfeas != 0): # Upper bound ubound = f(cxopt) # Update U and xopt if(ubound < U): U = ubound xopt = cxopt # Lower bound cn.lbound, cn.lReduced, cn.uReduced = bound(cn,Lg,Lh,f,g,H,D,A,b,E,d,U,optimality,initialRadius) # Add to priority queue add_task(cn) # Visualise if(Vis ==1): drawc(cn) # Intercomm: Send data if requested and previous data send has completed if((reqdn.Test())and(MPI.Request.Testall(reqdsendn))and(MPI.Request.Testall(reqdsizesendn))and(reqconfn.Test())): print('Intercomm: Node %i needs data from processor %i') % (rq_proc_loadn[0],rank) # Workload to send nit = min(int(rq_proc_loadn[1]/len(nodes[rq_proc_loadn[0]])),len(clist)/len(nodes[rq_proc_loadn[0]])) if(nit > 0): print('Intercomm: Sending %i subproblems from processor %i to node %i each of processors') % (nit,rank,rq_proc_loadn[0]), print nodes[rq_proc_loadn[0]][0:] # Send data asynchronously for p in nodes[rq_proc_loadn[0]]: reqdsizesendn[p-1] = comm.Issend(array([nit,rank],dtype='i'), dest=p, tag=30) # send array size reqdsendn[p-1] = comm.Issend(npop_task(nit), dest=p, tag=28) # send data array print('Intercomm: Data sent asynchronously.') # Send confirmation to master reqconfn = comm.Issend(array([1],dtype='i'), dest=0, tag=26) else: print('Intercomm: Not enough data to send.') # Send confirmation to master reqconfn = comm.Issend(array([1],dtype='i'), dest=0, tag=26) # Wait for other data requests reqdn = comm.Irecv(rq_proc_loadn, source=0, tag=24) # Send data if requested and previous data send has completed if((reqd.Test())and(reqdsend.Test())and(reqdsizesend.Test())and(reqconf.Test())): print('Processor %i needs data from processor %i') % (rq_proc_load[0],rank) # Workload to send nit = min(rq_proc_load[1],len(clist)) print('Sending %i subproblems from processor %i to processor %i') % (nit,rank,rq_proc_load[0]) # Send data asynchronously (Isend?) reqdsizesend = comm.Issend(array([nit,rank],dtype='i'), dest=rq_proc_load[0], tag=11) # send array size reqdsend = comm.Issend(npop_task(nit), dest=rq_proc_load[0], tag=1) # send data array (Isend?) print('Data sent asynchronously.') # Send confirmation to master (Isend?) reqconf = comm.Issend(array([1],dtype='i'), dest=0, tag=22) # Wait for other data requests reqd = comm.Irecv(rq_proc_load, source=0, tag=0) # Debug Output if (SD == 1): #if(rank == 0): print('Time: %f') % (time()), print('Processor %i Number of elements: %i') % (rank,len(clist)) print('U: %f') % U print('LL: %f') % L #print('Circle radius: %e') % rad print('----------------------------') # Run out of work else: # Notify master that ran out of work if previous send completed if(reqnsend.Test()): print('Time: %f') % (time()), print('Processor %i ran out of work!') % rank reqnsend = comm.Issend(array([0,0],dtype='i'), dest=0, tag=12) # If not waiting to receive data size if(dwaits == 0): # Receive data print('Processor %i asynchronously waiting to receive data.') % rank darrsize = array([0,0],dtype='i') reqdsize = comm.Irecv(darrsize, source=MPI.ANY_SOURCE, tag=11) # Waiting for data size dwaits = 1 # If data size received if(reqdsize.Test()): # If not waiting to receive data if(dwait == 0): darr = empty((darrsize[0],(3*D)+2)) reqds = comm.Irecv(darr,source=darrsize[1], tag=1) # Waiting for data dwait = 1 # If data received if(reqds.Test()): for i in range(0,darrsize[0]): ctemp = circle(darr[i,2:2+D],darr[i,1]) ctemp.lbound = darr[i,0] ctemp.lReduced = darr[i,2+D:2+2*D] ctemp.uReduced = darr[i,2+2*D:2+3*D] add_task(ctemp) print('Data received succesfully.') # Not waiting for data size or data dwaits = 0 dwait = 0 # Intercomm: If not waiting to receive data size if(dwaitsn == 0): # Receive data print('Intercomm: Processor %i asynchronously waiting to receive data.') % rank darrsizen = array([0,0],dtype='i') reqdsizen = comm.Irecv(darrsizen, source=MPI.ANY_SOURCE, tag=30) # Waiting for data size dwaitsn = 1 # Intercomm: If data size received if(reqdsizen.Test()): # If not waiting to receive data if(dwaitn == 0): darrn = empty((darrsizen[0],(3*D)+2)) reqdsn = comm.Irecv(darrn,source=darrsizen[1], tag=28) # Waiting for data dwaitn = 1 # If data received if(reqdsn.Test()): for i in range(0,darrsizen[0]): ctemp = circle(darrn[i,2:2+D],darrn[i,1]) ctemp.lbound = darrn[i,0] ctemp.lReduced = darrn[i,2+D:2+2*D] ctemp.uReduced = darrn[i,2+2*D:2+3*D] add_task(ctemp) print('Intercomm: Data received succesfully.') # Not waiting for data size or data dwaitsn = 0 dwaitn = 0 # Asynchronously send UL and len(clist) # If previous communication has finished start new if(reqbsend.Test()): # Send UL and len(clist) reqbsend = comm.Issend(array([U,len(clist)]), dest=0, tag=2) if(reqbrecv.Test()): # Update U if(rarr[0] < U): U = rarr[0] # New Receive reqbrecv = comm.Irecv(rarr, source=0, tag=3) # Asynchronously receive kill signal if(reqk.Test()): kill = 1 # Say if finished! print('Processor %i has finished!') % rank # Clean up redundant messages #reqbsend.Cancel() reqbrecv.Cancel() #reqd.Cancel() #reqbsend.Free() reqbrecv.Free() #reqd.Free() # Send xopt to master print('Processor %i sending final data to master') % rank if('xopt' not in locals()): # No xopt xopt = inf*ones(D) comm.Ssend(xopt, dest=0, tag=5) # Display figures and wait if(Vis == 1): show() return None, None, None, None
def animate(i): pass N = 10 width = 10 tab = permutation(N) fig = figure(figsize=(len(tab), 3)) axis('off') axis('equal') axis([0, len(tab) * width, 0, width]) rectangles = [ gca().add_patch( Rectangle(array([i * width, 0]), width - 1, width - 1, fc='b')) for i in range(N) ] annotations = [ gca().annotate(tab[i], array([i * width, 0]) + array([(width - 1) * .5, (width - 1) * .5]), color='w', weight='bold', fontsize=20, ha='center', va='center') for i in range(N) ] indices = [n for n in range(N)] ani = FuncAnimation(fig,
def runpar(f, g, H, Lg, Lh, l, u, bound, circle, A=None, b=None, E=None, d=None, Tol=1e-2, Heur=0, TolType='r', Vis=0, SD=1, Rtol=1e-15, TimeQP=0, TimeWidle=0, qpsolver='cvxopt'): # Optional Inputs # Tolerance # Heuristic lattice (0 - off, 1 - on) # Tolerance type (r - relative, a - absolute) # Visualisation (0 - off, 1 - on) # Step Debugging (0 - off, 1 - on) # Radius Tolerance # Time Worker Idling (0 - off, 1 - on) # Time QP solves (0 - off, 1 - on) # QP Solver (quadprog, cvxopt, nag) # MPI from mpi4py import MPI # MPI comm comm = MPI.COMM_WORLD rank = comm.Get_rank() # Get D D = len(l) # Master Process if (rank == 0): # Number of processors numprocs = comm.Get_size() # Import necessary functions from numpy import array, pi, sqrt, dot, identity, hstack, vstack, empty, inf from numpy.linalg import norm from time import time from itertools import product from sys import float_info # Initialise empty arrays if (A is None): A = empty((0, D)) b = empty(0) if (E is None): E = empty((0, D)) d = empty(0) # QuadProg++ solver (fast!) if (qpsolver == 'quadprog'): # Import QuadProg++ solver from PyQuadProg import PyQuadProg # Check if circle has feasible point def mfeasible(c): # Solve QP to check feasibility sol = PyQuadProg( 2 * identity(D), -2 * c.xc, E.transpose(), -1 * d, vstack([identity(D), -1 * identity(D), -1 * A]).transpose(), hstack([-l, u, b])) mxopt = sol.x.getArray() mr = dot(mxopt, mxopt) + dot(mxopt, -2 * c.xc) + dot( c.xc, c.xc) # Check if point lies inside domain if (mr < (c.r**2)): mf = 1 else: mf = 0 mxopt = None return mf, mxopt # CVXOPT QP solver (slow) elif (qpsolver == 'cvxopt'): # Import cvxopt solver from cvxopt import matrix from cvxopt.solvers import qp, options # Set tolerance options options['show_progress'] = False options['abstol'] = 1e-9 options['reltol'] = 1e-8 options['feastol'] = 1e-9 # Check if circle has feasible point def mfeasible(c): # Solve QP to check feasibility sol = qp(matrix(2 * identity(D)), matrix(-2 * c.xc), matrix(vstack([-1 * identity(D), identity(D), A])), matrix(hstack([-l, u, b])), matrix(E), matrix(d)) mxopt = array(sol['x']).flatten() mr = sol['primal objective'] mr = mr + dot(c.xc, c.xc) # Check if point lies inside domain if (mr < (c.r**2)): mf = 1 else: mf = 0 mxopt = None return mf, mxopt # NAG QP solver (fast!) elif (qpsolver == 'nag'): # Import QP Solver from qpsolver_lincon import qpsolver_lincon # Check if circle has feasible point def mfeasible(c): # Solve QP to check feasibility mxopt = c.xc.copy() mr = qpsolver_lincon(2 * identity(D), -2 * c.xc, hstack([l, -inf, d]), hstack([u, b, d]), mxopt, vstack([A, E]), D, A.shape[0] + E.shape[0]) mr = mr + dot(c.xc, c.xc) # Check if point lies inside domain if (mr < (c.r**2)): mf = 1 else: mf = 0 mxopt = None return mf, mxopt # Visualisation if (Vis == 1): from matplotlib.pyplot import figure, Rectangle, Circle, gca, show, title, axis, draw # Draw bound constraints [l,u] fig = figure('Processor ' + str(rank)) gca().add_patch( Rectangle((l[0], l[1]), u[0] - l[0], u[1] - l[1], fill=False)) axis([l[0] - 1, u[0] + 1, l[1] - 1, u[1] + 1]) title('Master Processor') show(block=False) # Circle drawing procedure def drawc(c, col): # Draw circle gca().add_patch( Circle((c.xc[0], c.xc[1]), radius=c.r, color=col, fill=False)) axis('equal') draw() if (Heur == 0): ksp = 3**D else: # Load relevant normalised lattice from numpy import loadtxt from pkg_resources import resource_stream if (D == 2): lat = array([[0., 0.], [1., 0.], [-1., 0.], [0.5, sqrt(3.) / 2.], [-0.5, sqrt(3.) / 2.], [0.5, -sqrt(3.) / 2.], [-0.5, -sqrt(3.) / 2.]]) elif (D == 3): lat = loadtxt(resource_stream('obb', 'lattices/d3')) elif (D == 4): lat = loadtxt(resource_stream('obb', 'lattices/d4')) elif (D == 5): lat = loadtxt(resource_stream('obb', 'lattices/d5')) elif (D == 6): lat = loadtxt(resource_stream('obb', 'lattices/e6')) elif (D == 7): lat = loadtxt(resource_stream('obb', 'lattices/e7')) elif (D == 8): lat = loadtxt(resource_stream('obb', 'lattices/e8')) else: raise RuntimeError('A lattice for ' + str(D) + ' Dimensions has yet to be provided.') # Get kissing number + 1 ksp = lat.shape[0] # Set up initial circle c0 = circle((u + l) / 2, norm(u - l) / 2) c0.xopt = c0.xc # Bound circle c0.lbound = bound(c0, Lg, Lh, f, g, H, D) # Upper bound c0.ubound = f(c0.xopt) # Set up circle list clist = [c0] cslb = clist[0] # Update global bounds U = cslb.ubound L = cslb.lbound xopt = cslb.xopt rad = cslb.r # Loop counter itr = 0 timer = time() if (TimeQP == 1): qptime = 0 # Debug Output if (SD == 1): print('----------------------------') print('Number of elements: %i') % len(clist) print('U: %f') % U print('L: %f') % L print('Circle radius: %e') % rad print('----------------------------') # Set tolerance if ((TolType == 'r') and (abs(U) > float_info.epsilon)): cutoff = (U - L) / abs(U) else: cutoff = U - L #and((time()-timer) < 3000) while ((cutoff > Tol) and (rad > Rtol)): # Update iteration count itr = itr + 1 # Prune list i = 0 while (i < len(clist)): if (clist[i].lbound > U): # Visualise if (Vis == 1): drawc(clist[i], 'k') del clist[i] i = i - 1 i = i + 1 if (Heur == 0): # Split circle into more circles inc = (cslb.r) / sqrt(D) # Increment rn = (cslb.r) / 2 # New radius xc = cslb.xc # Centre # Visualise if (Vis == 1): drawc(cslb, 'k') clist.remove(cslb) # Remove split circle from list # Create square spoke configuration spk = array([p for p in product([-inc, 0, inc], repeat=D)]) else: # Split circle into more circles inc = cslb.r # Increment rn = (cslb.r) / 2 # New radius xc = cslb.xc # Centre # Visualise if (Vis == 1): drawc(cslb, 'k') clist.remove(cslb) # Remove split circle from list # Scale configuration spk = inc * lat # List to distribute amongst processes dlist = [] # Create surrounding circles for i in range(0, ksp): # Create centre xcn = xc + spk[i, :] # Check if circle exists nc = 0 for k in range(0, len(clist)): if (all(xcn == clist[k].xc)): nc = 1 # If circle doesn't exist if (nc == 0): # Create circle cn = circle(xcn, rn) # Time QP Solve if (TimeQP == 1): eltime = MPI.Wtime() mfeas, cn.xopt = mfeasible(cn) if (TimeQP == 1): qptime += MPI.Wtime() - eltime # If circle has a feasible point (i.e. it's feasible) if (mfeas != 0): # Add to distribution list dlist.append(cn) # Visualise if (Vis == 1): drawc(cn, 'b') # Distribute data evenly amongst processes ihi = 0 trem = len(dlist) prem = numprocs req = [] for p in range(0, numprocs - 1): tproc = int(round(trem / prem)) ilo = ihi + 1 ihi = ihi + tproc req.append( comm.isend(dlist[ilo - 1:ihi], dest=numprocs - 1 - p, tag=0)) prem = prem - 1 trem = trem - tproc # Distribute remaining data to self tproc = int(round(trem / prem)) # Bound each item allocated to self for k in range(ihi, ihi + tproc): # Bound circle dlist[k].ubound = f(dlist[k].xopt) dlist[k].lbound = bound(dlist[k], Lg, Lh, f, g, H, D) # Add to circle list clist.append(dlist[k]) # Gather data back up for p in range(0, numprocs - 1): # Make sure data has been sent req[p].Wait() # Get list of bounded circles from other processes dlist = comm.recv(source=numprocs - 1 - p, tag=1) # Add to clist clist += dlist # Find circle c with smallest ubound cslb = min(clist, key=lambda x: x.ubound) # Update global feasible upper bound U = cslb.ubound xopt = cslb.xopt rad = cslb.r # Find circle with smallest lbound cslb = min(clist, key=lambda x: x.lbound) L = cslb.lbound # Set tolerance if ((TolType == 'r') and (abs(U) > float_info.epsilon)): cutoff = (U - L) / abs(U) else: cutoff = U - L # Debug Output if (SD == 1): print('Number of elements: %i') % len(clist) print('U: %f') % U print('L: %f') % L print('Circle radius: %e') % rad print('----------------------------') # Output end result print('Minimum value of %f at (') % f(xopt), for i in range(0, D - 1): print('%f,') % xopt[i], print('%f)') % xopt[D - 1] print('found with'), if ((TolType == 'r') and (abs(U) > float_info.epsilon)): print('relative'), else: print('absolute'), print('tolerance %f in %i iterations.') % (cutoff, itr) tol = cutoff xs = xopt fxs = f(xopt) print('Elapsed time %f seconds.') % (time() - timer) if (TimeQP == 1): print('Time taken for QP solves is %f seconds') % qptime # Kill worker processes for p in range(0, numprocs - 1): comm.send(None, dest=numprocs - 1 - p, tag=0) # Display figures and wait if (Vis == 1): show() return xs, fxs, tol, itr # Worker processes else: # Idle time if (TimeWidle == 1): eltime = MPI.Wtime() itime = 0 # Pick up scattered list rlist = comm.recv(source=0, tag=0) # Idle time if (TimeWidle == 1): itime += MPI.Wtime() - eltime while (rlist != None): # Bound each item in the list for k in range(0, len(rlist)): # Bound circle rlist[k].ubound = f(rlist[k].xopt) rlist[k].lbound = bound(rlist[k], Lg, Lh, f, g, H, D) # Send bounded list comm.send(rlist, dest=0, tag=1) # Idle time if (TimeWidle == 1): eltime = MPI.Wtime() # Pick up next scattered list rlist = comm.recv(source=0, tag=0) # Idle time if (TimeWidle == 1): itime += MPI.Wtime() - eltime # Output idle time if (TimeWidle == 1): print('Processor %i has been idle for %f seconds') % (rank, itime) return None, None, None, None