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?
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:
To enter these vector expressions, refer to the Basic Math assistant palette. The cross product can be entered as Esccross
Esc.
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
:
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
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP