Ask Your Question

How to do mul(function, i=1..n); like in Maple?

asked 2012-01-03 17:00:17 -0500

alejandroerickson gravatar image

I want to a product of polynomials which I define in Maple as

f := n->mul((1+x^k),k=1..n);

The obvious choice, mimicking Sage's 'sum' command does not work. I can't do

def f(n):
    return mul((1+x^k),k,1,n)

Instead I had to use

def S(n,k):
    return mul(1+x^(k+1) for k in range(n))

Maybe my problem is another, so I'll post my whole problem and traceback:

 def S(n,k):
    s = mul(1+x^(i+1) for i in range(n))
    return s.expand().coeff(x^k)
def H(n,k):
    return sum(sum( S(2*i+1,b)*S(n-2*i-3,k-(2*i+2)-b),b,0,k-(2*i+2)),i,0,floor((n-5)/4))

Traceback (most recent call last):        return sum(sum( S(2*i+1,b)*S(n-2*i-3,k-(2*i+2)-b),b,0,k-(2*i+2)),i,0,floor((n-5)/4))
  File "", line 1, in <module>

  File "/tmp/tmpKvQFbK/", line 10, in <module>
    exec compile(u'H(_sage_const_121 ,_sage_const_4 )
  File "", line 1, in <module>

  File "/tmp/tmpKvQFbK/", line 9, in H
    return sum(sum( S(_sage_const_2 *i+_sage_const_1 ,b)*S(n-_sage_const_2 *i-_sage_const_3 ,k-(_sage_const_2 *i+_sage_const_2 )-b),b,_sage_const_0 ,k-(_sage_const_2 *i+_sage_const_2 )),i,_sage_const_0 ,floor((n-_sage_const_5 )/_sage_const_4 ))
  File "/tmp/tmpKvQFbK/", line 4, in S
    s = mul(_sage_const_1 +x**(i+_sage_const_1 ) for i in range(n))
TypeError: range() integer end argument expected, got sage.symbolic.expression.Expression.

All advice is welcome.

edit retag flag offensive close merge delete



The Problem is the ``range``, which cannot take an symbolic input. E.g. defining ``r(n) = range(n)`` does not work.

Daniel Krenn gravatar imageDaniel Krenn ( 2012-01-03 23:01:09 -0500 )edit

1 answer

Sort by ยป oldest newest most voted

answered 2012-01-04 01:01:50 -0500

I agree with @Daniel Krenn that this is a problem that range() is a function in python, not the level of sage. Thus range(var('n')) does not work.

I also met similar cases recently. Thus I believe this case is not rare and it would great if someone improve the situation to have something more consistent. How I solved the problem is use a workaround: sum over a list instead of sum directly. The code is as follows:

def H(n,k):
    return sum([sum([ S(2*i+1,b)*S(n-2*i-3,k-(2*i+2)-b) for b in range(k-(2*i+2)+1)]) for i in range(floor((n-5)/4)+1)])

It takes me a long time to test H(121,4). I can run H(21, 4) or other a few small numbers, but they always return 1. I am not sure is it the desired answer. But at least it returns something.

Could I also suggest something: when asking a question, it would be better to isolate the problem into as simple case as possible. Then it may be easier for other people to debug and you can get better and quicker answers. For example, with the definition of S, the following already gives an error:

sum( S(i,1),i,0,1)
edit flag offensive delete link more


Thank you, that works. This is not the whole thing, so don't worry about the answers. edit: I should add that it is no suprise H(121,4) is slow, since I am creating the a generating polynomial each time I want a coefficient of it. I will eventually want a generating polynomial for H in terms of the generating polynomials S, but that will come later. edit 2: I improved the timing a lot with @cached_function

alejandroerickson gravatar imagealejandroerickson ( 2012-01-04 05:47:20 -0500 )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

1 follower


Asked: 2012-01-03 17:00:17 -0500

Seen: 395 times

Last updated: Jan 04 '12