Ejemplo n.º 1
0
def errors_test(lines_it, func_tests):
    func_name = next(lines_it)
    func = func_tests[func_name]

    nodes_x = np.fromiter(to_nums(next(lines_it)), dtype=float)
    nodes_y = func(nodes_x)

    i = int(next(lines_it))
    errors = (*to_nums(next(lines_it)), )

    y = nodes_y[i]

    S = si.get_spline(nodes_x, *si.calc_spline_data(nodes_x, nodes_y))
    func_list = [func, vectorize(S)]

    for err in errors:
        nodes_y[i] = y + err
        S = si.get_spline(nodes_x, *si.calc_spline_data(nodes_x, nodes_y))
        func_list.append(vectorize(S))

    title = f'f(x)={func_name},  узлы: {nodes_x}, ошибка в: {nodes_x[i]}'
    labels = (func_name, 'error: 0', *(f'error: {err}' for err in errors))
    image_name = get_plot_filename('errors', func_name, nodes_x)
    plot(*func_list,
         labels=labels,
         title=title,
         x_min=nodes_x[0],
         x_max=nodes_x[-1],
         need_show=False,
         img_name=image_name)
def test():
    import computational_math.Lagrange_polynomial_interpolation as cmLi

    err = 10**-5
    table_size = 1001

    # генерация таблицы
    x_values, y_values = gen_heart_table(table_size)
    t_nodes = gen_nodes_t_by_index(x_values, y_values)

    # создание сплайнов
    abcd_y_data = calc_spline_data(t_nodes, y_values)
    abcd_x_data = calc_spline_data(t_nodes, x_values)
    _, *bcd_dx_data = abcd_x_data

    y_func = get_spline(t_nodes, *abcd_y_data)
    dx_func = get_spline_derivative(t_nodes, *bcd_dx_data)

    # интегрирование формулой Симпсона
    integrand_func = vectorize(lambda t: y_func(t) * dx_func(t))
    simpson_sqr, *_ = autostep_integrate(integrand_func, t_nodes[0], t_nodes[-1], err)
    simpson_sqr = abs(simpson_sqr)

    # отображение графика

    t_vec = np.linspace(t_nodes[0], t_nodes[-1], int((t_nodes[-1]-t_nodes[0])/0.01) + 1)
    ft_vec = integrand_func(t_vec)

    # Лагранж
    def foo(a, b):
        t_nodes = np.linspace(a, b, 3)
        ft_values = integrand_func(t_nodes)

        Ln = cmLi.get_Lagrange_polynomial(t_nodes, ft_values)
        Ln = vectorize(Ln)

        t = np.linspace(a, b, int(100*(a+b)/2) + 1)
        return t, Ln(t)

    for p in range(7):
        _, ax = plt.subplots()
        ax.plot(t_vec, ft_vec, linewidth=3)

        t = np.linspace(t_nodes[0], t_nodes[-1], 2*(2**p)+1)
        for a, b in zip(t[:-1], t[1:]):
            ax.plot(*foo(a, b), linewidth=2)

        plt.show()
Ejemplo n.º 3
0
def generate_spline_list(nodes, values):
    spline_list = []

    i = 0
    while len(nodes) > 1:
        less = max_ordered(nodes, np.less)
        greater = max_ordered(nodes, np.greater)

        if less >= greater:
            sub_nodes, sub_values = nodes[:less + 1], values[:less + 1]
        else:
            sub_nodes, sub_values = nodes[greater::-1], values[greater::-1]

        assert len(sub_nodes) > 1 and sub_nodes[0] < sub_nodes[1]

        i = max(less, greater)
        values, nodes = values[i:], nodes[i:]

        if not (len(sub_nodes) == 2
                and abs(sub_nodes[0] - sub_nodes[-1]) <= 0):
            spline_data = cmsi.calc_spline_data(sub_nodes, sub_values)

            # добавляется (<первый узел>, <коэффициенты сплайна>)
            spline_list.append(
                (*sub_nodes[[0, -1]], (sub_nodes, *spline_data)))

    return spline_list
Ejemplo n.º 4
0
def standard_test(lines_it, func_tests):
    func_name = next(lines_it)
    func = func_tests[func_name]

    nodes_x = np.fromiter(to_nums(next(lines_it)), float)
    nodes_y = func(nodes_x)

    assert np.array_equal(np.array(sorted(set(nodes_x))),
                          nodes_x), 'nodes must be ordered without repetitions'

    L_n = Lpi.get_Lagrange_polynomial(nodes_x, nodes_y)
    S = si.get_spline(nodes_x, *si.calc_spline_data(nodes_x, nodes_y))
    L_n, S = vectorize(L_n), vectorize(S)

    title = f'f(x)={func_name},  узлы: {nodes_x}'

    labels = (func_name, 'Lagrange', 'spline')
    image_name = get_plot_filename('standard', func_name, nodes_x)
    plot(func,
         L_n,
         S,
         labels=labels,
         title=title,
         x_min=nodes_x[0],
         x_max=nodes_x[-1],
         need_show=False,
         img_name=image_name)
Ejemplo n.º 5
0
def test_parametric_func(list_len):
    # heart
    heart_name = 'heart'

    def heart_x(t):
        return 16 * (np.sin(t)**3)

    def heart_y(t):
        return 13 * np.cos(t) - 5 * np.cos(2 * t) - 2 * np.cos(3 * t) - np.cos(
            4 * t)

    heart_t = np.linspace(0, 2 * math.pi, num=list_len)

    # e^(-x^2)
    exp_name = 'e^(-x^2)'

    def exp_x(x):
        return x

    def exp_y(x):
        return np.exp(-x**2)

    exp_t = np.linspace(-4, 4, num=list_len)

    data = zip([heart_name, exp_name], [heart_x, exp_x], [heart_y, exp_y],
               [heart_t, exp_t])
    for func_name, func_x, func_y, init_t in data:
        nodes_x, nodes_y = func_x(init_t), func_y(init_t)
        dx = nodes_x[1:] - nodes_x[:-1]
        dy = nodes_y[1:] - nodes_y[:-1]

        # (i, x_i), (i, y_i)
        nodes_t = np.arange(len(nodes_x))
        nodes_t_list = [nodes_t]

        # dt = sqrt((x_i1 - x_i0)^2 + (y_i1 - y_i0)^2)
        dt = np.sqrt(dx**2 + dy**2)
        nodes_t = np.fromiter(accumulate((0, *dt)), float)
        nodes_t_list.append(nodes_t)

        # dt = max(|x_i|, |y_i|)
        dt = (max(abs(x), abs(y)) for x, y in zip(nodes_x, nodes_y))
        nodes_t = np.fromiter(accumulate(dt), float)
        nodes_t_list.append(nodes_t)

        # dt = |acos(x_i1/sqrt(x_i1^2 + y_i1^2)) - acos(x_i0/sqrt(x_i0^2 + y_i0^2))|
        dt = np.arccos(nodes_x / np.sqrt(nodes_x**2 + nodes_y**2))
        dt = abs(dt[1:] - dt[:-1])
        nodes_t = np.fromiter(accumulate((0, *dt)), float)
        nodes_t_list.append(nodes_t)

        nrows = math.ceil(len(nodes_t_list) / 2)
        ncols = math.floor(len(nodes_t_list) / 2)
        size = int(len(nodes_t_list) * 2.5)
        _, axes = plt.subplots(nrows, ncols, figsize=(size, size))
        axes = axes.flatten()

        for nodes_t, ax in zip(nodes_t_list, axes):
            vec_t = np.arange(init_t[0], init_t[-1], 0.01)
            ax.plot(func_x(vec_t), func_y(vec_t), label='heart')

            int_x = si.get_spline(nodes_t,
                                  *si.calc_spline_data(nodes_t, nodes_x))
            int_y = si.get_spline(nodes_t,
                                  *si.calc_spline_data(nodes_t, nodes_y))
            int_x, int_y = vectorize(int_x), vectorize(int_y)

            vec_t = np.arange(nodes_t[0], nodes_t[-1], 0.01)
            ax.plot(int_x(vec_t), int_y(vec_t), label='spline')

        titles = (
            f'{func_name}: (i, x_i), (i, y_i)',
            'dt = sqrt((x_i1 - x_i0)^2 + (y_i1 - y_i0)^2)',
            'dt = max(|x_i|, |y_i|)',
            'dt = delta(acos(x_i/sqrt(x_i^2 + y_i^2)))',
        )

        for ax, title in zip(axes, titles):
            ax.set_title(title)
            ax.legend()

        plt.subplots_adjust(left=0.05,
                            right=0.985,
                            bottom=0.06,
                            top=0.94,
                            wspace=0.11,
                            hspace=0.11)
        plt.savefig(get_plot_filename('parametric', func_name, [list_len]))
        # plt.show()
        plt.close('all')
def main():
    table_names = ('"Круг"', '"Сердце"', )
    table_generators = (gen_circle_table, gen_heart_table, )
    err = 10**-5
    table_size = 101

    points_amounts = (10**3, 10**4, 10**5, 10**6, )

    excess_files = set(os.listdir(IMG_DIR)) - \
        set(map(lambda i: f'{i}.png', range(len(table_names)*len(points_amounts))))
    for fname in excess_files:
        os.remove(f'{IMG_DIR}/{fname}')

    i = 0
    for name, gen_table in zip(table_names, table_generators):
        for points_amount in points_amounts:
            # генерация таблицы
            x_values, y_values = gen_table(table_size)
            t_nodes = gen_nodes_t_by_index(x_values, y_values)

            # интегрирование методом Монте-Карло
            monte_karlo_sqr, x_points, y_points, is_inside = monte_karlo_integrate(
                x_values, y_values, points_amount)

            # создание сплайнов
            abcd_y_data = calc_spline_data(t_nodes, y_values)
            abcd_x_data = calc_spline_data(t_nodes, x_values)
            _, *bcd_dx_data = abcd_x_data

            y_func = get_spline(t_nodes, *abcd_y_data)
            x_func = get_spline(t_nodes, *abcd_x_data)
            dx_func = get_spline_derivative(t_nodes, *bcd_dx_data)

            # интегрирование формулой Симпсона
            integrand_func = vectorize(lambda t: y_func(t) * dx_func(t))
            simpson_sqr, h, iter_amount = autostep_integrate(
                integrand_func, t_nodes[0], t_nodes[-1], err)
            simpson_sqr = abs(simpson_sqr)

            # отображение графика
            _, ax = plt.subplots()

            t_vec = np.linspace(t_nodes[0], t_nodes[-1], int((t_nodes[-1]-t_nodes[0])/0.01) + 1)
            x_func, y_func = vectorize(x_func), vectorize(y_func)

            x_vec, y_vec = x_func(t_vec), y_func(t_vec)

            ax.plot(x_points[is_inside], y_points[is_inside], marker='o', ls='', markersize=1)
            is_outside = not is_inside
            ax.plot(x_points[is_outside], y_points[is_outside], marker='o', ls='', markersize=1)
            ax.plot(x_vec, y_vec, linewidth=3)

            title = f'{name}, число точек: {points_amount:.0e}\n'
            title += f'По формуле Симпсона: {simpson_sqr}\n'
            title += f'Методом Монте-Карло: {monte_karlo_sqr}'
            ax.set_title(title)
            plt.savefig(f'{IMG_DIR}/{i}.png', bbox_inches='tight', pad_inches=0)

            print('test:', i)
            i += 1

    for fname in os.listdir(f'{IMG_DIR}'):
        scale_img(f'{IMG_DIR}/{fname}', 0.8)