예제 #1
0
def plot_distorted():
    figure, all_axes = plt.subplots(2, 3, sharex=True, sharey=True)
    all_axes = all_axes.flatten()
    for index in range(6):
        ax = all_axes[index]
        t = index / 5.0
        xt, yt = point_on_characteristic(NODES_X, NODES_Y, t)
        ax.triplot(xt, yt, TRIANGLES, color=plot_utils.BLUE)

        title = get_title(t)
        ax.set_title(title, fontsize=FONT_SIZE)
        # Set the axis.
        ax.axis("scaled")
        ax.set_xlim(-1.35, 3.6)
        ax.set_ylim(-1.35, 2.35)

    for ax in all_axes:
        ax.tick_params(labelsize=LABEL_SIZE, which="both")

    all_axes[0].set_yticks([-1.0, 0.5, 2.0])
    all_axes[0].set_xticks([-1.0, 1.0, 3.0])
    all_axes[0].set_xticklabels(["$-1.0$", "$1.0$", "$3.0$"])

    figure.set_size_inches(8.74, 4.8)
    figure.subplots_adjust(left=0.06,
                           bottom=0.06,
                           right=0.99,
                           top=0.93,
                           wspace=0.0,
                           hspace=0.2)
    filename = "mesh_distortion.pdf"
    path = plot_utils.get_path("slides", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #2
0
def plot_distorted():
    figure, all_axes = plt.subplots(1, 5, sharex=True, sharey=True)
    all_axes = all_axes.flatten()
    for index in range(5):
        ax = all_axes[index]
        t = index / 4.0
        xt, yt = point_on_characteristic(NODES_X, NODES_Y, t)
        ax.triplot(xt, yt, TRIANGLES, color=plot_utils.BLUE, linewidth=0.9)

        title = get_title(t)
        ax.set_title(title, fontsize=plot_utils.TEXT_SIZE)
        # Set the axis.
        ax.axis("scaled")
        ax.set_xlim(-1.35, 3.6)
        ax.set_ylim(-1.35, 2.35)

    all_axes[0].yaxis.set_tick_params(labelsize=plot_utils.TICK_SIZE)
    for ax in all_axes:
        ax.xaxis.set_tick_params(labelsize=plot_utils.TICK_SIZE)

    all_axes[0].set_yticks([-1.0, 0.5, 2.0])
    all_axes[0].set_xticks([-1.0, 1.0, 3.0])
    all_axes[0].set_xticklabels(["$-1.0$", "$1.0$", "$3.0$"])
    figure.set_size_inches(6.4, 1.45)
    figure.subplots_adjust(left=0.07,
                           bottom=0.02,
                           right=0.99,
                           top=0.98,
                           wspace=0.07,
                           hspace=0.2)
    filename = "mesh_distortion.pdf"
    path = plot_utils.get_path("solution-transfer", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #3
0
def image1():
    figure = plt.figure()
    ax = figure.gca()

    curve1 = bezier.Curve(COEFFS1, degree=2, _copy=False)
    curve2 = bezier.Curve(COEFFS2, degree=2, _copy=False)

    curve1.plot(256, ax=ax, color=plot_utils.BLUE)
    ax.lines[-1].set_label("$b_0(s)$")
    curve2.plot(256, ax=ax, color=plot_utils.GREEN)
    ax.lines[-1].set_label("$b_1(t)$")
    ax.plot(
        [0.0],
        [1.0],
        marker="o",
        markersize=4.0,
        color="black",
        linestyle="none",
    )

    ax.legend(fontsize=plot_utils.TEXT_SIZE)
    ax.tick_params(labelsize=plot_utils.TICK_SIZE)
    ax.axis("scaled")

    figure.set_size_inches(5.4, 1.6)
    figure.subplots_adjust(
        left=0.05, bottom=0.09, right=0.99, top=0.99, wspace=0.2, hspace=0.2
    )
    filename = "tangent_intersection.pdf"
    path = plot_utils.get_path("slides", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #4
0
def main(filename=None):
    s_vals = np.linspace(ROOT - DELTA_S, ROOT + DELTA_S, NUM_POINTS)

    evaluated1 = []
    evaluated2 = []
    evaluated3 = []

    for s in s_vals:
        b, db, d2b = de_casteljau._compensated_k(s, BEZIER_COEFFS, 3)
        evaluated1.append(b)
        b2 = b + db
        evaluated2.append(b2)
        b3 = b2 + d2b
        evaluated3.append(b3)

    figure, (ax1, ax2, ax3) = plt.subplots(1, 3, sharex=True)
    ax1.plot(s_vals, evaluated1)
    ax2.plot(s_vals, evaluated2)
    ax3.plot(s_vals, evaluated3)

    # Since ``sharex=True``, ticks only need to be set once.
    ax1.set_xticks(
        [
            ROOT - DELTA_S,
            ROOT - 0.5 * DELTA_S,
            ROOT,
            ROOT + 0.5 * DELTA_S,
            ROOT + DELTA_S,
        ]
    )

    ax1.set_title(r"$\mathtt{DeCasteljau}$")
    ax2.set_title(r"$\mathtt{CompDeCasteljau}$")
    ax3.set_title(r"$\mathtt{CompDeCasteljau3}$")

    if filename is None:
        plt.show()
    else:
        figure.set_size_inches(13.65, 6.41)
        figure.subplots_adjust(
            left=0.04,
            bottom=0.10,
            right=0.97,
            top=0.95,
            wspace=0.15,
            hspace=0.19,
        )
        path = plot_utils.get_path(filename)
        figure.savefig(path, bbox_inches="tight")
        print("Saved {}".format(filename))
        plt.close(figure)
예제 #5
0
def image3():
    figure, (ax1, ax2, ax3) = plt.subplots(1, 3)

    control_pts1a = np.asfortranarray([[0.0, 0.375, 1.0], [0.0, 0.5, 0.125]])
    curve1a = bezier.Curve(control_pts1a, degree=2)
    control_pts1b = np.asfortranarray([[0.25, -0.125, 0.5],
                                       [-0.125, 0.375, 1.0]])
    curve1b = bezier.Curve(control_pts1b, degree=2)
    plot_with_bbox(curve1a, ax1, plot_utils.BLUE)
    plot_with_bbox(curve1b, ax1, plot_utils.GREEN)

    control_pts2a = np.asfortranarray([[0.0, 0.75, 1.0], [1.0, 0.75, 0.0]])
    curve2a = bezier.Curve(control_pts2a, degree=2)
    control_pts2b = np.asfortranarray([[0.375, 0.625, 1.375],
                                       [1.375, 0.625, 0.375]])
    curve2b = bezier.Curve(control_pts2b, degree=2)
    plot_with_bbox(curve2a, ax2, plot_utils.BLUE)
    plot_with_bbox(curve2b, ax2, plot_utils.GREEN)

    control_pts3a = np.asfortranarray([[0.0, 0.25, 1.0], [-0.25, 0.25, -0.75]])
    curve3a = bezier.Curve(control_pts3a, degree=2)
    control_pts3b = np.asfortranarray([[1.0, 1.5, 2.0], [-1.0, -1.5, -1.0]])
    curve3b = bezier.Curve(control_pts3b, degree=2)
    plot_with_bbox(curve3a, ax3, plot_utils.BLUE)
    plot_with_bbox(curve3b, ax3, plot_utils.GREEN)

    for ax in (ax1, ax2, ax3):
        simple_axis(ax)

    ax1.set_xlim(-0.2, 1.1)
    ax1.set_ylim(-0.2, 1.1)
    ax1.set_title("MAYBE", fontsize=plot_utils.TEXT_SIZE)
    ax2.set_xlim(-0.1, 1.5)
    ax2.set_ylim(-0.1, 1.5)
    ax2.set_title("MAYBE", fontsize=plot_utils.TEXT_SIZE)
    ax3.set_xlim(-0.1, 2.1)
    ax3.set_ylim(-1.7, 0.5)
    ax3.set_title("NO", fontsize=plot_utils.TEXT_SIZE)

    figure.set_size_inches(6.0, 2.2)
    figure.subplots_adjust(left=0.01,
                           bottom=0.01,
                           right=0.99,
                           top=0.9,
                           wspace=0.04,
                           hspace=0.2)
    filename = "bbox_check.pdf"
    path = plot_utils.get_path("bezier-intersection", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #6
0
def image1():
    figure, (ax1, ax2, ax3) = plt.subplots(1, 3, sharex=True, sharey=True)
    nodes = np.asfortranarray([[0.0, 1.0, 2.0, 4.0], [0.0, 4.0, 0.0, 3.0]])
    curve = bezier.Curve(nodes, degree=2)
    left, right = curve.subdivide()
    curve.plot(256, ax=ax1, alpha=0.25, color="black")
    left.plot(256, ax=ax1)
    curve.plot(256, ax=ax2)
    curve.plot(256, ax=ax3, alpha=0.25, color="black")
    right.plot(256, ax=ax3)
    ax1.text(
        2.5,
        0.25,
        r"$\left[0, \frac{1}{2}\right]$",
        horizontalalignment="center",
        verticalalignment="center",
        fontsize=plot_utils.TEXT_SIZE,
    )
    ax2.text(
        2.5,
        0.25,
        r"$\left[0, 1\right]$",
        horizontalalignment="center",
        verticalalignment="center",
        fontsize=plot_utils.TEXT_SIZE,
    )
    ax3.text(
        2.5,
        0.25,
        r"$\left[\frac{1}{2}, 1\right]$",
        horizontalalignment="center",
        verticalalignment="center",
        fontsize=plot_utils.TEXT_SIZE,
    )

    for ax in (ax1, ax2, ax3):
        simple_axis(ax)

    figure.set_size_inches(6.0, 1.5)
    figure.subplots_adjust(left=0.01,
                           bottom=0.01,
                           right=0.99,
                           top=0.99,
                           wspace=0.04,
                           hspace=0.2)
    filename = "subdivide_curve.pdf"
    path = plot_utils.get_path("bezier-intersection", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #7
0
def image4():
    figure, all_axes = plt.subplots(2, 7)
    all_axes = all_axes.flatten()

    nodes15 = np.asfortranarray([[0.25, 0.625, 1.0], [0.625, 0.25, 1.0]])
    curve15 = bezier.Curve(nodes15, degree=2)
    nodes25 = np.asfortranarray([[0.0, 0.25, 0.75, 1.0], [0.5, 1.0, 1.5, 0.5]])
    curve25 = bezier.Curve(nodes25, degree=3)

    color1 = plot_utils.BLUE
    curve15.plot(256, ax=all_axes[0], color=color1)
    color2 = plot_utils.GREEN
    curve25.plot(256, ax=all_axes[0], color=color2)

    choices1 = [1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1]
    choices2 = [1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1]
    first = curve15
    second = curve25
    for i in range(13):
        ax = all_axes[i + 1]
        index1 = choices1[i]
        index2 = choices2[i]
        first = first.subdivide()[index1]
        second = second.subdivide()[index2]
        first.plot(256, ax=ax, color=color1)
        second.plot(256, ax=ax, color=color2)
        # After splitting, put the bounding box on the previous axis.
        prev_ax = all_axes[i]
        add_patch(first, prev_ax, color1)
        add_patch(second, prev_ax, color2)

    for ax in all_axes:
        ax.axis("equal")
        ax.set_xticklabels([])
        ax.set_yticklabels([])

    figure.set_size_inches(6.4, 2.4)
    figure.subplots_adjust(left=0.01,
                           bottom=0.01,
                           right=0.99,
                           top=0.99,
                           wspace=0.06,
                           hspace=0.04)
    filename = "subdivision_linearized.pdf"
    path = plot_utils.get_path("bezier-intersection", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #8
0
def _main():
    s_vals = np.linspace(ROOT - DELTA_S, ROOT + DELTA_S, NUM_POINTS)

    de_casteljau2 = []
    exact = []

    for s in s_vals:
        de_casteljau2.append(de_casteljau.compensated(s, BEZIER_COEFFS))

        exact_s = F(s)
        exact_p = (2 * exact_s - 1)**3 * (exact_s - 1)
        exact.append(float(exact_p))

    figure, (ax1, ax2) = plt.subplots(1, 2, sharex=True, sharey=True)
    ax1.plot(s_vals, de_casteljau2)
    ax2.plot(s_vals, exact)

    # Since ``sharex=True``, ticks only need to be set once.
    ax1.set_xticks([
        ROOT - DELTA_S,
        ROOT - 0.5 * DELTA_S,
        ROOT,
        ROOT + 0.5 * DELTA_S,
        ROOT + DELTA_S,
    ])

    ax1.set_title(r"$\mathtt{CompDeCasteljau}$", fontsize=plot_utils.TEXT_SIZE)
    ax2.set_title("$p(s)$", fontsize=plot_utils.TEXT_SIZE)

    ax1.tick_params(labelsize=plot_utils.TICK_SIZE, which="both")
    ax2.tick_params(labelsize=plot_utils.TICK_SIZE, which="both")

    filename = "compensated_insufficient.pdf"
    # NOTE: These are (intended to be) the same settings used in
    #       ``horner_inferior.py``, so they should probably be
    #       kept in sync.
    figure.set_size_inches(6.0, 2.9)
    figure.subplots_adjust(left=0.07,
                           bottom=0.13,
                           right=0.97,
                           top=0.92,
                           wspace=0.13,
                           hspace=0.20)
    path = plot_utils.get_path("k-compensated", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #9
0
def main():
    # u_t + u_x = 0
    # u(x, t) = u(x - t, 0)
    min_x = -1.5
    max_x = 3.5
    x_vals = np.linspace(min_x, max_x, 2048 + 1)
    # u(x, 0) = x^3
    u0 = x_vals * x_vals * x_vals
    u2 = (x_vals - 2.0) * (x_vals - 2.0) * (x_vals - 2.0)

    figure = plt.figure()
    ax = figure.gca()

    ax.plot(x_vals, u0, label="$u(x, 0)$", color=plot_utils.BLUE)
    ax.plot(x_vals, u2, label="$u(x, 2)$", color=plot_utils.GREEN)
    ax.annotate(
        "",
        xy=(2.875, 0.75),
        xytext=(1.0, 0.75),
        arrowprops={
            "arrowstyle": "->",
            "linewidth": 2.0,
            "color": "black"
        },
    )

    ax.legend(loc="upper left", fontsize=plot_utils.TEXT_SIZE)
    ax.axis("scaled")
    ax.set_xlim(min_x, max_x)
    ax.set_ylim(-1.1, 1.1)
    ax.set_xlabel("$x$", fontsize=plot_utils.TEXT_SIZE)
    ax.set_ylabel("$u$", rotation=0, fontsize=plot_utils.TEXT_SIZE)
    ax.xaxis.set_tick_params(labelsize=plot_utils.TICK_SIZE)
    ax.yaxis.set_tick_params(labelsize=plot_utils.TICK_SIZE)

    figure.set_size_inches(4.8, 2.4)
    figure.subplots_adjust(left=0.12,
                           bottom=0.1,
                           right=0.99,
                           top=1.04,
                           wspace=0.2,
                           hspace=0.2)
    filename = "simple_transport.pdf"
    path = plot_utils.get_path("solution-transfer", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #10
0
def image1():
    nodes = np.asfortranarray([[0.0, 1.5, 3.0, 0.75, 2.25, 0.0],
                               [0.0, -0.5, 0.0, 1.0, 1.5, 2.0]])
    triangle = bezier.Surface(nodes, degree=2, _copy=False)
    point = triangle.evaluate_cartesian(0.25, 0.125)
    xv, yv = point.flatten()
    sub_triangles = triangle.subdivide()
    edges = triangle.edges

    figure, all_axes = plt.subplots(2, 2, sharex=True, sharey=True)
    all_axes = all_axes.flatten()
    for ax, sub_triangle in zip(all_axes, sub_triangles):
        # Add the bounding box for the sub triangle.
        add_patch(sub_triangle, ax, plot_utils.GREEN)
        # Add the triangle boundary to each subplot.
        for edge in edges:
            edge.plot(256, ax=ax, color=plot_utils.BLUE)
        # Add the sub triangle.
        sub_triangle.plot(256, ax=ax, color=plot_utils.BLUE)
        # Add the point to be found.
        ax.plot(
            [xv],
            [yv],
            color="black",
            marker="o",
            markersize=3,
            linestyle="none",
        )

    for ax in all_axes:
        ax.set_aspect("equal")
    # One axis sets all axis
    all_axes[0].set_xticklabels([])
    all_axes[0].set_yticklabels([])

    figure.set_size_inches(4.0, 3.0)
    figure.subplots_adjust(left=0.01,
                           bottom=0.01,
                           right=0.99,
                           top=0.99,
                           wspace=0.03,
                           hspace=0.04)
    filename = "locate_in_triangle.pdf"
    path = plot_utils.get_path("bezier-intersection", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #11
0
def image2():
    nodes15 = np.asfortranarray([[0.25, 0.625, 1.0], [0.625, 0.25, 1.0]])
    curve15 = bezier.Curve(nodes15, degree=2)
    nodes25 = np.asfortranarray([[0.0, 0.25, 0.75, 1.0], [0.5, 1.0, 1.5, 0.5]])
    curve25 = bezier.Curve(nodes25, degree=3)

    figure, all_axes = plt.subplots(2, 3, sharex=True, sharey=True)
    ax1, ax2, ax3, ax4, ax5, ax6 = all_axes.flatten()

    color1 = plot_utils.BLUE
    color2 = plot_utils.GREEN
    plot_with_bbox(curve15, ax1, color1)
    plot_with_bbox(curve25, ax1, color2)

    left, right = refine_candidates([curve15], [curve25])
    for curve in left:
        plot_with_bbox(curve, ax2, color1)
    for curve in right:
        plot_with_bbox(curve, ax2, color2)

    for ax in (ax3, ax4, ax5, ax6):
        left, right = refine_candidates(left, right)
        curve15.plot(256, color=color1, alpha=0.5, ax=ax)
        for curve in left:
            plot_with_bbox(curve, ax, color=color1)
        curve25.plot(256, color=color2, alpha=0.5, ax=ax)
        for curve in right:
            plot_with_bbox(curve, ax, color2)

    for ax in (ax1, ax2, ax3, ax4, ax5, ax6):
        simple_axis(ax)
        ax.set_xlim(-0.05, 1.05)
        ax.set_ylim(0.4, 1.15)

    figure.set_size_inches(6.0, 2.8)
    figure.subplots_adjust(left=0.01,
                           bottom=0.01,
                           right=0.99,
                           top=0.99,
                           wspace=0.04,
                           hspace=0.04)
    filename = "subdivision_process.pdf"
    path = plot_utils.get_path("bezier-intersection", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #12
0
def _main():
    s_vals = np.linspace(ROOT - DELTA_S, ROOT + DELTA_S, NUM_POINTS)

    evaluated1 = []
    evaluated2 = []
    evaluated3 = []

    for s in s_vals:
        b, db, d2b = de_casteljau._compensated_k(s, BEZIER_COEFFS, 3)
        evaluated1.append(b)
        b2 = b + db
        evaluated2.append(b2)
        b3 = b2 + d2b
        evaluated3.append(b3)

    figure, (ax1, ax2, ax3) = plt.subplots(1, 3, sharex=True)
    ax1.plot(s_vals, evaluated1)
    ax2.plot(s_vals, evaluated2)
    ax3.plot(s_vals, evaluated3)

    # Since ``sharex=True``, ticks only need to be set once.
    ax1.set_xticks([ROOT - 0.8 * DELTA_S, ROOT, ROOT + 0.8 * DELTA_S])

    ax1.set_title(r"$\mathtt{DeCasteljau}$",
                  fontsize=plot_utils.TEXT_SIZE,
                  pad=16.0)
    ax2.set_title(r"$\mathtt{CompDeCasteljau}$",
                  fontsize=plot_utils.TEXT_SIZE,
                  pad=16.0)
    ax3.set_title(r"$\mathtt{CompDeCasteljau3}$",
                  fontsize=plot_utils.TEXT_SIZE,
                  pad=16.0)

    filename = "de_casteljau_smooth_drawing.pdf"
    figure.set_size_inches(6.0, 3.0)
    figure.subplots_adjust(left=0.07,
                           bottom=0.13,
                           right=0.98,
                           top=0.87,
                           wspace=0.21,
                           hspace=0.2)
    path = plot_utils.get_path("k-compensated", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #13
0
def main(filename=None):
    s_vals = np.linspace(ROOT - DELTA_S, ROOT + DELTA_S, NUM_POINTS)

    horner1 = []
    de_casteljau1 = []

    for s in s_vals:
        horner1.append(horner.basic(s, POLY_COEFFS))
        de_casteljau1.append(de_casteljau.basic(s, BEZIER_COEFFS))

    figure, (ax1, ax2) = plt.subplots(1, 2, sharex=True, sharey=True)
    ax1.plot(s_vals, horner1)
    ax2.plot(s_vals, de_casteljau1)

    # Since ``sharex=True``, ticks only need to be set once.
    ax1.set_xticks([
        ROOT - DELTA_S,
        ROOT - 0.5 * DELTA_S,
        ROOT,
        ROOT + 0.5 * DELTA_S,
        ROOT + DELTA_S,
    ])

    ax1.set_title(r"$\mathtt{Horner}$")
    ax2.set_title(r"$\mathtt{DeCasteljau}$")

    if filename is None:
        plt.show()
    else:
        figure.set_size_inches(9.87, 4.8)
        figure.subplots_adjust(
            left=0.06,
            bottom=0.12,
            right=0.97,
            top=0.92,
            wspace=0.13,
            hspace=0.20,
        )
        path = plot_utils.get_path(filename)
        figure.savefig(path, bbox_inches="tight")
        print("Saved {}".format(filename))
        plt.close(figure)
예제 #14
0
def image2():
    figure, (ax1, ax2) = plt.subplots(1, 2)

    nodes1a = np.asfortranarray([[0.0, 1.0, 0.0], [0.0, 0.0, 1.0]])
    nodes2a = np.asfortranarray([[-0.125, 1.0, 0.125], [-0.0625, 0.5, 0.375]])
    nodes1b = np.asfortranarray([[0.0, 0.375, 1.0, 0.25, 0.75, 0.5],
                                 [0.0, 0.375, 0.0, 0.5, 0.5, 1.0]])
    nodes2b = np.asfortranarray([
        [1.0, 0.625, 0.0, 0.75, 0.25, 0.5],
        [0.375, -0.125, 0.375, -0.1875, -0.1875, -0.75],
    ])
    info = ((nodes1a, nodes2a, ax1), (nodes1b, nodes2b, ax2))

    for nodes1, nodes2, ax in info:
        triangle1 = bezier.Surface.from_nodes(nodes1)
        triangle2 = bezier.Surface.from_nodes(nodes2)
        intersections = triangle1.intersect(triangle2)

        triangle1.plot(256, ax=ax, color=plot_utils.BLUE)
        triangle2.plot(256, ax=ax, color=plot_utils.GREEN)
        for intersection in intersections:
            intersection.plot(256, ax=ax, color=plot_utils.RED)

    for ax in (ax1, ax2):
        ax.tick_params(labelsize=LABEL_SIZE, which="both")
        ax.axis("equal")

    ax1.set_title("Convex Intersection", fontsize=FONT_SIZE)
    ax2.set_title("Multiple Intersections", fontsize=FONT_SIZE)

    figure.set_size_inches(8.74, 4.8)
    figure.subplots_adjust(left=0.06,
                           bottom=0.06,
                           right=0.99,
                           top=0.93,
                           wspace=0.18,
                           hspace=0.2)
    filename = "split_intersection.pdf"
    path = plot_utils.get_path("slides", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #15
0
def image1():
    figure, (ax1, ax2) = plt.subplots(1, 2)
    nodes1 = np.asfortranarray([[0.0, 3.0, 7.0], [5.0, 0.0, 8.0]])
    triangle1 = bezier.Surface(nodes1, degree=1)
    triangle1.plot(256, ax=ax1)

    nodes2 = np.asfortranarray([[0.0, 1.0, 2.0, 2.0, 2.0, 0.0],
                                [0.0, 0.0, 0.0, 1.0, 2.0, 2.0]])
    triangle2 = bezier.Surface(nodes2, degree=2)
    triangle2.plot(256, ax=ax2)

    params = np.asfortranarray([[0.125, 0.125], [0.125, 0.75]])
    points1 = triangle1.evaluate_cartesian_multi(params)
    ax1.plot(points1[0, :], points1[1, :], marker="o", color="black")
    points2 = triangle2.evaluate_cartesian_multi(params)
    ax2.plot(points2[0, :], points2[1, :], marker="o", color="black")

    for ax in (ax1, ax2):
        ax.tick_params(labelsize=LABEL_SIZE, which="both")
        ax.axis("equal")

    ax1.set_title("Convex", fontsize=FONT_SIZE)
    ax2.set_title("Not (Necessarily) Convex", fontsize=FONT_SIZE)

    figure.set_size_inches(8.74, 4.8)
    figure.subplots_adjust(left=0.05,
                           bottom=0.06,
                           right=0.99,
                           top=0.93,
                           wspace=0.12,
                           hspace=0.2)
    filename = "not_convex.pdf"
    path = plot_utils.get_path("slides", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #16
0
def main():
    figure, (ax1, ax2, ax3) = plt.subplots(1, 3)

    ctx = mpmath.MPContext()
    ctx.prec = 500
    add_plot(ax1, ctx, 5, 30)
    add_plot(ax2, ctx, 15, 30)
    add_plot(ax3, ctx, 25, 30)

    for ax in (ax1, ax2, ax3):
        ax.tick_params(labelsize=plot_utils.TICK_SIZE)

    filename = "root_plots.pdf"
    figure.set_size_inches(6.4, 2.4)
    figure.subplots_adjust(left=0.08,
                           bottom=0.11,
                           right=0.99,
                           top=0.92,
                           wspace=0.29,
                           hspace=0.2)
    path = plot_utils.get_path("compensated-newton", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #17
0
def distort_cubic_tri(num_columns):
    node1 = np.array([-0.75, 0.0])
    node2 = np.array([2.25, -1.5])
    node3 = np.array([1.5, 1.5])
    control_points = np.array([
        node1,
        0.5 * (node1 + node2),
        node2,
        0.5 * (node1 + node3),
        0.5 * (node2 + node3),
        node3,
    ])

    figure, all_axes = plt.subplots(2, 3, sharex=True, sharey=True)
    min_y = -1.65
    max_y = 2.8
    control_x = control_points[:, 0]
    control_y = control_points[:, 1]
    bezier_nodes = np.empty((2, len(control_x)), order="F")

    # First add characteristic curves to the top row of axes.
    for i, xv in enumerate(control_x):
        yv = control_y[i]
        min_t = min_y - yv
        max_t = max_y - yv
        t_vals = np.linspace(min_t, max_t, 100)
        to_plot = point_on_characteristic(xv, yv, t_vals)
        for index, ax in enumerate(all_axes[0, :]):
            if index == num_columns:
                break
            ax.plot(to_plot[0],
                    to_plot[1],
                    color=plot_utils.GREEN,
                    alpha=ALPHA)

    for index, ax_top in enumerate(all_axes[0, :]):
        if index == num_columns:
            break
        t = 0.5 * index
        xt, yt = point_on_characteristic(control_x, control_y, t)

        corner_x = xt[(0, 2, 5, 0), ]
        corner_y = yt[(0, 2, 5, 0), ]
        ax_top.plot(corner_x, corner_y)

        title = get_title(t)
        ax_top.set_title(title, fontsize=plot_utils.TEXT_SIZE)

        # Now plot the curved element in the "below" axis".
        ax_below = all_axes[1, index]
        # NOTE: This assumes quadratic nodes.
        bezier_nodes[:, 0] = xt[0], yt[0]
        bezier_nodes[:, 1] = (
            2.0 * xt[1] - 0.5 * xt[0] - 0.5 * xt[2],
            2.0 * yt[1] - 0.5 * yt[0] - 0.5 * yt[2],
        )
        bezier_nodes[:, 2] = xt[2], yt[2]
        bezier_nodes[:, 3] = (
            2.0 * xt[3] - 0.5 * xt[0] - 0.5 * xt[5],
            2.0 * yt[3] - 0.5 * yt[0] - 0.5 * yt[5],
        )
        bezier_nodes[:, 4] = (
            2.0 * xt[4] - 0.5 * xt[2] - 0.5 * xt[5],
            2.0 * yt[4] - 0.5 * yt[2] - 0.5 * yt[5],
        )
        bezier_nodes[:, 5] = xt[5], yt[5]
        surface = bezier.Surface.from_nodes(bezier_nodes)
        surface.plot(256, ax=ax_below)

        # Add "nodes" to both plots.
        for ax in (ax_top, ax_below):
            ax.plot(
                xt,
                yt,
                color="black",
                marker="o",
                linestyle="none",
                markersize=4,
            )
        # Add shadow "nodes" to top row for "next" plots.
        for next_index in range(index + 1, 3):
            if next_index == num_columns:
                break
            ax = all_axes[0, next_index]
            ax.plot(
                xt,
                yt,
                color="black",
                alpha=0.5 - 0.25 * (next_index - index - 1),
                marker="o",
                linestyle="none",
                markersize=4,
            )

    for ax in all_axes.flatten():
        ax.axis("scaled")
    # One axis, all axes (since sharex/sharey).
    ax1 = all_axes[0, 0]
    ax1.set_xlim(-1.0, 5.9)
    ax1.set_ylim(min_y, max_y)
    ax1.set_xticks([0.0, 1.0, 2.0, 3.0, 4.0, 5.0])
    ax1.set_xticklabels(["$0.0$", "$1.0$", "$2.0$", "$3.0$", "$4.0$", "$5.0$"])
    ax1.set_yticks([-1.5, -0.5, 0.5, 1.5, 2.5])
    ax1.set_yticklabels(["$-1.5$", "$-0.5$", "$0.5$", "$1.5$", "$2.5$"])
    ax1.yaxis.set_tick_params(labelsize=plot_utils.TICK_SIZE)
    all_axes[1, 0].yaxis.set_tick_params(labelsize=plot_utils.TICK_SIZE)
    for ax in all_axes[1, :]:
        ax.xaxis.set_tick_params(labelsize=plot_utils.TICK_SIZE)

    for ax in all_axes[:, num_columns:].flatten():
        ax.axis("off")

    figure.set_size_inches(6.0, 2.9)
    figure.subplots_adjust(left=0.07,
                           bottom=0.05,
                           right=0.99,
                           top=0.97,
                           wspace=0.04,
                           hspace=-0.1)
    filename = "element_distortion{}.pdf".format(num_columns)
    path = plot_utils.get_path("slides", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #18
0
def error_plot(slide_num, data):
    cond_nums, rel_errors_basic, rel_errors_accurate, rel_errors_full = data

    figure = plt.figure()
    ax = figure.gca()
    ax.loglog(
        cond_nums,
        rel_errors_basic,
        marker="d",
        linestyle="none",
        markersize=7,
        color=plot_utils.BLUE,
        zorder=2,
        label=r"$\mathtt{DNewtonBasic}$",
    )
    line2, = ax.loglog(
        cond_nums,
        rel_errors_accurate,
        marker="o",
        linestyle="none",
        markersize=3,
        color="black",
        zorder=2,
        label=r"$\mathtt{DNewtonAccurate}$",
    )
    # H/T: (http://widu.tumblr.com/post/43624348228/
    #       making-unfilled-hollow-markers-in-matplotlib)
    line3, = ax.loglog(
        cond_nums,
        rel_errors_full,
        marker="o",
        linestyle="none",
        markersize=6,
        markeredgewidth=1,
        markerfacecolor="none",
        color=plot_utils.GREEN,
        zorder=2,
        label=r"$\mathtt{DNewtonFull}$",
    )
    # Add the error lines.
    ax.loglog(
        [1e-3, 1e30],
        [U * 1e-3, U * 1e30],
        color="black",
        linestyle="dashed",
        alpha=ALPHA,
        zorder=1,
    )
    ax.loglog(
        [1e10, 1e40],
        [U ** 2 * 1e10, U ** 2 * 1e40],
        color="black",
        linestyle="dashed",
        alpha=ALPHA,
        zorder=1,
    )
    # Add the ``x = 1/u^k`` vertical lines.
    min_x, max_x = get_bounds(cond_nums)
    min_y, max_y = get_bounds(
        rel_errors_basic + rel_errors_accurate + rel_errors_full
    )
    delta_y = max_y - min_y
    for exponent in (1, 2, 3):
        u_inv = 1.0 / float(U) ** exponent
        ax.loglog(
            [u_inv, u_inv],
            [min_y - 0.05 * delta_y, max_y + 0.05 * delta_y],
            color="black",
            linestyle="dashed",
            alpha=ALPHA,
            zorder=1,
        )
    # Add the ``y = 1`` and ``y = u`` horizontal lines.
    for exponent in (0, 1):
        u_pow = float(U) ** exponent
        ax.loglog(
            [min_x, max_x],
            [u_pow, u_pow],
            color="black",
            linestyle="dashed",
            alpha=ALPHA,
            zorder=1,
        )
    # Set the axis limits.
    ax.set_xlim(min_x, max_x)
    ax.set_ylim(min_y, max_y)
    # Set "nice" ticks.
    ax.set_xticks([10.0 ** n for n in range(0, 50 + 10, 10)])
    ax.set_yticks([10.0 ** n for n in range(-16, 0 + 4, 4)])
    # Set special ``xticks`` for ``1/u^k``.
    u_xticks = [1.0 / float(U), 1.0 / float(U) ** 2, 1.0 / float(U) ** 3]
    u_xticklabels = [
        r"$1/\mathbf{u}$",
        r"$1/\mathbf{u}^2$",
        r"$1/\mathbf{u}^3$",
    ]
    ax.set_xticks(u_xticks, minor=True)
    ax.set_xticklabels(u_xticklabels, minor=True)
    ax.tick_params(
        axis="x",
        which="minor",
        direction="out",
        top=1,
        bottom=0,
        labelbottom=0,
        labeltop=1,
    )
    # Set special ``yticks`` for ``u`` and ``1``.
    ax.set_yticks([float(U), 1.0], minor=True)
    ax.set_yticklabels([r"$\mathbf{u}$", "$1$"], minor=True)
    ax.tick_params(
        axis="y",
        which="minor",
        direction="out",
        left=0,
        right=1,
        labelleft=0,
        labelright=1,
    )
    # Label the axes.
    ax.set_xlabel("Condition Number", fontsize=plot_utils.TEXT_SIZE)
    ax.set_ylabel("Relative Forward Error", fontsize=plot_utils.TEXT_SIZE)
    if slide_num < 2:
        line2.set_visible(False)
        # This is to fool the legend.
        line2.set_alpha(0.0)
    if slide_num < 3:
        line3.set_visible(False)
        # This is to fool the legend.
        line3.set_alpha(0.0)

    # Add the legend.
    legend = ax.legend(
        loc="lower right",
        framealpha=1.0,
        frameon=True,
        fontsize=plot_utils.TEXT_SIZE,
    )
    # Leave the text intact but make it "invisible".
    if slide_num < 2:
        _, text2, _ = legend.get_texts()
        text2.set_alpha(0.0)
    if slide_num < 3:
        _, _, text3 = legend.get_texts()
        text3.set_alpha(0.0)

    ax.tick_params(labelsize=plot_utils.TICK_SIZE)
    ax.tick_params(labelsize=plot_utils.TEXT_SIZE, which="minor")

    figure.set_size_inches(5.4, 4.0)
    figure.subplots_adjust(
        left=0.12, bottom=0.11, right=0.95, top=0.92, wspace=0.2, hspace=0.2
    )
    filename = "newton_de_casteljau{}.pdf".format(slide_num)
    path = plot_utils.get_path("slides", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #19
0
def main():
    n = 8
    gamma2n = (2 * n * U) / (1 - 2 * n * U)
    bound_coeff1 = float(gamma2n)
    bound_coeff2 = 3 * n * (3 * n + 7) * U ** 2 / 2
    bound_coeff2 = float(bound_coeff2)
    bound_coeff3 = 3 * n * (3 * n ** 2 + 36 * n + 61) * U ** 3 / 2
    bound_coeff3 = float(bound_coeff3)
    bound_coeff4 = (
        9 * n * (3 * n ** 3 + 102 * n ** 2 + 773 * n + 1122) * U ** 4 / 8
    )
    bound_coeff4 = float(bound_coeff4)

    cond_nums = []
    forward_errs1 = []
    forward_errs2 = []
    forward_errs3 = []
    forward_errs4 = []
    for j in range(-5, -90 - 1, -1):
        s = ROOT - POWER_VAL ** j
        exact_s = F(s)

        # Compute the condition number.
        exact_p = (exact_s - 1) * (4 * exact_s - 3) ** 7 / 16384
        # p_tilde(s) = SUM_j |b_j| B_{j, 8}(s) = (s - 1) (s/2 - 3/4)^7
        exact_p_tilde = (exact_s - 1) * (2 * exact_s - 3) ** 7 / 16384
        exact_cond = abs(exact_p_tilde / exact_p)
        cond_nums.append(float(exact_cond))

        # Compute the forward error for uncompensated de Casteljau.
        b, db, d2b, d3b = de_casteljau._compensated_k(s, BEZIER_COEFFS, 4)
        exact_b1 = F(b)
        exact_forward_err1 = abs((exact_b1 - exact_p) / exact_p)
        forward_errs1.append(float(exact_forward_err1))

        # Compute the forward error for compensated de Casteljau.
        b2 = b + db
        exact_b2 = F(b2)
        exact_forward_err2 = abs((exact_b2 - exact_p) / exact_p)
        forward_errs2.append(float(exact_forward_err2))

        # Compute the forward error for K-compensated de Casteljau (K=3).
        b3 = b2 + d2b
        exact_b3 = F(b3)
        exact_forward_err3 = abs((exact_b3 - exact_p) / exact_p)
        forward_errs3.append(float(exact_forward_err3))

        # Compute the forward error for K-compensated de Casteljau (K=3).
        b4 = b3 + d3b
        exact_b4 = F(b4)
        exact_forward_err4 = abs((exact_b4 - exact_p) / exact_p)
        forward_errs4.append(float(exact_forward_err4))

    # Set a tight ``x``-limit.
    min_exp = np.log(min(cond_nums))
    max_exp = np.log(max(cond_nums))
    delta_exp = max_exp - min_exp
    min_x = np.exp(min_exp - 0.01 * delta_exp)
    max_x = np.exp(max_exp + 0.01 * delta_exp)

    figure = plt.figure()
    ax = figure.gca()
    ax.loglog(
        cond_nums,
        forward_errs1,
        marker="v",
        linestyle="none",
        zorder=2,
        label=r"$\mathtt{DeCasteljau}$",
        color=plot_utils.BLUE,
    )
    ax.loglog(
        cond_nums,
        forward_errs2,
        marker="d",
        linestyle="none",
        zorder=2,
        label=r"$\mathtt{CompDeCasteljau}$",
        color=plot_utils.GREEN,
    )
    ax.loglog(
        cond_nums,
        forward_errs3,
        marker="P",
        linestyle="none",
        zorder=1.5,  # Beneath ``K=2``.
        label=r"$\mathtt{CompDeCasteljau3}$",
        color=plot_utils.RED,
    )
    ax.loglog(
        cond_nums,
        forward_errs4,
        marker="o",
        linestyle="none",
        zorder=1.25,  # Beneath ``K=2, 3``.
        label=r"$\mathtt{CompDeCasteljau4}$",
        color=plot_utils.PURPLE,
    )
    # Figure out the bounds before adding the bounding lines.
    min_y, max_y = ax.get_ylim()
    # Plot the lines of the a priori error bounds.
    ax.loglog(
        [min_x, max_x],
        [bound_coeff1 * min_x, bound_coeff1 * max_x],
        color="black",
        alpha=ALPHA,
        zorder=1,
    )
    ax.loglog(
        [min_x, max_x],
        [bound_coeff2 * min_x, bound_coeff2 * max_x],
        color="black",
        alpha=ALPHA,
        zorder=1,
    )
    ax.loglog(
        [min_x, max_x],
        [bound_coeff3 * min_x, bound_coeff3 * max_x],
        color="black",
        alpha=ALPHA,
        zorder=1,
    )
    ax.loglog(
        [min_x, max_x],
        [bound_coeff4 * min_x, bound_coeff4 * max_x],
        color="black",
        alpha=ALPHA,
        zorder=1,
    )
    # Add the ``x = 1/u^k`` vertical lines.
    delta_y = max_y - min_y
    for exponent in (1, 2, 3, 4):
        u_inv = 1.0 / float(U) ** exponent
        ax.loglog(
            [u_inv, u_inv],
            [min_y - 0.05 * delta_y, max_y + 0.05 * delta_y],
            color="black",
            linestyle="dashed",
            alpha=ALPHA,
            zorder=1,
        )
    # Add the ``y = u`` horizontal lines.
    ax.loglog(
        [min_x, max_x],
        [float(U), float(U)],
        color="black",
        linestyle="dashed",
        alpha=ALPHA,
        zorder=1,
    )

    # Make sure the ``y``-limit stays set (the bounds lines exceed).
    ax.set_ylim(min_y, 1.0)
    ax.set_xlim(min_x, max_x)
    # Add the legend.
    ax.legend(
        loc="lower right",
        framealpha=1.0,
        frameon=True,
        fontsize=plot_utils.TEXT_SIZE,
    )
    # Set "nice" ticks.
    ax.set_xticks([10.0 ** n for n in range(5, 65 + 10, 10)])
    ax.set_yticks([10.0 ** n for n in range(-18, 0 + 2, 2)])
    # Set special ``xticks`` for ``1/u^k``.
    u_xticks = []
    u_xticklabels = []
    for exponent in (1, 2, 3, 4):
        u_xticks.append(1.0 / float(U) ** exponent)
        if exponent == 1:
            u_xticklabels.append(r"$1/\mathbf{u}$")
        else:
            u_xticklabels.append(r"$1/\mathbf{{u}}^{}$".format(exponent))

    ax.set_xticks(u_xticks, minor=True)
    ax.set_xticklabels(u_xticklabels, minor=True)
    ax.tick_params(
        axis="x",
        which="minor",
        direction="out",
        top=1,
        bottom=0,
        labelbottom=0,
        labeltop=1,
    )
    # Set special ``yticks`` for ``u``.
    ax.set_yticks([float(U)], minor=True)
    ax.set_yticklabels([r"$\mathbf{u}$"], minor=True)
    ax.tick_params(
        axis="y",
        which="minor",
        direction="out",
        left=0,
        right=1,
        labelleft=0,
        labelright=1,
    )
    # Label the axes.
    ax.set_xlabel("Condition Number", fontsize=plot_utils.TEXT_SIZE)
    ax.set_ylabel("Relative Forward Error", fontsize=plot_utils.TEXT_SIZE)

    ax.tick_params(labelsize=plot_utils.TICK_SIZE)
    ax.tick_params(labelsize=plot_utils.TEXT_SIZE, which="minor")

    figure.set_size_inches(5.2, 3.9)
    figure.subplots_adjust(
        left=0.12, bottom=0.11, right=0.95, top=0.92, wspace=0.2, hspace=0.2
    )
    filename = "de_casteljau_rel_error.pdf"
    path = plot_utils.get_path("k-compensated", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #20
0
def main_jlcs10():
    """This recreates the plot from `JLCS10`_.

    .. _JLCS10: https://doi.org/10.1016/j.camwa.2010.05.021

    Note that it is essentially a copy of :func:`main` (and much of the
    code could be shared, but it isn't worth the effort).

    This seeks to recreate the plot from the original paper, but to show
    what happens as the exponent on ``POWER_VAL`` decreases from ``-44`` down
    to ``-64``. In particular, it shows that the compensated de Casteljau
    algorithm produces exactly zero.
    """
    n = 8
    gamma2n = (2 * n * U) / (1 - 2 * n * U)
    bound_coeff1 = float(gamma2n)
    bound_coeff2 = 3 * n * (3 * n + 7) * U ** 2 / 2
    bound_coeff2 = float(bound_coeff2)

    cond_nums = []
    forward_errs1 = []
    forward_errs2 = []
    for j in range(-5, -64 - 1, -1):
        s = ROOT - POWER_VAL ** j
        exact_s = F(s)

        # Compute the condition number.
        exact_p = (exact_s - 1) * (4 * exact_s - 3) ** 7 / 16384
        # p_tilde(s) = SUM_j |b_j| B_{j, 8}(s) = (s - 1) (s/2 - 3/4)^7
        exact_p_tilde = (exact_s - 1) * (2 * exact_s - 3) ** 7 / 16384
        exact_cond = abs(exact_p_tilde / exact_p)
        cond_nums.append(float(exact_cond))

        # Compute the forward error for uncompensated de Casteljau.
        b, db = de_casteljau._compensated_k(s, BEZIER_COEFFS, 2)
        exact_b1 = F(b)
        exact_forward_err1 = abs((exact_b1 - exact_p) / exact_p)
        forward_errs1.append(float(exact_forward_err1))

        # Compute the forward error for compensated de Casteljau.
        b2 = b + db
        exact_b2 = F(b2)
        exact_forward_err2 = abs((exact_b2 - exact_p) / exact_p)
        forward_errs2.append(float(exact_forward_err2))

    # Set a tight ``x``-limit.
    min_exp = np.log(min(cond_nums))
    max_exp = np.log(max(cond_nums))
    delta_exp = max_exp - min_exp
    min_x = np.exp(min_exp - 0.01 * delta_exp)
    max_x = np.exp(max_exp + 0.01 * delta_exp)

    figure = plt.figure()
    ax = figure.gca()
    ax.loglog(
        cond_nums,
        forward_errs1,
        marker="v",
        linestyle="none",
        zorder=2,
        label=r"$\mathtt{DeCasteljau}$",
        color=plot_utils.BLUE,
    )
    ax.loglog(
        cond_nums,
        forward_errs2,
        marker="d",
        linestyle="none",
        zorder=2,
        label=r"$\mathtt{CompDeCasteljau}$",
        color=plot_utils.GREEN,
    )
    # Figure out the bounds before adding the bounding lines.
    min_y, max_y = ax.get_ylim()
    # Plot the lines of the a priori error bounds.
    ax.loglog(
        [min_x, max_x],
        [bound_coeff1 * min_x, bound_coeff1 * max_x],
        color="black",
        alpha=ALPHA,
        zorder=1,
    )
    ax.loglog(
        [min_x, max_x],
        [bound_coeff2 * min_x, bound_coeff2 * max_x],
        color="black",
        alpha=ALPHA,
        zorder=1,
    )
    # Add the ``x = 1/u^k`` vertical lines.
    delta_y = max_y - min_y
    for exponent in (1, 2):
        u_inv = 1.0 / float(U) ** exponent
        ax.loglog(
            [u_inv, u_inv],
            [min_y - 0.05 * delta_y, max_y + 0.05 * delta_y],
            color="black",
            linestyle="dashed",
            alpha=ALPHA,
            zorder=1,
        )
    # Add the ``y = u`` and ``y = 1`` horizontal lines.
    ax.loglog(
        [min_x, max_x],
        [float(U), float(U)],
        color="black",
        linestyle="dashed",
        alpha=ALPHA,
        zorder=1,
    )
    ax.loglog(
        [min_x, max_x],
        [1.0, 1.0],
        color="black",
        linestyle="dashed",
        alpha=ALPHA,
        zorder=1,
    )

    # Make sure the ``y``-limit stays set (the bounds lines exceed).
    ax.set_ylim(min_y, 10.0 ** 18)
    ax.set_xlim(min_x, max_x)
    # Add the legend.
    ax.legend(
        loc="lower right",
        framealpha=1.0,
        frameon=True,
        fontsize=plot_utils.TEXT_SIZE,
    )
    # Set "nice" ticks.
    ax.set_xticks([10.0 ** n for n in range(5, 45 + 5, 5)])
    ax.set_yticks([10.0 ** n for n in range(-18, 14 + 4, 4)])
    # Set special ``xticks`` for ``1/u`` and ``1/u^2``.
    ax.set_xticks([1.0 / float(U), 1.0 / float(U) ** 2], minor=True)
    ax.set_xticklabels([r"$1/\mathbf{u}$", r"$1/\mathbf{u}^2$"], minor=True)
    ax.tick_params(
        axis="x",
        which="minor",
        direction="out",
        top=1,
        bottom=0,
        labelbottom=0,
        labeltop=1,
    )
    # Set special ``yticks`` for ``u`` and ``1``.
    ax.set_yticks([float(U), 1.0], minor=True)
    ax.set_yticklabels([r"$\mathbf{u}$", "$1$"], minor=True)
    ax.tick_params(
        axis="y",
        which="minor",
        direction="out",
        left=0,
        right=1,
        labelleft=0,
        labelright=1,
    )
    # Label the axes.
    ax.set_xlabel("Condition Number", fontsize=plot_utils.TEXT_SIZE)
    ax.set_ylabel("Relative Forward Error", fontsize=plot_utils.TEXT_SIZE)
    # Make sure the ticks are sized appropriately.
    ax.tick_params(labelsize=plot_utils.TICK_SIZE)
    ax.tick_params(labelsize=plot_utils.TEXT_SIZE, which="minor")

    figure.set_size_inches(5.2, 3.9)
    figure.subplots_adjust(
        left=0.12, bottom=0.11, right=0.95, top=0.92, wspace=0.2, hspace=0.2
    )
    filename = "jlcs10_plot.pdf"
    path = plot_utils.get_path("k-compensated", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #21
0
def intersection_area():
    # NOTE: These are surfaces 30Q and 31Q from the ``bezier`` project.
    nodes1 = np.asfortranarray([
        [-0.25, 0.1875, 0.625, -0.25, 0.1875, -0.25],
        [-0.25, -0.25, -0.25, 0.1875, 0.1875, 0.625],
    ])
    surface1 = bezier.Surface.from_nodes(nodes1)
    edge11, edge12, edge13 = surface1.edges
    nodes2 = np.asfortranarray([
        [0.0, 0.5, 1.0, 0.0625, 0.4375, -0.125],
        [-1.0, -0.5, 0.0, -0.5, 0.0, 0.0],
    ])
    surface2 = bezier.Surface.from_nodes(nodes2)
    edge21, edge22, edge23 = surface2.edges

    exact_area = F(7, 48)

    figure, all_axes = plt.subplots(2, 3)
    all_axes = all_axes.flatten()

    ax = all_axes[0]
    intersection, = surface1.intersect(surface2)
    surface1.plot(256, ax=ax, color=plot_utils.BLUE)
    surface2.plot(256, ax=ax, color=plot_utils.GREEN)
    intersection.plot(256, ax=ax, color=plot_utils.RED)
    ax.set_title("Curved", fontsize=plot_utils.TEXT_SIZE)

    error_vals = []
    for n in range(1, 20 + 1):
        N = 2**n
        s_vals = np.linspace(0.0, 1.0, N + 1)[:-1]
        polygon_nodes1 = edges_to_polygon(edge11, edge12, edge13, s_vals)
        polygon1 = shapely.geometry.Polygon(polygon_nodes1.T)
        polygon_nodes2 = edges_to_polygon(edge21, edge22, edge23, s_vals)
        polygon2 = shapely.geometry.Polygon(polygon_nodes2.T)

        poly_intersect = polygon1.intersection(polygon2)
        if not isinstance(poly_intersect, shapely.geometry.Polygon):
            raise TypeError(poly_intersect)
        # Compute the relative error.
        approximate_area = F(poly_intersect.area)
        rel_error = abs(approximate_area - exact_area) / exact_area
        error_vals.append((N, float(rel_error)))
        # Plot the "approximate" surfaces as well as their
        # polygonal intersection.
        if n in (1, 2, 3, 4):
            ax = all_axes[n]
            for polygon_nodes, color in (
                (polygon_nodes1, plot_utils.BLUE),
                (polygon_nodes2, plot_utils.GREEN),
            ):
                # Wrap-around the first node so the polygon is closed.
                polygon_nodes = np.hstack(
                    [polygon_nodes, polygon_nodes[:, :1]])
                patch = matplotlib.patches.PathPatch(
                    matplotlib.path.Path(polygon_nodes.T),
                    alpha=0.625,
                    color=color,
                )
                ax.add_patch(patch)
                ax.plot(
                    polygon_nodes[0, :],
                    polygon_nodes[1, :],
                    color=color,
                    marker="o",
                    markersize=4,
                )
            boundary_x, boundary_y = poly_intersect.exterior.coords.xy
            boundary = np.empty((len(boundary_x), 2))
            boundary[:, 0] = boundary_x
            boundary[:, 1] = boundary_y
            patch = matplotlib.patches.PathPatch(
                matplotlib.path.Path(boundary),
                alpha=0.625,
                color=plot_utils.RED,
            )
            new_nodes = []
            for i, node in enumerate(boundary):
                if not (contains_column(node, polygon_nodes1)
                        or contains_column(node, polygon_nodes2)):
                    new_nodes.append(i)

            if new_nodes:
                ax.plot(
                    boundary[new_nodes, 0],
                    boundary[new_nodes, 1],
                    color=plot_utils.RED,
                    marker="o",
                    markersize=4,
                    linestyle="none",
                )
            ax.plot(
                boundary[:-1, 0],
                boundary[:-1, 1],
                color=plot_utils.RED,
                marker="o",
                markersize=4,
                markeredgewidth=1,
                markerfacecolor="none",
                linestyle="none",
            )
            ax.add_patch(patch)
            ax.set_title("$N = {:d}$".format(N), fontsize=plot_utils.TEXT_SIZE)

    for ax in all_axes[:5]:
        ax.axis("equal")
        ax.set_xlim(-0.3125, 1.0625)
        ax.set_ylim(-1.08125, 0.70625)
    for ax in all_axes[:3]:
        ax.set_xticklabels([])
    for ax in all_axes[(1, 2, 4), ]:
        ax.set_yticklabels([])

    error_vals = np.array(error_vals)
    ax = all_axes[5]
    ax.loglog(
        error_vals[:, 0],
        error_vals[:, 1],
        basex=2,
        marker="o",
        markersize=4,
        label="Polygonal",
    )
    curved_poly_area = F(compute_area(*intersection._edges))
    curved_rel_error = float(abs(exact_area - curved_poly_area) / exact_area)
    ax.loglog(
        [error_vals[0, 0], error_vals[-1, 0]],
        [curved_rel_error, curved_rel_error],
        basex=2,
        color="black",
        linestyle="dashed",
        label="Curved",
    )
    ax.legend(loc="lower left", fontsize=plot_utils.TEXT_SIZE)
    ax.set_title("Intersection Area Estimates", fontsize=plot_utils.TEXT_SIZE)
    ax.set_xlabel("Line Segments per Side ($N$)",
                  fontsize=plot_utils.TEXT_SIZE)
    ax.set_ylabel("Relative Error", fontsize=plot_utils.TEXT_SIZE)
    ax.yaxis.tick_right()
    ax.yaxis.set_label_position("right")

    all_axes[0].yaxis.set_tick_params(labelsize=plot_utils.TICK_SIZE)
    all_axes[3].yaxis.set_tick_params(labelsize=plot_utils.TICK_SIZE)
    all_axes[5].yaxis.set_tick_params(labelsize=plot_utils.TICK_SIZE)
    all_axes[3].xaxis.set_tick_params(labelsize=plot_utils.TICK_SIZE)
    all_axes[4].xaxis.set_tick_params(labelsize=plot_utils.TICK_SIZE)
    all_axes[5].xaxis.set_tick_params(labelsize=plot_utils.TICK_SIZE)

    all_axes[3].set_xticks([-0.4, 0.1, 0.6, 1.1])
    all_axes[4].set_xticks([-0.4, 0.1, 0.6, 1.1])
    all_axes[5].set_xticks([2.0**4, 2.0**8, 2.0**12, 2.0**16, 2.0**20])

    figure.set_size_inches(6.0, 4.2)
    figure.subplots_adjust(left=0.08,
                           bottom=0.11,
                           right=0.9,
                           top=0.95,
                           wspace=0.03,
                           hspace=0.15)
    filename = "polygon_vs_curved_intersection.pdf"
    path = plot_utils.get_path("solution-transfer", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #22
0
def main():
    ctx = mpmath.MPContext()
    ctx.prec = 500

    s0 = 1.0
    t0 = 1.0

    cond_nums = np.empty((24, ))
    rel_errors1 = np.empty((24, ))
    rel_errors2 = np.empty((24, ))
    for n in range(3, 49 + 2, 2):
        r = 0.5**n
        r_inv = 1.0 / r
        cond_num = kappa(r, ctx)

        # Compute the coefficients.
        coeffs1 = np.asfortranarray([[-2.0 - r, -2.0 - r, 6.0 - r],
                                     [2.0 + r_inv, r_inv, 2.0 + r_inv]])
        coeffs2 = np.asfortranarray([[-4.0, -4.0, 12.0],
                                     [5.0 + r_inv, -3.0 + r_inv, 5.0 + r_inv]])
        # Use Newton's method to find the intersection.
        iterates1 = newton_bezier.newton(s0, coeffs1, t0, coeffs2,
                                         newton_bezier.standard_residual)
        iterates2 = newton_bezier.newton(s0, coeffs1, t0, coeffs2,
                                         newton_bezier.compensated_residual)
        # Just keep the final iterate and discard the rest.
        s1, t1 = iterates1[-1]
        s2, t2 = iterates2[-1]
        # Compute the relative error in the 2-norm.
        sqrt_r = ctx.sqrt(r)
        alpha = 0.5 * (1 + sqrt_r)
        beta = 0.25 * (2 + sqrt_r)
        size = ctx.norm([alpha, beta], p=2)
        rel_error1 = ctx.norm([alpha - s1, beta - t1], p=2) / size
        rel_error2 = ctx.norm([alpha - s2, beta - t2], p=2) / size
        # Convert the errors to floats and store.
        cond_nums[(n - 3) // 2] = plot_utils.to_float(cond_num)
        rel_errors1[(n - 3) // 2] = plot_utils.to_float(rel_error1)
        rel_errors2[(n - 3) // 2] = plot_utils.to_float(rel_error2)

    # Make sure all of the non-compensated errors are non-zero and
    # at least one of the compensated errors is zero.
    if rel_errors1.min() <= 0.0:
        raise ValueError("Unexpected minimum error (non-compensated).")
    if rel_errors2.min() <= 0.0:
        raise ValueError("Unexpected minimum error (compensated).")

    figure = plt.figure()
    ax = figure.gca()
    # Add all of the non-compensated errors.
    ax.loglog(
        cond_nums,
        rel_errors1,
        marker="v",
        linestyle="none",
        color=plot_utils.BLUE,
        label="Standard",
    )
    # Add all of the compensated errors.
    ax.loglog(
        cond_nums,
        rel_errors2,
        marker="d",
        linestyle="none",
        color=plot_utils.GREEN,
        label="Compensated",
    )

    # Plot the lines of the a priori error bounds.
    min_x = 1.5
    max_x = 5.0e+32
    for coeff in (U, U**2):
        start_x = min_x
        start_y = coeff * start_x
        ax.loglog(
            [start_x, max_x],
            [start_y, coeff * max_x],
            color="black",
            alpha=ALPHA,
            zorder=1,
        )
    # Add the ``x = 1/U`` and ``x = 1/U^2`` vertical lines.
    min_y = 1e-18
    max_y = 5.0
    for x_val in (1.0 / U, 1.0 / U**2):
        ax.loglog(
            [x_val, x_val],
            [min_y, max_y],
            color="black",
            linestyle="dashed",
            alpha=ALPHA,
            zorder=1,
        )
    # Add the ``y = u`` and ``y = 1`` horizontal lines.
    for y_val in (U, 1.0):
        ax.loglog(
            [min_x, max_x],
            [y_val, y_val],
            color="black",
            linestyle="dashed",
            alpha=ALPHA,
            zorder=1,
        )

    # Set "nice" ticks.
    ax.set_xticks([10.0**n for n in range(4, 28 + 8, 8)])
    ax.set_yticks([10.0**n for n in range(-16, 0 + 4, 4)])
    # Set special ``xticks`` for ``1/u`` and ``1/u^2``.
    ax.set_xticks([1.0 / U, 1.0 / U**2], minor=True)
    ax.set_xticklabels([r"$1/\mathbf{u}$", r"$1/\mathbf{u}^2$"], minor=True)
    ax.tick_params(
        axis="x",
        which="minor",
        direction="out",
        top=1,
        bottom=0,
        labelbottom=0,
        labeltop=1,
    )
    # Set special ``yticks`` for ``u`` and ``1``.
    ax.set_yticks([U, 1.0], minor=True)
    ax.set_yticklabels([r"$\mathbf{u}$", "$1$"], minor=True)
    ax.tick_params(
        axis="y",
        which="minor",
        direction="out",
        left=0,
        right=1,
        labelleft=0,
        labelright=1,
    )
    # Label the axes.
    ax.set_xlabel("Condition Number", fontsize=plot_utils.TEXT_SIZE)
    ax.set_ylabel("Relative Forward Error", fontsize=plot_utils.TEXT_SIZE)
    # Make sure the ticks are sized appropriately.
    ax.tick_params(labelsize=plot_utils.TICK_SIZE)
    ax.tick_params(labelsize=plot_utils.TEXT_SIZE, which="minor")

    # Set axis limits.
    ax.set_xlim(min_x, max_x)
    ax.set_ylim(min_y, max_y)
    # Add the legend.
    ax.legend(
        loc="upper left",
        framealpha=1.0,
        frameon=True,
        fontsize=plot_utils.TEXT_SIZE,
    )

    figure.set_size_inches(6.0, 4.5)
    figure.subplots_adjust(left=0.11,
                           bottom=0.09,
                           right=0.96,
                           top=0.94,
                           wspace=0.2,
                           hspace=0.2)
    filename = "almost_tangent.pdf"
    path = plot_utils.get_path("compensated-newton", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #23
0
def boundary_leak(slide_num):
    bez_triangle = bezier.Surface(NODES, degree=2, _copy=False)
    figure, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2,
                                                    2,
                                                    sharex=True,
                                                    sharey=True)
    # Add reference triangle to both top subplots.
    for ax in (ax1, ax2):
        if slide_num == 1:
            ax.plot([0, 1], [0, 0], color=plot_utils.BLUE)
            ax.plot([1, 0], [0, 1], color="black", alpha=ALPHA)
            ax.plot([0, 0], [1, 0], color="black", alpha=ALPHA)
        elif slide_num == 2:
            ax.plot([0, 1], [0, 0], color="black", alpha=ALPHA)
            ax.plot([1, 0], [0, 1], color=plot_utils.BLUE)
            ax.plot([0, 0], [1, 0], color="black", alpha=ALPHA)
        elif slide_num == 3:
            ax.plot([0, 1], [0, 0], color="black", alpha=ALPHA)
            ax.plot([1, 0], [0, 1], color="black", alpha=ALPHA)
            ax.plot([0, 0], [1, 0], color=plot_utils.BLUE)
        else:
            ax.plot([0, 1], [0, 0], color="black", alpha=ALPHA)
            ax.plot([1, 0], [0, 1], color="black", alpha=ALPHA)
            ax.plot([0, 0], [1, 0], color="black", alpha=ALPHA)

    # Add the "wrong" triangle to both bottom subplots.
    edge1, edge2, edge3 = bez_triangle.edges
    for ax in (ax3, ax4):
        bez_triangle.plot(256, ax=ax, color="black")
        ax.patches[-1].set_alpha(ALPHA)
        # Remove the black boundary and add colored.
        ax.lines.pop()
        if slide_num == 1:
            edge1.plot(256, ax=ax, color=plot_utils.BLUE)
        elif slide_num == 2:
            edge2.plot(256, ax=ax, color=plot_utils.BLUE)
        elif slide_num == 3:
            edge3.plot(256, ax=ax, color=plot_utils.BLUE)

    # det(J) = 4[t^2 + (s - 1) t + (s - s^2)]
    sv = np.linspace(0.0, 1.0 / 5.0, 250)
    sqrt_part = np.sqrt((1.0 - sv) * (1.0 - 5.0 * sv))
    jacobian_zero = np.empty((499, 2))
    jacobian_zero[:250, 0] = sv
    jacobian_zero[:250, 1] = 0.5 * (1.0 - sv - sqrt_part)
    jacobian_zero[250:, 0] = sv[-2::-1]
    jacobian_zero[250:, 1] = 0.5 * (1.0 - sv[-2::-1] + sqrt_part[-2::-1])
    ax2.plot(
        jacobian_zero[:, 0],
        jacobian_zero[:, 1],
        color="black",
        linestyle="dashed",
    )
    # Now, compute the image of the det(J) = 0 curve under b(s, t).
    poly4 = np.empty((598, 2))
    sv = jacobian_zero[::-1, 0]
    tv = jacobian_zero[::-1, 1]
    poly4[:499, 0] = (1.0 - sv - tv) * (1.0 - sv - tv) + sv * sv
    poly4[:499, 1] = sv * sv + tv * tv
    ax4.plot(poly4[:499, 0], poly4[:499, 1], color="black", linestyle="dashed")
    # Combine this with the image b(0, t)
    tv = np.linspace(0.0, 1.0, 100)[1:]
    poly4[499:, 0] = (1.0 - tv) * (1.0 - tv)
    poly4[499:, 1] = tv * tv
    if slide_num == 6:
        patch = matplotlib.patches.PathPatch(matplotlib.path.Path(poly4),
                                             color="black",
                                             alpha=1.5 * ALPHA)
        ax4.add_patch(patch)

    for ax in (ax1, ax2, ax3, ax4):
        ax.set_aspect("equal")
    # One axis sets all axis
    ax1.set_xticklabels([])
    ax1.set_yticklabels([])

    if slide_num < 5:
        ax4.set_visible(False)
    if slide_num < 4:
        ax2.set_visible(False)

    figure.set_size_inches(3.2, 3.3)
    figure.subplots_adjust(left=0.01,
                           bottom=0.01,
                           right=0.99,
                           top=0.99,
                           wspace=0.04,
                           hspace=0.0)
    filename = "boundary_leak{}.pdf".format(slide_num)
    path = plot_utils.get_path("slides", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #24
0
def remesh():
    figure, (ax1, ax2, ax3) = plt.subplots(1, 3, sharex=True, sharey=True)

    # Update to 1-second ahead in time.
    xt, yt = point_on_characteristic(NODES_X, NODES_Y, 1.0)
    nodes = np.empty((len(NODES_X), 2))
    nodes[:, 0] = xt
    nodes[:, 1] = yt
    for ax in (ax1, ax2):
        ax.triplot(
            nodes[:, 0],
            nodes[:, 1],
            TRIANGLES,
            color=plot_utils.BLUE,
            linewidth=1.0,
        )

    # Do a Delaunay triangulation and discard exterior triangles.
    tessellation = scipy.spatial.qhull.Delaunay(nodes)
    polygon1 = shapely.geometry.Polygon(nodes[BOUNDARY_INDICES, :])
    to_keep = []
    for i, tri in enumerate(tessellation.simplices):
        polygon2 = shapely.geometry.Polygon(nodes[tri, :])
        intersection = polygon1.intersection(polygon2)
        int_area = intersection.area
        if int_area == polygon2.area:
            to_keep.append(i)
        elif int_area != 0:
            raise NotImplementedError

    triangles_new = tessellation.simplices[to_keep, :]
    for ax in (ax2, ax3):
        ax.triplot(
            nodes[:, 0],
            nodes[:, 1],
            triangles_new,
            color=plot_utils.GREEN,
            linewidth=1.0,
        )

    ax1.set_yticks([-0.5, 1.0, 2.5])
    for ax in (ax1, ax2, ax3):
        ax.axis("scaled")
        ax.set_xlim(-1.3, 3.6)
        ax.set_ylim(-0.75, 2.75)
        ax.set_xticks([-1.0, 1.0, 3.0])
        ax.set_xticklabels(["$-1.0$", "$1.0$", "$3.0$"])
        ax.xaxis.set_tick_params(labelsize=plot_utils.TICK_SIZE)
        ax.yaxis.set_tick_params(labelsize=plot_utils.TICK_SIZE)

    ax1.set_title("Before Remeshing", fontsize=plot_utils.TEXT_SIZE)
    ax3.set_title("After Remeshing", fontsize=plot_utils.TEXT_SIZE)

    figure.set_size_inches(6.0, 1.8)
    figure.subplots_adjust(left=0.06,
                           bottom=0.01,
                           right=0.99,
                           top=1.0,
                           wspace=0.04,
                           hspace=0.2)
    filename = "distortion_remesh.pdf"
    path = plot_utils.get_path("solution-transfer", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #25
0
def main():
    nodes = np.asfortranarray(
        [[1.0, 0.0, 1.0, 0.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0, 0.0, 1.0]]
    )
    bez_triangle = bezier.Surface(nodes, degree=2, _copy=False)
    # b(s, t) = [(1 - s - t)^2 + t^2, s^2 + t^2]
    figure, ((ax1, ax2, ax3), (ax4, ax5, ax6)) = plt.subplots(
        2, 3, sharex=True, sharey=True
    )
    for ax in (ax1, ax2, ax3):
        ax.plot([0, 1, 0, 0], [0, 0, 1, 0], color="black")

    # The "left" edge b(0, t) = [(1 - t)^2 + t^2, t^2] lies on the algebraic
    # curve 4x = (1 + x - y)^2. Plugging b(s, t) into this algebraic curve
    # we find interior points as well.
    sv = np.linspace(0.0, 2.0 / 5.0, 250)
    sqrt_part = np.sqrt((2.0 - 5.0 * sv) / (2.0 - sv))
    poly1 = np.empty((501, 2))
    poly1[:250, 0] = sv
    poly1[:250, 1] = 0.5 * (1.0 - sv + sqrt_part)
    poly1[250:499, 0] = sv[-2::-1]
    poly1[250:499, 1] = 0.5 * (1.0 - sv[-2::-1] - sqrt_part[-2::-1])
    poly1[499, :] = 1.0, 0.0
    poly1[500, :] = 0.0, 1.0
    patch = matplotlib.patches.PathPatch(
        matplotlib.path.Path(poly1), color=plot_utils.GREEN
    )
    ax1.add_patch(patch)
    for ax in (ax2, ax3):
        patch = matplotlib.patches.PathPatch(
            matplotlib.path.Path(poly1), color=plot_utils.GREEN, alpha=ALPHA
        )
        ax.add_patch(patch)

    for ax in (ax4, ax5, ax6):
        bez_triangle.plot(256, ax=ax, color=plot_utils.GREEN)
        for edge in bez_triangle.edges:
            edge.plot(256, ax=ax, color="black")
    ax4.patches[-1].set_alpha(1.0)
    ax5.patches[-1].set_alpha(ALPHA)
    ax6.patches[-1].set_alpha(ALPHA)

    # det(J) = 4[t^2 + (s - 1) t + (s - s^2)]
    sv = np.linspace(0.0, 1.0 / 5.0, 250)
    sqrt_part = np.sqrt((1.0 - sv) * (1.0 - 5.0 * sv))
    poly2 = np.empty((500, 2))
    poly2[:250, 0] = sv
    poly2[:250, 1] = 0.5 * (1.0 - sv - sqrt_part)
    poly2[250:499, 0] = sv[-2::-1]
    poly2[250:499, 1] = 0.5 * (1.0 - sv[-2::-1] + sqrt_part[-2::-1])
    poly2[499, :] = 0.0, 0.0
    for ax in (ax1, ax2, ax3):
        ax.plot(
            poly2[:499, 0], poly2[:499, 1], color="black", linestyle="dashed"
        )
    patch = matplotlib.patches.PathPatch(
        matplotlib.path.Path(poly2), color=plot_utils.RED
    )
    ax3.add_patch(patch)
    for ax in (ax1, ax2):
        patch = matplotlib.patches.PathPatch(
            matplotlib.path.Path(poly2), color="black", alpha=ALPHA
        )
        ax.add_patch(patch)

    # Shared slice in between two curves.
    poly3 = np.empty((997, 2))
    poly3[:499, :] = poly2[498::-1, :]
    poly3[499:, :] = poly1[497::-1, :]
    patch = matplotlib.patches.PathPatch(
        matplotlib.path.Path(poly3), color=plot_utils.BLUE
    )
    ax2.add_patch(patch)
    for ax in (ax1, ax3):
        patch = matplotlib.patches.PathPatch(
            matplotlib.path.Path(poly3), color="black", alpha=ALPHA
        )
        ax.add_patch(patch)

    # Now, compute the image of the det(J) = 0 curve under b(s, t).
    poly4 = np.empty((598, 2))
    sv = poly2[:499, 0][::-1]
    tv = poly2[:499, 1][::-1]
    poly4[:499, 0] = (1.0 - sv - tv) * (1.0 - sv - tv) + sv * sv
    poly4[:499, 1] = sv * sv + tv * tv
    for ax in (ax4, ax5, ax6):
        ax.plot(
            poly4[:499, 0], poly4[:499, 1], color="black", linestyle="dashed"
        )
    # Combine this with the image b(0, t)
    tv = np.linspace(0.0, 1.0, 100)[1:]
    poly4[499:, 0] = (1.0 - tv) * (1.0 - tv)
    poly4[499:, 1] = tv * tv
    patch = matplotlib.patches.PathPatch(
        matplotlib.path.Path(poly4), color="black", alpha=ALPHA
    )
    ax4.add_patch(patch)
    for ax, color in ((ax5, plot_utils.BLUE), (ax6, plot_utils.RED)):
        patch = matplotlib.patches.PathPatch(
            matplotlib.path.Path(poly4), color=color
        )
        ax.add_patch(patch)

    for ax in (ax1, ax2, ax3, ax4, ax5, ax6):
        ax.set_aspect("equal")
    # One axis sets all axis
    ax1.set_xticklabels([])
    ax1.set_yticklabels([])

    ax2.text(
        0.3,
        0.35,
        r"$+$",
        horizontalalignment="center",
        verticalalignment="center",
        fontsize=16,
        fontweight="bold",
        color="black",
    )
    ax2.add_patch(
        matplotlib.patches.Circle(
            (0.3, 0.35),
            radius=0.06,
            fill=False,
            edgecolor="black",
            linewidth=1.0,
        )
    )
    ax3.text(
        0.1,
        0.42,
        r"$-$",
        horizontalalignment="center",
        verticalalignment="center",
        fontsize=16,
        fontweight="bold",
        color="black",
    )
    ax3.add_patch(
        matplotlib.patches.Circle(
            (0.1, 0.422),
            radius=0.06,
            fill=False,
            edgecolor="black",
            linewidth=1.0,
        )
    )
    figure.set_size_inches(4.8, 3.3)
    figure.subplots_adjust(
        left=0.01, bottom=0.01, right=0.99, top=0.99, wspace=0.04, hspace=0.0
    )
    filename = "inverted_element.pdf"
    path = plot_utils.get_path("preliminaries", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #26
0
def bezier_triangle_area(slide_num):
    nodes = np.asfortranarray([
        [0.0, 0.5, 1.0, 0.125, 0.375, 0.25],
        [0.0, 0.0, 0.25, 0.5, 0.375, 1.0],
    ])
    surface = bezier.Surface.from_nodes(nodes)
    exact_area = F(37, 96)
    edge1, edge2, edge3 = surface.edges

    figure, all_axes = plt.subplots(2, 3)
    all_axes = all_axes.flatten()
    surface.plot(256, ax=all_axes[0])
    all_axes[0].set_title("Curved", fontsize=plot_utils.TEXT_SIZE)

    error_vals = []
    for n in range(1, 20 + 1):
        N = 2**n
        s_vals = np.linspace(0.0, 1.0, N + 1)[:-1]
        polygon_nodes = edges_to_polygon(edge1, edge2, edge3, s_vals)
        polygon = shapely.geometry.Polygon(polygon_nodes.T)
        # Compute the relative error.
        poly_area = F(polygon.area)
        rel_error = abs(poly_area - exact_area) / exact_area
        error_vals.append((N, float(rel_error)))

        if n in (1, 2, 3, 4):
            ax = all_axes[n]
            # Wrap-around the first node so the polygon is closed.
            polygon_nodes = np.hstack([polygon_nodes, polygon_nodes[:, :1]])
            patch = matplotlib.patches.PathPatch(matplotlib.path.Path(
                polygon_nodes.T),
                                                 alpha=0.625)
            ax.add_patch(patch)
            ax.plot(
                polygon_nodes[0, :],
                polygon_nodes[1, :],
                marker="o",
                markersize=4,
            )
            ax.set_title("$N = {:d}$".format(N), fontsize=plot_utils.TEXT_SIZE)

    for ax in all_axes[:5]:
        ax.axis("equal")
        ax.set_xlim(-0.05, 1.05)
        ax.set_ylim(-0.05, 1.05)
    for ax in all_axes[:3]:
        ax.set_xticklabels([])
    for ax in all_axes[(1, 2, 4), ]:
        ax.set_yticklabels([])

    error_vals = np.array(error_vals)
    ax = all_axes[5]
    line1, = ax.loglog(
        error_vals[:, 0],
        error_vals[:, 1],
        basex=2,
        color=plot_utils.BLUE,
        marker="o",
        markersize=4,
        label="Polygonal",
    )
    if slide_num < 5:
        line1.set_visible(False)
        ax.loglog(
            error_vals[:slide_num, 0],
            error_vals[:slide_num, 1],
            basex=2,
            color=plot_utils.BLUE,
            marker="o",
            markersize=4,
            label="Polygonal",
        )

    surface_area = F(compute_area(edge1, edge2, edge3))
    curved_rel_error = float(abs(exact_area - surface_area) / exact_area)
    line2, = ax.loglog(
        [error_vals[0, 0], error_vals[-1, 0]],
        [curved_rel_error, curved_rel_error],
        basex=2,
        color="black",
        linestyle="dashed",
        label="Curved",
    )
    if slide_num != 6:
        line2.set_visible(False)

    ax.set_title("Area Estimates", fontsize=plot_utils.TEXT_SIZE)
    ax.set_xlabel("Line Segments per Side ($N$)",
                  fontsize=plot_utils.TEXT_SIZE)
    ax.set_ylabel("Relative Error", fontsize=plot_utils.TEXT_SIZE)
    ax.yaxis.tick_right()
    ax.yaxis.set_label_position("right")

    all_axes[0].yaxis.set_tick_params(labelsize=plot_utils.TICK_SIZE)
    all_axes[3].yaxis.set_tick_params(labelsize=plot_utils.TICK_SIZE)
    all_axes[5].yaxis.set_tick_params(labelsize=plot_utils.TICK_SIZE)
    all_axes[3].xaxis.set_tick_params(labelsize=plot_utils.TICK_SIZE)
    all_axes[4].xaxis.set_tick_params(labelsize=plot_utils.TICK_SIZE)
    all_axes[5].xaxis.set_tick_params(labelsize=plot_utils.TICK_SIZE)

    all_axes[3].set_xticks([0.1, 0.5, 0.9])
    all_axes[4].set_xticks([0.1, 0.5, 0.9])
    all_axes[5].set_xticks([2.0**4, 2.0**8, 2.0**12, 2.0**16, 2.0**20])

    if slide_num < 6:
        all_axes[0].set_visible(False)
    if slide_num < 4:
        all_axes[4].set_visible(False)
    if slide_num < 3:
        all_axes[3].set_visible(False)
    if slide_num < 2:
        all_axes[2].set_visible(False)

    figure.set_size_inches(6.0, 4.2)
    figure.subplots_adjust(left=0.06,
                           bottom=0.11,
                           right=0.9,
                           top=0.95,
                           wspace=0.03,
                           hspace=0.15)
    filename = "polygon_vs_curved{}.pdf".format(slide_num)
    path = plot_utils.get_path("slides", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #27
0
def image2():
    expected_s = 0.5
    expected_t = 0.5
    s0 = 1.0 - 0.5**40
    t0 = 0.75 + 0.5**20

    iterates1 = newton_bezier.newton(s0, COEFFS1, t0, COEFFS2,
                                     newton_bezier.standard_residual)
    iterates2 = newton_bezier.newton(s0, COEFFS1, t0, COEFFS2,
                                     newton_bezier.compensated_residual)
    errors1 = []
    errors2 = []
    for iterates, errors in ((iterates1, errors1), (iterates2, errors2)):
        for n, (s_val, t_val) in enumerate(iterates):
            rel_error_s = F(s_val) / F(expected_s) - 1
            if rel_error_s <= 0:
                raise ValueError(s_val, rel_error_s)
            rel_error_t = F(t_val) / F(expected_t) - 1
            if rel_error_t <= 0:
                raise ValueError(t_val, rel_error_t)
            errors.append((n, float(rel_error_s), float(rel_error_t)))

    figure, (ax1, ax2) = plt.subplots(1, 2, sharex=True, sharey=True)
    min_x = -2.0
    max_x = 51.0
    errors1 = np.array(errors1)
    errors2 = np.array(errors2)
    for index, ax in ((1, ax1), (2, ax2)):
        ax.semilogy(
            errors1[:, 0],
            errors1[:, index],
            marker="o",
            linestyle="none",
            markersize=7,
            markeredgewidth=1,
            markerfacecolor="none",
            label="Standard",
        )
        ax.semilogy(
            errors2[:, 0],
            errors2[:, index],
            color="black",
            marker="o",
            linestyle="none",
            markersize=3,
            label="Compensated",
        )
        ax.semilogy(
            [min_x, max_x],
            [np.cbrt(U), np.cbrt(U)],
            linestyle="dashed",
            color="black",
        )
        ax.semilogy(
            [min_x, max_x],
            [np.cbrt(U * U), np.cbrt(U * U)],
            linestyle="dashed",
            color="black",
        )

        ax.set_yscale("log", basey=2)
        ax.set_xlabel("Iteration", fontsize=plot_utils.TEXT_SIZE)

    ax1.set_ylabel("Relative Error", fontsize=plot_utils.TEXT_SIZE)
    ax1.set_title("$s$", fontsize=plot_utils.TEXT_SIZE)
    ax1.set_xlim(min_x, max_x)
    ax2.set_title("$t$", fontsize=plot_utils.TEXT_SIZE)
    ax2.legend(loc="upper right", fontsize=plot_utils.TEXT_SIZE)

    ax2.set_yticks([np.cbrt(U), np.cbrt(U * U)], minor=True)
    ax2.set_yticklabels(
        [r"$\sqrt[3]{\mathbf{u}}$", r"$\sqrt[3]{\mathbf{u}^2}$"], minor=True)
    plt.setp(ax1.get_yticklabels(minor=True), visible=False)
    ax2.tick_params(
        axis="y",
        which="minor",
        direction="out",
        left=0,
        right=1,
        labelleft=0,
        labelright=1,
    )

    ax1.tick_params(labelsize=plot_utils.TICK_SIZE)
    ax2.tick_params(labelsize=plot_utils.TICK_SIZE)
    ax2.tick_params(labelsize=plot_utils.TEXT_SIZE, which="minor")

    figure.set_size_inches(6.4, 2.6)
    figure.subplots_adjust(left=0.09,
                           bottom=0.16,
                           right=0.93,
                           top=0.9,
                           wspace=0.04,
                           hspace=0.2)
    filename = "newton_linear_converge.pdf"
    path = plot_utils.get_path("compensated-newton", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)
예제 #28
0
def main(filename=None):
    cond_nums = []
    rel_errors_basic = []
    rel_errors_accurate = []
    rel_errors_full = []
    bounds_vals1 = []
    bounds_vals2 = []
    for n in range(2, 55 + 1):
        cond, rel_error1, rel_error2, rel_error3 = root_info(n)
        cond_nums.append(cond)
        rel_errors_basic.append(rel_error1)
        rel_errors_accurate.append(rel_error2)
        rel_errors_full.append(rel_error3)
        gamma2n = (2 * n * U) / (1 - 2 * n * U)
        bounds_vals1.append(float(10 * gamma2n * cond))
        bounds_vals2.append(float(6 * gamma2n**2 * cond))

    figure = plt.figure()
    ax = figure.gca()
    ax.loglog(
        cond_nums,
        rel_errors_basic,
        marker="d",
        linestyle="none",
        markersize=7,
        color=plot_utils.BLUE,
        zorder=2,
        label=r"$\mathtt{HNewtonBasic}$",
    )
    ax.loglog(
        cond_nums,
        rel_errors_accurate,
        marker="o",
        linestyle="none",
        markersize=3,
        color="black",
        zorder=2,
        label=r"$\mathtt{HNewtonAccurate}$",
    )
    # H/T: (http://widu.tumblr.com/post/43624348228/
    #       making-unfilled-hollow-markers-in-matplotlib)
    ax.loglog(
        cond_nums,
        rel_errors_full,
        marker="o",
        linestyle="none",
        markersize=6,
        markeredgewidth=1,
        markerfacecolor="none",
        color=plot_utils.GREEN,
        zorder=2,
        label=r"$\mathtt{HNewtonFull}$",
    )
    # Add the error lines.
    ax.loglog(
        cond_nums,
        bounds_vals1,
        color="black",
        linestyle="dashed",
        alpha=ALPHA,
        zorder=1,
    )
    ax.loglog(
        cond_nums,
        bounds_vals2,
        color="black",
        linestyle="dashed",
        alpha=ALPHA,
        zorder=1,
    )
    # Add the ``x = 1/u^k`` vertical lines.
    min_x, max_x = 1e4, 1e33
    min_y, max_y = 1e-19, 1e2
    delta_y = max_y - min_y
    for exponent in (1, 2):
        u_inv = 1.0 / float(U)**exponent
        ax.loglog(
            [u_inv, u_inv],
            [min_y - 0.05 * delta_y, max_y + 0.05 * delta_y],
            color="black",
            linestyle="dashed",
            alpha=ALPHA,
            zorder=1,
        )
    # Add the ``y = 1`` and ``y = u`` horizontal lines.
    for exponent in (0, 1):
        u_pow = float(U)**exponent
        ax.loglog(
            [min_x, max_x],
            [u_pow, u_pow],
            color="black",
            linestyle="dashed",
            alpha=ALPHA,
            zorder=1,
        )
    # Set the axis limits.
    ax.set_xlim(min_x, max_x)
    ax.set_ylim(min_y, max_y)
    # Set the major x- and y-ticks.
    ax.set_xticks([1e5, 1e10, 1e15, 1e20, 1e25, 1e30])
    ax.set_yticks(
        [1e-18, 1e-16, 1e-14, 1e-12, 1e-10, 1e-8, 1e-6, 1e-4, 1e-2, 1])
    # Set special ``xticks`` for ``1/u`` and ``1/u^2``.
    u_xticks = [1.0 / float(U), 1.0 / float(U)**2]
    u_xticklabels = [r"$1/\mathbf{u}$", r"$1/\mathbf{u}^2$"]
    ax.set_xticks(u_xticks, minor=True)
    ax.set_xticklabels(u_xticklabels, minor=True)
    ax.tick_params(
        axis="x",
        which="minor",
        direction="out",
        top=1,
        bottom=0,
        labelbottom=0,
        labeltop=1,
    )
    # Set special ``yticks`` for ``u`` and ``1``.
    ax.set_yticks([float(U), 1.0], minor=True)
    ax.set_yticklabels([r"$\mathbf{u}$", "$1$"], minor=True)
    ax.tick_params(
        axis="y",
        which="minor",
        direction="out",
        left=0,
        right=1,
        labelleft=0,
        labelright=1,
    )
    # Label the axes.
    ax.set_xlabel("Condition Number", fontsize=plot_utils.TEXT_SIZE)
    ax.set_ylabel("Relative Forward Error", fontsize=plot_utils.TEXT_SIZE)
    # Add the legend.
    ax.legend(
        loc="lower right",
        framealpha=1.0,
        frameon=True,
        fontsize=plot_utils.TEXT_SIZE,
    )

    ax.tick_params(labelsize=plot_utils.TICK_SIZE)
    ax.tick_params(labelsize=plot_utils.TEXT_SIZE, which="minor")

    figure.set_size_inches(5.4, 4.0)
    figure.subplots_adjust(left=0.12,
                           bottom=0.11,
                           right=0.95,
                           top=0.92,
                           wspace=0.2,
                           hspace=0.2)
    filename = "newton_jghplus13.pdf"
    path = plot_utils.get_path("compensated-newton", filename)
    figure.savefig(path)
    print("Saved {}".format(filename))
    plt.close(figure)