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 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)
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 = cmsi.get_spline( sub_nodes, *cmsi.calc_spline_data(sub_nodes, sub_values)) # добавляется (<первый узел>, <последний узел>, <сплайн>) spline_list.append((*sub_nodes[[0, -1]], spline)) return spline_list
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()
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)