3
$\begingroup$

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?

$\endgroup$
  • 1
    $\begingroup$ 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. $\endgroup$ – QuantumDot Oct 1 '16 at 21:13
4
$\begingroup$

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]] *)
$\endgroup$
  • 1
    $\begingroup$ Great. And a third one should be with both a and b. $\endgroup$ – Ruslan Oct 1 '16 at 21:28
  • $\begingroup$ Yes, I will add this to the code for completeness. $\endgroup$ – user31159 Oct 1 '16 at 21:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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