# How to expand a general expression in cross and dot product in Mathematica

I am looking for a way to simply the general expression in cross product and dot product with general vectors. I got a help in How do I simplify a vector expression? but soon I find that it doesn't work in the case

FullSimplify[Cross[vec[x], 2*vec[y]] + Cross[vec[y], 2*vec[x]] ]


it doesn't give zero. It seems that Mathematica doesn't know how to expand the following expression

Cross[vec[x], 2*vec[y]] -> 2*Cross[vec[x], vec[y]]

-
You have to create some rules for instance vec/: Cross[Times[al___,vl_vec,ar___],Times[bl___,vr_vec,br___]] := Times[al,ar,bl,br,Cross[vl,vr]]. – Spawn1701D Apr 16 '13 at 23:17
Hi there, thanks for your reply. I try that code, but when I apply that, it reports "TagSetDelayed::tagnf: Tag OverVector not found in (al___\ ar___\ vl_vec)[Cross](bl___ br___ vr_vec)" – user1285419 Apr 17 '13 at 1:52
Yes my mistake sorry, its too deep. You got to Unprotect Cross and assign the rule to Cross instead: Cross[Times[al___,vl_vec,ar___],Times[bl___,vr_vec,br___]] := Times[al,ar,bl,br,Cross[vl,vr]] – Spawn1701D Apr 17 '13 at 2:05
I am sorry to bother again. I try the following but it doesn't work, am I doing anything wrong? Unprotect[Cross]; Cross[Times[al___, vl_vec, ar___], Times[bl___, vr_vec, br___]] := Times[al, ar, bl, br, Cross[vl, vr]] FullSimplify[Cross[x, 2*y] + Cross[y, 2*x]] – user1285419 Apr 17 '13 at 2:42

Lets write some simple rules for Cross that will work in conjunction with the object vec:

first of all we have to Unprotect the command Cross:

Unprotect[Cross]


to be safe because we are screwing around with a system command we save the current set of downvalues to a temporary varaiable:

temp = DownValues[Cross]


we begin with a rule for the skew-symmetric property:

Cross[vl_vec,vr_vec]/;!OrderedQ[{vl,vr}] := -Cross[vr,vl]


we continue for the multiplication by a scalar rule

Cross[Times[al__, vl_vec], vr_vec] := Times[al, Cross[vl, vr]]
Cross[vl_vec,Times[al__, vr_vec]] := Times[al, Cross[vl, vr]]
Cross[Times[al__ ,vl_vec],Times[bl__, vr_vec]] := Times[al, bl, Cross[vl, vr]]


I split them in two in order to cover the case Cross[vec[x],2*vec[y]] for instance where one of the is not multiplied by a scalar. Now the command

Cross[vec[x], 2*vec[y]] + Cross[2*vec[y], vec[x]]


will give

0

to return everything the way thy were:

DownValues[Cross] = temp


or just Quit the Kernel.

-
Rather than unprotecting Cross[], it is usually better to use TagSet[]/TagSetDelayed[] associated with vec[]. For instance, here's the flipping rule: vec /: Cross[v1_vec, v2_vec] /; ! OrderedQ[{v1, v2}] := -Cross[v2, v1]. Now, try Cross[vec[y], vec[x]]. – J. M. Apr 17 '13 at 3:44
@J.M. Its too deep, not for this rule but the following ones. – Spawn1701D Apr 17 '13 at 3:50
How so? If you add vec /: Cross[Times[al__, vl_vec], vr_vec] := Times[al, Cross[vl, vr]] and then do Cross[3 vec[y], vec[x]], it still works. – J. M. Apr 17 '13 at 4:32
@J.M. look the comments with the OP and you will understand why I thought so. – Spawn1701D Apr 17 '13 at 4:40
Apparently, there's something wrong with his implementation of vec[], since TagSet[] is seeing it as an OverVector[] object. I think an answer is in order... – J. M. Apr 17 '13 at 4:43

Since it seems you want your vec[] objects to be nicely formatted, here's one way to go about it:

Remove[vec]; (* clear everything!! *)

vec /: MakeBoxes[vec[x_], StandardForm] := TagBox[FormBox[
TemplateBox[{MakeBoxes[x, StandardForm]}, "vec",
DisplayFunction :> (OverscriptBox[#1, "⇀"] &)],
StandardForm], StandardForm, Editable -> True]


Now, vec[x] will display as $\overset{\tiny\rightharpoonup}{x}$ in StandardForm. Having done this, we can again do Spawn's initial suggestion to use TagSetDelayed[]:

vec /: Cross[v1_vec, v2_vec] /; ! OrderedQ[{v1, v2}] := -Cross[v2, v1];
vec /: Cross[p_ v1_vec, v2_vec] := p Cross[v1, v2];
vec /: Cross[v1_vec, q_ v2_vec] := q Cross[v1, v2];


Test:

-