0

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.

5
  • Recursion is pretty slow an inefficient in python. You might be better off with a for-loop that defines all the functions than with this recursive call. Commented May 24, 2022 at 8:18
  • It's hard to give you more advice because there are too many unknowns here. Could you write a math formula for these functions before you write the python code? Commented May 24, 2022 at 8:19
  • Hi Stef, thanks for your comment. I see. I did look into using a for-loop, but then I could not find out how to give the functions different names? In my first implementation I tried to use a for-loop, but every iteration of the loop would simply overwrite the function defined in the previous iteration. The functions are quite complicated even at the lowest order, and must be calculated numerically, so it is not easy to give an explicit formula for them. Commented May 24, 2022 at 8:28
  • You could have a function make_f and then write f_list.append(make_f(n, f_list)) Commented May 24, 2022 at 8:53
  • Although my guess is that the loop for i in range(n) inside function f_n is what makes it so slow. Perhaps you could try to simplify the formula to get rid of that loop. Commented May 24, 2022 at 8:55

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.