TransWikia.com

How do I simplify a vector expression?

Mathematica Asked on February 22, 2021

I am doing vector analysis. I have figured out that the following expression won’t be simplified in Mathematica:

Simplify[Dot[x, y] - Dot[y, x]]

I think the reason is that x and y could be matrices, so generally the operation does not commute. But for a vector, the commutation relation should hold. What I don’t know is how to tell Mathematica to consider x and y to be vectors.

Also, how can I expand Cross[x + y, z] to be Cross[x, y] + Cross[y, z]? I tried to use Expand and ExpandAll but neither worked.

BTW, in Mathematica, is it possible to define a abstract row/column vector without explicitly specifying the number of entries?

4 Answers

Here is a way to do all the things you asked for automatically, independently of Mathematica version. The approach relies on a special symbol to identify when we're dealing with a vector: Instead of using things like x, y etc. for vectors, the convention now is that vectors are written as vec[x], vec[y], etc.

You could also define the wrapper OverVector[x] for this purpose because it displays as $vec{x}$. But for this post I want to keep it simple, and the arrows wouldn't display easily in the source code below.

ClearAll[scalarProduct, vec]; 
SetAttributes[scalarProduct, {Orderless}]
vec /: Dot[vec[x_], vec[y_]] := scalarProduct[vec[x], vec[y]]
vec /: Cross[vec[x_], HoldPattern[Plus[y__]]] := 
 Map[Cross[vec[x], #] &, Plus[y]]
vec /: Cross[HoldPattern[Plus[y__]], vec[x_]] := 
 Map[Cross[#, vec[x]] &, Plus[y]]
scalarProduct /: MakeBoxes[scalarProduct[x_, y_], _] := 
 RowBox[{ToBoxes[x], ".", ToBoxes[y]}]

vec[x].vec[y]

(* ==> vec[x].vec[y] *)

vec[x].vec[y] == vec[y].vec[x]

(* ==> True *)

Cross[vec[x], vec[a] + vec[b]]

(* ==> vec[x][Cross]vec[a] + vec[x][Cross]vec[b] *)

Cross[vec[a] + vec[b], vec[x]]

(* ==> vec[a][Cross]vec[x] + vec[b][Cross]vec[x] *)

For the Dot product, I defined the behavior of vec such that it gets evaluated as a new function scalarProduct whose only algebraic property is that it's Orderless as you were expecting for the dot product of vectors. Of course this is only true for Euclidean dot products, so this assumption is implicit here. For more information on how this definition works, look up TagSetDelayed.

In addition, scalarProduct is given a customized display format by defining that it should again display as if it were a dot product when it appears in the low-level formatting function MakeBoxes.

For the distributive property of the cross product, I give vec the additional property that when it appears in Cross together with an expression of head Plus, the sum is expanded. Here the TagSetDelayed definitions are done for both orders, and contain a HoldPattern to prevent Plus from being evaluated too early in the definition.

Now you may come back with many more wishes: e.g., what about multiplicative scalars in the dot or cross product, and what about matrices. However, that's a wide field that opens up a can of worms, so I would say just implement the bare minimum of features you can get away with symbolically, then proceed with a concrete working basis so that you can write vectors as lists instead.

Another approach would be to define a new symbol for a custom dot product. That is done in this question.

Using OverVector

As mentioned above, you can replace vec by Overvector everywhere in the above source code, to get a better formatted result. Assuming you have done that (I won't bother to repeat the definitions with that change), here are some examples:

formatted

To enter these vector expressions, refer to the Basic Math assistant palette. The cross product can be entered as EsccrossEsc.

Another thing you asked for is to use the antisymmetry of the cross product in simplifications. That's actually done already if you invoke FullSimplify:

antisymmetry

Correct answer by Jens on February 22, 2021

If you have Mathematica Version 9, you can use Vectors and TensorReduce:

Assuming[(x | y) [Element] Vectors[n] , TensorReduce[Dot[x, y] - Dot[y, x]]]
(* 0 *)
TensorReduce[Dot[x, y] - Dot[y, x], Assumptions -> (x | y) [Element] Vectors[n]]
(* 0 *)
TensorReduce[Cross[x + y, z],  Assumptions -> (x | y | z) [Element] Vectors[n]]
(* x[Cross]z + y[Cross]z *)
Distribute[Cross[x + y, z]] (* this should work in all previous versions *)
(* x[Cross]z + y[Cross]z *)

Answered by kglr on February 22, 2021

Another way to achieve this, although possibly not the best (since it can have unintended consequences), is to use

SetAttributes[Dot, Orderless];

This will make all dot products commute (even matrices). However, if you only happen to be working with vectors, then this is by far the cleanest way.

Answered by Akoben on February 22, 2021

$Assumptions = (x | y) ∈ Vectors[d, Complexes]
Dot[x, y] - Dot[y, x] // TensorExpand

Answered by cvgmt on February 22, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP