Free Algebra with symbolic coefficients

70 views
Skip to first unread message

Chris Thron

unread,
Sep 7, 2014, 1:28:02 PM9/7/14
to sage-s...@googlegroups.com
HI,
I'm trying to write a program that converts electromagnetic equations from CGS to MKS units. I've run into the following issues:

(1)  I have expressions like curl*H - c^(-1)*d_t*D, where curl and d_t express derivatives. In the process of conversion, sage switches the order and outputs:

 H*curl - D*d_t/c

I thought of defining a free algebra  over a symbolic ring, but this turns out to have problems. Apparently expand and simplify are not defined for expressions in a free algebra.  Sage chokes on the following code.

var('c, pi, c, mu_0,epsilon_0')
F.<curl,H,d_t,D,J> = FreeAlgebra(SR,5,'curl,H,d_t,D,J')

eqCGS =                                 curl*H  - c^(-1)*d_t*D                         ### CGS expression on this line ###

eq = eqCGS *                            (1/2)*mu_0^(-1/2)*pi^(-1/2)                ### Multiplicative factor on this line ###


assume(c>0,mu_0>0,epsilon_0>0)
eq = eq.subs({c == mu_0^(-1/2)*epsilon_0^(-1/2)})
eq = eq.subs({H:2*H})
eq = eq.subs({D : 2*pi^(1/2)*epsilon_0^(-1/2)*D})
eq = eq.subs({J : (1/2)*pi^(-1/2)*epsilon_0^(-1/2)*J})
eq = eq.expand()
eq = eq.simplify()
show('Original~(CGS)~version')
show(eqCGS)
show('MKS~version')
show(eq)


Furthermore, the code does not substitute for c. 

Any guidance would be appreciated 



Message has been deleted

Nils Bruin

unread,
Sep 7, 2014, 6:25:31 PM9/7/14
to sage-s...@googlegroups.com
On Sunday, September 7, 2014 10:28:02 AM UTC-7, Chris Thron wrote:
(1)  I have expressions like curl*H - c^(-1)*d_t*D, where curl and d_t express derivatives. In the process of conversion, sage switches the order and outputs:

 H*curl - D*d_t/c

Are you sure D and d_tand H and curl get swapped? I don't see that. Free algebras are defined to have their base ring in the centre, so H and c will commute with curl, d_t, H and D. Indeed, it will coefficients to the left of monomials in your free algebra generators.
 
I thought of defining a free algebra  over a symbolic ring, but this turns out to have problems. Apparently expand and simplify are not defined for expressions in a free algebra.  Sage chokes on the following code.

var('c, pi, c, mu_0,epsilon_0')
F.<curl,H,d_t,D,J> = FreeAlgebra(SR,5,'curl,H,d_t,D,J')

eqCGS =                                 curl*H  - c^(-1)*d_t*D                         ### CGS expression on this line ###

eq = eqCGS *                            (1/2)*mu_0^(-1/2)*pi^(-1/2)                ### Multiplicative factor on this line ###

assume(c>0,mu_0>0,epsilon_0>0)
eq = eq.subs({c == mu_0^(-1/2)*epsilon_0^(-1/2)})

That's right: substituting c is something that needs to happen in SR. You can do this coefficient-wise:

sage: eq = sum(b.subs(c == mu_0^(-1/2)*epsilon_0^(-1/2))*F(a) for a,b in eq); eq
1/2/(sqrt(mu_0)*sqrt(pi))*curl*H + (-1/2*sqrt(epsilon_0)/sqrt(pi))*d_t*D

(if you realize FreeAlgebra can also be defined over GF(p), QQ, ZZ then you see why it can't delegate "subs" calls to its coefficients as well)

eq = eq.subs({H:2*H})
eq = eq.subs({D : 2*pi^(1/2)*epsilon_0^(-1/2)*D})
eq = eq.subs({J : (1/2)*pi^(-1/2)*epsilon_0^(-1/2)*J})

These work because they're on free algebra level.
 
eq = eq.expand()
eq = eq.simplify()

These methods don't exist because on free algebra level, there's no expanding or simplifying to do. Elements are always expanded. Perhaps you want to do it on coefficients, in which case you can use the same coefficient-wise trick:

eq = sum([b.expand()*F(a) for a,b in eq])
eq = sum([b.simplify()*F(a) for a,b in eq])

(neither has any actual effect for your example)

Furthermore, the code does not substitute for c. 

For reasons explained above.
 
Any guidance would be appreciated 

Be aware that FreeAlgebra assumes its base ring to actually be a ring. SR isn't really a ring (e.g., it can have floats in it, so precision problems might creep in). For your applications, SR might be close enough to a ring for things to work, but use at your own peril.

Chris Thron

unread,
Sep 8, 2014, 9:48:44 PM9/8/14
to sage-s...@googlegroups.com
This works beautifully, thanks.  

I have another small issue:  I can't do substitutions in equality expressions with terms in the free algebra.  For instance, Sage tells me "Not iterable"


var('c, pi, c, mu_0,epsilon_0,epsilon,mu,q,Q,e')
F.<curl,div,grad,d_t,d_x,d_y,d_z,J,I,K,P,p,E,V,Phi,D,B,A,H,M,m,rho,sigma,C,R,Z,L> = FreeAlgebra(SR,27,'curl,div,grad,d_t,d_x,d_y,d_z,J,I,K,P,p,E,V,Phi,D,B,A,H,M,m,rho,sigma,C,R,Z,L')

eqCGS =                           curl*H - (1/c)*d_t*D == 4*pi/c*K                                        ### CGS expression on this line ###

eq =eqCGS*                          (1/2)*mu_0^(-1/2)*pi^(-1/2)                                          ### Multiplicative factor on this line ###

assume(mu_0>0,epsilon_0>0,pi>0,c>0,e>0)
eq = sum(b.subs(c == mu_0^(-1/2)*epsilon_0^(-1/2))*F(a) for a,b in eq)

show('Original (CGS) version')
show(eqCGS)
show('MKS version')
show(eq)


Thanks again for your help.

Nils Bruin

unread,
Sep 9, 2014, 11:15:10 AM9/9/14
to sage-s...@googlegroups.com
On Monday, September 8, 2014 6:48:44 PM UTC-7, Chris Thron wrote:
This works beautifully, thanks.  

I have another small issue:  I can't do substitutions in equality expressions with terms in the free algebra.  For instance, Sage tells me "Not iterable"


var('c, pi, c, mu_0,epsilon_0,epsilon,mu,q,Q,e')
F.<curl,div,grad,d_t,d_x,d_y,d_z,J,I,K,P,p,E,V,Phi,D,B,A,H,M,m,rho,sigma,C,R,Z,L> = FreeAlgebra(SR,27,'curl,div,grad,d_t,d_x,d_y,d_z,J,I,K,P,p,E,V,Phi,D,B,A,H,M,m,rho,sigma,C,R,Z,L')

eqCGS =                           curl*H - (1/c)*d_t*D == 4*pi/c*K                                        ### CGS expression on this line ###

Do check what you get back. At this point, eqCGS is bound to "False", because you've asked sage if two elements of F are equal that are not. The fact that "==" on SR does not always return a boolean is a big concession to calculus students that makes SR fit rather poorly with the rest of Python. Other sage structures (including FreeAlgebra) don't follow this exceptional behaviour. Imagine a programming language in which "2 != 3" does not provide an immediate boolean ... with SR you have that:

sage: SR(2) != SR(3)
2 != 3
sage: F(2) != F(3)
True

Your options are keeping track of LHS and RHS yourself or to take the difference of them.

sage:  eqCGS =                           curl*H - (1/c)*d_t*D - 4*pi/c*K


eq =eqCGS*                          (1/2)*mu_0^(-1/2)*pi^(-1/2)                                          ### Multiplicative factor on this line ###

It would be nice if this would fail as a result, but Python specifies that "False" is essentially equivalent to 0, so after this, eq is bound to 0.
 
assume(mu_0>0,epsilon_0>0,pi>0,c>0,e>0)
eq = sum(b.subs(c == mu_0^(-1/2)*epsilon_0^(-1/2))*F(a) for a,b in eq)

 Note that False * ( (1/2)*mu_0^(-1/2)*pi^(-1/2) ), which evaluates as 0*(  (1/2)*mu_0^(-1/2)*pi^(-1/2) ) doesn't involve any free algebra elements, so you're just getting an element of SR:

sage: parent(eq)
Symbolic Ring

It doesn't necessarily have all the properties that elements of F have. As a work-around you could simply make sure that you have an element of F:

sage: eq = sum(b.subs(c == mu_0^(-1/2)*epsilon_0^(-1/2))*F(a) for a,b in F(eq))

(which results in 0 of course, due to the earlier problems)
Reply all
Reply to author
Forward
0 new messages