这是《The Numerical Solution of Integral Equations of the Second Kind》书上的例题代码实现,P59-61。如有您发现有问题,欢迎指出,,,
# -*- coding: utf-8 -*- """ Created on Tue May 29 12:37:44 2018 @author: shaowu 本代码主要运用collocation 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)cos(t)和sqrt(t),求出其对应的y(t),然后再来反解x(t).更详细说明可 参见《The Numerical Solution of Integral Equations of the Second Kind》P59-61. """ 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 gauss_xw(m=10): """ 默认用10个点求高斯——勒让德节点xi和权weight,并返回x和w数组 """ x,w=p_roots(m+1) return x,w def gauss_solve_y(x,w,lamda,a,b,n): #参数n>=1 """ 求解课本3.2.41式中的右端项y(ti). method:gauss_Legendre 参数: 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 [(lamda*scp.exp(-i)*scp.cos(i)- sum([c*w[j]*scp.exp(s[j]*i)*scp.exp(-s[j])*scp.cos(s[j]) for j in range(len(s))])) for i in t],\ [(lamda*scp.sqrt(i)- sum([c*w[j]*scp.exp(s[j]*i)*scp.sqrt(s[j]) for j in range(len(s))])) for i in 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,i,j,t,a,b,n): """ 对K(t,s)*lj(s)在[a,b]上求积分,即等式(3.2.41)中的积分项; 返回的是一个数,即对应系数矩阵中的一个元素 """ h=(b-a)/(n) if j==0: #c=h/2;s=h/2*x+(t[0]+t[1])/2 #区间变化 return -scp.integrate.quad(lambda x: (x-t[0])*scp.exp(t[i]*x),t[0],t[1])[0]/h #return -sum([w[k]*c*hat_f(j,s[k],a,b)*scp.exp(t[i]*s[k]) for k in range(len(s))]) elif j==n: #c=h/2;s=h/2*x+(t[n-1]+t[n])/2 #区间变化 return -scp.integrate.quad(lambda x: (t[n]-x)*scp.exp(t[i]*x),t[n-1],t[n])[0]/h #return -sum([w[k]*c*hat_f(j,s[k],a,b)*scp.exp(t[i]*s[k]) for k in range(len(s))]) else: #c=h;s=h*x+(t[j-1]+t[j+1])/2 #区间变化 return -scp.integrate.quad(lambda x: (x-t[j-1])*scp.exp(t[i]*x),t[j-1],t[j])[0]/h-\ scp.integrate.quad(lambda x: (t[j+1]-x)*scp.exp(t[i]*x),t[j],t[j+1])[0]/h #return -sum([w[k]*c*hat_f(j,s[k],a,b)*scp.exp(t[i]*s[k]) for k in range(len(s))]) def solve_xn(x,w,lamda,a,b,n,y1,y2): """ 计算xn1和xn2 返回xn1和xn2(一个n+1维的列表) """ xn=[] h=(b-a)/(n) t=[a+i*h for i in range(0,n+1)] #等距划分a=t0<t1<...<tn<tn+1=b #A.append([-scp.integrate.quad(lambda x:(1-abs(x-t[j])/h)*scp.exp(t[0]*x),t[0],t[1])[0] for j in range(n+1)]) #计算i=0时的 for i in range(0,n+1): #guodu=[-scp.integrate.quad(lambda x:(1-abs(x-t[0])/h)*scp.exp(t[i]*x),t[0],t[1])[0]]+\ guodu=[elements_of_matrix(x,w,i,j,t,a,b,n) for j in range(0,n+1)]#+\ # [-scp.integrate.quad(lambda x:(1-abs(x-t[n])/h)*scp.exp(t[i]*x),t[n-1],t[n])[0]] xn.append(guodu) #A.append([-scp.integrate.quad(lambda x:(1-abs(x-t[j])/h)*scp.exp(t[n]*x),t[n-1],t[n])[0] for j in range(n+1)]) #计算i=n时的 xn=np.array(xn) for i in range(n+1): xn[i][i]=lamda+xn[i][i] result1=np.linalg.solve(xn,y1) #求解xn1 result2=np.linalg.solve(xn,y2) #求解xn2 return result1,result2 def solve_error(lamda,a,b,n,xn1,xn2): """ 计算最大误差,并返回 """ h=(b-a)/(n) t=np.array([a+i*h for i in range(0,n+1)]) #tt=np.array([i for i in np.arange(a+0.1,b,0.1)]) xt1=scp.exp(-t)*scp.cos(t) ##第一个精确解xt1 xt2=scp.sqrt(t) ##第二个精确解xt2 #E1=LA.norm(xt1-xn,np.inf) ##计算无穷范数 E1=max(abs(xt1-xn1)) #E2=LA.norm(xt2-xnt2,np.inf) E2=max(abs(xt2-xn2)) print('The maximum error on the %d\'s collocation node points for xt1 is %s'%(n,E1)) print('The maximum error on the %d\'s collocation node points for xt2 is %s'%(n,E2)) """ #画图 plt.figure(1) plt.subplot(211) plt.title('Figure1.(where a=0,b=1,n=128,lambda=5)') plt.xlabel('t') plt.ylabel('x') plt.plot(t,xt1,'*--',t,xn1,'-') plt.subplot(212) plt.plot(t,xt2,'--+',t,xn2,'-') """ return E1,E2 if __name__ == '__main__': print('******************************程序入口*******************************') lamda=int(input('pleas input lambda:')) n=int(input('please input n:')) # n>0 为配置点个数 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) y1,y2=gauss_solve_y(x,w,lamda,a,b,n) xn1,xn2=solve_xn(x,w,lamda,a,b,n,y1,y2) E1,E2=solve_error(lamda,a,b,n,xn1,xn2) print('all_cost_time:',time.time()-start_time)
运行结果: