First time here? Check out the FAQ!

Ask Your Question
1

Print symbolic variables like a_1 in A[1] style

asked 6 years ago

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?

Preview: (hide)

1 Answer

Sort by » oldest newest most voted
2

answered 6 years ago

rburing gravatar image

updated 6 years ago

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.

Preview: (hide)
link

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 ( 6 years ago )
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 ( 6 years ago )

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 ( 6 years ago )
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 ( 6 years ago )

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 ( 6 years ago )

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: 6 years ago

Seen: 677 times

Last updated: Oct 06 '18