def show_frontier(X, Y, maxX=False, maxY=True, dots=False, XMAX=None, YMIN=None, ax=None, label=None, **style): """Plot Pareto frontier. Args: X, Y: data. maxX, maxY: (bool) whether to maximize or minimize along respective coordinate. dots: (bool) highlight points on the frontier (will use same color as `style`). ax: use an existing axis if non-null. style: keyword arguments, which will be passed to lines connecting the points on the Pareto frontier. XMAX: max value along x-axis YMIN: min value along y-axis """ if ax is None: ax = pl.gca() sty = {'c': 'b', 'alpha': 0.3, 'zorder': 0} sty.update(style) assert not maxX and maxY, 'need to update some hardcoded logic' f = pareto_frontier(X, Y, maxX=maxX, maxY=maxY) if not f: print yellow % '[warn] Empty frontier' return if dots: xs, ys = zip(*f) ax.scatter(xs, ys, lw=0, alpha=0.5, c=sty['c']) XMAX = XMAX if XMAX is not None else max(X) YMIN = YMIN if YMIN is not None else min(Y) assert XMAX >= max(X) assert YMIN <= min(Y) # Connect corners of frontier. The first and last points on frontier have # lines which surround the point cloud. f = [(min(X), YMIN)] + f + [(XMAX, max(Y))] # Make line segments from adjacent points pts = np.array([x for ((a,b), (c,d)) in window(f, 2) for x in [[a,b], [c,b], [c,b], [c,d]]]) # Plot ax.plot(pts[:,0], pts[:,1], label=label, **sty)
def show_frontier(X, Y, maxX=False, maxY=True, dots=False, ax=None, label=None, **style): """Plot Pareto frontier. Args: X, Y: data. maxX, maxY: (bool) whether to maximize or minimize along respective coordinate. dots: (bool) highlight points on the frontier (will use same color as `style`). ax: use an existing axis if non-null. style: keyword arguments, which will be passed to lines connecting the points on the Pareto frontier. """ if ax is None: ax = pl.gca() sty = {'c': 'b', 'alpha': 0.3, 'zorder': 0} sty.update(style) f = pareto_frontier(X, Y, maxX=maxX, maxY=maxY) if not f: print yellow % '[warn] Empty frontier' return if dots: xs, ys = zip(*f) ax.scatter(xs, ys, lw=0, alpha=0.5, c=sty['c']) # Connect corners of frontier. The first and last points on frontier have # lines which surround the point cloud. p, q = f[0], f[-1] (a,b) = min(X), max(X) (c,d) = min(Y), max(Y) # connect points with line segments pts = [] pts.extend([p, (a,c)]) pts.extend(x for ((a,b), (c,d)) in window(f, 2) for x in [[a,b], [c,b], [c,b], [c,d]]) pts.extend([q, (b,d)]) # make plot pts = np.array(pts) ax.plot(pts[:,0], pts[:,1], label=label, **sty)
def graphviz(self, output): from arsenal.iterextras import window with open(output, 'w') as f: print('digraph {', file=f) terminals = set() for x in list(self.incoming): for e in self.incoming[x]: print(' "%s" [label=\"\",shape=point];' % id(e), file=f) print(' "%s" -> "%s";' % (id(e), e.head), file=f) for b in e.body: print(' "%s" -> "%s" [arrowhead=none];' % (b, id(e)), file=f) if not self.incoming[b]: terminals.add(b) if terminals: print(terminals) f.write('{ rank = same; %s; }\n' % ('; '.join('"%s"' % (x, ) for x in terminals))) for a, b in window(sorted(terminals, key=lambda x: x[0]), 2): f.write( '"%s" -> "%s" [dir=none, style=invis, penwidth=1];\n' % (a, b)) f.write('{ rank = same; "%s"; "%s"; }\n' % (a, b)) print('}', file=f)
def show_frontier(X, Y, maxX=False, maxY=True, dots=False, XMIN=None, XMAX=None, YMIN=None, YMAX=None, ax=None, label=None, interpolation='pessimistic', **style): """Plot Pareto frontier. Args: X, Y: data. maxX, maxY: (bool) whether to maximize or minimize along respective coordinate. dots: (bool) highlight points on the frontier (will use same color as `style`). ax: use an existing axis if non-null. style: keyword arguments, which will be passed to lines connecting the points on the Pareto frontier. XMAX: max value along x-axis YMIN: min value along y-axis """ if ax is None: ax = pl.gca() sty = {'c': 'b', 'alpha': 0.3, 'zorder': 0} sty.update(style) if interpolation == 'linear-convex': # Convex hull by itself doesn't work, but what we have is ok because its # the intersection of the convex hull with the pareto frontier, which is # handled below. from scipy.spatial import ConvexHull X = np.array(X) Y = np.array(Y) hull = ConvexHull(np.array([X,Y]).T) X = X[hull.vertices] Y = Y[hull.vertices] # assert not maxX and maxY, 'need to update some hardcoded logic' f = pareto_frontier(X, Y, maxX=maxX, maxY=maxY) if not f: print(yellow % '[warn] Empty frontier') return if dots: xs, ys = list(zip(*f)) ax.scatter(xs, ys, lw=0, alpha=0.5, c=sty['c']) XMIN = min(min(X), XMIN) if XMIN is not None else min(X) XMAX = max(max(X), XMAX) if XMAX is not None else max(X) YMIN = min(min(Y), YMIN) if YMIN is not None else min(Y) YMAX = max(max(Y), YMAX) if YMAX is not None else max(Y) # if 0: # # This version lets you clip away points. I found it a little problematic to use. # XMIN = XMIN if XMIN is not None else min(X) # XMAX = XMAX if XMAX is not None else max(X) # YMIN = YMIN if YMIN is not None else min(Y) # YMAX = YMAX if YMAX is not None else max(Y) # if (max(X) > XMAX or min(X) < XMIN or min(Y) > YMIN or max(Y) < YMAX): # print '[PARETO] Warning: data out of bounds!' # Connect corners of frontier. The first and last points on frontier have # lines which surround the point cloud. # TODO: make this look nicer... if maxX and maxY: f = [(XMAX, YMIN)] + f + [(XMIN, YMAX)] elif not maxX and maxY: f = [(XMIN, YMIN)] + f + [(XMAX, YMAX)] elif maxX and not maxY: f = [(XMAX, YMAX)] + f + [(XMIN, YMIN)] else: f = [(XMIN, YMAX)] + f + [(XMAX, YMIN)] if interpolation == 'pessimistic': # Make line segments from adjacent points pts = np.array([x for ((a,b), (c,d)) in window(f, 2) for x in [[a,b], [c,b], [c,b], [c,d]]]) elif interpolation in {'linear','linear-convex'}: # Make line segments from adjacent points pts = np.array([x for ((a,b), (c,d)) in window(f, 2) for x in [[a,b], [c,d]]]) # Plot ax.plot(pts[:,0], pts[:,1], label=label, **sty) return pts
def show_frontier(X, Y, maxX=False, maxY=True, dots=False, XMIN=None, XMAX=None, YMIN=None, YMAX=None, ax=None, label=None, interpolation='pessimistic', **style): """Plot Pareto frontier. Args: X, Y: data. maxX, maxY: (bool) whether to maximize or minimize along respective coordinate. dots: (bool) highlight points on the frontier (will use same color as `style`). ax: use an existing axis if non-null. style: keyword arguments, which will be passed to lines connecting the points on the Pareto frontier. XMAX: max value along x-axis YMIN: min value along y-axis """ if ax is None: ax = pl.gca() sty = {'c': 'b', 'alpha': 0.3, 'zorder': 0} sty.update(style) if interpolation == 'linear-convex': # Convex hull by itself doesn't work, but what we have is ok because its # the intersection of the convex hull with the pareto frontier, which is # handled below. from scipy.spatial import ConvexHull X = np.array(X) Y = np.array(Y) hull = ConvexHull(np.array([X,Y]).T) X = X[hull.vertices] Y = Y[hull.vertices] # assert not maxX and maxY, 'need to update some hardcoded logic' f = pareto_frontier(X, Y, maxX=maxX, maxY=maxY) if not f: print yellow % '[warn] Empty frontier' return if dots: xs, ys = zip(*f) ax.scatter(xs, ys, lw=0, alpha=0.5, c=sty['c']) XMIN = min(min(X), XMIN) if XMIN is not None else min(X) XMAX = max(max(X), XMAX) if XMAX is not None else max(X) YMIN = min(min(Y), YMIN) if YMIN is not None else min(Y) YMAX = max(max(Y), YMAX) if YMAX is not None else max(Y) # if 0: # # This version lets you clip away points. I found it a little problematic to use. # XMIN = XMIN if XMIN is not None else min(X) # XMAX = XMAX if XMAX is not None else max(X) # YMIN = YMIN if YMIN is not None else min(Y) # YMAX = YMAX if YMAX is not None else max(Y) # if (max(X) > XMAX or min(X) < XMIN or min(Y) > YMIN or max(Y) < YMAX): # print '[PARETO] Warning: data out of bounds!' # Connect corners of frontier. The first and last points on frontier have # lines which surround the point cloud. # TODO: make this look nicer... if maxX and maxY: f = [(XMAX, YMIN)] + f + [(XMIN, YMAX)] elif not maxX and maxY: f = [(XMIN, YMIN)] + f + [(XMAX, YMAX)] elif maxX and not maxY: f = [(XMAX, YMAX)] + f + [(XMIN, YMIN)] else: f = [(XMIN, YMAX)] + f + [(XMAX, YMIN)] if interpolation == 'pessimistic': # Make line segments from adjacent points pts = np.array([x for ((a,b), (c,d)) in window(f, 2) for x in [[a,b], [c,b], [c,b], [c,d]]]) elif interpolation in {'linear','linear-convex'}: # Make line segments from adjacent points pts = np.array([x for ((a,b), (c,d)) in window(f, 2) for x in [[a,b], [c,d]]]) # Plot ax.plot(pts[:,0], pts[:,1], label=label, **sty) return pts
print '[fit] fitting...' from ldp.viz.parametric_fit import fit ff, gg = fit(runtime, accuracy) print '[fit] done.' pts = zip(penalty, runtime, accuracy) # Add two fake points: # TODO: some magic numbers... pts = [(None, runtime.max() * 2.0, accuracy.max() * 1.01) ] + pts + [(None, runtime.min() * .98, accuracy.min() * .98)] ddd = [] skip = [] for (((p1, x1, y1), (p, x2, y2), (p3, x3, y3))) in window(pts, 3): # slopes give a range for lambda values to try. m12 = (y2 - y1) / (x2 - x1) m23 = (y3 - y2) / (x3 - x2) #print 'penalty=%g point=%s, lambda=%s' % (p, [x2,y2], [m12, m23]) if m12 >= m23: # This point is not on the convex Pareto frontier. So, we back off to # the slope between the neighboring points m31 = (y3 - y1) / (x3 - x1) #print 'penalty=%g point=%s not on convex frontier.' % (p, [x2,y2]), 'try', m31 m12 = m23 = m31 skip.append([x2, y2])