# How to expand dot product by applying properties

I would like to expand a dot product which includes vectors $\vec{v_1}, \vec{v_2}, \dots$ and constants $c_1, c_2, \dots$

So that: $$c_1 \vec{v_1} \cdot \left(c_2 \vec{v_2}+ c_3 \vec{v_3}+\dots \right) = c_1 c_2 \left(\vec{v_1} \cdot \vec{v_2} \right)+ c_1 c_3 \left(\vec{v_1} \cdot \vec{v_3}\right) +\dots$$

I have:

Unprotect[Dot];
Dot[a_, Element[d_, Reals] b_, c_] := d Dot[a, b, c]
Protect[Dot];


Which works for:

$\qquad \left( 3 \vec{v_1}\right)\cdot\left( 4 \vec{v_2}\right) = 12 \vec{v_1}\cdot\vec{v_2}$

But this does not seem to work when I use variables:

$\qquad \mathsf{Element}[c_1 \mid c_2,\, \mathsf{Reals}]$

$\qquad \left( c_1 \vec{v_1}\right)\cdot\left( c_2 \vec{v_2}\right) = \left( c_1 \vec{v_1}\right)\cdot\left( c_2 \vec{v_2}\right)$

How can this be achieved? Ideally, I would like to do this in as general a way as possible.

• Does Distribute do what you want? – Patrick Stevens Oct 30 '15 at 18:24
• @Patrick Distribute[(c1 v1) . (c2 v2 + c3 v3)] will give (c1 v1).(c2 v2) + (c1 v1).(c3 v3), i.e. not quite there yet. Or where you suggesting something more? – MarcoB Oct 30 '15 at 19:38

Some time ago I developed a function for these sort of symbolic vector computations, called dotExand. For example, it will expand (2 x + 3 y, x-y) to 2(x,x)+(x,y)-3(y,y). Here I use the, at least in my country more common, notation (x,y) for the inner product of the vectors x and y. The advantage is that complicated expressions become more readable in this notation than in the infix notation with the dot. To achieve this output, I define

MakeBoxes[Dot[a_, b_], StandardForm] := RowBox[{"(", ToBoxes[a], ",", ToBoxes[b], ")"}];


The function dotExpand will work both in real and complex vector spaces. To this end, there is a second argument dom, which may take the values Reals or Complexes. The default value is Reals.

dotExpand[exp_, dom : (Reals | Complexes) : Reals] :=
Module[{res},
res = ExpandAll[exp] /. Dot[x_, y_] :> Distribute[Dot[x, y]];
res = res //. {
Dot[ (a_ /; Simplify[a \[Element] dom])   b_, c_] :> a Dot[b, c],
Dot[ a_,  (b_ /; Simplify[b \[Element] dom]) c_] :> Simplify[Conjugate[b]]  Dot[a, c],
If[dom === Reals, Dot[x_, y_] :> Sort[Dot[x, y]], Unevaluated[Sequence[]]]};
Collect[res, Dot[_, _]]  ]

dotExpand[Dot[ 2 x + 3 y, x - y ]]
(* 2 (x, x) + (x, y) - 3 (y, y) *)

dotExpand[Dot[ 2 x + I y, x - I y ], Complexes]
(* 2 (x, x) + 2 I (x, y) + I (y, x) - (y, y) *)


Assuming[ {c1, c2, c3} \[Element] Reals, dotExpand[ Dot[ c1 v1, c2 v2 + c3 v3]]]

(* c1 c2 (v1, v2) + c1 c3 (v1, v3) *)


The complex case:

Assuming[ {c1, c2, c3} \[Element] Complexes, dotExpand[ Dot[ c1 v1, c2 v2 + c3 v3], Complexes]]

(* c1 Conjugate[c2] (v1, v2) + c1 Conjugate[c3] (v1, v3) *)


Finally, consider in a real vector space a triangle with vertices a, b and c such that all three have the same lenght (i.e. the origin is in the centre of the circumscribed circle). Then the orthocentre of this triangle is given by h=a+b+c. The proof of this formula is a matter of substitution:

With[{h = a + b + c}, dotExpand[{(a - h).(c - b) == 0, (b - h).(a - c) == 0}] /. Dot[z_, z_] -> R^2]
(* {True, True} *)


Here is the best I've got so far. If you can be persuaded to write your vectors in a more distinguishable way, e.g. $v_1$ as v[1], then the following might work for you. I'm not so sure how robust it will be, but play around with it and let me know:

Clear[specialDot]
specialDot[expr_] := ReplaceAll[
Distribute[expr, Plus, Dot, Plus, Times],
v[a_] v[b_] -> v[a].v[b]
]


Here is the example you had:

specialDot[(c1 v[1]).(c2 v[2] + c3 v[3])]
(* Out: c1 c2 v[1].v[2] + c1 c3 v[1].v[3]*)


and here is another:

specialDot[(a v[1] + b v[2] - c v[3]).(d v[4] - e v[5])]
(* Out: a d v[1].v[4] - a e v[1].v[5] + b d v[2].v[4] - b e v[2].v[5] -
c d v[3].v[4] + c e v[3].v[5] *)


Let Subscript[v, 1][u], Subscript[v, 2][u], Subscript[v, 3][u] be the moving frame along the curve .

Define the dot product, cross product relations between the triad \ vectors

Clear[sc];
Clear[sd];
r1 = ((a_  Subscript[v, s_][u])\[Cross](b_  Subscript[v, t_][u]) :>
a b Subscript[v, s][u]\[Cross]Subscript[v, t][u]);
r2 = ((a_  Subscript[v, s_][u])\[Cross]( Subscript[v, t_][u]) :>
a Subscript[v, s][u]\[Cross] Subscript[v, t][u]);
r3 = (( Subscript[v, s_][u])\[Cross](b_  Subscript[v, t_][u]) :>
b Subscript[v, s][u]\[Cross]Subscript[v, t][u]);
r4 = ((a_  Subscript[v, s_][u])\[Cross](b_  Subscript[v, s_][u]) :> 0);
r5 = ((a_  Subscript[v, s_][u])\[Cross]( Subscript[v, s_][u]) :> 0);
r6 = (( Subscript[v, s_][u])\[Cross](b_  Subscript[v, s_][u]) :> 0);
r13 = ((a_[u]  Subscript[v, s_][u])\[Cross](b_[u]  Subscript[v, t_][
u]) :> a[u] b[u] Subscript[v, s][u]\[Cross]Subscript[v, t][u]);
r14 = ((a_ [u] Subscript[v, s_][u])\[Cross]( Subscript[v, t_][u]) :>
a[u] Subscript[v, s][u]\[Cross] Subscript[v, t][u]);
r15 = (( Subscript[v, s_][u])\[Cross](b_ [u] Subscript[v, t_][u]) :>
b[u] Subscript[v, s][u]\[Cross]Subscript[v, t][u]);
r16 = ((a_[u]  Subscript[v, s_][u])\[Cross](b_[u] Subscript[v, s_][
u]) :> 0);
r17 = ((a_ [u] Subscript[v, s_][u])\[Cross]( Subscript[v, s_][u]) :>
0);
r18 = (( Subscript[v, s_][u])\[Cross](b_ [u] Subscript[v, s_][u]) :>
0);
r19 = (Subscript[v, 1][u]\[Cross]Subscript[v, 2][u] :>
Subscript[v, 3][u]);
r20 = (Subscript[v, 2][u]\[Cross]Subscript[v, 1][u] :> -Subscript[v,
3][u]);
r21 = (Subscript[v, 2][u]\[Cross]Subscript[v, 3][u] :>
Subscript[v, 1][u]);
r22 = (Subscript[v, 3][u]\[Cross]Subscript[v, 2][u] :> -Subscript[v,
1][u]);
r23 = (Subscript[v, 3][u]\[Cross]Subscript[v, 1][u] :>
Subscript[v, 2][u]);
r24 = (Subscript[v, 1][u]\[Cross]Subscript[v, 3][u] :> -Subscript[v,
2][u]);
r25 = (Subscript[v, 1][u]\[Cross]Subscript[v, 1][u] :> 0);
r26 = (Subscript[v, 2][u]\[Cross]Subscript[v, 2][u] :> 0);
r27 = (Subscript[v, 3][u]\[Cross]Subscript[v, 3][u] :> 0);
f1 = ((a_  Subscript[v, s_][u]).(b_  Subscript[v, t_][u]) :>
a b Subscript[v, s][u].Subscript[v, t][u]);
f2 = ((a_  Subscript[v, s_][u]).( Subscript[v, t_][u]) :>
a Subscript[v, s][u]. Subscript[v, t][u]);
f3 = (( Subscript[v, s_][u]).(b_  Subscript[v, t_][u]) :>
b Subscript[v, s][u].Subscript[v, t][u]);
f4 = ((a_  Subscript[v, s_][u]).(b_  Subscript[v, s_][u]) :> a b);
f5 = ((a_  Subscript[v, s_][u]).( Subscript[v, s_][u]) :> a);
f6 = (( Subscript[v, s_][u]).(b_  Subscript[v, s_][u]) :> 0);
f13 = ((a_[u]  Subscript[v, s_][u]).(b_[u]  Subscript[v, t_][u]) :>
a[u] b[u] Subscript[v, s][u].Subscript[v, t][u]);
f14 = ((a_ [u] Subscript[v, s_][u]).( Subscript[v, t_][u]) :>
a[u] Subscript[v, s][u]. Subscript[v, t][u]);
f15 = (( Subscript[v, s_][u]).(b_ [u] Subscript[v, t_][u]) :>
b[u] Subscript[v, s][u].Subscript[v, t][u]);
f16 = ((a_[u]  Subscript[v, s_][u]).(b_[u] Subscript[v, s_][u]) :>
a b);
f17 = ((a_ [u] Subscript[v, s_][u]).( Subscript[v, s_][u]) :> a);
f18 = (( Subscript[v, s_][u]).(b_ [u] Subscript[v, s_][u]) :> b);
f19 = (Subscript[v, 1][u].Subscript[v, 2][u] :> 0);
f20 = (Subscript[v, 2][u].Subscript[v, 1][u] :> 0);
f21 = (Subscript[v, 2][u].Subscript[v, 3][u] :> 0);
f22 = (Subscript[v, 3][u].Subscript[v, 2][u] :> 0);
f23 = (Subscript[v, 3][u].Subscript[v, 1][u] :> 0);
f24 = (Subscript[v, 1][u].Subscript[v, 3][u] :> 0);
f25 = (Subscript[v, 1][u].Subscript[v, 1][u] :> 1);
f26 = (Subscript[v, 2][u].Subscript[v, 2][u] :> 1);
f27 = (Subscript[v, 3][u].Subscript[v, 3][u] :> 1);
sc[expr_] := {Distribute[expr] /. {r1, r2, r3, r4, r5, r6, r13, r14,
r15, r16, r17, r18}} /. {r19, r20, r21, r22, r23, r24, r25, r26,
r27}
sd[expr_] := {Distribute[expr] /. {f1, f2, f3, f4, f5, f6, f13, f14,
f15, f16, f17, f18}} /. {f19, f20, f21, f22, f23, f24, f25, f26,
f27}
{Derivative[1][Subscript[v, 1]][u_] := κ[u] Subscript[v, 2][u],
Derivative[1][Subscript[v, 2]][
u_] := τ[u] Subscript[v, 3][u] - κ[u] Subscript[v, 1][
u],
Derivative[1][Subscript[v, 3]][u_] := -τ[u] Subscript[v, 2][u]};
expr = (κ[u] τ[u] Subscript[v, 3][u] + κ[u] τ[
u] Subscript[v, 2][u] + κ[u] τ[u] Subscript[v, 1][
u])\[Cross](g[u] Subscript[v, 1][u] + y[u] Subscript[v, 2][u]);
expr1 = (κ[u] τ[u] Subscript[v, 3][u] + κ[
u] τ[u] Subscript[v, 2][u] + κ[u] τ[
u] Subscript[v, 1][u]).(g[u] Subscript[v, 1][u] +
y[u] Subscript[v, 2][u]);
sc[expr]
sd[expr1]
{-y[u] κ[u] τ[u] Subscript[v, 1][u] +
g[u] κ[u] τ[u] Subscript[v, 2][u] -
g[u] κ[u] τ[u] Subscript[v, 3][u] +
y[u] κ[u] τ[u] Subscript[v, 3][u]}

{g[u] κ[u] τ[u] + y[u] κ[u] τ[u]}