예제 #1
0
def plot(n, *args, **kwargs):
    import dufte
    from matplotlib import pyplot as plt

    plt.style.use(dufte.style)

    x = numpy.linspace(-1.0, 1.0, 100)
    evaluator = Eval(x, *args, **kwargs)
    for k in range(n + 1):
        plt.plot(x, next(evaluator), label=f"n={k}")

    plt.grid(axis="x")
    dufte.legend()
    ax = plt.gca()

    alpha, beta, scaling = args
    if alpha == beta:
        if alpha == 0:
            plt.title(f"Legendre polynomials (scaling={scaling})")
        elif alpha == -0.5:
            plt.title(f"Chebyshev 1 polynomials (scaling={scaling})")
        elif alpha == +0.5:
            plt.title(f"Chebyshev 2 polynomials (scaling={scaling})")
        else:
            plt.title(f"Gegenbauer polynomials (λ={alpha}, scaling={scaling})")
    else:
        plt.title(
            f"Jacobi polynomials (α={alpha}, β={beta}, scaling={scaling})")
    ax.spines["right"].set_visible(True)
    ax.spines["left"].set_visible(True)
예제 #2
0
def plot(n, *args, **kwargs):
    import dufte
    from matplotlib import pyplot as plt

    plt.style.use(dufte.style)

    x = numpy.linspace(-1.0, 1.0, 200)
    for k, level in enumerate(itertools.islice(Eval(x, *args, **kwargs), n + 1)):
        # Choose all colors in each level approximately equal, around the reference
        # color.
        ref_color = plt.rcParams["axes.prop_cycle"].by_key()["color"][k]
        ref_rgb = numpy.array(
            list(int(ref_color[1:][i : i + 2], 16) / 255 for i in (0, 2, 4))
        )
        for l, entry in enumerate(level):
            col = ref_rgb * (1 + (l - k) / (2 * (k + 1)))
            col[col < 0.0] = 0.0
            col[col > 1.0] = 1.0
            plt.plot(x, entry, label=f"n={k}, r={l - k}", color=col)

    plt.grid(axis="x")
    dufte.legend()
    ax = plt.gca()
    ax.spines["top"].set_visible(False)
    ax.spines["bottom"].set_visible(False)

    (scaling,) = args
    plt.title(f'Associated Legendre "polynomials" (scaling={scaling})')
    ax.spines["right"].set_visible(True)
    ax.spines["left"].set_visible(True)
    plt.xlim(-1.0, 1.0)
예제 #3
0
def test_accuracy_comparison_illcond(filename=None, target_conds=None):
    plt.style.use(dufte.style)

    if target_conds is None:
        target_conds = [10 ** k for k in range(1, 2)]

    kernels = [
        sum,
        numpy.sum,
        accupy.kahan_sum,
        lambda p: accupy.ksum(p, K=2),
        lambda p: accupy.ksum(p, K=3),
        accupy.fsum,
    ]
    labels = [
        "sum",
        "numpy.sum",
        "accupy.kahan_sum",
        "accupy.ksum[2]",
        "accupy.ksum[3]",
        "accupy.fsum",
    ]
    colors = plt.rcParams["axes.prop_cycle"].by_key()["color"][: len(labels)]

    data = numpy.empty((len(target_conds), len(kernels)))
    condition_numbers = numpy.empty(len(target_conds))
    numpy.random.seed(0)
    for k, target_cond in enumerate(target_conds):
        p, ref, C = accupy.generate_ill_conditioned_sum(1000, target_cond)
        condition_numbers[k] = C
        data[k] = [abs(kernel(p) - ref) / abs(ref) for kernel in kernels]

    # sort
    s = numpy.argsort(condition_numbers)
    condition_numbers = condition_numbers[s]
    data = data[s]

    for label, color, d in zip(labels, colors, data.T):
        plt.loglog(condition_numbers, d, label=label, color=color)

    dufte.legend()
    plt.xlabel("condition number")
    plt.ylabel("relative error")
    # plt.gca().set_aspect(1.3)

    # plt.show()
    # <https://stackoverflow.com/a/10154763/353337>
    if filename:
        plt.savefig(filename, transparent=True, bbox_inches="tight")
예제 #4
0
def plot(n, *args, **kwargs):
    import dufte
    from matplotlib import pyplot as plt

    plt.style.use(dufte.style)

    x = numpy.linspace(-2.2, 2.2, 100)
    for k, level in enumerate(itertools.islice(Eval(x, *args, **kwargs), n + 1)):
        plt.plot(x, level, label=f"n={k}")

    plt.grid(axis="x")
    dufte.legend()

    variant, scaling = args
    plt.title(f"Hermite polynomials ({variant}, scaling={scaling})")
예제 #5
0
파일: tools.py 프로젝트: aantti/stargraph
def plot(filenames, sort=True, cut=None, max_num=20):
    # read data
    data = []
    for filename in filenames:
        with open(filename) as f:
            data.append(json.load(f))

    if sort:
        # sort them such that the largest at the last time step gets plotted first and
        # the colors are in a nice order
        last_vals = [list(content["data"].values())[-1] for content in data]
        data = [data[i] for i in _argsort(last_vals)[::-1]]

    if cut is not None:
        # cut those files where the max data is less than cut*max_overall
        max_vals = [max(list(content["data"].values())) for content in data]
        max_overall = max(max_vals)
        data = [
            content for content, max_val in zip(data, max_vals)
            if max_val > cut * max_overall
        ]

    if max_num is not None:
        # show only max_num repos
        data = data[:max_num]

    n = len(data)
    for k, content in enumerate(data):
        data = content["data"]
        data = {
            datetime.fromisoformat(key): value
            for key, value in data.items()
        }

        times = list(data.keys())
        values = list(data.values())
        label = content["name"]

        plt.plot(times, values, label=label, zorder=n - k)

    dufte.legend()

    if "creator" in content:
        _add_license_statement(content)
예제 #6
0
def test_accuracy_comparison_illcond(filename=None, target_cond=None):
    plt.style.use(dufte.style)

    if target_cond is None:
        target_cond = [10**k for k in range(2)]

    kernels = [
        numpy.dot,
        lambda x, y: accupy.kdot(x, y, K=2),
        lambda x, y: accupy.kdot(x, y, K=3),
        accupy.fdot,
    ]
    labels = ["numpy.dot", "accupy.kdot[2]", "accupy.kdot[3]", "accupy.fdot"]
    data = numpy.empty((len(target_cond), len(kernels)))
    condition_numbers = numpy.empty(len(target_cond))
    numpy.random.seed(0)
    for k, tc in enumerate(target_cond):
        x, y, ref, C = accupy.generate_ill_conditioned_dot_product(1000, tc)
        condition_numbers[k] = C
        data[k] = [abs(kernel(x, y) - ref) / abs(ref) for kernel in kernels]

    # sort
    s = numpy.argsort(condition_numbers)
    condition_numbers = condition_numbers[s]
    data = data[s]

    for label, d in zip(labels, data.T):
        plt.loglog(condition_numbers, d, label=label)

    dufte.legend()
    plt.xlabel("condition number")
    plt.ylabel("relative error")

    # plt.show()
    # <https://stackoverflow.com/a/10154763/353337>
    if filename:
        plt.savefig(filename, transparent=True, bbox_inches="tight")
예제 #7
0
def test_comparison():
    plt.style.use(dufte.style)

    X, cells = circle_random(40, 1.0)

    # Do a few steps of a robust method to avoid too crazy meshes.
    tol = 0.0
    n = 10
    # X, cells = optimesh.cpt.fixed_point_uniform(X, cells, tol, n)
    # X, cells = optimesh.odt.fixed_point_uniform(X, cells, tol, n)
    X, cells = optimesh.optimize_points_cells(X,
                                              cells,
                                              "lloyd",
                                              tol,
                                              n,
                                              omega=2.0)

    # from meshplex import MeshTri
    # mesh = MeshTri(X, cells)
    # mesh.write("out.vtk")
    # exit(1)

    num_steps = 50
    names = [
        "cpt-fixed-point",
        "cpt-quasi-newton",
        #
        "lloyd",
        "lloyd(2.0)",
        "cvt-block-diagonal",
        "cvt-full",
        #
        "odt-fixed-point",
        "odt-bfgs",
    ]

    avg_quality = np.empty((len(names), num_steps + 1))

    for i, name in enumerate(names):

        def callback(k, mesh):
            avg_quality[i, k] = np.average(mesh.q_radius_ratio)
            return

        X_in = X.copy()
        cells_in = cells.copy()

        if name == "lloyd(2.0)":
            optimesh.optimize_points_cells(X_in,
                                           cells_in,
                                           "lloyd",
                                           0.0,
                                           num_steps,
                                           omega=2.0,
                                           callback=callback)
        else:
            optimesh.optimize_points_cells(X_in,
                                           cells_in,
                                           name,
                                           0.0,
                                           num_steps,
                                           callback=callback)

    # sort by best final quality
    idx = np.argsort(avg_quality[:, -1])[::-1]

    sorted_labels = [names[i] for i in idx]

    for i, label, values in zip(idx, sorted_labels, avg_quality[idx]):
        plt.plot(values, "-", label=label, zorder=i)

    plt.xlim(0, num_steps)
    plt.ylim(0.93, 1.0)
    plt.xlabel("step")
    plt.title("average cell quality")
    dufte.legend()

    plt.savefig("comparison.svg", transparent=True, bbox_inches="tight")
예제 #8
0
파일: tools.py 프로젝트: aantti/stargraph
def plot_per_day(filenames, sort=True, cut=None):
    if sort:
        # sort them such that the largest at the last time step gets plotted first and
        # the colors are in a nice order
        last_vals = []
        for filename in filenames:
            with open(filename) as f:
                content = json.load(f)
            vals = list(content["data"].values())
            last_vals.append(vals[-1] - vals[-2])

        filenames = [filenames[i] for i in _argsort(last_vals)[::-1]]

    if cut is not None:
        # cut those files where the max data is less than cut*max_overall
        max_vals = []
        for filename in filenames:
            with open(filename) as f:
                content = json.load(f)
            vals = list(content["data"].values())
            vals = [vals[k + 1] - vals[k] for k in range(len(vals) - 1)]
            max_vals.append(max(vals))

        max_overall = max(max_vals)
        filenames = [
            filename for filename, max_val in zip(filenames, max_vals)
            if max_val > cut * max_overall
        ]

    times = []
    values = []
    labels = []
    for filename in filenames:
        filename = pathlib.Path(filename)
        assert filename.is_file(), f"{filename} not found."

        with open(filename) as f:
            content = json.load(f)

        data = content["data"]
        data = {
            datetime.fromisoformat(key): value
            for key, value in data.items()
        }

        t = list(data.keys())
        v = list(data.values())
        times.append(_get_middle_times(t))
        values.append(_get_avg_per_day(t, v))
        labels.append(content["name"])

    # start plotting from the 0 before the first value
    for j, (tm, val) in enumerate(zip(times, values)):
        for i, x in enumerate(val):
            if x > 0:
                k = max(i - 1, 0)
                break
        times[j] = tm[k:]
        values[j] = val[k:]

    n = len(times)
    for k, (time, vals, label) in enumerate(zip(times, values, labels)):
        plt.plot(time, vals, label=label, zorder=n - k)

    dufte.legend()

    if "creator" in content:
        _add_license_statement(content)
예제 #9
0
    def plot(  # noqa: C901
        self,
        time_unit: str = "s",
        relative_to: Optional[int] = None,
        logx: Union[str, bool] = "auto",
        logy: Union[str, bool] = "auto",
    ):
        if logx == "auto":
            # Check if the x values are approximately equally spaced in log
            if np.any(self.n_range <= 0):
                logx = False
            else:
                log_n_range = np.log(self.n_range)
                diff = log_n_range - np.linspace(
                    log_n_range[0], log_n_range[-1], len(log_n_range)
                )
                logx = np.all(np.abs(diff) < 1.0e-5)

        if logy == "auto":
            if relative_to is not None:
                logy = False
            elif self.flop is not None:
                logy = False
            else:
                logy = logx

        if logx and logy:
            plotfun = plt.loglog
        elif logx:
            plotfun = plt.semilogx
        elif logy:
            plotfun = plt.semilogy
        else:
            plotfun = plt.plot

        if self.flop is None:
            if relative_to is None:
                # Set time unit of plots.
                # Allowed values: ("s", "ms", "us", "ns", "auto")
                if time_unit == "auto":
                    time_unit = _auto_time_unit(np.min(self.timings_s))
                else:
                    assert time_unit in si_time, "Provided `time_unit` is not valid"

                scaled_timings = self.timings_s / si_time[time_unit]
                ylabel = f"Runtime [{time_unit}]"
            else:
                scaled_timings = self.timings_s / self.timings_s[relative_to]
                ylabel = f"Runtime\nrelative to {self.labels[relative_to]}"

            # plt.title(ylabel)
            ylabel = plt.ylabel(ylabel, ha="center", ma="left")
            plt.gca().yaxis.set_label_coords(-0.1, 1.0)
            ylabel.set_rotation(0)

            for t, label in zip(scaled_timings, self.labels):
                plotfun(self.n_range, t, label=label)
        else:
            if relative_to is None:
                flops = self.flop / self.timings_s
                plt.title("FLOPS")
            else:
                flops = self.timings_s[relative_to] / self.timings_s
                plt.title(f"FLOPS relative to {self.labels[relative_to]}")

            for fl, label in zip(flops, self.labels):
                plotfun(self.n_range, fl, label=label)

        if self.xlabel:
            plt.xlabel(self.xlabel)
        if relative_to is not None and not logy:
            plt.gca().set_ylim(bottom=0)

        dufte.legend()
예제 #10
0
    def plot(  # noqa: C901
        self,
        time_unit="s",
        relative_to=None,
        logx="auto",
        logy="auto",
        style='dufte',
    ):
        if logx == "auto":
            # Check if the x values are approximately equally spaced in log
            log_n_range = numpy.log(self.n_range)
            diff = log_n_range - numpy.linspace(
                log_n_range[0], log_n_range[-1], len(log_n_range))
            logx = numpy.all(numpy.abs(diff) < 1.0e-5)

        if logy == "auto":
            if relative_to is not None:
                logy = False
            elif self.flop is not None:
                logy = False
            else:
                logy = logx

        if logx and logy:
            plotfun = plt.loglog
        elif logx:
            plotfun = plt.semilogx
        elif logy:
            plotfun = plt.semilogy
        else:
            plotfun = plt.plot

        if self.flop is None:
            if relative_to is None:
                # Set time unit of plots.
                # Allowed values: ("s", "ms", "us", "ns", "auto")
                if time_unit == "auto":
                    time_unit = _auto_time_unit(numpy.min(self.timings))
                else:
                    assert time_unit in si_time, "Provided `time_unit` is not valid"

                scaled_timings = self.timings * (si_time["ns"] /
                                                 si_time[time_unit])
                plt.title(f"Runtime [{time_unit}]")
            else:
                scaled_timings = self.timings / self.timings[relative_to]
                plt.title(f"Runtime relative to {self.labels[relative_to]}()")

            for t, label in zip(scaled_timings, self.labels):
                plotfun(self.n_range, t, label=label)
        else:
            if relative_to is None:
                flops = self.flop / self.timings / si_time["ns"]
                plt.title("FLOPS")
            else:
                flops = self.timings[relative_to] / self.timings
                plt.title(f"FLOPS relative to {self.labels[relative_to]}")

            for fl, label in zip(flops, self.labels):
                plotfun(self.n_range, fl, label=label)

        if self.xlabel:
            plt.xlabel(self.xlabel)
        if relative_to is not None and not logy:
            plt.gca().set_ylim(bottom=0)

        dufte.legend()
예제 #11
0
def create_plots(prefix, functions, H, time_limit=60):
    times = []
    quality_min = []
    quality_avg = []
    num_poisson_steps = []
    num_points = []

    poisson_tol = 1.0e-10
    with Progress() as progress:
        task1 = progress.add_task("Overall", total=len(H))
        task2 = progress.add_task("Functions", total=len(functions))
        for h in H:
            times.append([])
            quality_min.append([])
            quality_avg.append([])
            num_poisson_steps.append([])
            num_points.append([])
            progress.update(task2, completed=0)
            for fun in functions:
                try:
                    with time_limiter(time_limit):
                        tic = time.time()
                        points, cells = fun(h)
                        toc = time.time()
                except TimeoutException:
                    times[-1].append(numpy.nan)
                    quality_min[-1].append(numpy.nan)
                    quality_avg[-1].append(numpy.nan)
                    num_points[-1].append(numpy.nan)
                    num_poisson_steps[-1].append(numpy.nan)
                else:
                    if cells.shape[1] == 3:
                        mesh = meshplex.MeshTri(points, cells)
                    else:
                        assert cells.shape[1] == 4
                        mesh = meshplex.MeshTetra(points, cells)

                    times[-1].append(toc - tic)
                    quality_min[-1].append(numpy.min(mesh.q_radius_ratio))
                    quality_avg[-1].append(numpy.average(mesh.q_radius_ratio))
                    num_points[-1].append(mesh.node_coords.shape[0])

                    if numpy.min(mesh.q_radius_ratio) < 1.0e-5:
                        num_poisson_steps[-1].append(numpy.nan)
                    else:
                        num_steps = get_poisson_steps(points, cells, poisson_tol)
                        num_poisson_steps[-1].append(num_steps)

                progress.update(task2, advance=1)
            progress.update(task1, advance=1)

    times = numpy.array(times)
    quality_min = numpy.array(quality_min)
    quality_avg = numpy.array(quality_avg)
    num_poisson_steps = numpy.array(num_poisson_steps)
    num_points = numpy.array(num_points)

    names = [inspect.getmodule(fun).desc for fun in functions]
    colors = [inspect.getmodule(fun).colors for fun in functions]

    # plot the data
    plt.style.use(dufte.style)
    for name, num_pts, t, cols in zip(names, num_points.T, times.T, colors):
        plt.loglog(num_pts, t, color=cols[0], label=name)
    dufte.legend()
    plt.xlabel("num points")
    plt.title("mesh creation times [s]")
    plt.savefig(f"{prefix}-times.svg", transparent=True, bbox_inches="tight")
    # plt.show()
    plt.close()

    for name, num_pts, qa, qm, cols in zip(
        names, num_points.T, quality_avg.T, quality_min.T, colors
    ):
        plt.semilogx(num_pts, qa, color=cols[0], linestyle="-", label=f"{name}")
        plt.semilogx(num_pts, qm, color=cols[1], linestyle="--", label="")
        plt.ylim(0.0, 1.0)
    dufte.legend()
    plt.xlabel("num points")
    plt.title("cell quality, avg  and min (dashed)")
    plt.savefig(f"{prefix}-quality.svg", transparent=True, bbox_inches="tight")
    # plt.show()
    plt.close()

    for name, num_pts, np, cols in zip(
        names, num_points.T, num_poisson_steps.T, colors
    ):
        plt.semilogx(num_pts, np, color=cols[0], label=f"{name}")
    dufte.legend()
    plt.xlabel("num points")
    plt.title(f"number of CG steps for the Poisson problem (tol={poisson_tol:.1e})")
    plt.savefig(f"{prefix}-poisson.svg", transparent=True, bbox_inches="tight")
    # plt.show()
    plt.close()
예제 #12
0
def create_plots(domain):
    # plot the data
    plt.style.use(dufte.style)

    # num nodes vs. time
    for module in modules:
        name = module.packages[0][0]
        json_filename = name.lower() + ".json"
        with open(json_filename) as f:
            data = json.load(f)

        label = ", ".join(" ".join(package) for package in module.packages)
        if domain in data["data"]:
            x = numpy.array(data["data"][domain]["num_nodes"])
            y = numpy.array(data["data"][domain]["time"])
            idx = numpy.argsort(x)
            plt.loglog(x[idx], y[idx], color=module.colors[0], label=label)

    dufte.legend()
    plt.xlabel("num points")
    plt.title("mesh creation times [s]")
    plt.savefig(f"{domain}-times.svg", transparent=True, bbox_inches="tight")
    # plt.show()
    plt.close()

    # num nodes vs. cell quality
    for module in modules:
        name = module.packages[0][0]
        json_filename = name.lower() + ".json"
        with open(json_filename) as f:
            data = json.load(f)
        label = ", ".join(" ".join(package) for package in module.packages)
        if domain in data["data"]:
            x = numpy.array(data["data"][domain]["num_nodes"])
            y0 = numpy.array(data["data"][domain]["quality_avg"])
            y1 = numpy.array(data["data"][domain]["quality_min"])
            idx = numpy.argsort(x)
            plt.semilogx(
                x[idx], y0[idx], linestyle="-", color=module.colors[0], label=label
            )
            plt.semilogx(x[idx], y1[idx], linestyle="--", color=module.colors[1])
    dufte.legend()
    plt.xlabel("num points")
    plt.title("cell quality, avg  and min (dashed)")
    plt.ylim(0.0, 1.0)
    plt.savefig(f"{domain}-quality.svg", transparent=True, bbox_inches="tight")
    # plt.show()
    plt.close()

    # num nodes vs. energy
    for module in modules:
        name = module.packages[0][0]
        json_filename = name.lower() + ".json"
        with open(json_filename) as f:
            data = json.load(f)
        label = ", ".join(" ".join(package) for package in module.packages)
        if domain in data["data"]:
            x = numpy.array(data["data"][domain]["num_nodes"])
            idx = numpy.argsort(x)
            try:
                y = numpy.array(data["data"][domain]["energy"])
            except KeyError:
                pass
            else:
                plt.loglog(
                    x[idx], y[idx], linestyle="-", color=module.colors[0], label=label
                )
    dufte.legend()
    plt.xlabel("num points")
    plt.title("energy (lower is better)")
    plt.savefig(f"{domain}-energy.svg", transparent=True, bbox_inches="tight")
    # plt.show()
    plt.close()

    # num nodes vs. CG iterations for Poisson
    for module in modules:
        name = module.packages[0][0]
        json_filename = name.lower() + ".json"
        with open(json_filename) as f:
            data = json.load(f)
        label = ", ".join(" ".join(package) for package in module.packages)
        if domain in data["data"]:
            x = numpy.array(data["data"][domain]["num_nodes"])
            y = numpy.array(data["data"][domain]["num_poisson_steps"])
            idx = numpy.argsort(x)
            plt.semilogx(x[idx], y[idx], color=module.colors[0], label=label)
    dufte.legend()
    plt.xlabel("num points")
    poisson_tol = 1.0e-10
    plt.title(f"number of CG steps for the Poisson problem (tol={poisson_tol:.1e})")
    plt.ylim(0.0)
    plt.savefig(f"{domain}-poisson.svg", transparent=True, bbox_inches="tight")
    # plt.show()
    plt.close()
예제 #13
0
def plot(argv=None):
    import dufte
    import matplotlib.pyplot as plt

    plt.style.use(dufte.style)

    parser = _get_parser_plot()
    args = parser.parse_args(argv)

    data = [yaml.load(f, Loader=yaml.SafeLoader) for f in args.infiles]

    # actually plot it
    fig = plt.figure()
    ax1 = fig.add_subplot(1, 1, 1)
    for d in data:
        temperature_data = d["temperature"]
        if args.delta_t:
            temperature_data = []
            zip_object = zip(d["temperature"], d["ambient"])
            for d["temperature"], d["ambient"] in zip_object:
                temperature_data.append(d["temperature"] - d["ambient"])

        plt.plot(d["time"], temperature_data, label=d["name"])

    dufte.legend()

    if args.delta_t:
        plot_yaxis_label = "Δ temperature [°C over ambient]"
    else:
        plot_yaxis_label = "temperature [°C]"
    plt.xlabel("time [s]")
    plt.ylabel(plot_yaxis_label)

    if args.temp_lims:
        ax1.set_ylim(*args.temp_lims)

    # Only plot frequencies when using a single input file
    if len(data) == 1 and args.frequency:
        ax2 = plt.twinx()
        ax2.set_ylabel("core frequency (MHz)")
        if args.freq_lims:
            ax2.set_ylim(*args.freq_lims)
        try:
            for d in data:
                ax2.plot(
                    d["time"],
                    d["cpu frequency"],
                    label=d["name"],
                    color="C1",
                    alpha=0.9,
                )
            ax1.set_zorder(ax2.get_zorder() + 1)  # put ax1 plot in front of ax2
            ax1.patch.set_visible(False)  # hide the 'canvas'
        except KeyError():
            print("Source data does not contain CPU frequency data.")

    if args.outfile is not None:
        plt.savefig(
            args.outfile,
            transparent=args.transparent,
            bbox_inches="tight",
            dpi=args.dpi,
        )
    else:
        plt.show()
    return