1
$\begingroup$

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?

$\endgroup$
  • 3
    $\begingroup$ 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. $\endgroup$ – Szabolcs Mar 25 '14 at 15:44
1
$\begingroup$

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.

$\endgroup$
  • $\begingroup$ 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? $\endgroup$ – Y. Pei Mar 26 '14 at 11:18
  • $\begingroup$ @JeffBaxter: that last bit is the job of Expand ; remark that you can also use MatrixForm as a wrapper around your vectors. $\endgroup$ – Wouter Mar 28 '14 at 12:04

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.