Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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]]
share|improve this question
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
up vote 2 down vote accepted

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:


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


to return everything the way thy were:

DownValues[Cross] = temp

or just Quit the Kernel.

share|improve this answer
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];


samples of vec's behavior

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.