# Print symbolic variables like a_1 in A[1] style

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

Sort by » oldest newest most voted

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.

more

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.

( 2018-10-06 03:43:00 -0500 )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)}).

( 2018-10-06 03:46:39 -0500 )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?

( 2018-10-06 03:55:08 -0500 )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.

( 2018-10-06 04:00:32 -0500 )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?

( 2018-10-06 04:06:05 -0500 )edit