I am working on a computational project where I have to determine a series of functions f_0, f_1, f_2,...f_n, that will be used in a calculation. The evaluation of the nth function requires knowledge of all the previous functions, and once generated I would like to be able to call each function using the syntax f_n(x,y). They should all return a np.ndarray. I have tried to write a generating function that generates n+1 functions in the series recursively, but the code is extremely slow to the point that it is unusable. I'm hoping someone here can give me tips on how to improve the speed of my code, or perhaps ideas for a different method to obtain the same result.
The generating method (which lies inside a class) is defined as follows:
def calc_function_series(self,n):
#returns a list of (callable) functions [f_0, f_1, f_2,..., f_n].
#The list should contain a total of n+1 functions.
if n == 0:
return [self.f_0] #self.f_0 is class function which gives f_0. f_0 can be called with the syntax f_0(x,y), and returns an np.ndarray
elif n >0:
f_list = self.calc_function_series(n-1) #recursively generate the list of functions, starting at zero.
def f_n(x,y): #this is the n'th order function
f_Sigma_ret = self.f_Sigma_ret #(callable) function used in the calculation
H = self.f_H #another (callable) function used in the calculation
res = 0
for i in range(n):
res = res - self.Ln(f_Sigma_ret,f=f_list[i],H=H,x=x,y=y,n=n-i) #Ln returns an np.ndarray of a particular combination of the input functions evaluated at (x,y)
res = f_list[0](x,y) @ res #matrix multiply by f_0(x,y) from the left
return res
f_list.append(f_n) #append new function to the list and return entire list.
return f_list
I very much appreciate any help. I could not find a similar post on here, so I hope my question is alright. Thank you.
EDIT: A clarification: The problem does not in fact arise when generating the functions, but when calling the functions generated in this way. The functions seem to return the correct values, but do so incredibly slowly. I have manually written definitions for the functions f_0 and f_1 and evaluating these manual functions is much faster than evaluating the corresponding automatically generated ones.
for-loop that defines all the functions than with this recursive call.make_fand then writef_list.append(make_f(n, f_list))for i in range(n)inside functionf_nis what makes it so slow. Perhaps you could try to simplify the formula to get rid of that loop.