1 """Vectors of numbers, but indexed as a dictionary.
2 """
3
4 import math
5 import operator
6 import __builtin__
7 from gmisclib import gpkmisc
8 from gmisclib import dictops
9
10
12 SCALARS = (int, float)
13 ZERO = 0
14
17
18
19 - def incr(self, k, v):
20 """Increment slot C{k} by C{v}."""
21 if k in self:
22 self[k] += v
23 else:
24 self[k] = v
25
26
28 tmp = self.copy()
29 if isinstance(other, self.SCALARS):
30 for k in tmp.keys():
31 tmp[k] += other
32 else:
33 for (k, v) in other.items():
34 try:
35 tmp[k] += v
36 except KeyError:
37 tmp[k] = v
38 return tmp
39
40
42 tmp = dict_vector()
43 if isinstance(other, self.SCALARS):
44 for (k, v) in self.items():
45 tmp[k] = v > other
46 else:
47 for (k, v) in self.items():
48 tmp[k] = v > other.get(k, self.ZERO)
49 for (k, v) in other.items():
50 if k not in tmp:
51 tmp[k] = self.get(k, self.ZERO) > v
52 return tmp
53
54
56 tmp = dict_vector()
57 if isinstance(other, self.SCALARS):
58 for (k, v) in self.items():
59 tmp[k] = v < other
60 else:
61 for (k, v) in self.items():
62 tmp[k] = v < other.get(k, self.ZERO)
63 for (k, v) in other.items():
64 if k not in tmp:
65 tmp[k] = self.get(k, self.ZERO) < v
66 return tmp
67
68
70 tmp = dict_vector()
71 if isinstance(other, self.SCALARS):
72 for (k, v) in self.items():
73 tmp[k] = v >= other
74 else:
75 for (k, v) in self.items():
76 tmp[k] = v >= other.get(k, self.ZERO)
77 for (k, v) in other.items():
78 if k not in tmp:
79 tmp[k] = self.get(k, self.ZERO) >= v
80 return tmp
81
82
84 tmp = dict_vector()
85 if isinstance(other, self.SCALARS):
86 for (k, v) in self.items():
87 tmp[k] = v <= other
88 else:
89 for (k, v) in self.items():
90 tmp[k] = v <= other.get(k, self.ZERO)
91 for (k, v) in other.items():
92 if k not in tmp:
93 tmp[k] = self.get(k, self.ZERO) <= v
94 return tmp
95
96
97
98
100 tmp = dict_vector()
101 if isinstance(other, self.SCALARS):
102 tmp = self.copy()
103 for (k, v) in self.items():
104 tmp[k] = v * other
105 else:
106 for (k, v) in other.items():
107 tmp[k] = self.get(k, self.ZERO) * v
108 for (k, v) in self.items():
109 if k not in tmp:
110 tmp[k] = v * other.get(k, self.ZERO)
111 return tmp
112
113
114
116 if isinstance(other, self.SCALARS):
117 if other == self.ZERO:
118 raise ZeroDivisionError, "float denominator"
119 else:
120 tmp = dict_vector()
121 for (k, v) in self.items():
122 tmp[k] = v / other
123 else:
124 tmp = dict_vector()
125 for (k, v) in other.items():
126 if v != self.ZERO:
127 tmp[k] = self.get(k, self.ZERO) / v
128 else:
129 raise ZeroDivisionError, "denom[%s]=%s" % (str(k), str(v))
130 for (k, v) in self.items():
131 if k not in tmp:
132 try:
133 tmp[k] = v / other[k]
134 except KeyError:
135 raise ZeroDivisionError, "denom[%s] is empty" % str(k)
136 return tmp
137
138
140 if isinstance(other, self.SCALARS):
141 for k in self.keys():
142 self[k] += other
143 else:
144 for (k, v) in other.items():
145 try:
146 self[k] += v
147 except KeyError:
148 self[k] = v
149 return self
150
151
153 if isinstance(other, self.SCALARS):
154 for k in self.keys():
155 self[k] -= other
156 else:
157 for (k, v) in other.items():
158 try:
159 self[k] -= v
160 except KeyError:
161 self[k] = -v
162 return self
163
164
166 tmp = self.copy()
167 if isinstance(other, self.SCALARS):
168 for k in tmp.keys():
169 tmp[k] -= other
170 else:
171 for (k, v) in other.items():
172 try:
173 tmp[k] -= v
174 except KeyError:
175 tmp[k] = -v
176 return tmp
177
178
179 __radd__ = __add__
180 __rmul__ = __mul__
181
182
184 tmp = self.copy()
185 if isinstance(other, self.SCALARS):
186 for k in tmp.keys():
187 tmp[k] = other - tmp[k]
188 else:
189 for (k, v) in other.items():
190 try:
191 tmp[k] = v - tmp[k]
192 except KeyError:
193 tmp[k] = v
194 return tmp
195
196
198 tmp = dict_vector()
199 for (k, v) in self.items():
200 tmp[k] = __builtin__.abs(v)
201 return tmp
202
203
204
206 tmp = dict_vector()
207 for (k, v) in self.items():
208 tmp[k] = -v
209 return tmp
210
211
213 """Sum all the items in a vector."""
214 return reduce(operator.add, self.values())
215
216
220
221
223 """@return: true if all values are true.
224 @rtype: bool
225 """
226 for v in self.values():
227 if not v:
228 return False
229 return True
230
231
233 """@return: a dict_vector with float values."""
234 tmp = dict_vector()
235 for (k, v) in self.items():
236 tmp[k] = float(v)
237 return tmp
238
239
241 """@return: a dict_vector with int values."""
242 tmp = dict_vector()
243 for (k, v) in self.items():
244 tmp[k] = int(v)
245 return tmp
246
247
249 """Convert to integer, in place."""
250 for (k, v) in self.keys():
251 self[k] = int(v)
252
253
255 """Convert to float, in place."""
256 for (k, v) in self.keys():
257 self[k] = float(v)
258
259
261 """@return: a dict_vector which is -1, 0, or 1, showing the sign of each value.
262 @rtype: dict_vector of int.
263 """
264 tmp = dict_vector()
265 for (k, v) in self.items():
266 if v > self.ZERO:
267 tmp[k] = 1
268 elif v < self.ZERO:
269 tmp[k] = -1
270 else:
271 tmp[k] = 0
272 return tmp
273
274
276 """Round to the nearest int.
277 @rtype: dict_vector of ints.
278 @return: rounded dict vector.
279 """
280 tmp = dict_vector()
281 for (k, v) in self.items():
282 tmp[k] = __builtin__.int(__builtin__.round(v))
283 return tmp
284
285
287 """Round to the nearest int, in place."""
288 for (k,v) in self.items():
289 self[k] = __builtin__.int(__builtin__.round(v))
290
291
293 """Drop all zeros, in place."""
294 drops = [ k for (k,v) in self.items() if v==self.ZERO ]
295 for k in drops:
296 del self[k]
297
299 """@return: a dict_vector without any zeros."""
300 tmp = dict_vector()
301 for (k, v) in self.items():
302 if not v == self.ZERO:
303 tmp[k] = v
304 return tmp
305
308
309
315
316
317
319 best = None
320 vmin = None
321 first = True
322 for (k, v) in x.items():
323 if first or v < vmin:
324 vmin = v
325 best = k
326 first = False
327 if first:
328 raise ValueError, "Empty input sequence"
329 return (best, vmin)
330
331
333 best = None
334 vmin = None
335 first = True
336 for (k, v) in x.items():
337 if first or v > vmin:
338 vmin = v
339 best = k
340 first = False
341 if first:
342 raise ValueError, "Empty input sequence"
343 return (best, vmin)
344
345
359
360
374
375
377 """Ensure that all the values are float.
378 @return: a dict_vector made of floats.
379 @param d: a dictionary
380 @type d: dict(str:anything)
381 """
382 return dict_vector([(k, float(v)) for (k, v) in d.items()])
383
384
386 """Ensure that all the values are float.
387 @return: a dict_vector made of floats.
388 @param d: a dictionary
389 @type d: dict(str:anything)
390 """
391 import numpy
392 n = len(d)
393 rv= numpy.zeros((n,))
394 keys = []
395 for (k, v) in sorted(d.items()):
396 rv[len(keys)] = v
397 keys.append(k)
398 return (keys, rv)
399
400
402 """Ensure that all the values are float.
403 @return: a dict_vector made of floats.
404 @param d: a dictionary
405 @type d: dict(str:anything)
406 """
407 import numpy
408 import nice_hash
409 h1 = nice_hash.simple()
410 h2 = nice_hash.simple()
411 for ((k1,k2), v) in sorted(d.items()):
412 h1.add(k1)
413 h2.add(k2)
414 rv = numpy.zeros((h1.n, h2.n))
415 for ((k1,k2), v) in d.items():
416 rv[h1.get_image(k1), h2.get_image(k2)] = v
417 return (h1.classmap(), h2.classmap(), rv)
418
419
421 """Ensure that all the values are int.
422 @return: a dict_vector made of int.
423 @param d: a dictionary
424 @type d: dict(str:anything)
425 """
426 return dict_vector([(k, int(v)) for (k, v) in d.items()])
427
428
430 """@return: an outer product."""
431 rv = dict_vector()
432 for (k1, v1) in a.items():
433 for (k2, v2) in b.items():
434 rv[(k1,k2)] = v1*v2
435 return rv
436