def draw_error(max_n=15): """ This function draws the error for u and u_hat. Parameters ---------- max_n : int The plot is drawn from 2 upto this int. """ for d in [1, 2, 3]: errors = [] for n in range(2, max_n): hat_u = linear_solvers.solve_lu( *block_matrix.BlockMatrix(d, n).get_lu(), rhs(d, n, functions.f)) errors.append(compute_error(d, n, hat_u, functions.u)) plt.loglog([x for x in range(2, max_n)], errors, label="error for d = {}".format(d), linewidth=3) plt.xlabel("Number of Grid Points", fontsize=18) plt.ylabel("Error", fontsize=18) plt.legend(fontsize=24) # pylint: disable=anomalous-backslash-in-string plt.title("Plot of error of $u$ and $\hat{u}$ depending on n", fontsize=24) plt.show()
def compute_error_list(d, high_N, f, u): """ Computes the errors of the approximate solution of the poisson-problem in dependency of n. Input ----- d : int the dimension of the space high_N : int the highest N we want to plot the error for f : callable the f which is the negative of the laplace-operator u : callable Solution of the Possion problem Return ------ error_list : list list of maximal errors between the approxmative solution of the poisson problem and the real solution. """ error_list = [] for n in range(3, high_N): matrix = block_matrix.BlockMatrix(d, n) b = rhs(d, n, f) hat_u = linear_solvers.solve_lu(*matrix.lu, b) error_list.append(compute_error(d, n, hat_u, u)) return error_list
def plot_approximate_3d(n, f): """Plottet die approximierte Lösung des Poisson Problems zu einer gegebenen Funktion f mit Diskretisierung n. Input ----- n : int Die Feinheit der Diskretisierung f : callable die Funktion f, die gleich dem negativen Laplace Operators der zu approximierenden Funktion ist """ fig = plt.figure() ax = fig.add_subplot(111, projection="3d") x = [] y = [] for i in range(n-1): for j in range(n-1): x.append(i/n) y.append(j/n) b = rhs.rhs(2, n, f) matrix = block_matrix.BlockMatrix(2, n) z = linear_solvers.solve_lu(*matrix.lu, b) ax.plot_trisurf(x, y, z, linewidth=0.2, antialiased=True) ax.set_xlabel("x") ax.set_ylabel("y") ax.set_zlabel("z") plt.title("Plot der approximierten Lösung des Poisson-Problems für \ n = " + str(n)) plt.show()
def plot_error(u, f, d, n_list): #pylint: disable=invalid-name """ Plots the maxima of absolute errors of the numerical solution of the Poisson-problem for a given list of n-values. N = (n-1)^d is the dimension of the block matrix. Parameters ---------- u : callable Solution of the Poisson-problem The calling signature is u(x). Here x is a scalar or array_like of numpy. The return value is a scalar. f : callable Input function of the Poisson-problem The calling signature is f(x). Here x is a scalar or array_like of numpy. The return value is a scalar. d: int Dimension of the Poisson-problem n_list: list of ints The n-values for which to plot the errors. """ numbers_of_points = [] errors = [] for n in n_list: A = block_matrix.BlockMatrix(d, n) b = rhs(d, n, f) lu = A.get_lu() hat_u = linear_solvers.solve_lu(lu[0], lu[1], lu[2], lu[3], b) errors.append(compute_error(d, n, hat_u, u)) numbers_of_points.append((n - 1)**d) numbers_of_points_pow1 = [np.float_(N)**(-1) for N in numbers_of_points] numbers_of_points_pow2 = [np.float_(N)**(-2) for N in numbers_of_points] numbers_of_points_pow3 = [ np.float_(N)**(-1 / 2) for N in numbers_of_points ] plt.loglog(numbers_of_points, numbers_of_points_pow3, label='$N^{-1/2}$', color='lightgray', linestyle=':') plt.loglog(numbers_of_points, numbers_of_points_pow1, label='$N^{-1}$', color='lightgray') plt.loglog(numbers_of_points, numbers_of_points_pow2, label='$N^{-2}$', color='lightgray', linestyle='-.') plt.loglog(numbers_of_points, errors, 'go--') plt.xlabel('$N$') plt.ylabel('maximum of absolute error') plt.title('Maxima of absolute errors for $d$ = ' + str(d)) plt.legend() plt.grid() plt.show() plt.figure()
def draw_error_both(f, u, dlist=[1, 2, 3], max_n=MAX_N): """ This function draws a plot to compare the SOR algorithm and the LU-decomposition. Params: ------- f : callable The right hand side of the equation will be build from this function. u : callable The analytic solution of x will be build from this function. dlist : list, optional A list containing dimension for which the plot is drawn. max_n : int, optional The maximum number of n for which the plot is drawn. """ for d in dlist: errors_sor = [error_sor(d, n, f, u) for n in range(2, max_n)] plt.loglog([n for n in range(2, max_n)], errors_sor, label="error SOR for $d$ = {}".format(d), linewidth=3) errors_lu = [] for n in range(2, max_n): hat_u = linear_solvers.solve_lu( *block_matrix.BlockMatrix(d, n).get_lu(), rhs.rhs(d, n, functions.f)) errors_lu.append(rhs.compute_error(d, n, hat_u, functions.u)) plt.loglog([n for n in range(2, max_n)], errors_lu, label="error LU for $d$ = {}".format(d), linewidth=3, linestyle="--") plt.xlabel("Number of Grid Points, $N$", fontsize=18) plt.ylabel("Error", fontsize=18) plt.legend(fontsize=24) # pylint: disable=anomalous-backslash-in-string plt.title("Plot of error of $u$ and $\hat{u}$ depending on $N$", fontsize=24) plt.show()
def main(): """ A main function for demo. """ d, n = 2, 4 print("DEMONSTRATION OF MODULE") print("Consider sum_{l = 1}^d x_l * sin(k * pi * x_l).") print( "We have d = {} and n = {}, then the right hand side of Ax = b would be:" .format(d, n)) print(np.array(rhs(d, n, functions.f))) print("And the error would be:") hat_u = linear_solvers.solve_lu(*block_matrix.BlockMatrix(d, n).get_lu(), rhs(d, n, functions.f)) print(compute_error(d, n, hat_u, functions.u)) print() print("We can also the plot for the error.") print() print("See protocol for more information.") draw_error() draw_hilbert_cond()
def plot_approximation_3d(N): """ This function draws the analytic solution for the poissons equation for d = 2. Parameters: N : int The number of grid points. """ grid = np.linspace(0.0, 1.0, N + 1, endpoint=True) # grid_length = len(grid) x_grid, y_grid = np.meshgrid(grid, grid) b = linear_solvers.solve_lu(*block_matrix.BlockMatrix(2, N).get_lu(), rhs.rhs(2, N, f)) z_grid = np.zeros((N + 1, N + 1)) for i in range(N + 1): for j in range(N + 1): if i != 0 and i != N and j != 0 and j != N: z_grid[i][j] = b[0] b = np.delete(b, 0) print("z axis (approximation)\n{}".format(z_grid)) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') if N >= 10: ax.plot_surface(x_grid, y_grid, z_grid, cmap=plt.cm.CMRmap, linewidth=0) else: ax.plot_surface(x_grid, y_grid, z_grid, linewidth=0) lim = (-0.1, 1.1) ax.set_xlabel("$x$", fontsize=14), ax.set_xlim(lim) ax.set_ylabel("$y$", fontsize=14), ax.set_ylim(lim) ax.set_zlabel("$\hat{u}(x, y)$", fontsize=14), ax.set_zlim(lim) plt.title("Plot of the Approximated Solution (N = " + str(N) + ")", fontsize=18) plt.show()
def graph_error(d, high_N, f, u): """Plots the errors of the approximate solution of the Poisson Problem in dependency of N. d : int the dimension of the space high_N : int the highest N we want to plot the error for f : callable the f which is the negative of the laplace-operator u : callable Solution of the Possion problem """ error_list = [] plt.style.use("seaborn-white") plt.figure(figsize=(14, 7)) plt.gcf().canvas.set_window_title("Graph des Fehlers \ in Abhängigkeit von N") plt.title("Fehlerplot in Abhängigkeit von N") axis = plt.gca() for n in range(3, high_N): matrix = block_matrix.BlockMatrix(d, n) b = rhs(d, n, f) hat_u = linear_solvers.solve_lu(*matrix.lu, b) error_list.append(compute_error(d, n, hat_u, u)) axis.plot(range(3, high_N), error_list, label="Fehlerplot in Abhängigkeit\ von N für d = " + str(d)) plt.xlabel("n-Werte") plt.ylabel("Fehler") plt.grid(True) #axis.set_xscale('log') #axis.set_yscale('log') plt.legend() plt.show()
def plot_functions(u, f, n): #pylint: disable=invalid-name, too-many-locals """ Plots the numerical, the exact solution of our Poisson-problem (dimension d=2) for a given value of n (n is the number of intersections in each dimension and their absolute and their relative difference. Parameters ---------- u : callable Solution of the Poisson-problem The calling signature is u(x). Here x is a scalar or array_like of numpy. The return value is a scalar. f : callable Input function of the Poisson-problem The calling signature is f(x). Here x is a scalar or array_like of numpy. The return value is a scalar. n: int The n-value for which to plot the functions. """ x = np.linspace(0, 1, n + 1) y = np.linspace(0, 1, n + 1) X, Y = np.meshgrid(x, y) exact = u((X, Y)) A = block_matrix.BlockMatrix(2, n) b = rhs(2, n, f) lu = A.get_lu() hat_u = linear_solvers.solve_lu(lu[0], lu[1], lu[2], lu[3], b) approx = np.reshape(hat_u, (-1, n - 1)) vzeroes = [] for _ in range(n - 1): vzeroes.append([0]) hzeroes = np.zeros(n + 1) approx = np.hstack((vzeroes, approx, vzeroes)) approx = np.vstack((hzeroes, approx, hzeroes)) fig = plt.figure() ax1 = fig.add_subplot(221, projection='3d') ax2 = fig.add_subplot(222, projection='3d') ax3 = fig.add_subplot(223, projection='3d') #ax4 = fig.add_subplot(224, projection='3d') ax1.set_xlabel('$x_1$') ax1.set_ylabel('$x_2$') ax1.set_zlabel('$\hat{u}(x)$') #pylint: disable=anomalous-backslash-in-string ax1.plot_surface(X, Y, approx, cmap='viridis', edgecolor='none') ax1.set_title('Approximate solution') difference = abs(approx - exact) ax2.set_xlabel('$x_1$') ax2.set_ylabel('$x_2$') ax2.set_zlabel('$|\hat{u}(x)-u(x)|$') #pylint: disable=anomalous-backslash-in-string ax2.plot_surface(X, Y, difference, cmap='viridis', edgecolor='none') ax2.set_title('Difference') ax3.set_xlabel('$x_1$') ax3.set_ylabel('$x_2$') ax3.set_zlabel('$u(x)$') ax3.plot_surface(X, Y, exact, cmap='viridis', edgecolor='none') ax3.set_title('Exact solution') #rel_difference = difference/(exact+np.mean(difference)) #ax4.plot_surface(X, Y, rel_difference, cmap='viridis', edgecolor='none') #ax4.set_title('Relative Difference') plt.show()
def plot_error_list(u_list, f_list, n_list_list): #pylint: disable=invalid-name, too-many-locals """ Plots the maxima of absolute errors of the numerical solution of the Poisson-problem for a given list of n-values and for the dimension d = 1, 2, 3. Parameters ---------- n_list_list: list of list of ints The n-values for which to plot the errors. u_list : list of callable functions Solution of the Poisson-problem The calling signature is u(x). Here x is a scalar or array_like of numpy. The return value is a scalar. f_list : list of callable functions Input function of the Poisson-problem The calling signature is f(x). Here x is a scalar or array_like of numpy. The return value is a scalar. """ numbers_of_points_1 = [] errors_1 = [] for n in n_list_list[0]: A = block_matrix.BlockMatrix(1, n) b = rhs(1, n, f_list[0]) lu = A.get_lu() hat_u = linear_solvers.solve_lu(lu[0], lu[1], lu[2], lu[3], b) errors_1.append(compute_error(1, n, hat_u, u_list[0])) numbers_of_points_1.append((n - 1)**1) numbers_of_points_2 = [] errors_2 = [] for n in n_list_list[1]: A = block_matrix.BlockMatrix(2, n) b = rhs(2, n, f_list[1]) lu = A.get_lu() hat_u = linear_solvers.solve_lu(lu[0], lu[1], lu[2], lu[3], b) errors_2.append(compute_error(2, n, hat_u, u_list[1])) numbers_of_points_2.append((n - 1)**2) numbers_of_points_3 = [] errors_3 = [] for n in n_list_list[2]: A = block_matrix.BlockMatrix(3, n) b = rhs(3, n, f_list[2]) lu = A.get_lu() hat_u = linear_solvers.solve_lu(lu[0], lu[1], lu[2], lu[3], b) errors_3.append(compute_error(3, n, hat_u, u_list[2])) numbers_of_points_3.append((n - 1)**3) numbers_of_points_pow1 = [np.float_(N)**(-1) for N in numbers_of_points_3] numbers_of_points_pow2 = [np.float_(N)**(-2) for N in numbers_of_points_3] numbers_of_points_pow3 = [ np.float_(N)**(-1 / 2) for N in numbers_of_points_3 ] plt.loglog(numbers_of_points_3, numbers_of_points_pow3, label='$N^{-1/2}$', color='lightgray') plt.loglog(numbers_of_points_3, numbers_of_points_pow1, label='$N^{-1}$', color='lightgray', linestyle='-.') plt.loglog(numbers_of_points_3, numbers_of_points_pow2, label='$N^{-2}$', color='lightgray', linestyle=':') plt.loglog(numbers_of_points_1, errors_1, label='$d=1$', linestyle='--', color='blue') plt.loglog(numbers_of_points_2, errors_2, label='$d=2$', linestyle='--', color='magenta') plt.loglog(numbers_of_points_3, errors_3, label='$d=3$', linestyle='--', color='red') plt.xlabel('$N$') plt.ylabel('maximum of absolute error') plt.legend() plt.title('Maxima of absolute errors for $d=1,2,3$') plt.grid() plt.show()
def compute_error_lu(d, n): algorithm = linear_solvers.solve_lu( *block_matrix.BlockMatrix(d, n).get_lu(), rhs.rhs(d, n, functions.f)) exact = true_solution(cs.change(d=d, n=n)) return max([abs(ai - bi) for ai, bi in zip(exact, algorithm)])
def plot_error_list_comp(u_list, f_list, n_list_list): """ Plots the maxima of absolute errors of the numerical solution of the Poisson-problem with LU and CG for a given list of n-values and for the dimension d = 1, 2, 3. Parameters ---------- n_list_list: list of list of ints The n-values for which to plot the errors. u_list : list of callable functions Solution of the Poisson-problem The calling signature is u(x). Here x is a scalar or array_like of numpy. The return value is a scalar. f_list : list of callable functions Input function of the Poisson-problem The calling signature is f(x). Here x is a scalar or array_like of numpy. The return value is a scalar. """ numbers_of_points_1 = [] errors_1 = [] errors_cg1 = [] for n in n_list_list[0]: A = block_matrix.BlockMatrix(1, n) b = rhs(1, n, f_list[0]) lu = A.get_lu() hat_u = linear_solvers.solve_lu(lu[0], lu[1], lu[2], lu[3], b) errors_1.append(compute_error(1, n, hat_u, u_list[0])) cg = linear_solvers.solve_cg(A.get_sparse(), b, np.zeros((n - 1)), params=dict(eps=1e-8, max_iter=(2 * (n - 1)**2), min_red=0)) print(cg[0]) errors_cg1.append(compute_error(1, n, cg[1][-1], u_list[0])) numbers_of_points_1.append((n - 1)**1) numbers_of_points_2 = [] errors_2 = [] errors_cg2 = [] for n in n_list_list[1]: A = block_matrix.BlockMatrix(2, n) b = rhs(2, n, f_list[1]) lu = A.get_lu() hat_u = linear_solvers.solve_lu(lu[0], lu[1], lu[2], lu[3], b) cg = linear_solvers.solve_cg(A.get_sparse(), b, np.zeros((n - 1)**2), params=dict(eps=1e-8, max_iter=(2 * (n - 1)**2 * 2), min_red=0)) print(cg[0]) errors_cg2.append(compute_error(2, n, cg[1][-1], u_list[1])) errors_2.append(compute_error(2, n, hat_u, u_list[1])) numbers_of_points_2.append((n - 1)**2) numbers_of_points_3 = [] errors_3 = [] errors_cg3 = [] for n in n_list_list[2]: A = block_matrix.BlockMatrix(3, n) b = rhs(3, n, f_list[2]) lu = A.get_lu() hat_u = linear_solvers.solve_lu(lu[0], lu[1], lu[2], lu[3], b) cg = linear_solvers.solve_cg(A.get_sparse(), b, np.zeros((n - 1)**3), params=dict(eps=1e-8, max_iter=(2 * (n - 1)**2 * 3), min_red=0)) print(cg[0]) errors_cg3.append(compute_error(3, n, cg[1][-1], u_list[2])) errors_3.append(compute_error(3, n, hat_u, u_list[2])) numbers_of_points_3.append((n - 1)**3) numbers_of_points_pow1 = [np.float_(N)**(-1) for N in numbers_of_points_3] numbers_of_points_pow2 = [np.float_(N)**(-2) for N in numbers_of_points_3] numbers_of_points_pow3 = [ np.float_(N)**(-1 / 2) for N in numbers_of_points_3 ] plt.loglog(numbers_of_points_3, numbers_of_points_pow3, label='$N^{-1/2}$', color='lightgray') plt.loglog(numbers_of_points_3, numbers_of_points_pow1, label='$N^{-1}$', color='lightgray', linestyle='-.') plt.loglog(numbers_of_points_3, numbers_of_points_pow2, label='$N^{-2}$', color='lightgray', linestyle=':') plt.loglog(numbers_of_points_1, errors_1, label='LU $d=1$', linestyle='-', color='cornflowerblue', marker='X') plt.loglog(numbers_of_points_2, errors_2, label='LU $d=2$', linestyle='-', color='blue', marker='X') plt.loglog(numbers_of_points_3, errors_3, label='LU $d=3$', linestyle='-', color='navy', marker='X') plt.loglog(numbers_of_points_1, errors_cg1, label='CG $d=1$', linestyle='-.', color='tomato', marker='.') plt.loglog(numbers_of_points_2, errors_cg2, label='CG $d=2$', linestyle='-.', color='red', marker='.') plt.loglog(numbers_of_points_3, errors_cg3, label='CG $d=3$', linestyle='-.', color='darkred', marker='.') plt.xlabel('$N$') plt.ylabel('maximum of absolute error') plt.legend() plt.title('Maxima of absolute errors for $d=1,2,3$') plt.grid() plt.show()
def plot_error_comp(u, f, d, n_list): """ Plots the maxima of absolute errors of the numerical solution of the Poisson-problem with LU and CG for a given list of n-values. N = (n-1)^d is the dimension of the block matrix. Parameters ---------- u : callable Solution of the Poisson-problem The calling signature is u(x). Here x is a scalar or array_like of numpy. The return value is a scalar. f : callable Input function of the Poisson-problem The calling signature is f(x). Here x is a scalar or array_like of numpy. The return value is a scalar. d: int Dimension of the Poisson-problem n_list: list of ints The n-values for which to plot the errors. """ numbers_of_points = [] errors_cg = [] errors_lu = [] for n in n_list: A = block_matrix.BlockMatrix(d, n) b = rhs(d, n, f) lu = A.get_lu() hat_u = linear_solvers.solve_lu(lu[0], lu[1], lu[2], lu[3], b) errors_lu.append(compute_error(d, n, hat_u, u)) cg = linear_solvers.solve_cg(A.get_sparse(), b, np.zeros((n - 1)**d), params=dict(eps=1e-8, max_iter=(2 * (n - 1)**2 * d), min_red=0)) print(cg[0]) errors_cg.append(compute_error(d, n, cg[1][-1], u)) numbers_of_points.append((n - 1)**d) # numbers_of_points_pow1 = [np.float_(N)**(-1) for N in numbers_of_points] # numbers_of_points_pow2 = [np.float_(N)**(-2) for N in numbers_of_points] # numbers_of_points_pow3 = [np.float_(N)**(-1/2) for N in numbers_of_points] # # plt.loglog(numbers_of_points, numbers_of_points_pow3, label='$N^{-1/2}$', # color='lightgray', linestyle=':') # plt.loglog(numbers_of_points, numbers_of_points_pow1, label='$N^{-1}$', # color='lightgray') # plt.loglog(numbers_of_points, numbers_of_points_pow2, label='$N^{-2}$', # color='lightgray', linestyle='-.') plt.loglog(numbers_of_points, errors_cg, 'gX-', label='CG') plt.loglog(numbers_of_points, errors_lu, 'r.--', label='LU') plt.xlabel('$N$') plt.ylabel('maximum of absolute error') plt.title('Maxima of absolute errors for $d$ = ' + str(d)) plt.legend() plt.grid() plt.show() plt.figure()