Ejemplo n.º 1
0
def make_grad_convolve_0(ans, in0, in1, mode='full'):
    if mode == 'full':
        return lambda g: convolve(g, flipud(in1), mode='valid')
    elif mode == 'same':
        return lambda g: flipud(convolve(flipud(g), in1, mode='same'))
    elif mode == 'valid':
        return lambda g: convolve(g, flipud(in1), mode='full')
    else:
        raise Exception("Unrecognized mode {0}".format(mode))
Ejemplo n.º 2
0
def make_grad_convolve_1(ans, in0, in1, mode='full'):
    if mode == 'full':
        return lambda g: convolve(g, flipud(in0), mode='valid')
    elif mode == 'same':
        idxs = get_same_slice(in0.shape[0], in1.shape[0])
        return lambda g: convolve(g, flipud(in0), mode='full')[idxs]
    elif mode == 'valid':
        return lambda g: convolve(flipud(in0), g, mode='valid')
    else:
        raise Exception("Unrecognized mode {0}".format(mode))
Ejemplo n.º 3
0
    def get_sharp_TE_airfoil(self):
        # Returns a version of the airfoil with a sharp trailing edge.

        upper_original_coors = self.upper_coordinates()  # Note: includes leading edge point, be careful about duplicates
        lower_original_coors = self.lower_coordinates()  # Note: includes leading edge point, be careful about duplicates

        # Find data about the TE

        # Get the scale factor
        x_mcl = self.mcl_coordinates[:,0]
        x_max = np.max(x_mcl)
        x_min = np.min(x_mcl)
        scale_factor = (x_mcl - x_min) / (x_max - x_min) # linear contraction

        # Do the contraction
        upper_minus_mcl_adjusted = self.upper_minus_mcl - self.upper_minus_mcl[-1,:] * np.expand_dims(scale_factor,1)

        # Recreate coordinates
        upper_coordinates_adjusted = np.flipud(self.mcl_coordinates + upper_minus_mcl_adjusted)
        lower_coordinates_adjusted = self.mcl_coordinates - upper_minus_mcl_adjusted

        coordinates = np.vstack((
            upper_coordinates_adjusted[:-1,:],
            lower_coordinates_adjusted
        ))

        # Make a new airfoil with the coordinates
        name = self.name + ", with sharp TE"
        new_airfoil = Airfoil(name=name, coordinates=coordinates, repanel=False)

        return new_airfoil
Ejemplo n.º 4
0
    def populate_mcl_coordinates(self):
        # Populates self.mcl_coordinates, a Nx2 list of the airfoil's mean camber line coordinates.
        # Ordered from the leading edge to the trailing edge.
        #
        # Also populates self.upper_minus_mcl and self.lower_minus mcl, which are Nx2 lists of the vectors needed to
        # go from the mcl coordinates to the upper and lower surfaces, respectively. Both listed leading-edge to trailing-edge.
        #
        # Also populates self.thickness, a Nx2 list of the thicknesses at the mcl_coordinates x-points.

        upper = np.flipud(self.upper_coordinates())
        lower = self.lower_coordinates()

        mcl_coordinates = (upper + lower) / 2
        self.mcl_coordinates = mcl_coordinates

        self.upper_minus_mcl = upper - self.mcl_coordinates
        # self.lower_minus_mcl = -self.upper_minus_mcl

        thickness = np.sqrt(
            np.sum(
                np.power(self.upper_minus_mcl, 2),
                axis = 1
            )
        ) * 2
        self.thickness = np.column_stack((self.mcl_coordinates[:,0],thickness))
def draw_2d(g,steplength,max_steps,w_inits,num_samples,**kwargs):
    wmin = -3.1
    wmax = 3.1
    if 'wmin' in kwargs:            
        wmin = kwargs['wmin']
    if 'wmax' in kwargs:
        wmax = kwargs['wmax'] 
        
    # initialize figure
    fig = plt.figure(figsize = (9,4))
    artist = fig

    # create subplot with 3 panels, plot input function in center plot
    gs = gridspec.GridSpec(1, 3, width_ratios=[1,4,1]) 
    ax1 = plt.subplot(gs[0]); ax1.axis('off')
    ax3 = plt.subplot(gs[2]); ax3.axis('off')
    ax = plt.subplot(gs[1]); 

    # generate function for plotting on each slide
    w_plot = np.linspace(wmin,wmax,500)
    g_plot = [g(s) for s in w_plot]
    g_range = max(g_plot) - min(g_plot)
    ggap = g_range*0.1
    width = 30
       
    #### loop over all initializations, run gradient descent algorithm for each and plot results ###
    for j in range(len(w_inits)):
        # get next initialization
        w_init = w_inits[j]

        # run grad descent for this init
        func = g
        pt_history,eval_history = random_local_search_2d(func,w_init,max_steps,num_samples,steplength)

        # colors for points --> green as the algorithm begins, yellow as it converges, red at final point
        s = np.linspace(0,1,len(pt_history[:round(len(eval_history)/2)]))
        s.shape = (len(s),1)
        t = np.ones(len(eval_history[round(len(eval_history)/2):]))
        t.shape = (len(t),1)
        s = np.vstack((s,t))
        colorspec = []
        colorspec = np.concatenate((s,np.flipud(s)),1)
        colorspec = np.concatenate((colorspec,np.zeros((len(s),1))),1)
        
        # plot function, axes lines
        ax.plot(w_plot,g_plot,color = 'k',zorder = 2)                           # plot function
        ax.axhline(y=0, color='k',zorder = 1,linewidth = 0.25)
        ax.axvline(x=0, color='k',zorder = 1,linewidth = 0.25)
        ax.set_xlabel(r'$w$',fontsize = 13)
        ax.set_ylabel(r'$g(w)$',fontsize = 13,rotation = 0,labelpad = 25)            
            
        ### plot all local search points ###
        for k in range(len(eval_history)):
            # pick out current weight and function value from history, then plot
            w_val = pt_history[k]
            g_val = eval_history[k]

            ax.scatter(w_val,g_val,s = 90,c = colorspec[k],edgecolor = 'k',linewidth = 0.5*((1/(float(k) + 1)))**(0.4),zorder = 3,marker = 'X')            # evaluation on function
            ax.scatter(w_val,0,s = 90,facecolor = colorspec[k],edgecolor = 'k',linewidth = 0.5*((1/(float(k) + 1)))**(0.4), zorder = 3)
Ejemplo n.º 6
0
def transpose_lower_banded_matrix(Lab):
    # This is painful
    Uab = np.flipud(Lab)
    u = Uab.shape[0] - 1
    for i in range(1, u + 1):
        Uab[-(i + 1), i:] = Uab[-(i + 1), :-i]
        Uab[-(i + 1), :i] = 0
    return Uab
Ejemplo n.º 7
0
def prox_sdss_symmetry(X, step):
    """SDSS/HSC symmetry operator

    This function uses the *minimum* of the two
    symmetric pixels in the update.
    """
    Xs = np.fliplr(np.flipud(X))
    X[:] = np.min([X, Xs], axis=0)
    return X
Ejemplo n.º 8
0
def fft_convolve2d(x, y):
    """ 2D convolution, using FFT"""
    fr = fft.fft2(x)
    fr2 = fft.fft2(np.flipud(np.fliplr(y)))
    m, n = fr.shape
    cc = np.real(fft.ifft2(fr * fr2))
    cc = np.roll(cc, -int(m / 2) + 1, axis=0)
    cc = np.roll(cc, -int(n / 2) + 1, axis=1)
    return cc
Ejemplo n.º 9
0
def f_symmetry(dof, Mx, My, xsym, ysym, Nlayer=1):
    out = []
    for i in range(Nlayer):
        df = np.reshape(dof[i * Mx * My:(i + 1) * Mx * My], (Mx, My))
        if xsym == 1:
            df = np.hstack((df, np.fliplr(df)))
        if ysym == 1:
            df = np.vstack((df, np.flipud(df)))
        out.append(df.flatten())
    return np.concatenate(np.array(out))
Ejemplo n.º 10
0
def prox_soft_symmetry(X, step, strength=1):
    """Soft version of symmetry
    Using a `sigma` that varies from 0 to 1,
    with 0 meaning no symmetry enforced at all and
    1  being completely symmetric, the user can customize
    the level of symmetry required for a component
    """
    Xs = np.fliplr(np.flipud(X))
    X[:] = 0.5 * strength * (X + Xs) + (1 - strength) * X
    return X
Ejemplo n.º 11
0
 def make_colorspec(self, w_hist):
     # make color range for path
     s = np.linspace(0, 1, len(w_hist[:round(len(w_hist) / 2)]))
     s.shape = (len(s), 1)
     t = np.ones(len(w_hist[round(len(w_hist) / 2):]))
     t.shape = (len(t), 1)
     s = np.vstack((s, t))
     colorspec = []
     colorspec = np.concatenate((s, np.flipud(s)), 1)
     colorspec = np.concatenate((colorspec, np.zeros((len(s), 1))), 1)
     return colorspec
Ejemplo n.º 12
0
def plotit(X,
           Y=None,
           clf=None,
           markers=('s', 'o'),
           hold=False,
           transform=None):
    """
    Just a function for showing a data scatter plot and classification boundary
    of a classifier clf
    """
    minx, maxx = np.min(X[:, 0]), np.max(X[:, 0])
    miny, maxy = np.min(X[:, 1]), np.max(X[:, 1])
    if clf is not None:
        npts = 100
        x = np.linspace(minx, maxx, npts)
        y = np.linspace(miny, maxy, npts)
        t = np.array(list(itertools.product(x, y)))
        if transform is not None:
            t = transform(t)
        z = clf(t)
        z = np.reshape(z, (npts, npts))

        extent = [minx, maxx, miny, maxy]
        plt.imshow(z, vmin=-2, vmax=+2)
        plt.contour(z, [-1, 0, 1],
                    linewidths=[2],
                    colors=('b', 'k', 'r'),
                    extent=extent,
                    label='f(x)=0')
        plt.imshow(np.flipud(z),
                   extent=extent,
                   cmap=plt.cm.Purples,
                   vmin=-2,
                   vmax=+2)
        plt.colorbar()
        plt.axis([minx, maxx, miny, maxy])
    if Y is not None:
        plt.scatter(X[Y == 1, 0], X[Y == 1, 1], marker=markers[0], c='y', s=30)
        plt.scatter(X[Y == -1, 0],
                    X[Y == -1, 1],
                    marker=markers[1],
                    c='c',
                    s=30)
        plt.xlabel('$x_1$')
        plt.ylabel('$x_2$')

    else:
        plt.scatter(X[:, 0], X[:, 1], marker='.', c='k', s=5)
    if not hold:
        plt.grid()
        plt.show()
Ejemplo n.º 13
0
    def add_control_surface(self, deflection=0., hinge_point=0.75):
        # Returns a version of the airfoil with a control surface added at a given point.
        # Inputs:
        #   # deflection: the deflection angle, in degrees. Downwards-positive.
        #   # hinge_point: the location of the hinge, as a fraction of chord.

        # Make the rotation matrix for the given angle.
        sintheta = np.sin(np.radians(-deflection))
        costheta = np.cos(np.radians(-deflection))
        rotation_matrix = np.array([[costheta, -sintheta],
                                    [sintheta, costheta]])

        # Find the hinge point
        hinge_point = np.array(
            (hinge_point, self.get_camber_at_chord_fraction(hinge_point)
             ))  # Make hinge_point a vector.

        # Split the airfoil into the sections before and after the hinge
        split_index = np.where(
            self.mcl_coordinates[:, 0] > hinge_point[0])[0][0]
        mcl_coordinates_before = self.mcl_coordinates[:split_index, :]
        mcl_coordinates_after = self.mcl_coordinates[split_index:, :]
        upper_minus_mcl_before = self.upper_minus_mcl[:split_index, :]
        upper_minus_mcl_after = self.upper_minus_mcl[split_index:, :]

        # Rotate the mean camber line (MCL) and "upper minus mcl"
        new_mcl_coordinates_after = np.transpose(
            rotation_matrix
            @ np.transpose(mcl_coordinates_after - hinge_point)) + hinge_point
        new_upper_minus_mcl_after = np.transpose(
            rotation_matrix @ np.transpose(upper_minus_mcl_after))

        # Do blending

        # Assemble airfoil
        new_mcl_coordinates = np.vstack(
            (mcl_coordinates_before, new_mcl_coordinates_after))
        new_upper_minus_mcl = np.vstack(
            (upper_minus_mcl_before, new_upper_minus_mcl_after))
        upper_coordinates = np.flipud(new_mcl_coordinates +
                                      new_upper_minus_mcl)
        lower_coordinates = new_mcl_coordinates - new_upper_minus_mcl
        coordinates = np.vstack((upper_coordinates, lower_coordinates[1:, :]))

        new_airfoil = Airfoil(name=self.name + " flapped",
                              coordinates=coordinates,
                              repanel=False)
        return new_airfoil  # TODO fix self-intersecting airfoils at high deflections
    def animate(k):
        # clear the panels
        ax1.cla()
        ax2.cla()

        # print rendering update
        if np.mod(k + 1, 25) == 0:
            print('rendering animation frame ' + str(k + 1) + ' of ' +
                  str(num_frames))
        if k == num_frames - 1:
            print('animation rendering complete!')
            time.sleep(1.5)
            clear_output()

        if k > 0:
            # pull current tracer
            tracer = tracer_range[k - 1]
            tracer = np.array([float(tracer[0]), float(tracer[1])])
            tracer.shape = (2, 1)
            g_tracer = func(tracer)

        ### draw 3d version ###
        for ax in [ax1, ax2]:
            # plot function
            plot_func(func, view, ax)

            if k > 0:
                # scatter anchor point
                ax.scatter(anchor[0],
                           anchor[1],
                           g_anchor,
                           s=50,
                           c='lime',
                           edgecolor='k',
                           linewidth=1)
                # plot hyperplane connecting the anchor to tracer
                secant(func, anchor, tracer, ax)

                # reset tracer
                tracer = np.flipud(tracer)

        return artist,
Ejemplo n.º 15
0
 def fun(x): return to_scalar(np.flipud(x))
 d_fun = lambda x : to_scalar(grad(fun)(x))
Ejemplo n.º 16
0
    def animate_it(self, **kwargs):
        # get new initial point if desired
        if 'w_init' in kwargs:
            self.w_init = float(kwargs['w_init'])

        # take in user defined step length
        if 'alpha' in kwargs:
            self.alpha = float(kwargs['alpha'])

        # take in user defined maximum number of iterations
        if 'max_its' in kwargs:
            self.max_its = float(kwargs['max_its'])

        # viewing range
        wmax = 5
        if 'wmax' in kwargs:
            wmax = kwargs['wmax']

        # initialize figure
        fig = plt.figure(figsize=(10, 5))
        artist = fig

        # create subplot with 3 panels, plot input function in center plot
        gs = gridspec.GridSpec(1, 3, width_ratios=[1, 5, 1])
        ax1 = plt.subplot(gs[0])
        ax1.axis('off')
        ax3 = plt.subplot(gs[2])
        ax3.axis('off')

        # plot input function
        ax = plt.subplot(gs[1], aspect='equal')

        # generate function for plotting on each slide
        w_plot = np.linspace(-wmax, wmax, 1000)
        g_plot = self.g(w_plot)
        g_range = max(g_plot) - min(g_plot)
        ggap = g_range * 0.25
        width = 30

        # run gradient descent method
        self.w_hist = []
        self.run_gradient_descent()

        # colors for points --> green as the algorithm begins, yellow as it converges, red at final point
        s = np.linspace(0, 1, len(self.w_hist[:round(len(self.w_hist) / 2)]))
        s.shape = (len(s), 1)
        t = np.ones(len(self.w_hist[round(len(self.w_hist) / 2):]))
        t.shape = (len(t), 1)
        s = np.vstack((s, t))
        self.colorspec = []
        self.colorspec = np.concatenate((s, np.flipud(s)), 1)
        self.colorspec = np.concatenate((self.colorspec, np.zeros(
            (len(s), 1))), 1)

        # animation sub-function
        print('starting animation rendering...')
        num_frames = len(self.w_hist)

        def animate(k):
            ax.cla()

            # print rendering update
            if np.mod(k + 1, 25) == 0:
                print('rendering animation frame ' + str(k + 1) + ' of ' +
                      str(num_frames))
            if k == num_frames - 1:
                print('animation rendering complete!')
                time.sleep(1.5)
                clear_output()

            # plot function
            ax.plot(w_plot, g_plot, color='k', zorder=2)  # plot function

            # plot initial point and evaluation
            if k == 0:
                w_val = self.w_init
                g_val = self.g(w_val)
                ax.scatter(w_val,
                           g_val,
                           s=100,
                           c='r',
                           edgecolor='k',
                           linewidth=0.7,
                           zorder=3)  # plot point of tangency
                ax.scatter(w_val,
                           0,
                           s=100,
                           c='r',
                           edgecolor='k',
                           linewidth=0.7,
                           zorder=3,
                           marker='X')
                # draw dashed line connecting w axis to point on cost function
                s = np.linspace(0, g_val)
                o = np.ones((len(s)))
                ax.plot(o * w_val, s, 'k--', linewidth=1)

            # plot all input/output pairs generated by algorithm thus far
            if k > 0 and k < len(self.w_hist) + 1:
                # plot all points up to this point
                for j in range(min(k, len(self.w_hist))):
                    alpha_val = 1
                    if j < k - 1:
                        alpha_val = 0.1

                    # get next value of weight, function and gradient evaluation
                    w_val = self.w_hist[j]
                    g_val = self.g(w_val)
                    grad_val = float(self.grad(w_val))

                    # plot current point
                    ax.scatter(w_val,
                               g_val,
                               s=90,
                               c='r',
                               edgecolor='k',
                               linewidth=0.7,
                               zorder=3,
                               alpha=alpha_val)  # plot point of tangency
                    ax.scatter(w_val,
                               0,
                               s=90,
                               facecolor='r',
                               marker='X',
                               edgecolor='k',
                               linewidth=0.7,
                               zorder=3,
                               alpha=alpha_val)

                    #### plot linear surrogate ####
                    # determine width to plot the approximation -- so its length == width defined above
                    div = float(1 + grad_val**2)
                    w1 = w_val - math.sqrt(width / div)
                    w2 = w_val + math.sqrt(width / div)

                    # use point-slope form of line to plot
                    wrange = np.linspace(w1, w2, 100)
                    h = g_val + grad_val * (wrange - w_val)

                    # plot tangent line
                    ax.plot(wrange,
                            h,
                            color=self.colors[0],
                            linewidth=2,
                            zorder=1,
                            alpha=alpha_val)  # plot approx

                    # plot tangent point
                    ax.scatter(w_val,
                               g_val,
                               s=100,
                               c='r',
                               edgecolor='k',
                               linewidth=0.7,
                               zorder=3,
                               alpha=alpha_val)  # plot point of tangency

                    # plot next point learned from surrogate
                    # create next point information
                    w_zero = w_val - self.alpha * grad_val
                    g_zero = self.g(w_zero)
                    h_zero = g_val + grad_val * (w_zero - w_val)

                    # draw intersection at zero and associated point on cost function you hop back too
                    ax.scatter(w_zero,
                               h_zero,
                               s=100,
                               c=self.colors[0],
                               edgecolor='k',
                               linewidth=0.7,
                               zorder=3,
                               marker='X',
                               alpha=alpha_val)
                    ax.scatter(w_zero,
                               0,
                               s=100,
                               c='r',
                               edgecolor='k',
                               linewidth=0.7,
                               zorder=3,
                               marker='X',
                               alpha=alpha_val)
                    ax.scatter(w_zero,
                               g_zero,
                               s=100,
                               c='r',
                               edgecolor='k',
                               linewidth=0.7,
                               zorder=3,
                               alpha=alpha_val)  # plot point of tangency

                    ### draw simple quadratic surrogate ###
                    # decide on range for quadratic so it looks nice
                    quad_term = 1 / float(2 * self.alpha)
                    a = 0.5 * quad_term
                    b = grad_val - 2 * 0.5 * quad_term * w_val
                    c = 0.5 * quad_term * w_val**2 - grad_val * w_val - width

                    # solve for zero points
                    w1 = (-b + math.sqrt(b**2 - 4 * a * c)) / float(2 * a +
                                                                    0.00001)
                    w2 = (-b - math.sqrt(b**2 - 4 * a * c)) / float(2 * a +
                                                                    0.00001)
                    wrange = np.linspace(w1, w2, 100)

                    # create simple quadratic surrogate
                    h = g_val + grad_val * (wrange - w_val) + quad_term * (
                        wrange - w_val)**2

                    # plot simple quadratic surrogate
                    ax.plot(wrange,
                            h,
                            color=self.colors[1],
                            linewidth=2,
                            zorder=1,
                            alpha=alpha_val)  # plot approx

                    # plot point of intersection - next gradient descent step - on simple quadratic surrogate
                    h_zero_2 = g_val + grad_val * (w_zero - w_val) + 1 / float(
                        2 * self.alpha) * (w_zero - w_val)**2

                    ax.scatter(w_zero,
                               h_zero_2,
                               s=100,
                               c=self.colors[1],
                               edgecolor='k',
                               linewidth=0.7,
                               zorder=3,
                               marker='X',
                               alpha=alpha_val)

                    # draw dashed line connecting w axis to point on cost function
                    s = np.linspace(0, g_val)
                    o = np.ones((len(s)))
                    ax.plot(o * w_val, s, 'k--', linewidth=1, alpha=alpha_val)

                    vals = [0, h_zero, h_zero_2, g_zero]
                    vals = np.sort(vals)

                    s = np.linspace(vals[0], vals[3])
                    o = np.ones((len(s)))
                    w_val = self.w_hist[j + 1]
                    ax.plot(o * w_val, s, 'k--', linewidth=1, alpha=alpha_val)

            # fix viewing limits
            ax.set_xlim([-wmax, wmax])
            ax.set_ylim([min(g_plot) - ggap, max(g_plot) + ggap])
            ax.axhline(y=0, color='k', zorder=0, linewidth=0.5)
            ax.set_xlabel(r'$w$', fontsize=12)
            ax.set_ylabel(r'$g(w)$', fontsize=12, rotation=0, labelpad=20)

            return artist,

        anim = animation.FuncAnimation(fig,
                                       animate,
                                       frames=num_frames,
                                       interval=num_frames,
                                       blit=True)

        return (anim)
    def draw_panel(self, ax, title, **kwargs):
        # set viewing limits on contour plot
        xvals = [self.w_hist[s][0] for s in range(len(self.w_hist))]
        xvals.append(self.w_init[0])
        yvals = [self.w_hist[s][1] for s in range(len(self.w_hist))]
        yvals.append(self.w_init[1])
        xmax = max(xvals)
        xmin = min(xvals)
        xgap = (xmax - xmin) * 0.1
        ymax = max(yvals)
        ymin = min(yvals)
        ygap = (ymax - ymin) * 0.1
        xmin -= xgap
        xmax += xgap
        ymin -= ygap
        ymax += ygap

        if 'xmin' in kwargs:
            xmin = kwargs['xmin']
        if 'xmax' in kwargs:
            xmax = kwargs['xmax']
        if 'ymin' in kwargs:
            ymin = kwargs['ymin']
        if 'ymax' in kwargs:
            ymax = kwargs['ymax']
        axes = False
        if 'axes' in kwargs:
            axes = kwargs['ymax']
        pts = False
        if 'pts' in kwargs:
            pts = kwargs['pts']

        pts = False
        if 'pts' in kwargs:
            pts = kwargs['pts']

        linewidth = 2.5
        if 'linewidth' in kwargs:
            linewidth = kwargs['linewidth']

        #### define input space for function and evaluate ####
        w1 = np.linspace(xmin, xmax, 400)
        w2 = np.linspace(ymin, ymax, 400)
        w1_vals, w2_vals = np.meshgrid(w1, w2)
        w1_vals.shape = (len(w1)**2, 1)
        w2_vals.shape = (len(w2)**2, 1)
        h = np.concatenate((w1_vals, w2_vals), axis=1)
        func_vals = np.asarray([self.g(s) for s in h])
        w1_vals.shape = (len(w1), len(w1))
        w2_vals.shape = (len(w2), len(w2))
        func_vals.shape = (len(w1), len(w2))

        ### make contour right plot - as well as horizontal and vertical axes ###
        # set level ridges
        num_contours = kwargs['num_contours']
        levelmin = min(func_vals.flatten())
        levelmax = max(func_vals.flatten())
        cutoff = 0.5
        cutoff = (levelmax - levelmin) * cutoff
        numper = 3
        levels1 = np.linspace(cutoff, levelmax, numper)
        num_contours -= numper

        levels2 = np.linspace(levelmin, cutoff, min(num_contours, numper))
        levels = np.unique(np.append(levels1, levels2))
        num_contours -= numper
        while num_contours > 0:
            cutoff = levels[1]
            levels2 = np.linspace(levelmin, cutoff, min(num_contours, numper))
            levels = np.unique(np.append(levels2, levels))
            num_contours -= numper

        a = ax.contour(w1_vals, w2_vals, func_vals, levels=levels, colors='k')
        ax.contourf(w1_vals, w2_vals, func_vals, levels=levels, cmap='Blues')

        if axes == True:
            ax.axhline(linestyle='--', color='k', linewidth=1)
            ax.axvline(linestyle='--', color='k', linewidth=1)

        # colors for points
        s = np.linspace(0, 1, len(self.w_hist[:round(len(self.w_hist) / 2)]))
        s.shape = (len(s), 1)
        t = np.ones(len(self.w_hist[round(len(self.w_hist) / 2):]))
        t.shape = (len(t), 1)
        s = np.vstack((s, t))
        colorspec = []
        colorspec = np.concatenate((s, np.flipud(s)), 1)
        colorspec = np.concatenate((colorspec, np.zeros((len(s), 1))), 1)

        ### plot function decrease plot in right panel
        for j in range(len(self.w_hist)):
            w_val = self.w_hist[j]
            g_val = self.g(w_val)

            # plot in left panel
            if pts == 'True':
                ax.scatter(w_val[0],
                           w_val[1],
                           s=30,
                           c=colorspec[j],
                           edgecolor='k',
                           linewidth=1.5 * math.sqrt((1 / (float(j) + 1))),
                           zorder=3)

            # plot connector between points for visualization purposes
            if j > 0:
                w_old = self.w_hist[j - 1]
                w_new = self.w_hist[j]

                ax.plot([w_old[0], w_new[0]], [w_old[1], w_new[1]],
                        color=colorspec[j],
                        linewidth=linewidth,
                        alpha=1,
                        zorder=2)  # plot approx
                ax.plot([w_old[0], w_new[0]], [w_old[1], w_new[1]],
                        color='k',
                        linewidth=linewidth + 0.4,
                        alpha=1,
                        zorder=1)  # plot approx

        # clean panel
        ax.set_title(title, fontsize=12)
        ax.set_xlabel('$w_1$', fontsize=12)
        ax.set_ylabel('$w_2$', fontsize=12, rotation=0)
        ax.axhline(y=0, color='k', zorder=0, linewidth=0.5)
        ax.axvline(x=0, color='k', zorder=0, linewidth=0.5)
        ax.set_xlim([xmin, xmax])
        ax.set_ylim([ymin, ymax])
Ejemplo n.º 18
0
    def draw_it_newtons(self,**args):
        # user-defined input point
        if 'w_init' in args:
            self.w_init = float(args['w_init'])
            
        # user-defined max_its
        if 'max_its' in args:
            self.max_its = float(args['max_its'])
            
        # initialize figure
        fig = plt.figure(figsize = (12,4))
        artist = fig
        
        # create subplot with 3 panels, plot input function in center plot
        gs = gridspec.GridSpec(1, 2, width_ratios=[1,1]) 
        ax1 = plt.subplot(gs[0]); 
        ax2 = plt.subplot(gs[1]);       
        artist = fig

        # generate function for plotting on each slide
        w_plot = np.linspace(-3.1,3.1,200)
        g_plot = self.g(w_plot)
        grad_plot = [self.grad(v) for v in w_plot]
        g_range = max(g_plot) - min(g_plot)
        ggap = g_range*0.1
        w_vals = np.linspace(-2.5,2.5,50)
        
        # run newtons method
        self.w_hist = []
        self.run_newtons_method()
        
        # colors for points
        s = np.linspace(0,1,len(self.w_hist[:round(len(self.w_hist)/2)]))
        s.shape = (len(s),1)
        t = np.ones(len(self.w_hist[round(len(self.w_hist)/2):]))
        t.shape = (len(t),1)
        s = np.vstack((s,t))
        self.colorspec = []
        self.colorspec = np.concatenate((s,np.flipud(s)),1)
        self.colorspec = np.concatenate((self.colorspec,np.zeros((len(s),1))),1)
        
        # animation sub-function
        print ('beginning animation rendering...')
        def animate(k):
            ax1.cla()
            ax2.cla()
                        
            # print rendering update
            if k == len(self.w_hist):
                print ('animation rendering complete!')
                time.sleep(1.5)
                clear_output()
            
            # plot functions
            ax1.plot(w_plot,g_plot,color = 'k',zorder = 0)               # plot function
            ax2.plot(w_plot,grad_plot,color = 'k',zorder = 2)                           # plot function
            
            # plot initial point and evaluation
            if k == 0:
                w_val = self.w_init
                g_val = self.g(w_val)
                ax1.scatter(w_val,g_val,s = 120,c = 'm',edgecolor = 'k',linewidth = 0.7,zorder = 2)            # plot point of tangency
                ax1.scatter(w_val,0,s = 120,c = 'm',edgecolor = 'k',linewidth = 0.7, zorder = 2, marker = 'X')

                g_val = self.grad(w_val)
                ax2.scatter(w_val,g_val,s = 120,c = 'm',edgecolor = 'k',linewidth = 0.7,zorder = 2)            # plot point of tangency
                ax2.scatter(w_val,0,s = 120,c = 'm',edgecolor = 'k',linewidth = 0.7, zorder = 2, marker = 'X')
            
            # draw functions first, then start animating process
            if k > 0:
                #### cost function (minimizing) view ####
                w_val = self.w_hist[k-1]

                # plug in value into func and derivative
                g_val = self.g(w_val)
                g_grad_val = self.grad(w_val)
                g_hess_val = self.hess(w_val)

                # determine width of plotting area for second order approximator
                width = 5
                if g_hess_val < 0:
                    width = - width

                # setup quadratic formula params
                a = 0.5*g_hess_val
                b = g_grad_val - 2*0.5*g_hess_val*w_val
                c = 0.5*g_hess_val*w_val**2 - g_grad_val*w_val - width

                # solve for zero points
                w1 = (-b + math.sqrt(b**2 - 4*a*c))/float(2*a + 0.00001)
                w2 = (-b - math.sqrt(b**2 - 4*a*c))/float(2*a + 0.00001)

                # compute second order approximation
                wrange = np.linspace(w1,w2, 100)
                h = g_val + g_grad_val*(wrange - w_val) + 0.5*g_hess_val*(wrange - w_val)**2 

                # create next point information
                w_zero = w_val - g_grad_val/(g_hess_val + 10**-5)
                g_zero = self.g(w_zero)
                h_zero = g_val + g_grad_val*(w_zero - w_val) + 0.5*g_hess_val*(w_zero - w_val)**2

                # draw dashed linen connecting the three
                vals = [0,h_zero,g_zero]
                vals = np.sort(vals)
                s = np.linspace(vals[0],vals[2])
                o = np.ones((len(s)))

                # plot all
                ax1.plot(wrange,h,color = 'b',linewidth = 2,zorder = 1)      # plot approx

                # plot tangent point
                ax1.scatter(w_val, g_val, s = 120, c='m',edgecolor = 'k',linewidth = 0.7,zorder = 3)

                # created dashed linen connecting the three            
                ax1.plot(o*w_zero,s,'k--',linewidth=1)

                # draw intersection at zero and associated point on cost function you hop back too
                ax1.scatter(w_zero,h_zero,s = 120,c = 'k', zorder = 2)
                ax1.scatter(w_zero,g_zero,s = 120,c = self.colorspec[k-1],edgecolor = 'k',linewidth = 0.7,zorder = 3)            # plot point of tangency
                ax1.scatter(w_zero,0,s = 120,facecolor = self.colorspec[k-1],marker = 'X',edgecolor = 'k',linewidth = 0.7, zorder = 2)

                #### derivative (zero-crossing) view ####
                # grab historical weight, compute function and derivative evaluations
                g_val = float(self.grad(w_val))
                grad_val = float(self.hess(w_val))
                h = g_val + grad_val*(wrange - w_val)

                # draw points
                w_zero = -g_val/grad_val + w_val
                g_zero = self.grad(w_zero)
                s = np.linspace(0,g_zero)
                o = np.ones((len(s)))

                # plot tangent line
                ax2.plot(wrange,h,color = 'b',linewidth = 2,zorder = 1)      # plot approx

                # plot tangent point
                ax2.scatter(w_val, g_val, s = 120, c='m',edgecolor = 'k',linewidth = 0.7,zorder = 3)

                # draw dashed lines to highlight zero crossing point
                ax2.plot(o*w_zero,s,'k--',linewidth=1)

                # draw intersection at zero and associated point on cost function you hop back too
                ax2.scatter(w_zero,g_zero,s = 120,c = self.colorspec[k-1],edgecolor = 'k',linewidth = 0.7,zorder = 3)            # plot point of tangency
                ax2.scatter(w_zero,0,s = 120,facecolor = self.colorspec[k-1],marker = 'X',edgecolor = 'k',linewidth = 0.7, zorder = 2)
             
            # fix viewing limits
            ax1.set_xlim([-3,3])
            ax1.set_ylim([min(g_plot) - ggap,max(g_plot) + ggap])
                
            # fix viewing limits
            ax2.set_xlim([-3,3])
            ax2.set_ylim([min(g_plot) - ggap,max(g_plot) + ggap])

            # set titles
            ax1.set_title('cost function (minimizing) view',fontsize = 15)
            ax2.set_title('gradient (zero-crossing) view',fontsize = 15)
   
            # draw axes
            ax1.axhline(y=0, color='k',zorder = 0,linewidth = 0.5)
            ax2.axhline(y=0, color='k',zorder = 0,linewidth = 0.5)

            return artist,

        anim = animation.FuncAnimation(fig, animate,frames=len(self.w_hist)+1, interval=len(self.w_hist)+1, blit=True)

        return(anim)
Ejemplo n.º 19
0
 def fun(x):
     return to_scalar(np.flipud(x))
Ejemplo n.º 20
0
    def draw_it_secant(self, **args):
        if 'w_init' in args:
            self.w_init = float(args['w_init'])

        # initialize figure
        fig = plt.figure(figsize=(6, 6))
        artist = fig
        ax = fig.add_subplot(111)

        # generate function for plotting on each slide
        w_plot = np.linspace(-3.1, 3.1, 200)
        g_plot = self.g(w_plot)
        g_range = max(g_plot) - min(g_plot)
        ggap = g_range * 0.1
        width = 30

        # run newtons method
        self.w_hist = []
        self.run_secant()

        # colors for points
        s = np.linspace(0, 1, len(self.w_hist[:round(len(self.w_hist) / 2)]))
        s.shape = (len(s), 1)
        t = np.ones(len(self.w_hist[round(len(self.w_hist) / 2):]))
        t.shape = (len(t), 1)
        s = np.vstack((s, t))
        self.colorspec = []
        self.colorspec = np.concatenate((s, np.flipud(s)), 1)
        self.colorspec = np.concatenate((self.colorspec, np.zeros(
            (len(s), 1))), 1)

        # animation sub-function
        print('beginning animation rendering...')

        def animate(t):
            ax.cla()
            k = math.floor((t + 1) / float(2))

            # print rendering update
            if k == 2 * len(self.w_hist) - 1:
                print('animation rendering complete!')
                time.sleep(1.5)
                clear_output()

            # plot function
            ax.plot(w_plot, g_plot, color='k', zorder=2)  # plot function

            # plot initial point and evaluation
            if k == 0:
                w_val = self.w_init
                g_val = self.g(w_val)
                ax.scatter(w_val,
                           g_val,
                           s=100,
                           c='m',
                           edgecolor='k',
                           linewidth=0.7,
                           zorder=2)  # plot point of tangency
                ax.scatter(w_val,
                           0,
                           s=100,
                           c='m',
                           edgecolor='k',
                           linewidth=0.7,
                           zorder=2,
                           marker='X')

            # plot all input/output pairs generated by algorithm thus far
            if k > 0:
                # plot all points up to this point
                for j in range(min(k - 1, len(self.w_hist))):
                    w_val = self.w_hist[j]
                    g_val = self.g(w_val)

                    ax.scatter(w_val,
                               g_val,
                               s=90,
                               c=self.colorspec[j],
                               edgecolor='k',
                               linewidth=0.7,
                               zorder=3)  # plot point of tangency
                    ax.scatter(w_val,
                               0,
                               s=90,
                               facecolor=self.colorspec[j],
                               marker='X',
                               edgecolor='k',
                               linewidth=0.7,
                               zorder=2)

            # plot surrogate function and travel-to point
            if k > 0 and k < len(self.w_hist):

                # grab historical weights, form associated secant line
                w2 = self.w_hist[k - 1]
                w1 = self.w_hist[k]
                g2 = self.g(w2)
                g1 = self.g(w1)
                m = (g1 - g2) / (w1 - w2)

                # determine width to plot the approximation -- so its length == width defined above
                div = float(1 + m**2)
                wa = w1 - math.sqrt(width / div)
                wb = w1 + math.sqrt(width / div)

                # use point-slope form of line to plot
                wrange = np.linspace(wa, wb, 100)
                h = g1 + m * (wrange - w1)

                # plot secant line
                ax.plot(wrange, h, color='b', linewidth=2,
                        zorder=1)  # plot approx

                # plot intersection points
                ax.scatter(w2,
                           g2,
                           s=100,
                           c='m',
                           edgecolor='k',
                           linewidth=0.7,
                           zorder=3)
                ax.scatter(w1,
                           g1,
                           s=100,
                           c='m',
                           edgecolor='k',
                           linewidth=0.7,
                           zorder=3)

                # plot next point learned from surrogate
                if np.mod(t, 2) == 0:

                    # draw dashed lines to highlight zero crossing point
                    w_zero = -g1 / m + w1
                    g_zero = self.g(w_zero)
                    s = np.linspace(0, g_zero)
                    o = np.ones((len(s)))
                    ax.plot(o * w_zero, s, 'k--', linewidth=1, zorder=1)

                    # draw zero intersection, and associated point on cost function you hop back too
                    ax.scatter(w_zero,
                               g_zero,
                               s=100,
                               c='m',
                               edgecolor='k',
                               linewidth=0.7,
                               zorder=3)  # plot point of tangency
                    ax.scatter(w_zero,
                               0,
                               s=100,
                               c='m',
                               edgecolor='k',
                               linewidth=0.7,
                               zorder=3,
                               marker='X')

            # fix viewing limits
            ax.set_xlim([-3.1, 3.1])
            ax.set_ylim([min(g_plot) - ggap, max(g_plot) + ggap])

            # draw axes
            # ax.grid(True, which='both')
            ax.axhline(y=0, color='k', zorder=0, linewidth=0.5)
            # ax.axvline(x=0, color='k',linewidth = 0.5)

            return artist,

        anim = animation.FuncAnimation(fig,
                                       animate,
                                       frames=2 * len(self.w_hist),
                                       interval=2 * len(self.w_hist),
                                       blit=True)

        return (anim)
Ejemplo n.º 21
0
    def run(self, g, w_init, max_its, **kwargs):
        ### input arguments ###
        self.g = g
        self.max_its = max_its
        self.grad = compute_grad(self.g)  # gradient of input function

        pts = 'off'
        if 'pts' in kwargs:
            pts = 'off'

        linewidth = 2.5
        if 'linewidth' in kwargs:
            linewidth = kwargs['linewidth']

        view = [20, -50]
        if 'view' in kwargs:
            view = kwargs['view']

        axes = False
        if 'axes' in kwargs:
            axes = kwargs['axes']

        plot_final = False
        if 'plot_final' in kwargs:
            plot_final = kwargs['plot_final']

        num_contours = 15
        if 'num_contours' in kwargs:
            num_contours = kwargs['num_contours']

        # version of gradient descent to use (normalized or unnormalized)
        self.version = 'unnormalized'
        if 'version' in kwargs:
            self.version = kwargs['version']

        # get initial point
        self.w_init = np.asarray([float(s) for s in w_init])

        # take in user defined maximum number of iterations
        self.max_its = max_its

        # construct figure
        fig, axs = plt.subplots(1, 2, figsize=(9, 4))

        # create subplot with 3 panels, plot input function in center plot
        gs = gridspec.GridSpec(1, 2, width_ratios=[2, 1])
        ax = plt.subplot(gs[0], aspect='equal')
        ax2 = plt.subplot(gs[1])  #  ,sharey = ax);

        #### run local random search algorithm ####
        self.w_hist = []
        self.steplength = 'exact'
        self.run_coordinate_descent()

        # set viewing limits on contour plot
        xvals = [self.w_hist[s][0] for s in range(len(self.w_hist))]
        xvals.append(self.w_init[0])
        yvals = [self.w_hist[s][1] for s in range(len(self.w_hist))]
        yvals.append(self.w_init[1])
        xmax = max(xvals)
        xmin = min(xvals)
        xgap = (xmax - xmin) * 0.1
        ymax = max(yvals)
        ymin = min(yvals)
        ygap = (ymax - ymin) * 0.1
        xmin -= xgap
        xmax += xgap
        ymin -= ygap
        ymax += ygap

        if 'xmin' in kwargs:
            xmin = kwargs['xmin']
        if 'xmax' in kwargs:
            xmax = kwargs['xmax']
        if 'ymin' in kwargs:
            ymin = kwargs['ymin']
        if 'ymax' in kwargs:
            ymax = kwargs['ymax']

        #### define input space for function and evaluate ####
        w1 = np.linspace(xmin, xmax, 400)
        w2 = np.linspace(ymin, ymax, 400)
        w1_vals, w2_vals = np.meshgrid(w1, w2)
        w1_vals.shape = (len(w1)**2, 1)
        w2_vals.shape = (len(w2)**2, 1)
        h = np.concatenate((w1_vals, w2_vals), axis=1)
        func_vals = np.asarray([g(s) for s in h])
        w1_vals.shape = (len(w1), len(w1))
        w2_vals.shape = (len(w2), len(w2))
        func_vals.shape = (len(w1), len(w2))

        ### make contour right plot - as well as horizontal and vertical axes ###
        # set level ridges
        num_contours = kwargs['num_contours']
        levelmin = min(func_vals.flatten())
        levelmax = max(func_vals.flatten())
        cutoff = 0.5
        cutoff = (levelmax - levelmin) * cutoff
        numper = 3
        levels1 = np.linspace(cutoff, levelmax, numper)
        num_contours -= numper

        levels2 = np.linspace(levelmin, cutoff, min(num_contours, numper))
        levels = np.unique(np.append(levels1, levels2))
        num_contours -= numper
        while num_contours > 0:
            cutoff = levels[1]
            levels2 = np.linspace(levelmin, cutoff, min(num_contours, numper))
            levels = np.unique(np.append(levels2, levels))
            num_contours -= numper

        a = ax.contour(w1_vals, w2_vals, func_vals, levels=levels, colors='k')
        ax.contourf(w1_vals, w2_vals, func_vals, levels=levels, cmap='Blues')

        # label contour lines?
        #ax.clabel(a, inline=1, fontsize=10)

        if axes == True:
            ax.axhline(linestyle='--', color='k', linewidth=1)
            ax.axvline(linestyle='--', color='k', linewidth=1)

        # colors for points
        s = np.linspace(0, 1, len(self.w_hist[:round(len(self.w_hist) / 2)]))
        s.shape = (len(s), 1)
        t = np.ones(len(self.w_hist[round(len(self.w_hist) / 2):]))
        t.shape = (len(t), 1)
        s = np.vstack((s, t))
        colorspec = []
        colorspec = np.concatenate((s, np.flipud(s)), 1)
        colorspec = np.concatenate((colorspec, np.zeros((len(s), 1))), 1)

        ### plot function decrease plot in right panel
        for j in range(len(self.w_hist)):
            w_val = self.w_hist[j]
            g_val = self.g(w_val)

            # plot in left panel
            if pts == 'True':
                ax.scatter(w_val[0],
                           w_val[1],
                           s=30,
                           c=colorspec[j],
                           edgecolor='k',
                           linewidth=1.5 * math.sqrt((1 / (float(j) + 1))),
                           zorder=3)

                ax2.scatter(j,
                            g_val,
                            s=30,
                            c=colorspec[j],
                            edgecolor='k',
                            linewidth=0.7,
                            zorder=3)  # plot point of tangency

            # plot connector between points for visualization purposes
            if j > 0:
                w_old = self.w_hist[j - 1]
                w_new = self.w_hist[j]
                g_old = self.g(w_old)
                g_new = self.g(w_new)

                ax.plot([w_old[0], w_new[0]], [w_old[1], w_new[1]],
                        color=colorspec[j],
                        linewidth=linewidth,
                        alpha=1,
                        zorder=2)  # plot approx
                ax.plot([w_old[0], w_new[0]], [w_old[1], w_new[1]],
                        color='k',
                        linewidth=linewidth + 0.4,
                        alpha=1,
                        zorder=1)  # plot approx
                ax2.plot([j - 1, j], [g_old, g_new],
                         color=colorspec[j],
                         linewidth=2,
                         alpha=1,
                         zorder=2)  # plot approx
                ax2.plot([j - 1, j], [g_old, g_new],
                         color='k',
                         linewidth=2.5,
                         alpha=1,
                         zorder=1)  # plot approx

        # clean panels
        title = self.steplength
        if type(self.steplength) == float:
            title = r'$\alpha = $' + str(self.steplength)
        #ax.set_title(title,fontsize = 12)
        ax.set_xlabel('$w_1$', fontsize=12)
        ax.set_ylabel('$w_2$', fontsize=12, rotation=0)
        ax.axhline(y=0, color='k', zorder=0, linewidth=0.5)
        ax.axvline(x=0, color='k', zorder=0, linewidth=0.5)
        ax2.axhline(y=0, color='k', zorder=0, linewidth=0.5)
        ax2.set_xlabel('iteration', fontsize=12)
        ax2.set_ylabel(r'$g(w)$', fontsize=12, rotation=0, labelpad=25)

        ax.set_xlim([xmin, xmax])
        ax.set_ylim([ymin, ymax])

        ax.set(aspect='equal')
        a = ax.get_position()
        yr = ax.get_position().y1 - ax.get_position().y0
        xr = ax.get_position().x1 - ax.get_position().x0
        aspectratio = 1.25 * xr / yr  # + min(xr,yr)
        ratio_default = (ax2.get_xlim()[1] - ax2.get_xlim()[0]) / (
            ax2.get_ylim()[1] - ax2.get_ylim()[0])
        ax2.set_aspect(ratio_default * aspectratio)

        # plot
        plt.show()
Ejemplo n.º 22
0
    def draw_it_newton(self, **args):
        if 'w_init' in args:
            self.w_init = float(args['w_init'])

        # initialize figure
        fig = plt.figure(figsize=(4, 4))
        artist = fig
        ax = fig.add_subplot(111)

        # run newtons method and collect path history
        self.w_hist = []
        self.run_newtons()

        # set viewing range
        wmax = max([v for v in self.w_hist])
        wmin = min([v for v in self.w_hist])
        wgap = (wmax - wmin) * 0.5
        wmax += wgap
        wmin -= wgap

        w_plot = np.linspace(wmin, wmax, 200)
        g_plot = self.g(w_plot)
        width = 30

        # set range for function plotting
        w_plot1 = np.linspace(-3, 3)
        g_plot1 = self.g(w_plot1)
        gmin = min(copy.deepcopy(g_plot1))
        gmax = max(copy.deepcopy(g_plot1))
        ggap = (gmax - gmin) * 0.2
        gmin -= ggap
        gmax += ggap

        # colors for points
        s = np.linspace(0, 1, len(self.w_hist[:round(len(self.w_hist) / 2)]))
        s.shape = (len(s), 1)
        t = np.ones(len(self.w_hist[round(len(self.w_hist) / 2):]))
        t.shape = (len(t), 1)
        s = np.vstack((s, t))
        self.colorspec = []
        self.colorspec = np.concatenate((s, np.flipud(s)), 1)
        self.colorspec = np.concatenate((self.colorspec, np.zeros(
            (len(s), 1))), 1)

        # animation sub-function
        print('beginning animation rendering...')

        def animate(k):
            ax.cla()

            # print rendering update
            if k == len(self.w_hist):
                print('animation rendering complete!')
                time.sleep(1.5)
                clear_output()

            # plot function
            ax.plot(w_plot1, g_plot1, color='k', zorder=1)  # plot function

            # plot all input/output pairs generated by algorithm thus far
            if k > 0:
                # plot all points up to this point
                for j in range(0, min(k + 1, len(self.w_hist))):
                    w_val = self.w_hist[j]
                    g_val = self.g(w_val)

                    if j == k - 1:
                        # draw guide line to visua
                        s = np.linspace(0, g_val)
                        o = np.ones((len(s)))
                        ax.plot(o * w_val, s, 'k--', linewidth=1, zorder=1)

                        ax.scatter(w_val,
                                   g_val,
                                   s=90,
                                   c=self.colorspec[j],
                                   edgecolor='k',
                                   linewidth=1,
                                   zorder=3)  # plot point of tangency
                        ax.scatter(w_val,
                                   0,
                                   s=90,
                                   facecolor=self.colorspec[j],
                                   marker='X',
                                   edgecolor='k',
                                   linewidth=1,
                                   zorder=2)

                    if j == k:
                        # draw guide line to visua
                        s = np.linspace(0, g_val)
                        o = np.ones((len(s)))
                        ax.plot(o * w_val, s, 'k--', linewidth=1, zorder=1)

                        ax.scatter(w_val,
                                   g_val,
                                   s=90,
                                   c='w',
                                   edgecolor='k',
                                   linewidth=1,
                                   zorder=3)  # plot point of tangency
                        ax.scatter(w_val,
                                   0,
                                   s=90,
                                   facecolor='w',
                                   marker='X',
                                   edgecolor='k',
                                   linewidth=1,
                                   zorder=2)

            # plot surrogate function and travel-to point
            if k > 0 and k < len(self.w_hist) + 1:
                # grab historical weight, compute function and derivative evaluations
                w = self.w_hist[k - 1]
                g_eval = self.g(w)
                grad_eval = float(self.grad(w))

                # determine width to plot the approximation -- so its length == width defined above
                div = float(1 + grad_eval**2)
                w1 = w - math.sqrt(width / div)
                w2 = w + math.sqrt(width / div)

                # use point-slope form of line to plot
                wrange = np.linspace(w1, w2, 100)
                h = g_eval + grad_eval * (wrange - w)

                # plot tangent line
                ax.plot(wrange,
                        h,
                        color=self.colorspec[k - 1],
                        linewidth=2,
                        zorder=1)  # plot approx

                # plot tangent point
                #ax.scatter(w,g_eval,s = 100,c = 'm',edgecolor = 'k',linewidth = 0.7,zorder = 2)            # plot point of tangency

                # plot go-too line on surrogate
                w_zero = -g_eval / grad_eval + w
                #ax.scatter(w_zero,0,s = 100,c = 'm',edgecolor = 'k',linewidth = 0.7, zorder = 2, marker = 'X')
                '''
                # plot next point learned from surrogate
                if k > 0:
                    # draw dashed lines to highlight zero crossing point
                    g_zero = self.g(w_zero)

                    s = np.linspace(0,g_zero)
                    o = np.ones((len(s)))
                    ax.plot(o*w_zero,s,'k--',linewidth=1,zorder = 1)

                    
                    # draw associated point on cost function you hop back too
                    #ax.scatter(w_zero,g_zero,s = 100,c = 'm',edgecolor = 'k',linewidth = 0.7,zorder = 2)            # plot point of tangency
               '''
            # fix viewing limits
            ax.set_xlim([wmin, wmax])
            ax.set_ylim([gmin, gmax])

            # draw axes
            # ax.grid(True, which='both')
            ax.axhline(y=0, color='k', zorder=0, linewidth=0.5)
            # ax.axvline(x=0, color='k')

            # place title
            ax.set_title("Newton's method (zero finding)", fontsize=12)

            return artist,

        anim = animation.FuncAnimation(fig,
                                       animate,
                                       frames=len(self.w_hist) + 1,
                                       interval=len(self.w_hist) + 1,
                                       blit=True)

        return (anim)
Ejemplo n.º 23
0
anp.roll.defjvp(
    lambda g, ans, gvs, vs, x, shift, axis=None: anp.roll(g, shift, axis=axis))
anp.array_split.defjvp(lambda g, ans, gvs, vs, ary, idxs, axis=0: anp.
                       array_split(g, idxs, axis=axis))
anp.split.defjvp(
    lambda g, ans, gvs, vs, ary, idxs, axis=0: anp.split(g, idxs, axis=axis))
anp.vsplit.defjvp(lambda g, ans, gvs, vs, ary, idxs: anp.vsplit(g, idxs))
anp.hsplit.defjvp(lambda g, ans, gvs, vs, ary, idxs: anp.hsplit(g, idxs))
anp.dsplit.defjvp(lambda g, ans, gvs, vs, ary, idxs: anp.dsplit(g, idxs))
anp.ravel.defjvp(
    lambda g, ans, gvs, vs, x, order=None: anp.ravel(g, order=order))
anp.expand_dims.defjvp(
    lambda g, ans, gvs, vs, x, axis: anp.expand_dims(g, axis))
anp.squeeze.defjvp(lambda g, ans, gvs, vs, x, axis=None: anp.squeeze(g, axis))
anp.diag.defjvp(lambda g, ans, gvs, vs, x, k=0: anp.diag(g, k))
anp.flipud.defjvp(lambda g, ans, gvs, vs, x, : anp.flipud(g))
anp.fliplr.defjvp(lambda g, ans, gvs, vs, x, : anp.fliplr(g))
anp.rot90.defjvp(lambda g, ans, gvs, vs, x, k=1: anp.rot90(g, k))
anp.trace.defjvp(lambda g, ans, gvs, vs, x, offset=0: anp.trace(g, offset))
anp.full.defjvp(lambda g, ans, gvs, vs, shape, fill_value, dtype=None: anp.
                full(shape, g, dtype),
                argnum=1)
anp.triu.defjvp(lambda g, ans, gvs, vs, x, k=0: anp.triu(g, k=k))
anp.tril.defjvp(lambda g, ans, gvs, vs, x, k=0: anp.tril(g, k=k))
anp.clip.defjvp(lambda g, ans, gvs, vs, x, a_min, a_max: g * anp.logical_and(
    ans != a_min, ans != a_max))
anp.swapaxes.defjvp(
    lambda g, ans, gvs, vs, x, axis1, axis2: anp.swapaxes(g, axis1, axis2))
anp.rollaxis.defjvp(
    lambda g, ans, gvs, vs, a, axis, start=0: anp.rollaxis(g, axis, start))
anp.real_if_close.defjvp(lambda g, ans, gvs, vs, x: npg.match_complex(vs, g))
Ejemplo n.º 24
0
def visualize3d(func, **kwargs):
    ### input arguments ###
    wmax = 1
    if 'wmax' in kwargs:
        wmax = kwargs['wmax'] + 0.5

    view = [20, -50]
    if 'view' in kwargs:
        view = kwargs['view']

    axes = False
    if 'axes' in kwargs:
        axes = kwargs['axes']

    plot_final = False
    if 'plot_final' in kwargs:
        plot_final = kwargs['plot_final']

    num_contours = 10
    if 'num_contours' in kwargs:
        num_contours = kwargs['num_contours']

    pt = [0, 0]
    if 'pt' in kwargs:
        pt = kwargs['pt']
    pt = np.asarray(pt)
    pt.shape = (2, 1)

    max_steps = 10
    if 'max_steps' in kwargs:
        max_steps = kwargs['max_steps']
    num_samples = 10
    if 'num_samples' in kwargs:
        num_samples = kwargs['num_samples']
    steplength = 1
    if 'steplength' in kwargs:
        steplength = kwargs['steplength']

    ##### construct figure with panels #####
    # construct figure
    fig = plt.figure(figsize=(9, 3))

    # remove whitespace from figure
    fig.subplots_adjust(left=0, right=1, bottom=0, top=1)  # remove whitespace

    # create subplot with 3 panels, plot input function in center plot
    gs = gridspec.GridSpec(1, 2, width_ratios=[1, 2])
    ax = plt.subplot(gs[0], projection='3d')
    ax2 = plt.subplot(gs[1], aspect='equal')

    #### define input space for function and evaluate ####
    w = np.linspace(-wmax, wmax, 200)
    w1_vals, w2_vals = np.meshgrid(w, w)
    w1_vals.shape = (len(w)**2, 1)
    w2_vals.shape = (len(w)**2, 1)
    h = np.concatenate((w1_vals, w2_vals), axis=1)
    func_vals = np.asarray([func(s) for s in h])
    w1_vals.shape = (len(w), len(w))
    w2_vals.shape = (len(w), len(w))
    func_vals.shape = (len(w), len(w))

    # plot function
    ax.plot_surface(w1_vals,
                    w2_vals,
                    func_vals,
                    alpha=0.1,
                    color='w',
                    rstride=25,
                    cstride=25,
                    linewidth=1,
                    edgecolor='k',
                    zorder=2)

    # plot z=0 plane
    ax.plot_surface(w1_vals,
                    w2_vals,
                    func_vals * 0,
                    alpha=0.1,
                    color='w',
                    zorder=1,
                    rstride=25,
                    cstride=25,
                    linewidth=0.3,
                    edgecolor='k')

    ### make contour right plot - as well as horizontal and vertical axes ###
    ax2.contour(w1_vals, w2_vals, func_vals, num_contours, colors='k')
    if axes == True:
        ax2.axhline(linestyle='--', color='k', linewidth=1)
        ax2.axvline(linestyle='--', color='k', linewidth=1)

    #### run local random search algorithm ####
    pt_history, eval_history = random_local_search(func, pt, max_steps,
                                                   num_samples, steplength)

    ### plot circle on which point lies, as well as step length circle - used only for simple quadratic
    if plot_final == True:
        # plot contour of quadratic on which final point was plotted
        f = pt_history[-1]
        val = np.linalg.norm(f)
        theta = np.linspace(0, 1, 400)
        x = val * np.cos(2 * np.pi * theta)
        y = val * np.sin(2 * np.pi * theta)
        ax2.plot(x, y, color='r', linestyle='--', linewidth=1)

        # plot direction sampling circle centered at final point
        x = steplength * np.cos(2 * np.pi * theta) + f[0]
        y = steplength * np.sin(2 * np.pi * theta) + f[1]
        ax2.plot(x, y, color='b', linewidth=1)

    # colors for points
    s = np.linspace(0, 1, len(eval_history[:round(len(eval_history) / 2)]))
    s.shape = (len(s), 1)
    t = np.ones(len(eval_history[round(len(eval_history) / 2):]))
    t.shape = (len(t), 1)
    s = np.vstack((s, t))
    colorspec = []
    colorspec = np.concatenate((s, np.flipud(s)), 1)
    colorspec = np.concatenate((colorspec, np.zeros((len(s), 1))), 1)

    #### scatter path points ####
    for k in range(len(eval_history)):
        ax.scatter(pt_history[k, 0],
                   pt_history[k, 1],
                   0,
                   s=60,
                   c=colorspec[k],
                   edgecolor='k',
                   linewidth=0.5 * math.sqrt((1 / (float(k) + 1))),
                   zorder=3)

        ax2.scatter(pt_history[k, 0],
                    pt_history[k, 1],
                    s=60,
                    c=colorspec[k],
                    edgecolor='k',
                    linewidth=1.5 * math.sqrt((1 / (float(k) + 1))),
                    zorder=3)

    #### connect points with arrows ####
    if len(eval_history) < 10:
        for i in range(len(eval_history) - 1):
            pt1 = pt_history[i]
            pt2 = pt_history[i + 1]

            # draw arrow in left plot
            a = Arrow3D([pt1[0], pt2[0]], [pt1[1], pt2[1]], [0, 0],
                        mutation_scale=10,
                        lw=2,
                        arrowstyle="-|>",
                        color="k")
            ax.add_artist(a)

            # draw 2d arrow in right plot
            ax2.arrow(pt1[0],
                      pt1[1], (pt2[0] - pt1[0]) * 0.78,
                      (pt2[1] - pt1[1]) * 0.78,
                      head_width=0.1,
                      head_length=0.1,
                      fc='k',
                      ec='k',
                      linewidth=3,
                      zorder=2,
                      length_includes_head=True)

    ### cleanup panels ###
    ax.set_xlabel('$w_1$', fontsize=12)
    ax.set_ylabel('$w_2$', fontsize=12, rotation=0)
    ax.set_title('$g(w_1,w_2)$', fontsize=12)
    ax.view_init(view[0], view[1])

    ax2.set_xlabel('$w_1$', fontsize=12)
    ax2.set_ylabel('$w_2$', fontsize=12, rotation=0)

    # clean up axis
    ax.xaxis.pane.fill = False
    ax.yaxis.pane.fill = False
    ax.zaxis.pane.fill = False

    ax.xaxis.pane.set_edgecolor('white')
    ax.yaxis.pane.set_edgecolor('white')
    ax.zaxis.pane.set_edgecolor('white')

    ax.xaxis._axinfo["grid"]['color'] = (1, 1, 1, 0)
    ax.yaxis._axinfo["grid"]['color'] = (1, 1, 1, 0)
    ax.zaxis._axinfo["grid"]['color'] = (1, 1, 1, 0)

    # plot
    plt.show()
        def animate(k):
            ax1.cla()
            ax2.cla()
            
            # print rendering update            
            if np.mod(k+1,25) == 0:
                print ('rendering animation frame ' + str(k+1) + ' of ' + str(num_frames))
            if k == num_frames - 1:
                print ('animation rendering complete!')
                time.sleep(1.5)
                clear_output()
            
            # plot initial point and evaluation
            if k == 0:
                w_val = self.w_init
                g_val = self.g(w_val)
                ax1.scatter(w_val[0],w_val[1],g_val,s = 100,c = 'm',edgecolor = 'k',linewidth = 0.7,zorder = 2)            # plot point of tangency
                
                # plot function 
                r = np.linspace(-3,3,100)

                # create grid from plotting range
                w1_vals,w2_vals = np.meshgrid(r,r)
                w1_vals.shape = (len(r)**2,1)
                w2_vals.shape = (len(r)**2,1)
                g_vals = self.g([w1_vals,w2_vals])

                # vals for cost surface
                w1_vals.shape = (len(r),len(r))
                w2_vals.shape = (len(r),len(r))
                g_vals.shape = (len(r),len(r))

                ax1.plot_surface(w1_vals,w2_vals,g_vals,alpha = 0.1,color = 'k',rstride=15, cstride=15,linewidth=1,edgecolor = 'k')    

            # plot function alone first along with initial point
            if k > 0:
                alpha = self.alpha_range[k-1]
                
                # setup axes
                ax1.set_title(r'$\alpha = $' + r'{:.2f}'.format(alpha),fontsize = 14)
                ax2.set_xlabel('iteration',fontsize = 13)
                ax2.set_ylabel('cost function value',fontsize = 13)          
                
                # run gradient descent method
                self.w_hist = []
                self.run_gradient_descent(alpha = alpha)
                
                # plot function
                self.plot_function(ax1)
        
                # colors for points
                s = np.linspace(0,1,len(self.w_hist[:round(len(self.w_hist)/2)]))
                s.shape = (len(s),1)
                t = np.ones(len(self.w_hist[round(len(self.w_hist)/2):]))
                t.shape = (len(t),1)
                s = np.vstack((s,t))
                self.colorspec = []
                self.colorspec = np.concatenate((s,np.flipud(s)),1)
                self.colorspec = np.concatenate((self.colorspec,np.zeros((len(s),1))),1)
        
                # plot everything for each iteration 
                for j in range(len(self.w_hist)):  
                    w_val = self.w_hist[j]
                    g_val = self.g(w_val)
                    grad_val = self.grad(w_val)
                    ax1.scatter(w_val[0],w_val[1],g_val,s = 90,c = self.colorspec[j],edgecolor = 'k',linewidth = 0.7,zorder = 3)            # plot point of tangency
            
                    ### plot all on cost function decrease plot
                    ax2.scatter(j,g_val,s = 90,c = self.colorspec[j],edgecolor = 'k',linewidth = 0.7,zorder = 3)            # plot point of tangency
                    
                    # clean up second axis
                    ax2.set_xticks(np.arange(len(self.w_hist)))
                    
                    # plot connector between points for visualization purposes
                    if j > 0:
                        w_old = self.w_hist[j-1]
                        w_new = self.w_hist[j]
                        g_old = self.g(w_old)
                        g_new = self.g(w_new)
                        ax2.plot([j-1,j],[g_old,g_new],color = self.colorspec[j],linewidth = 2,alpha = 0.4,zorder = 1)      # plot approx
                        
            # clean up plot
            ax1.view_init(view[0],view[1])
            ax1.set_axis_off()
 
            return artist,
    def animate_run(self,w_hist,**kwargs):     
        self.w_hist = w_hist
        
        ##### setup figure to plot #####
        # initialize figure
        fig = plt.figure(figsize = (8,3))
        artist = fig
        
        # create subplot with 3 panels, plot input function in center plot
        gs = gridspec.GridSpec(1, 2, width_ratios=[1,1]) 
        ax1 = plt.subplot(gs[0]); 
        ax2 = plt.subplot(gs[1]);

        # produce color scheme
        s = np.linspace(0,1,len(self.w_hist[:round(len(w_hist)/2)]))
        s.shape = (len(s),1)
        t = np.ones(len(self.w_hist[round(len(w_hist)/2):]))
        t.shape = (len(t),1)
        s = np.vstack((s,t))
        self.colorspec = []
        self.colorspec = np.concatenate((s,np.flipud(s)),1)
        self.colorspec = np.concatenate((self.colorspec,np.zeros((len(s),1))),1)
        
        # seed left panel plotting range
        xmin = copy.deepcopy(min(self.x))
        xmax = copy.deepcopy(max(self.x))
        xgap = (xmax - xmin)*0.1
        xmin-=xgap
        xmax+=xgap
        x_fit = np.linspace(xmin,xmax,300)
        
        # seed right panel contour plot
        viewmax = 3
        if 'viewmax' in kwargs:
            viewmax = kwargs['viewmax']
        view = [20,100]
        if 'view' in kwargs:
            view = kwargs['view']
        num_contours = 15
        if 'num_contours' in kwargs:
            num_contours = kwargs['num_contours']        
        self.contour_plot(ax2,viewmax,num_contours)
        
        # start animation
        num_frames = len(self.w_hist)
        print ('starting animation rendering...')
        def animate(k):
            # clear panels
            ax1.cla()
            
            # current color
            color = self.colorspec[k]

            # print rendering update
            if np.mod(k+1,25) == 0:
                print ('rendering animation frame ' + str(k+1) + ' of ' + str(num_frames))
            if k == num_frames - 1:
                print ('animation rendering complete!')
                time.sleep(1.5)
                clear_output()
            
            ###### make left panel - plot data and fit ######
            # initialize fit
            w = self.w_hist[k]
            y_fit = self.sigmoid(w[0] + x_fit*w[1])
            
            # scatter data
            self.scatter_pts(ax1)
            
            # plot fit to data
            ax1.plot(x_fit,y_fit,color = color,linewidth = 2) 

            ###### make right panel - plot contour and steps ######
            if k == 0:
                ax2.scatter(w[0],w[1],s = 90,facecolor = color,edgecolor = 'k',linewidth = 0.5, zorder = 3)
            if k > 0 and k < num_frames:
                self.plot_pts_on_contour(ax2,k,color)
            if k == num_frames -1:
                ax2.scatter(w[0],w[1],s = 90,facecolor = color,edgecolor = 'k',linewidth = 0.5, zorder = 3)
               
            return artist,

        anim = animation.FuncAnimation(fig, animate ,frames=num_frames, interval=num_frames, blit=True)
        
        return(anim)
    def static_fig(self,w_hist,**kwargs):
        self.w_hist = w_hist
        ind = -1
        show_path = True
        if np.size(w_hist) == 0:
            show_path = False
        w = 0
        if show_path:
            w = w_hist[ind]
        
        ##### setup figure to plot #####
        # initialize figure
        fig = plt.figure(figsize = (8,3))
        artist = fig
        
        # create subplot with 3 panels, plot input function in center plot
        gs = gridspec.GridSpec(1, 2, width_ratios=[1,1]) 
        ax1 = plt.subplot(gs[0]); 
        ax2 = plt.subplot(gs[1]);

        # produce color scheme
        s = np.linspace(0,1,len(self.w_hist[:round(len(self.w_hist)/2)]))
        s.shape = (len(s),1)
        t = np.ones(len(self.w_hist[round(len(self.w_hist)/2):]))
        t.shape = (len(t),1)
        s = np.vstack((s,t))
        self.colorspec = []
        self.colorspec = np.concatenate((s,np.flipud(s)),1)
        self.colorspec = np.concatenate((self.colorspec,np.zeros((len(s),1))),1)
        
        # seed left panel plotting range
        xmin = copy.deepcopy(min(self.x))
        xmax = copy.deepcopy(max(self.x))
        xgap = (xmax - xmin)*0.1
        xmin-=xgap
        xmax+=xgap
        x_fit = np.linspace(xmin,xmax,300)
        
        # seed right panel contour plot
        viewmax = 3
        if 'viewmax' in kwargs:
            viewmax = kwargs['viewmax']
        view = [20,100]
        if 'view' in kwargs:
            view = kwargs['view']
        num_contours = 15
        if 'num_contours' in kwargs:
            num_contours = kwargs['num_contours']   
            
        ### contour plot in right panel ###
        self.contour_plot(ax2,viewmax,num_contours)
        
        ### make left panel - plot data and fit ###
        # scatter data
        self.scatter_pts(ax1)
        
        if show_path:
            # initialize fit
            y_fit = self.sigmoid(w[0] + x_fit*w[1])

            # plot fit to data
            color = self.colorspec[-1]
            ax1.plot(x_fit,y_fit,color = color,linewidth = 2) 

            # add points to right panel contour plot
            num_frames = len(self.w_hist)
            for k in range(num_frames):
                # current color
                color = self.colorspec[k]

                # current weights
                w = self.w_hist[k]

                ###### make right panel - plot contour and steps ######
                if k == 0:
                    ax2.scatter(w[0],w[1],s = 90,facecolor = color,edgecolor = 'k',linewidth = 0.5, zorder = 3)
                if k > 0 and k < num_frames:
                    self.plot_pts_on_contour(ax2,k,color)
                if k == num_frames -1:
                    ax2.scatter(w[0],w[1],s = 90,facecolor = color,edgecolor = 'k',linewidth = 0.5, zorder = 3)
        
        plt.show()
sigma = 0.15
scl = 0.

veclin = -1. + 2. * np.random.rand(2)
veclin = veclin / np.linalg.norm(veclin)
#veclin = np.array( [ 0., 0. ] )

Q = -1. + 2. * np.random.rand(2)
Q = Q / np.linalg.norm(Q)

lineslope = 2.

######################################################################################

x, y = np.meshgrid(np.linspace(-1., 1., 500), np.linspace(-1., 1., 500))
y = np.flipud(y)
mask = (np.sqrt(x**2 + y**2) < gbrad).astype(float)

# gradients calculated here
dp_x = egrad(radfun, 0)  #( x, y, mu=gbrad, sigma=sigma, veclin=veclin )
dp_y = egrad(radfun, 1)  #( x, y, mu=gbrad, sigma=sigma, veclin=veclin )

linerange = np.linspace(-1., 1., 500)
linecoords = Q.reshape(-1, 1) @ linerange.reshape(1, -1)
linevalues = radfun(linecoords[0, :],
                    linecoords[1, :],
                    mu=gbrad,
                    sigma=sigma,
                    scl=scl,
                    Q=Q,
                    veclin=veclin)
Ejemplo n.º 29
0
    def animate_2d(self, **kwargs):
        self.g = kwargs['g']  # input function
        self.grad = compute_grad(self.g)  # gradient of input function
        self.w_init = float(
            -2
        )  # user-defined initial point (adjustable when calling each algorithm)
        self.alpha = 10**-4  # user-defined step length for gradient descent (adjustable when calling gradient descent)
        self.max_its = 20  # max iterations to run for each algorithm
        self.w_hist = []  # container for algorithm path

        wmin = -3.1
        wmax = 3.1
        if 'wmin' in kwargs:
            wmin = kwargs['wmin']
        if 'wmax' in kwargs:
            wmax = kwargs['wmax']

        # version of gradient descent to use (normalized or unnormalized)
        self.version = 'unnormalized'
        if 'version' in kwargs:
            self.version = kwargs['version']

        # get new initial point if desired
        if 'w_init' in kwargs:
            self.w_init = float(kwargs['w_init'])

        # take in user defined step length
        if 'steplength' in kwargs:
            self.steplength = kwargs['steplength']

        # take in user defined maximum number of iterations
        if 'max_its' in kwargs:
            self.max_its = float(kwargs['max_its'])

        # initialize figure
        fig = plt.figure(figsize=(9, 4))
        artist = fig

        # remove whitespace from figure
        #fig.subplots_adjust(left=0, right=1, bottom=0, top=1) # remove whitespace
        #fig.subplots_adjust(wspace=0.01,hspace=0.01)

        # create subplot with 3 panels, plot input function in center plot
        gs = gridspec.GridSpec(1, 3, width_ratios=[1, 4, 1])

        ax1 = plt.subplot(gs[0])
        ax1.axis('off')
        ax3 = plt.subplot(gs[2])
        ax3.axis('off')
        ax = plt.subplot(gs[1])

        # generate function for plotting on each slide
        w_plot = np.linspace(wmin, wmax, 200)
        g_plot = self.g(w_plot)
        g_range = max(g_plot) - min(g_plot)
        ggap = g_range * 0.1
        width = 30

        # run gradient descent method
        self.w_hist = []
        self.run_gradient_descent()

        # colors for points --> green as the algorithm begins, yellow as it converges, red at final point
        s = np.linspace(0, 1, len(self.w_hist[:round(len(self.w_hist) / 2)]))
        s.shape = (len(s), 1)
        t = np.ones(len(self.w_hist[round(len(self.w_hist) / 2):]))
        t.shape = (len(t), 1)
        s = np.vstack((s, t))
        self.colorspec = []
        self.colorspec = np.concatenate((s, np.flipud(s)), 1)
        self.colorspec = np.concatenate((self.colorspec, np.zeros(
            (len(s), 1))), 1)

        # animation sub-function
        num_frames = 2 * len(self.w_hist) + 2
        print('starting animation rendering...')

        def animate(t):
            ax.cla()
            k = math.floor((t + 1) / float(2))

            # print rendering update
            if np.mod(t + 1, 25) == 0:
                print('rendering animation frame ' + str(t + 1) + ' of ' +
                      str(num_frames))
            if t == num_frames - 1:
                print('animation rendering complete!')
                time.sleep(1.5)
                clear_output()

            # plot function
            ax.plot(w_plot, g_plot, color='k', zorder=2)  # plot function

            # plot initial point and evaluation
            if k == 0:
                w_val = self.w_init
                g_val = self.g(w_val)
                ax.scatter(w_val,
                           g_val,
                           s=90,
                           c=self.colorspec[k],
                           edgecolor='k',
                           linewidth=0.5 * ((1 / (float(k) + 1)))**(0.4),
                           zorder=3,
                           marker='X')  # evaluation on function
                ax.scatter(w_val,
                           0,
                           s=90,
                           facecolor=self.colorspec[k],
                           edgecolor='k',
                           linewidth=0.5 * ((1 / (float(k) + 1)))**(0.4),
                           zorder=3)

                # draw dashed line connecting w axis to point on cost function
                s = np.linspace(0, g_val)
                o = np.ones((len(s)))
                ax.plot(o * w_val, s, 'k--', linewidth=1)

            # plot all input/output pairs generated by algorithm thus far
            if k > 0:
                # plot all points up to this point
                for j in range(min(k - 1, len(self.w_hist))):
                    w_val = self.w_hist[j]
                    g_val = self.g(w_val)
                    ax.scatter(w_val,
                               g_val,
                               s=90,
                               c=self.colorspec[j],
                               edgecolor='k',
                               linewidth=0.5 * ((1 / (float(j) + 1)))**(0.4),
                               zorder=3,
                               marker='X')  # plot point of tangency
                    ax.scatter(w_val,
                               0,
                               s=90,
                               facecolor=self.colorspec[j],
                               edgecolor='k',
                               linewidth=0.5 * ((1 / (float(j) + 1)))**(0.4),
                               zorder=2)

            # plot surrogate function and travel-to point
            if k > 0 and k < len(self.w_hist) + 1:
                # grab historical weight, compute function and derivative evaluations
                w = self.w_hist[k - 1]
                g_eval = self.g(w)
                grad_eval = float(self.grad(w))

                # determine width to plot the approximation -- so its length == width defined above
                div = float(1 + grad_eval**2)
                w1 = w - math.sqrt(width / div)
                w2 = w + math.sqrt(width / div)

                # use point-slope form of line to plot
                wrange = np.linspace(w1, w2, 100)
                h = g_eval + grad_eval * (wrange - w)

                # plot tangent line
                ax.plot(wrange, h, color='lime', linewidth=2,
                        zorder=1)  # plot approx

                # plot tangent point
                ax.scatter(w,
                           g_eval,
                           s=100,
                           c='m',
                           edgecolor='k',
                           linewidth=0.7,
                           zorder=3,
                           marker='X')  # plot point of tangency

                # plot next point learned from surrogate
                if np.mod(t, 2) == 0:
                    # create next point information
                    w_zero = w - self.alpha * grad_eval
                    g_zero = self.g(w_zero)
                    h_zero = g_eval + grad_eval * (w_zero - w)

                    # draw dashed line connecting the three
                    vals = [0, h_zero, g_zero]
                    vals = np.sort(vals)

                    s = np.linspace(vals[0], vals[2])
                    o = np.ones((len(s)))
                    ax.plot(o * w_zero, s, 'k--', linewidth=1)

                    # draw intersection at zero and associated point on cost function you hop back too
                    ax.scatter(w_zero,
                               h_zero,
                               s=100,
                               c='k',
                               zorder=3,
                               marker='X')
                    ax.scatter(w_zero,
                               0,
                               s=100,
                               c='m',
                               edgecolor='k',
                               linewidth=0.7,
                               zorder=3)
                    ax.scatter(w_zero,
                               g_zero,
                               s=100,
                               c='m',
                               edgecolor='k',
                               linewidth=0.7,
                               zorder=3,
                               marker='X')  # plot point of tangency

            # fix viewing limits
            ax.set_xlim([wmin - 0.1, wmax + 0.1])
            ax.set_ylim([min(g_plot) - ggap, max(g_plot) + ggap])
            ax.axhline(y=0, color='k', zorder=0, linewidth=0.5)

            # place title
            ax.set_xlabel(r'$w$', fontsize=14)
            ax.set_ylabel(r'$g(w)$', fontsize=14, rotation=0, labelpad=25)

            return artist,

        anim = animation.FuncAnimation(fig,
                                       animate,
                                       frames=num_frames,
                                       interval=num_frames,
                                       blit=True)

        return (anim)
Ejemplo n.º 30
0
    def compare_versions_3d(self, g, w_init, steplength, max_its, **kwargs):
        ### input arguments ###
        self.g = g
        self.steplength = steplength
        self.max_its = max_its
        self.grad = compute_grad(self.g)  # gradient of input function

        wmax = 1
        if 'wmax' in kwargs:
            wmax = kwargs['wmax'] + 0.5

        view = [20, -50]
        if 'view' in kwargs:
            view = kwargs['view']

        axes = False
        if 'axes' in kwargs:
            axes = kwargs['axes']

        plot_final = False
        if 'plot_final' in kwargs:
            plot_final = kwargs['plot_final']

        num_contours = 10
        if 'num_contours' in kwargs:
            num_contours = kwargs['num_contours']

        # get initial point
        self.w_init = np.asarray([float(s) for s in w_init])

        # take in user defined step length
        self.steplength = steplength

        # take in user defined maximum number of iterations
        self.max_its = max_its

        ##### construct figure with panels #####
        # construct figure
        fig = plt.figure(figsize=(12, 6))

        # create subplot with 3 panels, plot input function in center plot
        gs = gridspec.GridSpec(2, 2, width_ratios=[1, 4])
        ax3 = plt.subplot(gs[0], projection='3d')
        ax4 = plt.subplot(gs[1], aspect='equal')
        ax5 = plt.subplot(gs[2], projection='3d')
        ax6 = plt.subplot(gs[3], aspect='equal')

        # remove whitespace from figure
        fig.subplots_adjust(left=0, right=1, bottom=0,
                            top=1)  # remove whitespace

        #### define input space for function and evaluate ####
        w = np.linspace(-wmax, wmax, 200)
        w1_vals, w2_vals = np.meshgrid(w, w)
        w1_vals.shape = (len(w)**2, 1)
        w2_vals.shape = (len(w)**2, 1)
        h = np.concatenate((w1_vals, w2_vals), axis=1)
        func_vals = np.asarray([g(s) for s in h])
        w1_vals.shape = (len(w), len(w))
        w2_vals.shape = (len(w), len(w))
        func_vals.shape = (len(w), len(w))

        #### run local random search algorithms ####
        for algo in ['normalized', 'unnormalized']:
            # switch normalized / unnormalized
            self.version = algo
            title = ''
            if self.version == 'normalized':
                ax = ax3
                ax2 = ax4
                title = 'normalized gradient descent'
            else:
                ax = ax5
                ax2 = ax6
                title = 'unnormalized gradient descent'

        # plot function
            ax.plot_surface(w1_vals,
                            w2_vals,
                            func_vals,
                            alpha=0.1,
                            color='w',
                            rstride=25,
                            cstride=25,
                            linewidth=1,
                            edgecolor='k',
                            zorder=2)

            # plot z=0 plane
            ax.plot_surface(w1_vals,
                            w2_vals,
                            func_vals * 0,
                            alpha=0.1,
                            color='w',
                            zorder=1,
                            rstride=25,
                            cstride=25,
                            linewidth=0.3,
                            edgecolor='k')

            ### make contour right plot - as well as horizontal and vertical axes ###
            ax2.contour(w1_vals, w2_vals, func_vals, num_contours, colors='k')
            if axes == True:
                ax2.axhline(linestyle='--', color='k', linewidth=1)
                ax2.axvline(linestyle='--', color='k', linewidth=1)

            self.w_hist = []
            self.run_gradient_descent()

            # colors for points
            s = np.linspace(0, 1,
                            len(self.w_hist[:round(len(self.w_hist) / 2)]))
            s.shape = (len(s), 1)
            t = np.ones(len(self.w_hist[round(len(self.w_hist) / 2):]))
            t.shape = (len(t), 1)
            s = np.vstack((s, t))
            colorspec = []
            colorspec = np.concatenate((s, np.flipud(s)), 1)
            colorspec = np.concatenate((colorspec, np.zeros((len(s), 1))), 1)

            #### scatter path points ####
            for k in range(len(self.w_hist)):
                w_now = self.w_hist[k]
                ax.scatter(w_now[0],
                           w_now[1],
                           0,
                           s=60,
                           c=colorspec[k],
                           edgecolor='k',
                           linewidth=0.5 * math.sqrt((1 / (float(k) + 1))),
                           zorder=3)

                ax2.scatter(w_now[0],
                            w_now[1],
                            s=60,
                            c=colorspec[k],
                            edgecolor='k',
                            linewidth=1.5 * math.sqrt((1 / (float(k) + 1))),
                            zorder=3)

            #### connect points with arrows ####
            if len(self.w_hist) < 10:
                for i in range(len(self.w_hist) - 1):
                    pt1 = self.w_hist[i]
                    pt2 = self.w_hist[i + 1]

                    # draw arrow in left plot
                    a = Arrow3D([pt1[0], pt2[0]], [pt1[1], pt2[1]], [0, 0],
                                mutation_scale=10,
                                lw=2,
                                arrowstyle="-|>",
                                color="k")
                    ax.add_artist(a)

                    # draw 2d arrow in right plot
                    ax2.arrow(pt1[0],
                              pt1[1], (pt2[0] - pt1[0]) * 0.78,
                              (pt2[1] - pt1[1]) * 0.78,
                              head_width=0.1,
                              head_length=0.1,
                              fc='k',
                              ec='k',
                              linewidth=3,
                              zorder=2,
                              length_includes_head=True)

            ### cleanup panels ###
            ax.set_xlabel('$w_1$', fontsize=12)
            ax.set_ylabel('$w_2$', fontsize=12, rotation=0)
            ax.set_title(title, fontsize=12)
            ax.view_init(view[0], view[1])

            ax2.set_xlabel('$w_1$', fontsize=12)
            ax2.set_ylabel('$w_2$', fontsize=12, rotation=0)
            ax2.axhline(y=0, color='k', zorder=0, linewidth=0.5)
            ax2.axvline(x=0, color='k', zorder=0, linewidth=0.5)

            # clean up axis
            ax.xaxis.pane.fill = False
            ax.yaxis.pane.fill = False
            ax.zaxis.pane.fill = False

            ax.xaxis.pane.set_edgecolor('white')
            ax.yaxis.pane.set_edgecolor('white')
            ax.zaxis.pane.set_edgecolor('white')

            ax.xaxis._axinfo["grid"]['color'] = (1, 1, 1, 0)
            ax.yaxis._axinfo["grid"]['color'] = (1, 1, 1, 0)
            ax.zaxis._axinfo["grid"]['color'] = (1, 1, 1, 0)

        # plot
        plt.show()
def draw_it(func, **kwargs):
    view = [33, 50]
    if 'view' in kwargs:
        view = kwargs['view']

    # compute gradient, points
    anchor = [0, 0]
    anchor = np.array([float(anchor[0]), float(anchor[1])])
    anchor.shape = (2, 1)
    g_anchor = func(anchor)

    # file tracer
    tracer = np.asarray([0, 10**-5])
    tracer = np.array([float(tracer[0]), float(tracer[1])])
    tracer.shape = (2, 1)
    g_tracer = func(tracer)

    # construct figure
    fig = plt.figure(figsize=(9, 3))
    artist = fig

    # remove whitespace from figure
    fig.subplots_adjust(left=0, right=1, bottom=0, top=1)  # remove whitespace
    fig.subplots_adjust(wspace=0.01, hspace=0.01)

    # create subplot with 3 panels, plot input function in center plot
    gs = gridspec.GridSpec(1, 3, width_ratios=[1, 1, 1])
    ax1 = plt.subplot(gs[0], projection='3d')
    ax2 = plt.subplot(gs[1], projection='3d')
    ax3 = plt.subplot(gs[2], projection='3d')

    ### first panel - partial with respect to w_1 ###
    # scatter anchor point
    ax1.scatter(anchor[0],
                anchor[1],
                g_anchor,
                s=50,
                c='lime',
                edgecolor='k',
                linewidth=1)

    # plot hyperplane connecting the anchor to tracer
    secant(func, anchor, tracer, ax1)

    # plot function
    plot_func(func, view, ax1)

    ### second panel - partial with respect to w_2 ###
    tracer = np.flipud(tracer)

    ax2.scatter(anchor[0],
                anchor[1],
                g_anchor,
                s=50,
                c='lime',
                edgecolor='k',
                linewidth=1)

    # plot hyperplane connecting the anchor to tracer
    secant(func, anchor, tracer, ax2)

    # plot function
    plot_func(func, view, ax2)

    ### third panel - plot full tangent hyperplane at anchor ###
    ax3.scatter(anchor[0],
                anchor[1],
                g_anchor,
                s=50,
                c='lime',
                edgecolor='k',
                linewidth=1)

    # plot hyperplane connecting the anchor to tracer
    tangent(func, anchor, ax3)

    # plot function
    plot_func(func, view, ax3)