Simplification with dot products

147 views
Skip to first unread message

Nico Schlömer

unread,
Feb 27, 2017, 12:04:13 PM2/27/17
to sympy
I have a somewhat large expression in inner products,
```
          zeta = (
              - <e0, e0> * <e1, e1> * <e2, e2>
              + 4 * <e0, e1> * <e1, e2> * <e2, e0>
              + (
                  + <e0, e0> * <e1, e2>
                  + <e1, e1> * <e2, e0>
                  + <e2, e2> * <e0, e1>
              ) * (
                  + <e0, e0> + <e1, e1> + <e2, e2>
                  - <e0, e1> - <e1, e2> - <e2, e0>
                  )
              - <e0, e0>**2 * <e1, e2>
              - <e1, e1>**2 * <e2, e0>
              - <e2, e2>**2 * <e0, e1>
              )
```
and the symmetry in the expression has me suspect that it can be further simplified. Is sympy capable of simplifying vector/dot product expressions? A small example that, for example, takes
```
<a, c> + <b,d> - <b,c> - <a, d>
```
and spits out
```
<a-b, c-d>
```
would be great.

Alan Bromborsky

unread,
Feb 27, 2017, 12:37:59 PM2/27/17
to sy...@googlegroups.com
How the expression zeta obtained.  Do input the expression you show or is it obtained by vector algebraic operations on vector expressions.  I assume e0, e1, and e2 are arbitrary vectors.

--
You received this message because you are subscribed to the Google Groups "sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sympy+unsubscribe@googlegroups.com.
To post to this group, send email to sy...@googlegroups.com.
Visit this group at https://groups.google.com/group/sympy.
To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/2cb85a5e-2b5f-402f-82cb-fd4e2f738d93%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Nico Schlömer

unread,
Feb 27, 2017, 12:44:10 PM2/27/17
to sympy
Thanks for the reply.

>  I assume e0, e1, and e2 are arbitrary vectors.

Indeed, they can be anything. (I'm looking at 3 dimensions here but given the fact that everything is a dot product I assume that doesn't play much of a role.)

Cheers,
Nico

To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.

Aaron Meurer

unread,
Feb 27, 2017, 3:39:24 PM2/27/17
to sy...@googlegroups.com
The function that does the simplification you want is factor():

In [22]: var('a b c d')
Out[22]: (a, b, c, d)

In [23]: factor(a*c + b*d - a*d - b*c)
Out[23]: (a - b)⋅(c - d)

However, I'm not sure how to apply it here. You can't just convert
your dot products to multiplications because it isn't true that <a,
b>*<c, d> = <a, c>*<b, d>.

You might need to write a naive factor that recursively collects terms
with the same coefficient. For instance

<a, c> + <b,d> - <b,c> - <a, d>

-> <a, c - d> + <b, d - c>
-> <a - b, c - d>

This also needs to recognize that c - d = -(d - c).
could_extract_minus_sign is useful for this.

I don't recall if something like this is already written in SymPy.

Aaron Meurer


On Mon, Feb 27, 2017 at 12:44 PM, Nico Schlömer
> https://groups.google.com/d/msgid/sympy/232c66f6-19a3-4672-8507-88631357e9c2%40googlegroups.com.

Aaron Meurer

unread,
Feb 27, 2017, 3:44:45 PM2/27/17
to sy...@googlegroups.com
Actually, I think you can just convert the symbols to multiplications,
but set them all as commutative=False so that they don't get
rearranged. Then you can apply factor() (which I believe basically
does the above algorithm for noncommutatives), and to convert back to
dot products, convert each multiplication pairwise, like a*b*c*d ->
<a, b>*<c, d> (also accounting for powers, like e1**2 == <e1, e1>).
I'm not 100% sure this won't produce a wrong answer, so it's worth
double checking it somehow (perhaps numerically).

This won't catch simplifications that require rearranging the inner
products, like <a, b> = <b, a> (or <a, b> = conjugate(<b, a>) as the
case may be).

Aaron Meurer

Nico Schlömer

unread,
Feb 27, 2017, 4:31:40 PM2/27/17
to sympy
Thanks for the suggestions.

The noncommutative option is probably too strict since `<a,b><c, d> != <c,d><a,b>` then. Or can I make only some multiplications noncommutative?

> You might need to write a naive factor 

Is there any documentation on this?

Cheers,
Nico

Aaron Meurer

unread,
Feb 27, 2017, 4:57:09 PM2/27/17
to sy...@googlegroups.com
It's possible you can get decent results just by sorting the dot
products before converting to multiplication, like (<e1, e1>*<e0, e1>
=> <e0, e1>*<e1, e1>).

I'm more worried about the order in the dot products themselves. You
could sort within the dot products themselves, like <e1, e0> => <e0,
e1>, but you might still run into problems, e.g., <e0, e1> + <e1, e2>
won't combine. Most likely the safest bet is that whatever you used to
generate your expression put the dot products in the order they should
be for the best simplification. And of course, if you are dealing with
complex inner products, you probably just want the expression with no
conjugates (since <a, b> + conjugate(<a, c>) doesn't really simplify
anyway).

It's not possible to have a*b*c*d = c*d*a*b but not a*b = b*a. The way
noncommutativity works is that it is defined on symbols. Each product
of terms pulls out the "commutative part" (everything with
commutative=True) to the front, and then keeps the rest, the
noncommutative part, in the order it was created in. For example:

In [27]: var('a')
Out[27]: a

In [28]: var("A B", commutative=False)
Out[28]: (A, B)

In [29]: A*a*B
Out[29]: a⋅A⋅B

There have been discussions in the past on being able to represent
more complex commutation relationships. But even if that were
implemented, you would need some algorithms for simplifying
expressions.

Aaron Meurer
> https://groups.google.com/d/msgid/sympy/8b71de13-95d8-410d-9f1e-d73f3c555aac%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages