5
$\begingroup$

In mathematics the matrix product is a bilinear operation $$ \alpha A \cdot(\beta B + \gamma C) = \alpha\beta ( A \cdot B )+ \alpha \gamma (A\cdot C ), $$ where capital letters denote matrices and greek letters scalars.

Therefore $$ A \cdot B + A\cdot (-B) = 0. $$

But it seems this relation is not implemented in Mathematicas Dot function, especially

Dot[a,b]+Dot[a,-b]

does not evaluate to 0. So, how can I define a bilinear matrix product in Mathematica?

$\endgroup$

3 Answers 3

7
$\begingroup$

Mathematica is "aware" of linearity of Dot in all its arguments, but to exploit it you need to tell Mathematica which expressions represent Matrices, and explicitly ask to expand expression using TensorExpand function:

ClearAll[α, β, γ, δ, a, b, c, d, k, l, m, n]
TensorExpand[
    Dot[α a, β b + γ c, δ d],
    Assumptions ->
        a ∈ Matrices[{k, l}] && (b|c) ∈ Matrices[{l, m}] && d ∈ Matrices[{m, n}]
]
(* α β δ a.b.d + α γ δ a.c.d *)

You can also use it to exploit $a \cdot b + a\cdot (-b) = 0$ identity:

TensorExpand[
    Dot[a, b] + Dot[a, -b],
    Assumptions -> a ∈ Matrices[{m, n}] && b ∈ Matrices[{n, k}]
]
(* 0 *)

Old answer using TensorReduce

Mathematica is "aware" of $a \cdot b + a\cdot (-b) = 0$ identity for matrices, but you need to tell Mathematica that a and b represent Matrices, and explicitly ask for "canonical form" using TensorReduce:

ClearAll[a, b, m, n, k]
$Assumptions = a ∈ Matrices[{m, n}] && b ∈ Matrices[{n, k}];
Dot[a, b] + Dot[a, -b]
% // TensorReduce
(* a.(-b) + a.b *)
(* 0 *)

As with any function taking Assumptions option defaulting to $Assumptions, you can localize assumptions by passing them explicitly to TensorReduce:

TensorReduce[
    Dot[a, b] + Dot[a, -b], 
    Assumptions -> a ∈ Matrices[{m, n}] && b ∈ Matrices[{n, k}]
]
(* 0 *)

or by using Assuming, as suggested in comment by Jason B:

Assuming[
    a ∈ Matrices[{m, n}] && b ∈ Matrices[{n, k}],
    Dot[a, b] + Dot[a, -b] // TensorReduce
]
(* 0 *)
$\endgroup$
2
  • 3
    $\begingroup$ You could use Assuming[a \[Element] Matrices[{m, n}] && b \[Element] Matrices[{n, k}], Dot[a, b] + Dot[a, -b] // TensorReduce ] to avoid modifying the global $Assumptions $\endgroup$
    – Jason B.
    Mar 8, 2016 at 13:42
  • $\begingroup$ @JasonB Thanks, added it to the answer. $\endgroup$
    – jkuczm
    Mar 8, 2016 at 14:08
6
$\begingroup$

In raw symbolic form, Mathematica, simply doesn't know what a and b in a.b + a.-bare, so it doesn't evaluate the expression. However, given a hint ...

With[{a = {x, y}, b = {u, y}}, a.b + a.-b]]

0

$\endgroup$
5
  • 1
    $\begingroup$ Slightly simpler: With[{a = {x, y}, b = {u, y}}, a.b + a.-b] $\endgroup$ Mar 8, 2016 at 13:22
  • $\begingroup$ But Mathematica doesn't have to know anything about a and b, because the relation holds for all a and b. Much like a-a=0. $\endgroup$
    – murphy
    Mar 8, 2016 at 13:36
  • 3
    $\begingroup$ @murphy, but from the documentation "When its arguments are not lists or sparse arrays, Dot remains unevaluated." $\endgroup$
    – Jason B.
    Mar 8, 2016 at 13:38
  • $\begingroup$ @DavidG.Stork. Good catch. My brain doesn't seem to be fully functional today. $\endgroup$
    – m_goldberg
    Mar 8, 2016 at 13:42
  • 1
    $\begingroup$ @murphy : So, when $a$ is a 4-by-3 matrix and $b$ is a 17 element vector, this relation holds? Remember, if I don't tell you anything about the types of $a$ and $b$, they can be anything. $\endgroup$ Mar 8, 2016 at 21:55
4
$\begingroup$

There are small number of rules that make a function bilinear, so why not just implement them directly?

ClearAll@blDot;
Attributes[blDot] = {OneIdentity, Flat, Orderless};
blDot[Plus[a_, b_], c_] := blDot[a, c] + blDot[b, c];
blDot[Times[a_, b_], c_] := Times[a, blDot[b, c]];
blDot[a_, b_] := Dot[a, b]

It works on these examples,

blDot[a, (b + c)]
blDot[(a + d), (b + c)]
blDot[a, b] + blDot[a, -b]
(* a.b + a.c *)
(* a.b + a.c + b.d + c.d *)
(* 0 *)

But you have to be careful, since Times still has the attribute Orderless (and I wouldn't recommend changing that), it has no way of knowing which of the multiplied items is a number and which a vector. So you get this,

blDot[A, -α B]
(* -B A.α *)

when you might have wanted this

(* -α A.B *)
$\endgroup$

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.