# Revision history [back]

I first thought you found a bug, but here is the reason of your problem, and a workaround:

Your problem summarizes as follows:

sage: A1, A2, A3, P1, P3, u1, u2, u3, r1, r2, r3 = var('A1 A2 A3 P1 P3 u1 u2 u3 r1 r2 r3')
sage: eq7a = P1 - P3 == -(A1*r1*u1^2 + A2*r2*u2^2 - A3*r3*u3^2)/A3
sage: eq7a.subs_expr(A3*r3*u3^2 == (A2*u2*r2 + A1*r1*u1)*u3)
P1 - P3 == -(A1*r1*u1^2 + A2*r2*u2^2 - A3*r3*u3^2)/A3


While you expect (as we got with d/g == ((b + c)*k + f)/g):

P1 - P3 == -(A1*r1*u1^2 + A2*r2*u2^2 - (A2*u2*r2 + A1*r1*u1)*u3)/A3


The fun thing is that, if we reverse two signs, it works as expected:

sage: A1, A2, A3, P1, P3, u1, u2, u3, r1, r2, r3 = var('A1 A2 A3 P1 P3 u1 u2 u3 r1 r2 r3')
sage: eq7a = P1 - P3 == -(A1*r1*u1^2 - A2*r2*u2^2 + A3*r3*u3^2)/A3
sage: eq7a.subs_expr(A3*r3*u3^2 == (A2*u2*r2 + A1*r1*u1)*u3)
P1 - P3 == -(A1*r1*u1^2 - A2*r2*u2^2 + (A1*r1*u1 + A2*r2*u2)*u3)/A3


The problem is not in the product, but in the subtraction, or more precisely the interplay between both. Let us understand this:

When you write:

sage: a, b = var('a b')
sage: y = a - b


You do not have the operator sub with operands a and b:

sage: y.operator()
sage: y.operands()
[a, -b]


Also:

sage: (-b).operator()
<function operator.mul>
sage: (-b).operands()
[b, -1]


As you can see, the symbolic ring understands a - b as the sum of a and -b and -b as the product of b and -1. So a-b is like sum([a,mul[b,-1]]), which you can vizualize as a tree:

  a
/
-
\
b


versus

  a
/
+   b
\ /
*
\
-1


sage: (-A3*r3*u3^2).operator()
<function operator.mul>
sage: (-A3*r3*u3^2).operands()
[A3, r3, u3^2, -1]


If you imagine symbolic expressions as trees, it is now easy to understand why Sage is not able to do your substitution, you want to substitute mul([A3, r3, u3^2]) which is not a subtree of your expression (while mul([A3, r3, u3^2, -1]) is).

So, the workaround is now easy guess: you should not substitute A3*r3*u3^2 in your expression, but -A3*r3*u3^2:

sage: sage: A1, A2, A3, P1, P3, u1, u2, u3, r1, r2, r3 = var('A1 A2 A3 P1 P3 u1 u2 u3 r1 r2 r3')
sage: sage: eq7a = P1 - P3 == -(A1*r1*u1^2 + A2*r2*u2^2 - A3*r3*u3^2)/A3
sage: sage: eq7a.subs_expr(-A3*r3*u3^2 == -(A2*u2*r2 + A1*r1*u1)*u3)
P1 - P3 == -(A1*r1*u1^2 + A2*r2*u2^2 - (A1*r1*u1 + A2*r2*u2)*u3)/A3


As you wanted.

That said, you should know that in general the symbolic ring is very stupid. If you only use products and sums (i mean no sin, log or stuff like that), it could be worth trying to work with multivariate polynomial or fractions rings and quotients.

I first thought you found a bug, but here is the reason of your problem, and a workaround:

Your problem summarizes as follows:

sage: A1, A2, A3, P1, P3, u1, u2, u3, r1, r2, r3 = var('A1 A2 A3 P1 P3 u1 u2 u3 r1 r2 r3')
sage: eq7a = P1 - P3 == -(A1*r1*u1^2 + A2*r2*u2^2 - A3*r3*u3^2)/A3
sage: eq7a.subs_expr(A3*r3*u3^2 == (A2*u2*r2 + A1*r1*u1)*u3)
P1 - P3 == -(A1*r1*u1^2 + A2*r2*u2^2 - A3*r3*u3^2)/A3


While you expect (as we got with d/g == ((b + c)*k + f)/g): in your smaller example):

P1 - P3 == -(A1*r1*u1^2 + A2*r2*u2^2 - (A2*u2*r2 + A1*r1*u1)*u3)/A3


The fun thing is that, if we reverse two signs, it works as expected:

sage: A1, A2, A3, P1, P3, u1, u2, u3, r1, r2, r3 = var('A1 A2 A3 P1 P3 u1 u2 u3 r1 r2 r3')
sage: eq7a = P1 - P3 == -(A1*r1*u1^2 - A2*r2*u2^2 + A3*r3*u3^2)/A3
sage: eq7a.subs_expr(A3*r3*u3^2 == (A2*u2*r2 + A1*r1*u1)*u3)
P1 - P3 == -(A1*r1*u1^2 - A2*r2*u2^2 + (A1*r1*u1 + A2*r2*u2)*u3)/A3


The problem is not in the product, but in the subtraction, or more precisely the interplay between both. Let us understand this:

When you write:

sage: a, b = var('a b')
sage: y = a - b


You do not have the operator sub with operands a and b:

sage: y.operator()
sage: y.operands()
[a, -b]


Also:

sage: (-b).operator()
<function operator.mul>
sage: (-b).operands()
[b, -1]


As you can see, the symbolic ring understands a - b as the sum of a and -b and -b as the product of b and -1. So a-b is like sum([a,mul[b,-1]]), which you can vizualize as a tree:

  a
/
-
\
b


versus

  a
/
+   b
\ /
*
\
-1


sage: (-A3*r3*u3^2).operator()
<function operator.mul>
sage: (-A3*r3*u3^2).operands()
[A3, r3, u3^2, -1]


If you imagine symbolic expressions as trees, it is now easy to understand why Sage is not able to do your substitution, you want to substitute mul([A3, r3, u3^2]) which is not a subtree of your expression (while mul([A3, r3, u3^2, -1]) is).

So, the workaround is now easy guess: you should not substitute A3*r3*u3^2 in your expression, but -A3*r3*u3^2:

sage: sage: A1, A2, A3, P1, P3, u1, u2, u3, r1, r2, r3 = var('A1 A2 A3 P1 P3 u1 u2 u3 r1 r2 r3')
sage: sage: eq7a = P1 - P3 == -(A1*r1*u1^2 + A2*r2*u2^2 - A3*r3*u3^2)/A3
sage: sage: eq7a.subs_expr(-A3*r3*u3^2 == -(A2*u2*r2 + A1*r1*u1)*u3)
P1 - P3 == -(A1*r1*u1^2 + A2*r2*u2^2 - (A1*r1*u1 + A2*r2*u2)*u3)/A3


As you wanted.

That said, you should know that in general the symbolic ring is very stupid. If you only use products and sums (i mean no sin, log or stuff like that), it could be worth trying to work with multivariate polynomial or fractions rings and quotients.

I first thought you found a bug, but here is the reason of your problem, and a workaround:

Your problem summarizes as follows:

sage: A1, A2, A3, P1, P3, u1, u2, u3, r1, r2, r3 = var('A1 A2 A3 P1 P3 u1 u2 u3 r1 r2 r3')
sage: eq7a = P1 - P3 == -(A1*r1*u1^2 + A2*r2*u2^2 - A3*r3*u3^2)/A3
sage: eq7a.subs_expr(A3*r3*u3^2 == (A2*u2*r2 + A1*r1*u1)*u3)
P1 - P3 == -(A1*r1*u1^2 + A2*r2*u2^2 - A3*r3*u3^2)/A3


While you expect (as we got with d/g == ((b + c)*k + f)/g in your smaller example):

P1 - P3 == -(A1*r1*u1^2 + A2*r2*u2^2 - (A2*u2*r2 + A1*r1*u1)*u3)/A3


The fun thing is that, if we reverse two signs, it works as expected:

sage: A1, A2, A3, P1, P3, u1, u2, u3, r1, r2, r3 = var('A1 A2 A3 P1 P3 u1 u2 u3 r1 r2 r3')
sage: eq7a = P1 - P3 == -(A1*r1*u1^2 - A2*r2*u2^2 + A3*r3*u3^2)/A3
sage: eq7a.subs_expr(A3*r3*u3^2 == (A2*u2*r2 + A1*r1*u1)*u3)
P1 - P3 == -(A1*r1*u1^2 - A2*r2*u2^2 + (A1*r1*u1 + A2*r2*u2)*u3)/A3


The problem is not in the product, but in the subtraction, or more precisely the interplay between both. Let us understand this:

When you write:

sage: a, b = var('a b')
sage: y = a - b


You do not have the operator sub with operands a and b:

sage: y.operator()
sage: y.operands()
[a, -b]


Also:

sage: (-b).operator()
<function operator.mul>
sage: (-b).operands()
[b, -1]


As you can see, the symbolic ring understands a - b as the sum of a and -b and -b as the product of b and -1. So a-b is like sum([a,mul[b,-1]]), which you can vizualize as a tree:

  a
/
-
\
b


versus

  a
/
+   b
\ /
*
\
-1


sage: (-A3*r3*u3^2).operator()
<function operator.mul>
sage: (-A3*r3*u3^2).operands()
[A3, r3, u3^2, -1]


If you imagine symbolic expressions as trees, it is now easy to understand why Sage is not able to do your substitution, you want to substitute mul([A3, r3, u3^2]) which is not a subtree of your expression (while mul([A3, r3, u3^2, -1]) is).

So, the workaround is now easy guess: you should not substitute A3*r3*u3^2 in your expression, but -A3*r3*u3^2:

sage: sage: A1, A2, A3, P1, P3, u1, u2, u3, r1, r2, r3 = var('A1 A2 A3 P1 P3 u1 u2 u3 r1 r2 r3')
sage: sage: eq7a = P1 - P3 == -(A1*r1*u1^2 + A2*r2*u2^2 - A3*r3*u3^2)/A3
sage: sage: eq7a.subs_expr(-A3*r3*u3^2 == -(A2*u2*r2 + A1*r1*u1)*u3)
P1 - P3 == -(A1*r1*u1^2 + A2*r2*u2^2 - (A1*r1*u1 + A2*r2*u2)*u3)/A3


As you wanted.

That said, you should know that in general the symbolic ring is very stupid. If you only use products and sums (i mean no sin, log or stuff like that), it could be worth trying to work with multivariate polynomial or fractions rings and their quotients.