info.py revision 1934:84c12fdd57f9
19665Sandreas.hansson@arm.com# Copyright (c) 2003-2004 The Regents of The University of Michigan 29665Sandreas.hansson@arm.com# All rights reserved. 39665Sandreas.hansson@arm.com# 49665Sandreas.hansson@arm.com# Redistribution and use in source and binary forms, with or without 59665Sandreas.hansson@arm.com# modification, are permitted provided that the following conditions are 69665Sandreas.hansson@arm.com# met: redistributions of source code must retain the above copyright 79665Sandreas.hansson@arm.com# notice, this list of conditions and the following disclaimer; 89665Sandreas.hansson@arm.com# redistributions in binary form must reproduce the above copyright 99665Sandreas.hansson@arm.com# notice, this list of conditions and the following disclaimer in the 109665Sandreas.hansson@arm.com# documentation and/or other materials provided with the distribution; 119665Sandreas.hansson@arm.com# neither the name of the copyright holders nor the names of its 129665Sandreas.hansson@arm.com# contributors may be used to endorse or promote products derived from 135353Svilas.sridharan@gmail.com# this software without specific prior written permission. 143395Shsul@eecs.umich.edu# 153395Shsul@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 163395Shsul@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 173395Shsul@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 183395Shsul@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 193395Shsul@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 203395Shsul@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 213395Shsul@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 223395Shsul@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 233395Shsul@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 243395Shsul@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 253395Shsul@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 263395Shsul@eecs.umich.edu 273395Shsul@eecs.umich.edufrom __future__ import division 283395Shsul@eecs.umich.eduimport operator, re, types 293395Shsul@eecs.umich.edu 303395Shsul@eecs.umich.edudef unproxy(proxy): 313395Shsul@eecs.umich.edu if hasattr(proxy, '__unproxy__'): 323395Shsul@eecs.umich.edu return proxy.__unproxy__() 333395Shsul@eecs.umich.edu 343395Shsul@eecs.umich.edu return proxy 353395Shsul@eecs.umich.edu 363395Shsul@eecs.umich.edudef scalar(stat): 373395Shsul@eecs.umich.edu stat = unproxy(stat) 383395Shsul@eecs.umich.edu assert(stat.__scalar__() != stat.__vector__()) 393395Shsul@eecs.umich.edu return stat.__scalar__() 403395Shsul@eecs.umich.edu 418920Snilay@cs.wisc.edudef vector(stat): 428920Snilay@cs.wisc.edu stat = unproxy(stat) 438920Snilay@cs.wisc.edu assert(stat.__scalar__() != stat.__vector__()) 448920Snilay@cs.wisc.edu return stat.__vector__() 457025SBrad.Beckmann@amd.com 469520SAndreas.Sandberg@ARM.comdef value(stat, *args): 479665Sandreas.hansson@arm.com stat = unproxy(stat) 489520SAndreas.Sandberg@ARM.com return stat.__value__(*args) 499520SAndreas.Sandberg@ARM.com 509520SAndreas.Sandberg@ARM.comdef values(stat, run): 519520SAndreas.Sandberg@ARM.com stat = unproxy(stat) 529520SAndreas.Sandberg@ARM.com result = [] 539665Sandreas.hansson@arm.com for i in xrange(len(stat)): 549665Sandreas.hansson@arm.com val = value(stat, run, i) 559665Sandreas.hansson@arm.com if val is None: 569665Sandreas.hansson@arm.com return None 578920Snilay@cs.wisc.edu result.append(val) 588920Snilay@cs.wisc.edu return result 599520SAndreas.Sandberg@ARM.com 609520SAndreas.Sandberg@ARM.comdef total(stat, run): 619520SAndreas.Sandberg@ARM.com return sum(values(stat, run)) 628920Snilay@cs.wisc.edu 639520SAndreas.Sandberg@ARM.comdef len(stat): 648920Snilay@cs.wisc.edu stat = unproxy(stat) 659665Sandreas.hansson@arm.com return stat.__len__() 669665Sandreas.hansson@arm.com 679665Sandreas.hansson@arm.comclass Value(object): 689665Sandreas.hansson@arm.com def __scalar__(self): 699665Sandreas.hansson@arm.com raise AttributeError, "must define __scalar__ for %s" % (type (self)) 709665Sandreas.hansson@arm.com def __vector__(self): 718920Snilay@cs.wisc.edu raise AttributeError, "must define __vector__ for %s" % (type (self)) 728920Snilay@cs.wisc.edu 738920Snilay@cs.wisc.edu def __add__(self, other): 748920Snilay@cs.wisc.edu return BinaryProxy(operator.__add__, self, other) 758920Snilay@cs.wisc.edu def __sub__(self, other): 769647Sdam.sunwoo@arm.com return BinaryProxy(operator.__sub__, self, other) 779647Sdam.sunwoo@arm.com def __mul__(self, other): 789647Sdam.sunwoo@arm.com return BinaryProxy(operator.__mul__, self, other) 799647Sdam.sunwoo@arm.com def __div__(self, other): 808920Snilay@cs.wisc.edu return BinaryProxy(operator.__div__, self, other) 819789Sakash.bagdia@arm.com def __truediv__(self, other): 829789Sakash.bagdia@arm.com return BinaryProxy(operator.__truediv__, self, other) 839789Sakash.bagdia@arm.com def __floordiv__(self, other): 848920Snilay@cs.wisc.edu return BinaryProxy(operator.__floordiv__, self, other) 858920Snilay@cs.wisc.edu 868920Snilay@cs.wisc.edu def __radd__(self, other): 878920Snilay@cs.wisc.edu return BinaryProxy(operator.__add__, other, self) 888920Snilay@cs.wisc.edu def __rsub__(self, other): 898920Snilay@cs.wisc.edu return BinaryProxy(operator.__sub__, other, self) 908920Snilay@cs.wisc.edu def __rmul__(self, other): 918920Snilay@cs.wisc.edu return BinaryProxy(operator.__mul__, other, self) 928920Snilay@cs.wisc.edu def __rdiv__(self, other): 938920Snilay@cs.wisc.edu return BinaryProxy(operator.__div__, other, self) 948920Snilay@cs.wisc.edu def __rtruediv__(self, other): 958920Snilay@cs.wisc.edu return BinaryProxy(operator.__truediv__, other, self) 968920Snilay@cs.wisc.edu def __rfloordiv__(self, other): 979197Snilay@cs.wisc.edu return BinaryProxy(operator.__floordiv__, other, self) 989197Snilay@cs.wisc.edu 999197Snilay@cs.wisc.edu def __neg__(self): 1009197Snilay@cs.wisc.edu return UnaryProxy(operator.__neg__, self) 1019197Snilay@cs.wisc.edu def __pos__(self): 1023395Shsul@eecs.umich.edu return UnaryProxy(operator.__pos__, self) 1038920Snilay@cs.wisc.edu def __abs__(self): 1048920Snilay@cs.wisc.edu return UnaryProxy(operator.__abs__, self) 1058920Snilay@cs.wisc.edu 1068920Snilay@cs.wisc.educlass Scalar(Value): 1078920Snilay@cs.wisc.edu def __scalar__(self): 1088920Snilay@cs.wisc.edu return True 1098920Snilay@cs.wisc.edu 1108920Snilay@cs.wisc.edu def __vector__(self): 1118920Snilay@cs.wisc.edu return False 1128920Snilay@cs.wisc.edu 1138920Snilay@cs.wisc.edu def __value__(self, run): 1148920Snilay@cs.wisc.edu raise AttributeError, '__value__ must be defined' 1158920Snilay@cs.wisc.edu 1168920Snilay@cs.wisc.educlass VectorItemProxy(Value): 1178920Snilay@cs.wisc.edu def __init__(self, proxy, index): 1188920Snilay@cs.wisc.edu self.proxy = proxy 1198920Snilay@cs.wisc.edu self.index = index 1208920Snilay@cs.wisc.edu 1216776SBrad.Beckmann@amd.com def __scalar__(self): 1228920Snilay@cs.wisc.edu return True 1238920Snilay@cs.wisc.edu 1248920Snilay@cs.wisc.edu def __vector__(self): 1258920Snilay@cs.wisc.edu return False 1269357Sandreas.hansson@arm.com 1278920Snilay@cs.wisc.edu def __value__(self, run): 1288920Snilay@cs.wisc.edu return value(self.proxy, run, self.index) 1298920Snilay@cs.wisc.edu 1308920Snilay@cs.wisc.educlass Vector(Value): 1318920Snilay@cs.wisc.edu def __scalar__(self): 1328920Snilay@cs.wisc.edu return False 1338920Snilay@cs.wisc.edu 1348920Snilay@cs.wisc.edu def __vector__(self): 1358920Snilay@cs.wisc.edu return True 1368920Snilay@cs.wisc.edu 1378920Snilay@cs.wisc.edu def __value__(self, run, index): 1388920Snilay@cs.wisc.edu raise AttributeError, '__value__ must be defined' 1398920Snilay@cs.wisc.edu 1408920Snilay@cs.wisc.edu def __getitem__(self, index): 1418920Snilay@cs.wisc.edu return VectorItemProxy(self, index) 1429736Sandreas@sandberg.pp.se 1438920Snilay@cs.wisc.educlass ScalarConstant(Scalar): 1443395Shsul@eecs.umich.edu def __init__(self, constant): 1455361Srstrong@cs.ucsd.edu self.constant = constant 1468920Snilay@cs.wisc.edu def __value__(self, run): 1478920Snilay@cs.wisc.edu return self.constant 1488920Snilay@cs.wisc.edu 1499151Satgutier@umich.educlass VectorConstant(Vector): 1509151Satgutier@umich.edu def __init__(self, constant): 1519151Satgutier@umich.edu self.constant = constant 1529151Satgutier@umich.edu def __value__(self, run, index): 1539151Satgutier@umich.edu return self.constant[index] 1549151Satgutier@umich.edu def __len__(self): 1559562Ssaidi@eecs.umich.edu return len(self.constant) 1568920Snilay@cs.wisc.edu 1578920Snilay@cs.wisc.edudef WrapValue(value): 1588920Snilay@cs.wisc.edu if isinstance(value, (int, long, float)): 1598920Snilay@cs.wisc.edu return ScalarConstant(value) 1608920Snilay@cs.wisc.edu if isinstance(value, (list, tuple)): 1618920Snilay@cs.wisc.edu return VectorConstant(value) 1628920Snilay@cs.wisc.edu if isinstance(value, Value): 1638920Snilay@cs.wisc.edu return value 1648920Snilay@cs.wisc.edu 1658920Snilay@cs.wisc.edu raise AttributeError, 'Only values can be wrapped' 1668920Snilay@cs.wisc.edu 1678920Snilay@cs.wisc.educlass Statistic(object): 1688920Snilay@cs.wisc.edu def __getattr__(self, attr): 1698920Snilay@cs.wisc.edu if attr in ('data', 'x', 'y'): 1708920Snilay@cs.wisc.edu result = self.source.data(self, self.bins, self.ticks) 1718920Snilay@cs.wisc.edu self.data = result.data 1728920Snilay@cs.wisc.edu self.x = result.x 1738920Snilay@cs.wisc.edu self.y = result.y 1748920Snilay@cs.wisc.edu return super(Statistic, self).__getattribute__(attr) 1758920Snilay@cs.wisc.edu 1768920Snilay@cs.wisc.edu def __setattr__(self, attr, value): 1778920Snilay@cs.wisc.edu if attr == 'stat': 1788920Snilay@cs.wisc.edu raise AttributeError, '%s is read only' % stat 1798920Snilay@cs.wisc.edu if attr in ('source', 'bins', 'ticks'): 1808920Snilay@cs.wisc.edu if getattr(self, attr) != value: 1818920Snilay@cs.wisc.edu if hasattr(self, 'data'): 1828920Snilay@cs.wisc.edu delattr(self, 'data') 1838920Snilay@cs.wisc.edu 1848920Snilay@cs.wisc.edu super(Statistic, self).__setattr__(attr, value) 1858920Snilay@cs.wisc.edu 1868920Snilay@cs.wisc.educlass ValueProxy(Value): 1878920Snilay@cs.wisc.edu def __getattr__(self, attr): 1888920Snilay@cs.wisc.edu if attr == '__value__': 1898920Snilay@cs.wisc.edu if scalar(self): 1908920Snilay@cs.wisc.edu return self.__scalarvalue__ 1918920Snilay@cs.wisc.edu if vector(self): 1928920Snilay@cs.wisc.edu return self.__vectorvalue__ 1938920Snilay@cs.wisc.edu if attr == '__len__': 1948920Snilay@cs.wisc.edu if vector(self): 1958920Snilay@cs.wisc.edu return self.__vectorlen__ 1968920Snilay@cs.wisc.edu return super(ValueProxy, self).__getattribute__(attr) 1978920Snilay@cs.wisc.edu 1988920Snilay@cs.wisc.educlass UnaryProxy(ValueProxy): 1998920Snilay@cs.wisc.edu def __init__(self, op, arg): 2008920Snilay@cs.wisc.edu self.op = op 2018920Snilay@cs.wisc.edu self.arg = WrapValue(arg) 2028920Snilay@cs.wisc.edu 2038920Snilay@cs.wisc.edu def __scalar__(self): 2048920Snilay@cs.wisc.edu return scalar(self.arg) 2059539Satgutier@umich.edu 2069539Satgutier@umich.edu def __vector__(self): 2079539Satgutier@umich.edu return vector(self.arg) 2088920Snilay@cs.wisc.edu 2098920Snilay@cs.wisc.edu def __scalarvalue__(self, run): 2108920Snilay@cs.wisc.edu val = value(self.arg, run) 2118920Snilay@cs.wisc.edu if val is None: 2128920Snilay@cs.wisc.edu return None 2138920Snilay@cs.wisc.edu return self.op(val) 2148920Snilay@cs.wisc.edu 2158920Snilay@cs.wisc.edu def __vectorvalue__(self, run, index): 2168920Snilay@cs.wisc.edu val = value(self.arg, run, index) 2178920Snilay@cs.wisc.edu if val is None: 2188920Snilay@cs.wisc.edu return None 2198920Snilay@cs.wisc.edu return self.op(val) 2208956Sjayneel@cs.wisc.edu 2218956Sjayneel@cs.wisc.edu def __vectorlen__(self): 2228956Sjayneel@cs.wisc.edu return len(unproxy(self.arg)) 2238956Sjayneel@cs.wisc.edu 2248956Sjayneel@cs.wisc.educlass BinaryProxy(ValueProxy): 2258956Sjayneel@cs.wisc.edu def __init__(self, op, arg0, arg1): 2268956Sjayneel@cs.wisc.edu super(BinaryProxy, self).__init__() 2278976Sjayneel@cs.wisc.edu self.op = op 228 self.arg0 = WrapValue(arg0) 229 self.arg1 = WrapValue(arg1) 230 231 def __scalar__(self): 232 return scalar(self.arg0) and scalar(self.arg1) 233 234 def __vector__(self): 235 return vector(self.arg0) or vector(self.arg1) 236 237 def __scalarvalue__(self, run): 238 val0 = value(self.arg0, run) 239 val1 = value(self.arg1, run) 240 if val0 is None or val1 is None: 241 return None 242 return self.op(val0, val1) 243 244 def __vectorvalue__(self, run, index): 245 if scalar(self.arg0): 246 val0 = value(self.arg0, run) 247 if vector(self.arg0): 248 val0 = value(self.arg0, run, index) 249 if scalar(self.arg1): 250 val1 = value(self.arg1, run) 251 if vector(self.arg1): 252 val1 = value(self.arg1, run, index) 253 254 if val0 is None or val1 is None: 255 return None 256 257 return self.op(val0, val1) 258 259 def __vectorlen__(self): 260 if vector(self.arg0) and scalar(self.arg1): 261 return len(self.arg0) 262 if scalar(self.arg0) and vector(self.arg1): 263 return len(self.arg1) 264 265 len0 = len(self.arg0) 266 len1 = len(self.arg1) 267 268 if len0 != len1: 269 raise AttributeError, \ 270 "vectors of different lengths %d != %d" % (len0, len1) 271 272 return len0 273 274class Proxy(Value): 275 def __init__(self, name, dict): 276 self.name = name 277 self.dict = dict 278 279 def __unproxy__(self): 280 return unproxy(self.dict[self.name]) 281 282 def __getitem__(self, index): 283 return ItemProxy(self, index) 284 285 def __getattr__(self, attr): 286 return AttrProxy(self, attr) 287 288class ItemProxy(Proxy): 289 def __init__(self, proxy, index): 290 self.proxy = proxy 291 self.index = index 292 293 def __unproxy__(self): 294 return unproxy(unproxy(self.proxy)[self.index]) 295 296class AttrProxy(Proxy): 297 def __init__(self, proxy, attr): 298 self.proxy = proxy 299 self.attr = attr 300 301 def __unproxy__(self): 302 return unproxy(getattr(unproxy(self.proxy), self.attr)) 303 304class ProxyGroup(object): 305 def __init__(self, dict=None, **kwargs): 306 self.__dict__['dict'] = {} 307 308 if dict is not None: 309 self.dict.update(dict) 310 311 if kwargs: 312 self.dict.update(kwargs) 313 314 def __getattr__(self, name): 315 return Proxy(name, self.dict) 316 317 def __setattr__(self, attr, value): 318 self.dict[attr] = value 319 320class ScalarStat(Statistic,Scalar): 321 def __value__(self, run): 322 if run not in self.data: 323 return None 324 return self.data[run][0][0] 325 326 def display(self, run=None): 327 import display 328 p = display.Print() 329 p.name = self.name 330 p.desc = self.desc 331 p.value = value(self, run) 332 p.flags = self.flags 333 p.precision = self.precision 334 if display.all or (self.flags & flags.printable): 335 p.display() 336 337class VectorStat(Statistic,Vector): 338 def __value__(self, run, item): 339 if run not in self.data: 340 return None 341 return self.data[run][item][0] 342 343 def __len__(self): 344 return self.x 345 346 def display(self, run=None): 347 import display 348 d = display.VectorDisplay() 349 d.name = self.name 350 d.desc = self.desc 351 d.value = [ value(self, run, i) for i in xrange(len(self)) ] 352 d.flags = self.flags 353 d.precision = self.precision 354 d.display() 355 356class Formula(Value): 357 def __getattribute__(self, attr): 358 if attr not in ( '__scalar__', '__vector__', '__value__', '__len__' ): 359 return super(Formula, self).__getattribute__(attr) 360 361 formula = re.sub(':', '__', self.formula) 362 value = eval(formula, self.source.stattop) 363 return getattr(value, attr) 364 365class SimpleDist(Statistic): 366 def __init__(self, sums, squares, samples): 367 self.sums = sums 368 self.squares = squares 369 self.samples = samples 370 371 def display(self, name, desc, flags, precision): 372 import display 373 p = display.Print() 374 p.flags = flags 375 p.precision = precision 376 377 if self.samples > 0: 378 p.name = name + ".mean" 379 p.value = self.sums / self.samples 380 p.display() 381 382 p.name = name + ".stdev" 383 if self.samples > 1: 384 var = (self.samples * self.squares - self.sums ** 2) \ 385 / (self.samples * (self.samples - 1)) 386 if var >= 0: 387 p.value = math.sqrt(var) 388 else: 389 p.value = 'NaN' 390 else: 391 p.value = 0.0 392 p.display() 393 394 p.name = name + ".samples" 395 p.value = self.samples 396 p.display() 397 398 def comparable(self, other): 399 return True 400 401 def __eq__(self, other): 402 return self.sums == other.sums and self.squares == other.squares and \ 403 self.samples == other.samples 404 405 def __isub__(self, other): 406 self.sums -= other.sums 407 self.squares -= other.squares 408 self.samples -= other.samples 409 return self 410 411 def __iadd__(self, other): 412 self.sums += other.sums 413 self.squares += other.squares 414 self.samples += other.samples 415 return self 416 417 def __itruediv__(self, other): 418 if not other: 419 return self 420 self.sums /= other 421 self.squares /= other 422 self.samples /= other 423 return self 424 425class FullDist(SimpleDist): 426 def __init__(self, sums, squares, samples, minval, maxval, 427 under, vec, over, min, max, bsize, size): 428 self.sums = sums 429 self.squares = squares 430 self.samples = samples 431 self.minval = minval 432 self.maxval = maxval 433 self.under = under 434 self.vec = vec 435 self.over = over 436 self.min = min 437 self.max = max 438 self.bsize = bsize 439 self.size = size 440 441 def display(self, name, desc, flags, precision): 442 import display 443 p = display.Print() 444 p.flags = flags 445 p.precision = precision 446 447 p.name = name + '.min_val' 448 p.value = self.minval 449 p.display() 450 451 p.name = name + '.max_val' 452 p.value = self.maxval 453 p.display() 454 455 p.name = name + '.underflow' 456 p.value = self.under 457 p.display() 458 459 i = self.min 460 for val in self.vec[:-1]: 461 p.name = name + '[%d:%d]' % (i, i + self.bsize - 1) 462 p.value = val 463 p.display() 464 i += self.bsize 465 466 p.name = name + '[%d:%d]' % (i, self.max) 467 p.value = self.vec[-1] 468 p.display() 469 470 471 p.name = name + '.overflow' 472 p.value = self.over 473 p.display() 474 475 SimpleDist.display(self, name, desc, flags, precision) 476 477 def comparable(self, other): 478 return self.min == other.min and self.max == other.max and \ 479 self.bsize == other.bsize and self.size == other.size 480 481 def __eq__(self, other): 482 return self.sums == other.sums and self.squares == other.squares and \ 483 self.samples == other.samples 484 485 def __isub__(self, other): 486 self.sums -= other.sums 487 self.squares -= other.squares 488 self.samples -= other.samples 489 490 if other.samples: 491 self.minval = min(self.minval, other.minval) 492 self.maxval = max(self.maxval, other.maxval) 493 self.under -= under 494 self.vec = map(lambda x,y: x - y, self.vec, other.vec) 495 self.over -= over 496 return self 497 498 def __iadd__(self, other): 499 if not self.samples and other.samples: 500 self = other 501 return self 502 503 self.sums += other.sums 504 self.squares += other.squares 505 self.samples += other.samples 506 507 if other.samples: 508 self.minval = min(self.minval, other.minval) 509 self.maxval = max(self.maxval, other.maxval) 510 self.under += other.under 511 self.vec = map(lambda x,y: x + y, self.vec, other.vec) 512 self.over += other.over 513 return self 514 515 def __itruediv__(self, other): 516 if not other: 517 return self 518 self.sums /= other 519 self.squares /= other 520 self.samples /= other 521 522 if self.samples: 523 self.under /= other 524 for i in xrange(len(self.vec)): 525 self.vec[i] /= other 526 self.over /= other 527 return self 528 529class Dist(Statistic): 530 def display(self): 531 import display 532 if not display.all and not (self.flags & flags.printable): 533 return 534 535 self.dist.display(self.name, self.desc, self.flags, self.precision) 536 537 def comparable(self, other): 538 return self.name == other.name and \ 539 self.dist.compareable(other.dist) 540 541 def __eq__(self, other): 542 return self.dist == other.dist 543 544 def __isub__(self, other): 545 self.dist -= other.dist 546 return self 547 548 def __iadd__(self, other): 549 self.dist += other.dist 550 return self 551 552 def __itruediv__(self, other): 553 if not other: 554 return self 555 self.dist /= other 556 return self 557 558class VectorDist(Statistic): 559 def display(self): 560 import display 561 if not display.all and not (self.flags & flags.printable): 562 return 563 564 if isinstance(self.dist, SimpleDist): 565 return 566 567 for dist,sn,sd,i in map(None, self.dist, self.subnames, self.subdescs, 568 range(len(self.dist))): 569 if len(sn) > 0: 570 name = '%s.%s' % (self.name, sn) 571 else: 572 name = '%s[%d]' % (self.name, i) 573 574 if len(sd) > 0: 575 desc = sd 576 else: 577 desc = self.desc 578 579 dist.display(name, desc, self.flags, self.precision) 580 581 if (self.flags & flags.total) or 1: 582 if isinstance(self.dist[0], SimpleDist): 583 disttotal = SimpleDist( \ 584 reduce(sums, [d.sums for d in self.dist]), 585 reduce(sums, [d.squares for d in self.dist]), 586 reduce(sums, [d.samples for d in self.dist])) 587 else: 588 disttotal = FullDist( \ 589 reduce(sums, [d.sums for d in self.dist]), 590 reduce(sums, [d.squares for d in self.dist]), 591 reduce(sums, [d.samples for d in self.dist]), 592 min([d.minval for d in self.dist]), 593 max([d.maxval for d in self.dist]), 594 reduce(sums, [d.under for d in self.dist]), 595 reduce(sums, [d.vec for d in self.dist]), 596 reduce(sums, [d.over for d in self.dist]), 597 dist[0].min, 598 dist[0].max, 599 dist[0].bsize, 600 dist[0].size) 601 602 name = '%s.total' % (self.name) 603 desc = self.desc 604 disttotal.display(name, desc, self.flags, self.precision) 605 606 def comparable(self, other): 607 return self.name == other.name and \ 608 alltrue(map(lambda x, y : x.comparable(y), 609 self.dist, 610 other.dist)) 611 612 def __eq__(self, other): 613 return alltrue(map(lambda x, y : x == y, self.dist, other.dist)) 614 615 def __isub__(self, other): 616 if isinstance(self.dist, (list, tuple)) and \ 617 isinstance(other.dist, (list, tuple)): 618 for sd,od in zip(self.dist, other.dist): 619 sd -= od 620 else: 621 self.dist -= other.dist 622 return self 623 624 def __iadd__(self, other): 625 if isinstance(self.dist, (list, tuple)) and \ 626 isinstance(other.dist, (list, tuple)): 627 for sd,od in zip(self.dist, other.dist): 628 sd += od 629 else: 630 self.dist += other.dist 631 return self 632 633 def __itruediv__(self, other): 634 if not other: 635 return self 636 if isinstance(self.dist, (list, tuple)): 637 for dist in self.dist: 638 dist /= other 639 else: 640 self.dist /= other 641 return self 642 643class Vector2d(Statistic): 644 def display(self): 645 import display 646 if not display.all and not (self.flags & flags.printable): 647 return 648 649 d = display.VectorDisplay() 650 d.__dict__.update(self.__dict__) 651 652 if self.__dict__.has_key('ysubnames'): 653 ysubnames = list(self.ysubnames) 654 slack = self.x - len(ysubnames) 655 if slack > 0: 656 ysubnames.extend(['']*slack) 657 else: 658 ysubnames = range(self.x) 659 660 for x,sname in enumerate(ysubnames): 661 o = x * self.y 662 d.value = self.value[o:o+self.y] 663 d.name = '%s[%s]' % (self.name, sname) 664 d.display() 665 666 if self.flags & flags.total: 667 d.value = [] 668 for y in range(self.y): 669 xtot = 0.0 670 for x in range(self.x): 671 xtot += self.value[y + x * self.x] 672 d.value.append(xtot) 673 674 d.name = self.name + '.total' 675 d.display() 676 677 def comparable(self, other): 678 return self.name == other.name and self.x == other.x and \ 679 self.y == other.y 680 681 def __eq__(self, other): 682 return True 683 684 def __isub__(self, other): 685 return self 686 687 def __iadd__(self, other): 688 return self 689 690 def __itruediv__(self, other): 691 if not other: 692 return self 693 return self 694 695def NewStat(source, data): 696 stat = None 697 if data.type == 'SCALAR': 698 stat = ScalarStat() 699 elif data.type == 'VECTOR': 700 stat = VectorStat() 701 elif data.type == 'DIST': 702 stat = Dist() 703 elif data.type == 'VECTORDIST': 704 stat = VectorDist() 705 elif data.type == 'VECTOR2D': 706 stat = Vector2d() 707 elif data.type == 'FORMULA': 708 stat = Formula() 709 710 stat.__dict__['source'] = source 711 stat.__dict__['bins'] = None 712 stat.__dict__['ticks'] = None 713 stat.__dict__.update(data.__dict__) 714 715 return stat 716 717