# How to extract out a scalar multiplier?

I'm trying to make a custom multiplication operation, which would be distributive, as well as associative with normal multiplication by scalar. Using Distribute I can get the distributive transformation:

Distribute[dot[235 vec[i] + vec[j], vec[k] + vec[l]]]


dot[235 vec[i], vec[k]] + dot[235 vec[i], vec[l]] + dot[vec[j], vec[k]] + dot[vec[j], vec[l]]

Here dot is only defined via dot[vec[i_],vec[j_]]:=....

Now I need to transform these dot[235 vec[i], vec[k]]-like items into 235 dot[vec[i], vec[k]]. How can I do this?

• You should add a rule that factors out constants: dot[n_?NumericQ c_, d_] := n dot[c,d]. Another alternative taking advantage of the fact that your have your own vec datatype is dot[n_ c_vec, d_vec] := n dot[c,d]. Finally, you might be interested in setting SetAttributes[dot, Orderless] before the mentioned rules so that it works on the second argument also, automatically sort its arguments, etc. – QuantumDot Oct 1 '16 at 21:13

Code.

This will extract the factors from the arguments of dot that do not have head vec.

dot[(a : Except[_vec, _]) v1_vec, v2_vec] := a dot[v1, v2];

dot[v1_vec, (b : Except[_vec, _]) v2_vec] := b dot[v1, v2];

dot[(a : Except[_vec, _]) v1_vec, (b : Except[_vec, _]) v2_vec] := a b dot[v1, v2];


Usage.

dot[235 vec[i], vec[k]]
(* 235 dot[vec[i], vec[k]] *)

dot[vec[i], n vec[k]]
(* n dot[vec[i], vec[k]] *)

dot[235 vec[i], n vec[k]]
(* 235 n dot[vec[i], vec[k]] *)

• Great. And a third one should be with both a and b. – Ruslan Oct 1 '16 at 21:28
• Yes, I will add this to the code for completeness. – user31159 Oct 1 '16 at 21:29