Package teamwork :: Package test :: Package math :: Module testKeyedMatrix
[hide private]
[frames] | no frames]

Source Code for Module teamwork.test.math.testKeyedMatrix

  1  from teamwork.math.Keys import * 
  2  from teamwork.math.KeyedMatrix import * 
  3  from testPWL import TestPWL,makeDynamics,makeVector 
  4  import copy 
  5  import random 
  6  import time 
  7  import unittest 
  8   
9 -class TestKeyedVector(TestPWL):
10 """ 11 @cvar iterations: the number of times to repeat each test 12 @type iterations: int 13 @cvar horizon: the number of steps to consider in a projection 14 @type horizon: int 15 @cvar features: a list of state features to use as test case 16 @type features: C{str}[] 17 @cvar agents: a list of entity names to use as test cases 18 @type agents: C{str}[] 19 @cvar step: the granularity of the iteration through vector space 20 @type step: C{float} 21 """ 22 features = [ 23 'strength', 24 'dexterity', 25 'constitution', 26 'intelligence', 27 'charisma', 28 'wisdom', 29 ] 30 agents = [ 31 'warrior', 32 'wizard', 33 'cleric', 34 'thief', 35 ] 36 step = 0.5 37 iterations = 10 38 horizon = 10 39
40 - def setUp(self):
41 self.keys = [] 42 for agent in self.agents: 43 self.keys += map(lambda f:makeStateKey(agent,f),self.features) 44 self.keys.sort()
45
46 - def firstVector(self):
47 """Generate the first state vector in an exhaustive sequence 48 @rtype: L{KeyedVector} instance""" 49 vec = KeyedVector() 50 vec.setArray() 51 return vec
52
53 - def nextVector(self,vec):
54 """Return the next state vector in sequence following the given one 55 @param vec: the current vector from the sequence 56 @type vec: L{KeyedVector} instance 57 @rtype: L{KeyedVector} instance""" 58 for key in self.keys + [keyConstant]: 59 if vec.has_key(key): 60 vec[key] += self.step 61 if vec[key] > 1.: 62 del vec[key] 63 else: 64 break 65 else: 66 vec[key] = -1. 67 break 68 else: 69 return None 70 vec.setArray() 71 return vec
72
73 - def verifyAdd(self,row1,row2):
74 """Checks a single addition between two vectors 75 @type row1,row2: L{KeyedVector}""" 76 row3 = row1 + row2 77 self.assertEqual(row1.keys(),row3.keys()) 78 self.assertEqual(row2.keys(),row3.keys()) 79 for key in row1.keys(): 80 self.assert_(key in row3.keys()) 81 for key in row2.keys(): 82 self.assert_(key in row3.keys()) 83 for key in row3.keys(): 84 if key in row1.keys(): 85 if key in row2.keys(): 86 self.assertAlmostEqual(row1[key]+row2[key],row3[key],8) 87 else: 88 self.assertAlmostEqual(row1[key],row3[key],8) 89 elif key in row2.keys(): 90 self.assertAlmostEqual(row2[key],row3[key],8) 91 else: 92 self.fail()
93
94 - def verifyScale(self,vec1,scale):
95 """Checks a single product between vector and float scaling factor 96 @param vec1: the vector to scale 97 @type vec1: L{KeyedVector} 98 @param scale: the factor to scale vector by 99 @type scale: C{float}""" 100 vec2 = vec1 * scale 101 for key in vec2.keys(): 102 self.assert_(key in vec1.keys()) 103 for key in vec1.keys(): 104 self.assertAlmostEqual(vec2[key],vec1[key]*scale,8) 105 self.assertEqual(len(vec2),len(vec1.keys()))
106
107 - def verifyMultiply(self,row1,row2):
108 """Checks a single product between two vectors 109 @type row1,row2: L{KeyedVector}""" 110 total = 0. 111 for key in row1.keys(): 112 try: 113 total += row1[key]*row2[key] 114 except KeyError: 115 # Assume row2[key] == 0 116 pass 117 keyList = self.keys+[keyConstant] 118 keyList.sort() 119 row1.fill(keyList,0.) 120 row1.freeze() 121 row2.fill(keyList,0.) 122 row2.freeze() 123 result = row1 * row2 124 self.assertAlmostEqual(result,total,8)
125
126 - def testMatrix(self):
127 keyList = self.keys+[keyConstant] 128 keyList.sort() 129 size = len(keyList) 130 for index in range(self.iterations): 131 matrix = makeDynamics(self.keys) 132 self.assertEqual(len(matrix),size) 133 self.assertEqual(matrix.rowKeys(),keyList) 134 colCopy = matrix.colKeys()[:] 135 colCopy.sort() 136 self.assertEqual(colCopy,matrix.colKeys()) 137 for row in matrix.values(): 138 self.assertEqual(row.keys(),matrix.colKeys()) 139 self.assertEqual(matrix.colKeys(),keyList) 140 for index in range(size): 141 key = keyList[index] 142 self.assertEqual(matrix._rowOrder[key],index) 143 other = matrix.colKeys()[index] 144 self.assertEqual(other,key) 145 self.assertEqual(matrix.colOrder(key),index)
146
147 - def testSet(self):
148 for index in range(self.iterations): 149 matrix = makeDynamics(self.keys) 150 row = random.choice(self.keys) 151 col = random.choice(self.keys) 152 value = random.random() 153 matrix.set(row,col,value) 154 self.assertAlmostEqual(matrix[row][col],value,8) 155 a = matrix.getArray() 156 self.assertAlmostEqual(a[matrix._rowOrder[row]][matrix.colOrder(col)],value,8)
157
158 - def testVector(self):
159 # Test filling and key ordering 160 keyList = self.keys+[keyConstant] 161 keyList.sort() 162 size = len(keyList) 163 for index in range(self.iterations): 164 vector = makeVector(self.keys) 165 vector.fill(keyList) 166 self.assertEqual(len(vector),len(keyList)) 167 self.assertEqual(vector.keys(),keyList) 168 for index in range(size): 169 key = keyList[index] 170 self.assert_(vector.has_key(key)) 171 self.assertEqual(vector._order[key],index) 172 self.assertEqual(vector.keys(),keyList) 173 # Test that setting existing keys works, too 174 key = random.choice(keyList) 175 vector[key] = random.random() 176 self.assertEqual(len(vector),len(keyList)) 177 self.assertEqual(len(vector.keys()),len(keyList)) 178 self.assertEqual(len(vector.getArray()),len(keyList)) 179 # Test deletion 180 del vector[key] 181 self.assertEqual(len(vector),len(keyList)-1) 182 self.assertEqual(len(vector.keys()),len(keyList)-1) 183 self.assertEqual(len(vector.getArray()),len(keyList)-1) 184 self.assert_(not vector.has_key(key))
185
186 - def testMatrixEdit(self):
187 keyList = self.keys+[keyConstant] 188 keyList.sort() 189 for index in range(self.iterations): 190 matrix = KeyedMatrix() 191 for key in self.keys: 192 if random.random() <= 0.5: 193 row = makeVector(self.keys) 194 matrix[key] = row 195 matrix[keyConstant] = KeyedVector({keyConstant:1.}) 196 matrix.fill(keyList)
197
198 - def testVectorAddition(self):
199 keyList = self.keys+[keyConstant] 200 keyList.sort() 201 for index in range(self.iterations): 202 vec1 = makeVector(self.keys) 203 vec1.fill(keyList) 204 vec1.freeze() 205 vec2 = makeVector(self.keys) 206 vec2.fill(keyList) 207 vec2.freeze() 208 self.verifyAdd(vec1,vec2)
209
210 - def testVectorScaling(self):
211 for index in range(self.iterations): 212 vec1 = makeVector(self.keys) 213 vec1.freeze() 214 scale = random.uniform(-1.,1.) 215 self.verifyScale(vec1,scale)
216
217 - def testVectorDotProduct(self):
218 for index in range(self.iterations): 219 vec1 = makeVector(self.keys) 220 vec2 = makeVector(self.keys) 221 self.verifyMultiply(vec1,vec2)
222
223 - def testMatrixTimesVector(self):
224 for index in range(self.iterations): 225 mat1 = makeDynamics(self.keys) 226 self.assertEqual(mat1.colOrder(keyConstant),0.) 227 self.assertEqual(mat1._rowOrder[keyConstant],0.) 228 vec2 = makeVector(self.keys) 229 vec2[keyConstant] = 1. 230 self.verifyMatrixVector(mat1,vec2)
231
232 - def verifyMatrixVector(self,mat,vec):
233 """Checks a single product between 2D and 1D matrices 234 @type mat: L{KeyedMatrix} 235 @type vec: L{KeyedVector}""" 236 vec.fill(self.keys,0.) 237 result = mat*vec 238 for key in self.keys: 239 self.assertAlmostEqual(result[key],mat[key]*vec,8) 240 self.assertAlmostEqual(result[keyConstant],1.,8)
241
243 for index in range(self.iterations): 244 vec1 = makeVector(self.keys) 245 vec1[keyConstant] = 0. 246 ## vec1.fill(self.keys) 247 mat2 = makeDynamics(self.keys) 248 self.verifyVectorMatrix(vec1,mat2)
249
250 - def verifyVectorMatrix(self,vector,matrix):
251 """Checks a single product between 1D and 2D matrices 252 @type vector: L{KeyedVector} 253 @type matrix: L{KeyedMatrix} 254 """ 255 vector.fill(self.keys) 256 self.assertEqual(vector.keys(),matrix.rowKeys()) 257 self.assertEqual(vector._order,matrix._rowOrder) 258 self.assertEqual(vector.keys(),matrix.colKeys()) 259 self.assertEqual(vector._order,matrix.values()[0]._order) 260 result = vector * matrix 261 self.assertEqual(vector.keys(),result.keys()) 262 for col in self.keys+[keyConstant]: 263 total = 0. 264 for row in self.keys+[keyConstant]: 265 total += vector[row]*matrix[row][col] 266 self.assertAlmostEqual(result[col],total,8) 267 self.assertEqual(result.getArray().shape,vector.getArray().shape)
268
269 - def testMatrixTimesMatrix(self):
270 for index in range(self.iterations): 271 state = makeVector(self.keys) 272 state[keyConstant] = 1. 273 state.fill(self.keys,0.) 274 dynamics = makeDynamics(self.keys) 275 iterative = dynamics * state 276 for t in range(self.horizon): 277 matrix = makeDynamics(self.keys) 278 iterative = matrix * iterative 279 dynamics = matrix * dynamics 280 new = dynamics * state 281 for key in self.keys: 282 self.assertAlmostEqual(new[key],iterative[key],8) 283 self.assertAlmostEqual(new[keyConstant],1.,8) 284 self.assertAlmostEqual(iterative[keyConstant],1.,8)
285
286 - def testMatrixPlusMatrix(self):
287 for index in range(self.iterations): 288 state = makeVector(self.keys) 289 state[keyConstant] = 1. 290 state.fill(self.keys,0.) 291 state.freeze() 292 cumulative = makeDynamics(self.keys) 293 cumulative.freeze() 294 total = cumulative * state 295 for t in range(self.horizon-1): 296 matrix = makeDynamics(self.keys) 297 matrix.freeze() 298 total += matrix * state 299 cumulative += matrix 300 new = cumulative * state 301 for key in self.keys: 302 self.assertAlmostEqual(new[key],total[key],8) 303 self.assertAlmostEqual(new[keyConstant],float(self.horizon),8) 304 self.assertAlmostEqual(total[keyConstant],float(self.horizon),8)
305
307 """Verifies exhaustive space of generated math problems""" 308 # Test addition 309 vec1 = self.firstVector() 310 while not vec1 is None: 311 vec2 = self.firstVector() 312 while not vec2 is None: 313 self.verifyAdd(vec1,vec2) 314 vec2 = self.nextVector(vec2) 315 vec1 = self.nextVector(vec1) 316 # Test scaling 317 vec1 = self.firstVector() 318 while not vec1 is None: 319 scale = random.uniform(-1.,1.) 320 self.verifyScale(vec1,scale) 321 # Test multiplication 322 vec1 = self.firstVector() 323 while not vec1 is None: 324 vec2 = self.firstVector() 325 while not vec2 is None: 326 self.verifyMultiply(vec1,vec2) 327 vec2 = self.nextVector(vec2) 328 vec1 = self.nextVector(vec1)
329
330 - def testDelta(self):
331 typeList = getDeltaTypes() 332 for cls1 in typeList.values(): 333 if cls1.keyClass is StateKey: 334 key = random.choice(self.keys) 335 elif cls1.keyClass is ConstantKey: 336 key = keyConstant 337 else: 338 self.fail() 339 row1 = cls1(sourceKey=StateKey({'entity':'self', 340 'feature':self.features[0]}), 341 deltaKey=key,value=random.uniform(-1.,1.)) 342 for cls2 in typeList.values(): 343 if cls2.keyClass is StateKey: 344 key = random.choice(self.keys) 345 elif cls2.keyClass is ConstantKey: 346 key = keyConstant 347 else: 348 self.fail() 349 row2 = cls2(sourceKey=StateKey({'entity':'self', 350 'feature':self.features[1]}), 351 deltaKey=key,value=random.uniform(-1.,1.)) 352 row3 = row1 + row2 353 if isinstance(row3,row1.__class__): 354 self.assert_(isinstance(row2,row1.__class__)) 355 else: 356 self.assert_(not isinstance(row3,DeltaRow))
357
358 - def testVectorCopy(self):
359 for index in range(self.iterations): 360 old = makeVector(self.keys) 361 new = copy.copy(old) 362 self.verifyVector(old,new) 363 self.assert_(not old is new) 364 365 for index in range(self.iterations): 366 old = ScaleRow(sourceKey=StateKey({'entity':self.agents[0], 367 'feature':self.features[0]}), 368 deltaKey=StateKey({'entity':self.agents[1], 369 'feature':self.features[1]}), 370 value=0.1) 371 new = copy.deepcopy(old) 372 self.verifyVector(old,new) 373 self.assert_(not old is new)
374
375 - def testVectorXML(self):
376 for index in range(self.iterations): 377 old = makeVector(self.keys) 378 doc = old.__xml__() 379 new = KeyedVector() 380 new = new.parse(doc.documentElement) 381 self.verifyVector(old,new)
382
383 - def testMatrixCopy(self):
384 for index in range(self.iterations): 385 old = makeDynamics(self.keys) 386 new = copy.copy(old) 387 self.verifyMatrix(old,new) 388 self.assert_(not old is new) 389 for key,row in old.items(): 390 self.assert_(new[key] is row) 391 # What the heck, let's test a dynamics subclass 392 feature = random.choice(self.keys)['feature'] 393 key = None # random.choice(self.keys) 394 delta = random.random() 395 old = IncrementMatrix(feature,key,delta) 396 new = copy.deepcopy(old) 397 self.verifyMatrix(old,new)
398
399 - def testMatrixXML(self):
400 for index in range(self.iterations): 401 old = makeDynamics(self.keys) 402 doc = old.__xml__() 403 new = KeyedMatrix() 404 new.parse(doc.documentElement) 405 self.verifyMatrix(old,new)
406
407 - def testFill(self):
408 size = len(self.keys)+1 409 keyList = self.keys+[keyConstant] 410 keyList.sort() 411 for index in range(self.iterations): 412 matrix = KeyedMatrix() 413 for entry in range(len(self.keys)): 414 row = random.choice(self.keys) 415 col = random.choice(self.keys) 416 matrix.set(row,col,1.) 417 matrix.fill(keyList) 418 for row in matrix.values(): 419 self.assertEqual(len(row),size) 420 self.assertEqual(row.getArray().shape,(size,)) 421 self.assertEqual(len(matrix),size) 422 self.assertEqual(matrix.getArray().shape,(size,size))
423 424
425 - def testSetToMatrix(self):
426 from teamwork.agent.Agent import Agent 427 keyList = self.keys+[keyConstant] 428 keyList.sort() 429 for index in range(self.iterations): 430 value = random.random() 431 matrix = SetToConstantMatrix(feature=self.features[0], 432 value=value) 433 table = {'self':Agent(self.agents[0])} 434 matrix.instantiateKeys(table) 435 matrix.fill(keyList) 436 old = makeVector(self.keys) 437 old[keyConstant] = 1. 438 old.fill(self.keys) 439 key = StateKey({'entity':self.agents[0], 440 'feature':self.features[0]}) 441 new = matrix*old 442 self.assertAlmostEqual(new[key],value,8) 443 for index in range(self.iterations): 444 value = random.random() 445 deltaKey = StateKey({'entity':self.agents[1], 446 'feature':self.features[1]}) 447 matrix = SetToFeatureMatrix(feature=self.features[0], 448 key=deltaKey, 449 value=value) 450 table = {'self':Agent(self.agents[0])} 451 matrix.instantiateKeys(table) 452 matrix.fill(keyList) 453 old = makeVector(self.keys) 454 old[keyConstant] = 1. 455 old[deltaKey] = random.random() 456 old.fill(self.keys) 457 key = StateKey({'entity':self.agents[0], 458 'feature':self.features[0]}) 459 new = matrix*old 460 self.assertAlmostEqual(new[key],value*old[deltaKey],8)
461
462 - def testInvert(self):
463 from numpy.linalg.linalg import LinAlgError 464 for index in range(self.iterations): 465 done = False 466 while not done: 467 matrix = makeDynamics(self.keys,1.) 468 try: 469 inverse = matrix.inverse() 470 done = True 471 except LinAlgError: 472 pass 473 result1 = matrix*inverse 474 result2 = inverse*matrix 475 for rowKey in matrix.rowKeys(): 476 for colKey in matrix.colKeys(): 477 if colKey == rowKey: 478 self.assertAlmostEqual(result1[rowKey][colKey],1.,8) 479 self.assertAlmostEqual(result2[rowKey][colKey],1.,8) 480 else: 481 self.assertAlmostEqual(result1[rowKey][colKey],0.,8) 482 self.assertAlmostEqual(result2[rowKey][colKey],0.,8)
483 484 if __name__ == '__main__': 485 unittest.main() 486