I am using a math software based on Python 2.7. The following simplified code is to recursively compute two functions starting from their initial estimations. When I try to introduce a "numerical integral operator" to the code, instead of using the built-in functions, it gives an error:
PicklingError: Can't pickle <type 'function'="">: attribute lookup __ builtin__.function failed
the code is:
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])
As far as I have understood from searching the web and reading the documents this pickling error is either due to the integral operator (a function anyway) not being Picklable or due to its arguments not being picklable. I tried to make the operator itself picklable at no success, but I guess the problem should be due to the integral operator itself being a functional of its integrand, and as it is an operator the function in its integrand is not to be determined since the very beginning, so maybe the first argument of the operator (which itself is a function) not being clearly defined at top level is the reason for the operator not being in overall picklable? Any idea how to overcome this error?
NOTE. the main code is much more complex than the minimalistic code provided here, so I rather need to define an integral operator to prevent the code's readability.