这是《The Numerical Solution of Integral Equations of the Second Kind》书上的例题代码实现(Galerkin方法),P66-P68,P74-77
# -*- coding: utf-8 -*- """ Created on Fri Jun 1 19:45:59 2018 @author: shaowu 本代码主要运用Galerkin method实现Fredholm integral equations of the second kind的求解,方程如下: lamda*x(t)-integrate(K(t,s)*x(s))ds=y(t),a=0<=t<=b,K(t,s)取exp(s*t) 首先,我们给定两个精确解exp(t),求出其对应的y(t),然后再来反解x(t).更详细说明可 参见《The Numerical Solution of Integral Equations of the Second Kind》P66-P68,P74-77. """ import sympy as sp import scipy as scp import numpy as np import pandas as pd import numpy.linalg as LA import matplotlib.pyplot as plt from scipy.special.orthogonal import p_roots import time start_time=time.time() def function_x(t): return scp.exp(t) def function_k(s,t): return scp.exp(s*t) def gauss_xw(m=100): """ 默认用100个点求高斯——勒让德节点xi和权weight,并返回x和w数组 """ x,w=p_roots(m+1) return x,w def gauss_solve_f(x,w,lamda,a,b,n): #参数n>=1 """ 求解课本3.3.67式中的右端项,记为f 参数: x,w为高斯点和对应的权, a,b 对应于区间[a,b], n 子区间的个数 返回的是一个n+1维的列表 """ c=(b-a)/2 s=(b-a)/2*x+(a+b)/2 #把区间[a,b]变化到[-1,1] h=(b-a)/(n) t=[a+i*h for i in range(0,n+1)] #等距划分a=t0<t1<...<tn=b return [sum([c*w[k]*lamda*function_x(s[k])*hat_f(i,s[k],a,b)- c*w[k]*sum([c*w[j]*function_k(s[j],s[k])*function_x(s[j])*hat_f(i,s[k],a,b)\ for j in range(len(s))]) for k in range(len(s))])\ for i in range(len(t))] def hat_f(j,x,a,b): """ 定义hat函数 """ h=(b-a)/(n) t=[a+i*h for i in range(0,n+1)] if j==0: if x>=t[0] and x<=t[1]: return 1-abs(x-t[0])/h else: return 0 if j==n: if t[n-1]<=x and x<=t[n]: return 1-abs(x-t[n])/h else: return 0 if j>0 and j<n: if t[j-1]<=x and x<=t[j+1]: return 1-abs(x-t[j])/h else: return 0 def elements_of_matrix(x,w,a,b,lamda,n): """ 求方程(3.3.67)中的系数矩阵; 返回的是一个数,即对应系数矩阵中的一个元素 """ c=(b-a)/2 s=(b-a)/2*x+(a+b)/2 #把区间[a,b]变化到[-1,1] h=(b-a)/(n) t=[a+i*h for i in range(0,n+1)] #等距划分a=t0<t1<...<tn=b A=[] for i in range(len(t)): A.append([scp.integrate.quad(lambda x: lamda*hat_f(i,x,a,b)*hat_f(j,x,a,b),a,b)[0]-\ sum([c*w[k]*sum([c*w[e]*function_k(s[e],s[k])*hat_f(i,s[e],a,b)*hat_f(j,s[k],a,b)\ for e in range(len(s))]) for k in range(len(s))]) for j in range(len(t))]) return np.array(A) def solve_c(A,f): """ 计算c """ return np.linalg.solve(A,f) def solve_xn(c,a,b,n): """ 计算xn """ h=(b-a)/(n) t=[a+i*h for i in range(0,n+1)] #等距划分a=t0<t1<...<tn=b xn=[sum([c[j]*hat_f(j,i,a,b) for j in range(len(t))]) for i in t] error=function_x(t)-xn #print(LA.norm(error,np.inf)) return xn,LA.norm(error,np.inf) if __name__ == '__main__': print('******************************程序入口*******************************') lamda=int(input('pleas input lambda:')) n=int(input('please input n:')) a=int(input('please input the left value of interval:')) b=int(input('please input the right value of interval:')) m=int(input('please input the node of Gauss_Legendre:')) print('计算中...') x,w=gauss_xw(m) f=gauss_solve_f(x,w,lamda,a,b,n) A=elements_of_matrix(x,w,a,b,lamda,n) c=solve_c(A,f) xn,error=solve_xn(c,a,b,n) print('the error is:',error) print('all_cost_time:',time.time()-start_time)
运行结果:
******************************程序入口*******************************
pleas input lambda:50
please input n:8
please input the left value of interval:0
please input the right value of interval:1
please input the node of Gauss_Legendre:400
计算中...
the error is: 0.00360146251855
all_cost_time: 188.2648663520813