Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I want to work with a formal vector space spanned by integer triplets: $$ V=\text{span}\{(a,b,c):a,b,c\in\mathbb N^3\}, $$ such that Mathematica can do additions for me. For example,if I input

{1,0,1} + {2,0,1} + 3{1,0,1} - {4,4,7} - 3{2,0,1}

Instead of getting

{-4, -4, -5}

where it is calculated entrywise,

I would like Mathematica to return

4{1,0,1} - 2{2,0,1} - {4,4,7}

What is the simplest way to implement this?

share|improve this question
3  
It's difficult to answer without knowing what you want to do with these vectors. You should not try to force Mma to return what you quote. But instead of {1,0,1} you can use a symbol a and later substitute a -> {1,0,1}. Or you can use a special head 4 vec[1,0,1] - 2 vec[2,0,1] ... and later substitute vec -> List as needed. Or something similar to this. –  Szabolcs Mar 25 at 15:44

1 Answer 1

up vote 1 down vote accepted

The simplest way to get the output you want is to enter the objects representing the vectors as String like this:

"{1,0,1}" + "{2,0,1}" + 3 "{1,0,1}" - "{4,4,7}" - 3 "{2,0,1}"

4 {1,0,1} - 2 {2,0,1} - {4,4,7}

This is just a particularly simple version of what @Szabolcs mentioned in the comment: you don't want the lists representing the vectors to be understood as List objects, because otherwise Times will always look into them. By giving the "vectors" a Head different from List for which no special multiplication rules exist, they become like indivisible objects that behave the way you want under multiplication.

The good thing about String as the Head is that it not only hides the content from Times, but also still displays the way you want. The latter can in principle also be achieved by coming up with a completely new name like vec to wrap your list of components, and then defining how that new object displays by using Format:

Format[vec[x_, y_, z_]] = {x, y, z}
vec[1, 0, 1] + vec[2, 0, 1] + 3 vec[1, 0, 1] - vec[4, 4, 7] - 3 vec[2, 0, 1]

4 {1,0,1} -2 {2,0,1} - {4,4,7}

With the latter approach, you can also add more tricks:

vec[x_, y_, z_] /; GCD[x, y, z] != 1 := 
 Module[{g = GCD[x, y, z]}, g Apply[vec, {x, y, z}/g]]

vec[2, 2, 4]

(* ==> 2 {1, 1, 2} *)

This way, the integers in the vec components are reduced to the point where they are mutually prime, further reducing the number of vectors in a general expression, which is a simplification that can be done without doing all the other multiplications.

share|improve this answer
    
Both of these work thanks. But how can I also implement bracket / distributive rule, i.e. how can I make Mathematica return "4{1,0,1}+2{1,1,1}" when I type "2(2"{1,0,1}"+"{1,1,1}")", or "2(2vec[1,0,1]+vec[1,1,1])" if I use Format? –  Jeff Baxter Mar 26 at 11:18
    
@JeffBaxter: that last bit is the job of Expand ; remark that you can also use MatrixForm as a wrapper around your vectors. –  Wouter Mar 28 at 12:04

Your Answer

 
discard

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.