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]]
  • $\begingroup$ 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]]. $\endgroup$
    – Spawn1701D
    Apr 16, 2013 at 23:17
  • $\begingroup$ 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)" $\endgroup$ Apr 17, 2013 at 1:52
  • $\begingroup$ 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]] $\endgroup$
    – Spawn1701D
    Apr 17, 2013 at 2:05
  • $\begingroup$ 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]] $\endgroup$ Apr 17, 2013 at 2:42

3 Answers 3


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.

  • $\begingroup$ 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]]. $\endgroup$ Apr 17, 2013 at 3:44
  • $\begingroup$ @J.M. Its too deep, not for this rule but the following ones. $\endgroup$
    – Spawn1701D
    Apr 17, 2013 at 3:50
  • $\begingroup$ 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. $\endgroup$ Apr 17, 2013 at 4:32
  • $\begingroup$ @J.M. look the comments with the OP and you will understand why I thought so. $\endgroup$
    – Spawn1701D
    Apr 17, 2013 at 4:40
  • $\begingroup$ 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... $\endgroup$ Apr 17, 2013 at 4:43

You can use TensorReduce and Vectors:

$Assumptions = Element[vec[x] | vec[y], Vectors[{n}]];




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


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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