1

我正在使用基于 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,要么是因为它的参数不是 Picklable。我试图让操作符本身可腌制但没有成功,但我想问题应该是由于积分操作符本身是它的被积函数的函数,并且由于它是一个操作符,它的被积函数中的函数没有被确定,因为一开始,所以也许操作符的第一个参数(它本身是一个函数)没有在顶层明确定义是操作符不能整体picklable的原因?知道如何克服这个错误吗?

注意。主要代码比这里提供的简约代码复杂得多,所以我宁愿定义一个整数运算符来防止代码的可读性。

4

0 回答 0