我正在使用基于Python 2.7的数学软件SageMath。以下简化代码是从初始估计开始递归计算两个函数。当我尝试在代码中引入“数值积分运算符”时,它不会使用内置函数,而是会出错:
> PicklingError: Can't pickle <type 'function'>: attribute lookup __ builtin__.function failed
代码是:
reset()
forget()
from multiprocessing import Pool, cpu_count
#variables
var('x,y, x1,y1')
N=5 #number of iterations
var('q')
#functions' name definition (without specifying the rules) # n is the level of estimation
U0=[]
U1=[]
for n in range(N+1):
U0.append(function('U0_%s' %i, x,y))
U1.append(function('U1_%s' %i, x,y, x1,y1))
#initial estimation of the functions
U0[0]=sin(x+y)
U1[0]=sin(x1+y1)*cos(x-y)
#numerical integrator
num=20.0 # at each call of the int function h is assigned (b-a)/num, so assigned to num here
def numint(f, x, a, b, h):
#pickle_function(f)
integ = 0.5*h*(f(x=a) + f(x=b))
for i in range(1,num):
integ = integ + h * f(x=a+i*h)
return integ
#the integral operators
def Ix(f,x):
return pool.apply( numint, (f,x,-1.0,+1.0,2.0/num) )
def Iy(f,y):
return pool.apply_async( numint, (f,y,-1.0,+1.0,2.0/num) )
def IR(f,x,y):
return Iy(Ix(f,x),y)
def N0(n,f0,f1):
return f0[n] + IR(f1[n],x1,y1) + IR(IR(f1[n],x,y),x1,y1)
def N1(n,f0,f1):
return f1[n] + IR(f0[n],x,y) - IR(IR(f1[n],x,y),x1,y1)
#the calculations
pool = Pool(processes=cpu_count())
for n in range(N):
worker0 = N0(n,U0,U1)
worker1 = N1(n,U0,U1)
U0[n+1] = U0[n] - worker0.get()
U1[n+1] = U1[n] - worker1.get()
show(U0[n+1])
show(U1[n+1])
据我所知,从搜索网页和阅读文档时,这种酸洗错误要么是因为整数运算符(无论如何都是函数)不是Picklable,要么是因为它的参数不可选。我试图让运算符本身可选,但没有成功,但我想问题应该是由于积分运算符本身是其被积函数的函数,并且因为它是一个运算符它的被积函数从一开始就没有确定,所以运营商的第一个参数(它本身就是一个函数)可能没有在顶层明确定义,这是运营商不能整体选择的原因吗?知道如何克服这个错误吗?
注意即可。主代码比这里提供的简约代码复杂得多,所以我宁愿定义一个整数运算符来阻止代码的可读性。