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$
1
  • 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, 2014 at 15:44

1 Answer 1

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$
2
  • $\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, 2014 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, 2014 at 12:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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