# Type error in recursion

Consider the following function:

def f(n) :
def retfunc(x) :
return 1 if n == 0 else x*add(f(n-k) for k in (1..n))
return retfunc


The test

w = f(9); print w, type(w)


gives

"function retfunc at 0x43d3de8" "type 'function'"


which looks fine to me. However an evaluation w(3) gives

TypeError: unsupported operand type(s) for +: 'int' and 'function'


How can I get around this error?

EDIT: One solution is, as indicated by DSM,

def f(n):
retfunc(x) = 1 if n == 0 else add(x*f(n-k) for k in (1..n))
return retfunc


What I am trying to do here? Let's see:

for i in [1..8] : [c[0] for c in expand(f(i)(x)).coeffs()]
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]

edit retag close merge delete

Sort by » oldest newest most voted

I think the confusion here involves the fact that your examples use f(1) as an expression, but Python functions and the values those functions take are two different things. There are several ways to get around this:

# method 1
def f(n):
if n == 0:
retfunc(x) = 1
else:
retfunc(x) = add(x*f(n-k) for k in (1..n))
return retfunc

sage: f(0)
x |--> 1
sage: f(1)
x |--> x
sage: f(2)
x |--> x^2 + x
sage: f(3)
x |--> (x^2 + x)*x + x^2 + x
sage: f(3)(4)
100


(2) Use expressions instead, and substitute manually when you want to call it later:

# method 2
def f(n):
if n == 0:
retexpr = 1
else:
retexpr = add(x*f(n-k) for k in (1..n))
return retexpr

sage: f(0)
1
sage: f(1)
x
sage: f(2)
x^2 + x
sage: f(3)
(x^2 + x)*x + x^2 + x
sage: f(3)(x=4)
100


(3) Evaluate the function at x before doing the addition in your code:

# method 3
def f(n) :
def retfunc(x) :
return 1 if n == 0 else x*add(f(n-k)(x) for k in (1..n))
return retfunc

sage: [f(i) for i in [0..3]]
[<function retfunc at 0x10eee66e0>, <function retfunc at 0x10eee6668>, <function retfunc at 0x10eee6758>, <function retfunc at 0x10eee67d0>]
sage: [f(i)(x) for i in [0..3]]
[1, x, (x + 1)*x, ((x + 1)*x + x + 1)*x]
sage: [f(i)(x) for i in [0..3]]
[1, x, (x + 1)*x, ((x + 1)*x + x + 1)*x]
sage: f(3)(x=4)
100


I'd prefer (1) or (2) because it's somewhat easier to work with Sage-level objects in a calculus-y way than Python functions, but YMMV.

more

Thank you! First time that I hear about Sage-level functions versus Python functions.

( 2012-03-03 02:22:16 -0500 )edit

Your error is not due to recursion. The following example (slightly simplified with respect to yours) produces the same error :

def f(n) :
def retfunc(x) :
if n==0:
return 1
return x*f(3)
return retfunc

w=f(9)
w(3)


The error is at x*f(3). f(3) is a function, not a number. I don't really understand what you are trying to do. Some kind of factorial ?

The following code does not produce the error :

def f(n) :
def retfunc(x) :
if n==0:
return 1
return x*f(n-1)(3)
return retfunc

w=f(9)
print w(3)


Note : f(n-1)(3)

Hope it helps

Laurent

more

Thank you Laurent for your help. "The following code does not produce the error." Unfortunately the code also does not produce what I need :) "I don't really understand what you are trying to do." Well, I hoped that this would happen: f(0) returns the function retfunc(x) = 1 f(1) returns the function retfunc(x) = x*add(f(1-k) for k in (1..1)) = x*f(0) = x f(2) returns the function retfunc(x) = x*add(f(2-k) for k in (1..2)) = x*(f(1)+f(0)) = x*(x+1) f(3) returns the function retfunc(x) = x*add(f(3-k) for k in (1..3)) = x*(f(2)+f(1)+f(0)) = x*(x*(x+1)+x+1)

( 2012-03-03 01:13:56 -0500 )edit