Ask Your Question
0

Type error in recursion

asked 2012-03-03 02:32:30 +0100

petropolis gravatar image

updated 2012-03-03 10:05:32 +0100

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 flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
2

answered 2012-03-03 08:57:50 +0100

DSM gravatar image

updated 2012-03-03 12:59:50 +0100

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:

(1) Use Sage-level functions instead; those can be added and multiplied.

# 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.

edit flag offensive delete link more

Comments

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

petropolis gravatar imagepetropolis ( 2012-03-03 09:22:16 +0100 )edit
1

answered 2012-03-03 05:00:28 +0100

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

edit flag offensive delete link more

Comments

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)

petropolis gravatar imagepetropolis ( 2012-03-03 08:13:56 +0100 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

Stats

Asked: 2012-03-03 02:32:30 +0100

Seen: 705 times

Last updated: Mar 03 '12