Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/combinat/integer_vector_weighted.py
4036 views
1
"""
2
Weighted Integer Vectors
3
"""
4
#*****************************************************************************
5
# Copyright (C) 2007 Mike Hansen <[email protected]>,
6
#
7
# Distributed under the terms of the GNU General Public License (GPL)
8
#
9
# This code is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
# General Public License for more details.
13
#
14
# The full text of the GPL is available at:
15
#
16
# http://www.gnu.org/licenses/
17
#*****************************************************************************
18
19
from combinat import CombinatorialClass
20
from __builtin__ import list as builtinlist
21
from sage.rings.integer import Integer
22
from sage.combinat.words.word import Word
23
from permutation import Permutation_class
24
25
def WeightedIntegerVectors(n, weight):
26
"""
27
Returns the combinatorial class of integer vectors of n weighted by
28
weight.
29
30
EXAMPLES::
31
32
sage: WeightedIntegerVectors(8, [1,1,2])
33
Integer vectors of 8 weighted by [1, 1, 2]
34
sage: WeightedIntegerVectors(8, [1,1,2]).first()
35
[0, 0, 4]
36
sage: WeightedIntegerVectors(8, [1,1,2]).last()
37
[8, 0, 0]
38
sage: WeightedIntegerVectors(8, [1,1,2]).cardinality()
39
25
40
sage: WeightedIntegerVectors(8, [1,1,2]).random_element()
41
[1, 1, 3]
42
"""
43
return WeightedIntegerVectors_nweight(n, weight)
44
45
class WeightedIntegerVectors_nweight(CombinatorialClass):
46
def __init__(self, n, weight):
47
"""
48
TESTS::
49
50
sage: WIV = WeightedIntegerVectors(8, [1,1,2])
51
sage: WIV == loads(dumps(WIV))
52
True
53
"""
54
self.n = n
55
self.weight = weight
56
57
def __repr__(self):
58
"""
59
TESTS::
60
61
sage: repr(WeightedIntegerVectors(8, [1,1,2]))
62
'Integer vectors of 8 weighted by [1, 1, 2]'
63
"""
64
return "Integer vectors of %s weighted by %s"%(self.n, self.weight)
65
66
def __contains__(self, x):
67
"""
68
TESTS::
69
70
sage: [] in WeightedIntegerVectors(0, [])
71
True
72
sage: [] in WeightedIntegerVectors(1, [])
73
False
74
sage: [3,0,0] in WeightedIntegerVectors(6, [2,1,1])
75
True
76
sage: [1] in WeightedIntegerVectors(1, [1])
77
True
78
sage: [1] in WeightedIntegerVectors(2, [2])
79
True
80
sage: [2] in WeightedIntegerVectors(4, [2])
81
True
82
sage: [2, 0] in WeightedIntegerVectors(4, [2, 2])
83
True
84
sage: [2, 1] in WeightedIntegerVectors(4, [2, 2])
85
False
86
sage: [2, 1] in WeightedIntegerVectors(6, [2, 2])
87
True
88
sage: [2, 1, 0] in WeightedIntegerVectors(6, [2, 2])
89
False
90
sage: [0] in WeightedIntegerVectors(0, [])
91
False
92
"""
93
if not isinstance(x, builtinlist):
94
return False
95
if len(self.weight) != len(x):
96
return False
97
s = 0
98
for i in range(len(x)):
99
if not isinstance(x[i], (int, Integer)):
100
return False
101
s += x[i]*self.weight[i]
102
if s != self.n:
103
return False
104
105
return True
106
107
def _recfun(self, n, l):
108
"""
109
EXAMPLES::
110
111
sage: w = WeightedIntegerVectors(3, [2,1,1])
112
sage: w._recfun(3, [1,1,2])
113
[[0, 1, 1], [1, 0, 1], [0, 3, 0], [1, 2, 0], [2, 1, 0], [3, 0, 0]]
114
"""
115
result = []
116
w = l[-1]
117
l = l[:-1]
118
if l == []:
119
d = int(n) / int(w)
120
if n%w == 0:
121
return [[d]]
122
else:
123
return [] #bad branch...
124
125
for d in range(int(n)/int(w), -1, -1):
126
result += [ x + [d] for x in self._recfun(n-d*w, l) ]
127
128
return result
129
130
def list(self):
131
"""
132
TESTS::
133
134
sage: WeightedIntegerVectors(7, [2,2]).list()
135
[]
136
sage: WeightedIntegerVectors(3, [2,1,1]).list()
137
[[1, 0, 1], [1, 1, 0], [0, 0, 3], [0, 1, 2], [0, 2, 1], [0, 3, 0]]
138
139
::
140
141
sage: ivw = [ WeightedIntegerVectors(k, [1,1,1]) for k in range(11) ]
142
sage: iv = [ IntegerVectors(k, 3) for k in range(11) ]
143
sage: all( [ sorted(iv[k].list()) == sorted(ivw[k].list()) for k in range(11) ] )
144
True
145
146
::
147
148
sage: ivw = [ WeightedIntegerVectors(k, [2,3,7]) for k in range(11) ]
149
sage: all( [ i.cardinality() == len(i.list()) for i in ivw] )
150
True
151
"""
152
if len(self.weight) == 0:
153
if self.n == 0:
154
return [[]]
155
else:
156
return []
157
158
perm = Word(self.weight).standard_permutation()
159
l = [x for x in sorted(self.weight)]
160
return [perm._left_to_right_multiply_on_right(Permutation_class(x)) for x in self._recfun(self.n,l)]
161
162
163