Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I want to define my own little 'Inner Product' function satisfying properties of linearity and commutativity, and I'd like to use the "$\langle$" and "$\rangle$" symbols to output my results. For this I am using AngleBracket which has no built-in meaning.

I was able to use SetAttributes[AngleBracket,Orderless] to give my inner product the property of commutativity. $\langle v,w\rangle=\langle w,v\rangle$.

Then I am able to inconsistently get the AngleBracket to distribute over addition using for example Distribute[AngleBracket[u+v,w]]

But I am at a loss to impose the conditions $\langle a v, w\rangle=a\langle v,w \rangle$ where $a$ satisfies NumericQ[a]==True, and especially $\langle 0,v\rangle = 0$.

How can do this? Do I need to write my own 'myInnerProductSimplify' function?

share|improve this question
this could be a start: Format[bk[a_, b_]] = AngleBracket[a, b]; bk[a_ u_, v_] := a bk[u, v] /; NumericQ[a]; bk[b_, a_ + c__] := bk[b, a] + bk[b, c] – chris Jan 8 '13 at 10:25
By definition, the arguments of an inner product have to be elements of the same vector space. Because 0 is not the same as {0} which is not the same as {0,0}, which is not the same as (say) an $L^2$ integrable complex-valued function on a space--all of which could be considered vectors--it should not be the case that $\langle 0,v\rangle = 0$: that expression is, in general, nonsensical. To avoid hidden surprises, consider creating an appropriate vector type and defining AngleBracket as a (sesquilinear) bivariate function of vectors. – whuber Jan 8 '13 at 17:29
up vote 4 down vote accepted

From your question it can be deduced that you're interested only in the Euclidean scalar product for real vector spaces, so I'll make that assumption.

In version 9, I think the cleanest way to do the symbolic manipulations you're after is to use the new capabilities of TensorReduce. The special case of a null vector does require care because the product of the scalar $0$ with a vector is evaluated by Mathematica to yield $0$ which should then be interpreted as the null vector. This causes no problems if we define AngleBracket to yield zero for such $0$ arguments. So the following works if we make a decision at the outset what symbols we will assume to represent vectors - here I add that to the global variable $Assumptions:

AngleBracket[0, y_] := 0
AngleBracket[x_, 0] := 0
AngleBracket[x_, y_] := Dot[x, y]

$Assumptions = 
a ∈ Vectors[dim, Reals] && b ∈ Vectors[dim, Reals];

Now some tests:

AngleBracket[3 a, b] == 3 AngleBracket[a, b] // TensorReduce

(* ==> True *)

Assuming[x ∈ Reals, 
 TensorReduce[AngleBracket[x a, b] == x AngleBracket[a, b]]]

(* ==> True *)

Assuming[x ∈ Reals, 
 TensorReduce[AngleBracket[a, x b] == x AngleBracket[a, b]]]

(* ==> True *)

So to do the simplifications in the above equations, one wraps them in TensorReduce. The scalar x is introduced through an additional assumption which I could have added to $Assumptions, too.

The use of AngleBracket instead of purely the built-in Dot is still useful here because it allows me to handle the special case involving the null vector. For that I personally prefer to use BraKet, by the way, because it only requires a single escape sequence to get the template for both factors of the scalar product.

share|improve this answer
+1 for TensorReduce and Vectors -- I hadn't run across these yet. – Michael E2 Jan 9 '13 at 3:16

If I set

SetAttributes[AngleBracket, Orderless];
AngleBracket[a_?NumericQ u_, v_] := a AngleBracket[u, v];

then I get

2 AngleBracket[u, 6 v] == AngleBracket[3 u, 4 v]
(* -> True *)
share|improve this answer
+1 because this does solve the question as it was posed. – Jens Jan 9 '13 at 3:25

For a starter, I would use a function angleExpand like this:

SetAttributes[AngleBracket, Orderless];
ruAB = {
  AngleBracket[a_ (k_?NumericQ), b_] :> k AngleBracket[a, b],
  AngleBracket[(k_?NumericQ) a_, b_] :> k AngleBracket[a, b],
  AngleBracket[a_, (k_?NumericQ) b_] :> k AngleBracket[a, b],
  AngleBracket[a_, b_ (k_?NumericQ)] :> k AngleBracket[a, b]

angleExpand[expr_] := Expand[expr //. ruAB]


AngleBracket[7u, v 5]
% //angleExpand

will give:

<7 u,5 v>  
35 <u,v>
share|improve this answer
Given that AngleBracket and Times are orderless you should only need one of those 4 rules I believe (untested) – Rojo Jan 8 '13 at 13:55
@Rojo That's a good point. Although the OP hasn't asked for it, in general an inner product is sesquilinear, not bilinear, so it may be of use to illustrate a solution--as here--that would apply in full generality. – whuber Jan 8 '13 at 18:07

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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