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

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)


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))
H(121,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/___code___.py", line 10, in <module>
exec compile(u'H(_sage_const_121 ,_sage_const_4 )
File "", line 1, in <module>

File "/tmp/tmpKvQFbK/___code___.py", 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/___code___.py", 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.


edit retag close merge delete

1

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

Sort by » oldest newest most voted

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)

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