Ask Your Question
1

Print symbolic variables like a_1 in A[1] style

asked 2018-10-06 05:30:25 +0200

DanialBagh gravatar image

Because of Sagemath's problem with symbolic arrays, I have defined my vectors like this:

A =[0 for j in range(4)]
for j in range(4):
    A[j]=var('a_'+str(j))

I have some symbolic variables stored in another variable. Lets say I have a subroutine that works with A[i] and in the end, L becomes something such as: L=a_1+a_2*a_3. When I print L, I want to have it printed in the original vector format. So when I type L or print(L) in a cell and press enter, my desired output is A[1]+A[2]*A[3] and not a_1+a_2*a_3. I want this type of output because I am transferring SageMath outputs to C where I employ indexed arrays. How can I achieve this?

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
2

answered 2018-10-06 10:23:45 +0200

rburing gravatar image

updated 2018-10-06 10:39:04 +0200

Indeed var('A[0]') is not allowed, because it requires the name to be a valid Python identifier (probably because it wants to be able to inject it into the namespace). However we don't care about injecting into the namespace, because this is effectively already done through the name of the list.

Reading the source of var we find it calls SR.var which calls SR.symbol. This is the one we want:

sage: A = [SR.symbol('A[%d]' % j) for j in range(4)]
sage: A[3]^2
A[3]^2

Note that not all expressions are immediately valid C-expressions in this way, e.g. you still have to transform a^b to pow(a, b) or something similar. For this purpose you can e.g. convert the expression to a sympy expression with sympy.sympify(...) and use their C-code generator.

edit flag offensive delete link more

Comments

1

Thank you for the answer. However, the solution you said is causing problems for me. When I try to apply the trig_reduce() command to something such as (B[2]*cos(x)*cos(2*x)).trig_reduce(), it returns an error unable to make sense of Maxima expression.

DanialBagh gravatar imageDanialBagh ( 2018-10-06 10:43:00 +0200 )edit
1

Ah, I didn't think about the interfaces to other programs. What you can do is use your original variable names, and substitute them by the ones I defined at the very last step before output. Something like expr.subs({var('a_%d' % j) : SR.symbol('A[%d]' % j) for j in range(4)}).

rburing gravatar imagerburing ( 2018-10-06 10:46:39 +0200 )edit

Thank you very much! Yes your solution actually works! I will make the substitution at the very end before interfacing to C. Incidentally, since you have been so helpful, would it be possible to give me a hint about what I can do about the conversion of a^b to pow(a,b) problem? Should I iterate over expressions with operands() and factor_list() to identify powers and print out the power formulas in a new format?

DanialBagh gravatar imageDanialBagh ( 2018-10-06 10:55:08 +0200 )edit
2

You're welcome. I wouldn't try to do that myself. I recommend (also in my answer, slightly edited since the original) to convert the expression to a sympy expression and to use their codegen which can generate C code.

rburing gravatar imagerburing ( 2018-10-06 11:00:32 +0200 )edit

Yes, I noticed your answer edit. Thanks alot. I was trying to substitute but I had to use a new name, but your approach eliminates the need for declaring new names. Thank you. Also thanks about the sympy advice for automatic C code conversion. Are there options for MATLAB and BASIC languages too?

DanialBagh gravatar imageDanialBagh ( 2018-10-06 11:06:05 +0200 )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

Stats

Asked: 2018-10-06 05:30:25 +0200

Seen: 477 times

Last updated: Oct 06 '18