# Defining vector partition functions in sage

I want to define a vector partition function starting from a given list of vectors. For example, let's say I have vectors $v_1,v_2,v_1+v_2$ where $v_1,v_2$ are linearly independent and I want to list all the partitions using these three vectors. For convenience I can define the set of positive vectors to be the set ${kv_1+lv_2:k,l \in \mathbb{Z}_{\geq 0} }$, and for the program to be finite I am okay with taking $k,l$ only up to some fixed number, for example I have taken 2 below. I am trying as follows:

sage: v1,v2 = var('v1','v2')
sage: S = [v1,v2,v1+v2]
sage: Pos = [k*v1+l*v2 for k in [0,1,2] for l in [0,1,2]]
sage: def par(x):
sage:       p(x) = []
sage:       for y in S :
sage:            if x-y in Pos:
sage:               for z in p(x-y):
sage:                    n = z + y
sage:                    if n not in p(x):
sage:                        p(x)=p(x)+n
sage:       return p(x)


This does not work. I don't understand why. Somehow sage: par(v1) gives () as answer and sage: par(v1+v2) gives TypeError: Must construct a function with a tuple (or list) of variables.

Edit:

Vector partition function: I have a fixed set $S={ v_1,...,v_n}$ of vectors, let $v$ be a vector. An expression of the form $v=c_1v_1+...+c_nv_n$ with $c_i\in \mathbb{Z}_{\geq 0}$ is called a partition of $v$. $Par(v)$ be the set of partitions of $v$. I want to find out this set at the end of the program.

Roughly, what I wanted was: Start with L an empty list/set. Find $P(v-v_i)$ for each $i$. For each partition of $v-v_i$ attach $v_i$ to make it a partition of $v$. Now check whether the new partition thus formed is already counted before or not, if not then enter it in L.

edit retag close merge delete

Sort by » oldest newest most voted • The line p(x) = [] attempts to construct a symbolic function, and when you call par(v1+v2), it calls p(v1+v2) which tries to construct a symbolic function without the correct form for the arguments. I think a dictionary would be better for this.

• Is p supposed to be local to the function, or are its values supposed to be remembered from one call to the next?

• You define p(x) = [], and then you never provide a way to change this: the main loop says for z in p(x-y), but since p(x-y) starts off empty, the loop will never do anything.

EDIT:

You need a place to start: p(x) can't be empty for every x. You also need to know when you're done. Here is a start, not sure if it works:

p = {}

def initialize_p():
for x in Pos:
if x:
p[x] = [[x]]
else:
# if x is zero, don't include it in the partition.
p[x] = []

def par(x):
for y in S:
if x-y in Pos:
for z in p[x-y]:
# z should be a list, so add a new element to that list
n = z + [y]
# sort n so we don't get both [v1, v2] and [v2, v1]
n = sorted(n, key=str)
if n not in p[x]:
p[x].append(n)
return p[x]


I put this in a file called vec.sage and did:

sage: var('v1, v2')
sage: S = [v1, v2] # why include v1+v2?
sage: Pos = [k*v1+l*v2 for k in [0,1,2] for l in [0,1,2]]

sage: %attach vec.sage
sage: initialize_p()
sage: par(v1)
[[v1]]
sage: par(v1+v2)
[[v1 + v2], [v1, v2]]
sage: par(2*v1+v2)
[[2*v1 + v2], [v1, v1 + v2], [v1, v1, v2], [2*v1, v2]]

more

Understood. I wanted to get all partitions by somehow subtracting one part and knowing the smaller partitions. Do you have any suggestions for fixing the algorithm?

You'll have to explain what you mean by a vector partition function, and how you hope the algorithm would work for your small example with Pos as defined.

See my edit. Another option is to make the function par recursive: when computing par(x), call par(x-y). par(0) should return [], maybe par(v) should return [v] when v is either v1 or v2.