info.py revision 1758
11758Ssaidi@eecs.umich.edu
21758Ssaidi@eecs.umich.edu# Copyright (c) 2003-2004 The Regents of The University of Michigan
31758Ssaidi@eecs.umich.edu# All rights reserved.
41758Ssaidi@eecs.umich.edu#
51758Ssaidi@eecs.umich.edu# Redistribution and use in source and binary forms, with or without
61758Ssaidi@eecs.umich.edu# modification, are permitted provided that the following conditions are
71758Ssaidi@eecs.umich.edu# met: redistributions of source code must retain the above copyright
81758Ssaidi@eecs.umich.edu# notice, this list of conditions and the following disclaimer;
91758Ssaidi@eecs.umich.edu# redistributions in binary form must reproduce the above copyright
101758Ssaidi@eecs.umich.edu# notice, this list of conditions and the following disclaimer in the
111758Ssaidi@eecs.umich.edu# documentation and/or other materials provided with the distribution;
121758Ssaidi@eecs.umich.edu# neither the name of the copyright holders nor the names of its
131758Ssaidi@eecs.umich.edu# contributors may be used to endorse or promote products derived from
141758Ssaidi@eecs.umich.edu# this software without specific prior written permission.
151758Ssaidi@eecs.umich.edu#
161758Ssaidi@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171758Ssaidi@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181758Ssaidi@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191758Ssaidi@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201758Ssaidi@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211758Ssaidi@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221758Ssaidi@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231758Ssaidi@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241758Ssaidi@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251758Ssaidi@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261758Ssaidi@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
271758Ssaidi@eecs.umich.edu
281758Ssaidi@eecs.umich.edu#Permission is granted to use, copy, create derivative works and
291758Ssaidi@eecs.umich.edu#redistribute this software and such derivative works for any purpose,
301758Ssaidi@eecs.umich.edu#so long as the copyright notice above, this grant of permission, and
311758Ssaidi@eecs.umich.edu#the disclaimer below appear in all copies made; and so long as the
321758Ssaidi@eecs.umich.edu#name of The University of Michigan is not used in any advertising or
331758Ssaidi@eecs.umich.edu#publicity pertaining to the use or distribution of this software
341758Ssaidi@eecs.umich.edu#without specific, written prior authorization.
351758Ssaidi@eecs.umich.edu#
361758Ssaidi@eecs.umich.edu#THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE
371758Ssaidi@eecs.umich.edu#UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND WITHOUT
381758Ssaidi@eecs.umich.edu#WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER EXPRESS OR
391758Ssaidi@eecs.umich.edu#IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
401758Ssaidi@eecs.umich.edu#MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE REGENTS OF
411758Ssaidi@eecs.umich.edu#THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE FOR ANY DAMAGES,
421758Ssaidi@eecs.umich.edu#INCLUDING DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
431758Ssaidi@eecs.umich.edu#DAMAGES, WITH RESPECT TO ANY CLAIM ARISING OUT OF OR IN CONNECTION
441758Ssaidi@eecs.umich.edu#WITH THE USE OF THE SOFTWARE, EVEN IF IT HAS BEEN OR IS HEREAFTER
451758Ssaidi@eecs.umich.edu#ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
461758Ssaidi@eecs.umich.edu
471049Sbinkertn@umich.edufrom __future__ import division
481049Sbinkertn@umich.eduimport operator, re, types
491049Sbinkertn@umich.edu
501049Sbinkertn@umich.edusource = None
511049Sbinkertn@umich.edudisplay_run = 0
521329Ssaidi@eecs.umich.eduglobal globalTicks
531329Ssaidi@eecs.umich.eduglobalTicks = None
541049Sbinkertn@umich.edu
551049Sbinkertn@umich.edudef total(f):
561049Sbinkertn@umich.edu    if isinstance(f, FormulaStat):
571049Sbinkertn@umich.edu        v = f.value
581049Sbinkertn@umich.edu    else:
591049Sbinkertn@umich.edu        v = f
601049Sbinkertn@umich.edu
611049Sbinkertn@umich.edu    f = FormulaStat()
621547Sbinkertn@umich.edu    if isinstance(v, (list, tuple)):
631049Sbinkertn@umich.edu        f.value = reduce(operator.add, v)
641049Sbinkertn@umich.edu    else:
651049Sbinkertn@umich.edu        f.value = v
661049Sbinkertn@umich.edu
671049Sbinkertn@umich.edu    return f
681049Sbinkertn@umich.edu
691049Sbinkertn@umich.edudef unaryop(op, f):
701049Sbinkertn@umich.edu    if isinstance(f, FormulaStat):
711049Sbinkertn@umich.edu        v = f.value
721049Sbinkertn@umich.edu    else:
731049Sbinkertn@umich.edu        v = f
741049Sbinkertn@umich.edu
751547Sbinkertn@umich.edu    if isinstance(v, (list, tuple)):
761049Sbinkertn@umich.edu        return map(op, v)
771049Sbinkertn@umich.edu    else:
781049Sbinkertn@umich.edu        return op(v)
791049Sbinkertn@umich.edu
801049Sbinkertn@umich.edudef zerodiv(lv, rv):
811049Sbinkertn@umich.edu    if rv == 0.0:
821049Sbinkertn@umich.edu        return 0.0
831049Sbinkertn@umich.edu    else:
841049Sbinkertn@umich.edu        return operator.truediv(lv, rv)
851049Sbinkertn@umich.edu
861049Sbinkertn@umich.edudef wrapop(op, lv, rv):
871049Sbinkertn@umich.edu    if isinstance(lv, str):
881049Sbinkertn@umich.edu        return lv
891049Sbinkertn@umich.edu
901049Sbinkertn@umich.edu    if isinstance(rv, str):
911049Sbinkertn@umich.edu        return rv
921049Sbinkertn@umich.edu
931049Sbinkertn@umich.edu    return op(lv, rv)
941049Sbinkertn@umich.edu
951269Sbinkertn@umich.edudef same(lrun, rrun):
961269Sbinkertn@umich.edu    for lx,rx in zip(lrun.keys(),rrun.keys()):
971269Sbinkertn@umich.edu        if lx != rx:
981269Sbinkertn@umich.edu            print 'lx != rx'
991269Sbinkertn@umich.edu            print lx, rx
1001269Sbinkertn@umich.edu            print lrun.keys()
1011269Sbinkertn@umich.edu            print rrun.keys()
1021049Sbinkertn@umich.edu            return False
1031269Sbinkertn@umich.edu        for ly,ry in zip(lrun[lx].keys(),rrun[rx].keys()):
1041269Sbinkertn@umich.edu            if ly != ry:
1051269Sbinkertn@umich.edu                print 'ly != ry'
1061269Sbinkertn@umich.edu                print ly, ry
1071269Sbinkertn@umich.edu                print lrun[lx].keys()
1081269Sbinkertn@umich.edu                print rrun[rx].keys()
1091049Sbinkertn@umich.edu                return False
1101049Sbinkertn@umich.edu    return True
1111049Sbinkertn@umich.edu
1121049Sbinkertn@umich.edu
1131049Sbinkertn@umich.edudef binaryop(op, lf, rf):
1141049Sbinkertn@umich.edu    result = {}
1151049Sbinkertn@umich.edu
1161049Sbinkertn@umich.edu    if isinstance(lf, FormulaStat) and isinstance(rf, FormulaStat):
1171049Sbinkertn@umich.edu        lv = lf.value
1181049Sbinkertn@umich.edu        rv = rf.value
1191049Sbinkertn@umich.edu
1201269Sbinkertn@umich.edu        theruns = []
1211269Sbinkertn@umich.edu        for r in lv.keys():
1221269Sbinkertn@umich.edu            if rv.has_key(r):
1231269Sbinkertn@umich.edu                if same(lv[r], rv[r]):
1241269Sbinkertn@umich.edu                    theruns.append(r)
1251269Sbinkertn@umich.edu                else:
1261269Sbinkertn@umich.edu                    raise AttributeError
1271049Sbinkertn@umich.edu
1281269Sbinkertn@umich.edu        for run in theruns:
1291049Sbinkertn@umich.edu            result[run] = {}
1301049Sbinkertn@umich.edu            for x in lv[run].keys():
1311049Sbinkertn@umich.edu                result[run][x] = {}
1321049Sbinkertn@umich.edu                for y in lv[run][x].keys():
1331049Sbinkertn@umich.edu                    result[run][x][y] = wrapop(op, lv[run][x][y],
1341049Sbinkertn@umich.edu                                               rv[run][x][y])
1351049Sbinkertn@umich.edu    elif isinstance(lf, FormulaStat):
1361049Sbinkertn@umich.edu        lv = lf.value
1371049Sbinkertn@umich.edu        for run in lv.keys():
1381049Sbinkertn@umich.edu            result[run] = {}
1391049Sbinkertn@umich.edu            for x in lv[run].keys():
1401049Sbinkertn@umich.edu                result[run][x] = {}
1411049Sbinkertn@umich.edu                for y in lv[run][x].keys():
1421049Sbinkertn@umich.edu                    result[run][x][y] = wrapop(op, lv[run][x][y], rf)
1431049Sbinkertn@umich.edu    elif isinstance(rf, FormulaStat):
1441049Sbinkertn@umich.edu        rv = rf.value
1451049Sbinkertn@umich.edu        for run in rv.keys():
1461049Sbinkertn@umich.edu            result[run] = {}
1471049Sbinkertn@umich.edu            for x in rv[run].keys():
1481049Sbinkertn@umich.edu                result[run][x] = {}
1491049Sbinkertn@umich.edu                for y in rv[run][x].keys():
1501049Sbinkertn@umich.edu                    result[run][x][y] = wrapop(op, lf, rv[run][x][y])
1511049Sbinkertn@umich.edu
1521049Sbinkertn@umich.edu    return result
1531049Sbinkertn@umich.edu
1541049Sbinkertn@umich.edudef sums(x, y):
1551547Sbinkertn@umich.edu    if isinstance(x, (list, tuple)):
1561049Sbinkertn@umich.edu        return map(lambda x, y: x + y, x, y)
1571049Sbinkertn@umich.edu    else:
1581049Sbinkertn@umich.edu        return x + y
1591049Sbinkertn@umich.edu
1601547Sbinkertn@umich.edudef alltrue(seq):
1611547Sbinkertn@umich.edu    return reduce(lambda x, y: x and y, seq)
1621049Sbinkertn@umich.edu
1631547Sbinkertn@umich.edudef allfalse(seq):
1641547Sbinkertn@umich.edu    return not reduce(lambda x, y: x or y, seq)
1651049Sbinkertn@umich.edu
1661547Sbinkertn@umich.edudef enumerate(seq):
1671547Sbinkertn@umich.edu    return map(None, range(len(seq)), seq)
1681049Sbinkertn@umich.edu
1691049Sbinkertn@umich.edudef cmp(a, b):
1701049Sbinkertn@umich.edu    if a < b:
1711049Sbinkertn@umich.edu        return -1
1721049Sbinkertn@umich.edu    elif a == b:
1731049Sbinkertn@umich.edu        return 0
1741049Sbinkertn@umich.edu    else:
1751049Sbinkertn@umich.edu        return 1
1761049Sbinkertn@umich.edu
1771049Sbinkertn@umich.educlass Statistic(object):
1781329Ssaidi@eecs.umich.edu
1791049Sbinkertn@umich.edu    def __init__(self, data):
1801049Sbinkertn@umich.edu        self.__dict__.update(data.__dict__)
1811049Sbinkertn@umich.edu        if not self.__dict__.has_key('value'):
1821049Sbinkertn@umich.edu            self.__dict__['value'] = None
1831049Sbinkertn@umich.edu        if not self.__dict__.has_key('bins'):
1841049Sbinkertn@umich.edu            self.__dict__['bins'] = None
1851049Sbinkertn@umich.edu        if not self.__dict__.has_key('ticks'):
1861049Sbinkertn@umich.edu            self.__dict__['ticks'] = None
1871329Ssaidi@eecs.umich.edu        if 'vc' not in self.__dict__:
1881329Ssaidi@eecs.umich.edu            self.vc = {}
1891049Sbinkertn@umich.edu
1901049Sbinkertn@umich.edu    def __getattribute__(self, attr):
1911329Ssaidi@eecs.umich.edu        if attr == 'ticks':
1921329Ssaidi@eecs.umich.edu            if self.__dict__['ticks'] != globalTicks:
1931329Ssaidi@eecs.umich.edu                self.__dict__['value'] = None
1941329Ssaidi@eecs.umich.edu                self.__dict__['ticks'] = globalTicks
1951329Ssaidi@eecs.umich.edu            return self.__dict__['ticks']
1961049Sbinkertn@umich.edu        if attr == 'value':
1971329Ssaidi@eecs.umich.edu            if self.__dict__['ticks'] != globalTicks:
1981329Ssaidi@eecs.umich.edu                if self.__dict__['ticks'] != None and \
1991329Ssaidi@eecs.umich.edu                                    len(self.__dict__['ticks']) == 1:
2001329Ssaidi@eecs.umich.edu                    self.vc[self.__dict__['ticks'][0]] = self.__dict__['value']
2011329Ssaidi@eecs.umich.edu                self.__dict__['ticks'] = globalTicks
2021329Ssaidi@eecs.umich.edu                if len(globalTicks) == 1 and self.vc.has_key(globalTicks[0]):
2031329Ssaidi@eecs.umich.edu                    self.__dict__['value'] = self.vc[globalTicks[0]]
2041329Ssaidi@eecs.umich.edu                else:
2051329Ssaidi@eecs.umich.edu                    self.__dict__['value'] = None
2061049Sbinkertn@umich.edu            if self.__dict__['value'] == None:
2071049Sbinkertn@umich.edu                self.__dict__['value'] = self.getValue()
2081049Sbinkertn@umich.edu            return self.__dict__['value']
2091049Sbinkertn@umich.edu        else:
2101049Sbinkertn@umich.edu            return super(Statistic, self).__getattribute__(attr)
2111049Sbinkertn@umich.edu
2121049Sbinkertn@umich.edu    def __setattr__(self, attr, value):
2131049Sbinkertn@umich.edu        if attr == 'bins' or attr == 'ticks':
2141049Sbinkertn@umich.edu            if attr == 'bins':
2151049Sbinkertn@umich.edu                if value is not None:
2161165Sbinkertn@umich.edu                    value = source.getBin(value)
2171329Ssaidi@eecs.umich.edu            #elif attr == 'ticks' and type(value) is str:
2181329Ssaidi@eecs.umich.edu            #    value = [ int(x) for x in value.split() ]
2191049Sbinkertn@umich.edu
2201049Sbinkertn@umich.edu            self.__dict__[attr] = value
2211049Sbinkertn@umich.edu            self.__dict__['value'] = None
2221329Ssaidi@eecs.umich.edu            self.vc = {}
2231049Sbinkertn@umich.edu        else:
2241049Sbinkertn@umich.edu            super(Statistic, self).__setattr__(attr, value)
2251049Sbinkertn@umich.edu
2261049Sbinkertn@umich.edu    def getValue(self):
2271049Sbinkertn@umich.edu        raise AttributeError, 'getValue() must be defined'
2281049Sbinkertn@umich.edu
2291049Sbinkertn@umich.edu    def zero(self):
2301049Sbinkertn@umich.edu        return False
2311049Sbinkertn@umich.edu
2321049Sbinkertn@umich.edu    def __ne__(self, other):
2331049Sbinkertn@umich.edu        return not (self == other)
2341049Sbinkertn@umich.edu
2351049Sbinkertn@umich.edu    def __str__(self):
2361049Sbinkertn@umich.edu        return '%f' % (float(self))
2371049Sbinkertn@umich.edu
2381049Sbinkertn@umich.educlass FormulaStat(object):
2391049Sbinkertn@umich.edu    def __add__(self, other):
2401049Sbinkertn@umich.edu        f = FormulaStat()
2411049Sbinkertn@umich.edu        f.value = binaryop(operator.add, self, other)
2421049Sbinkertn@umich.edu        return f
2431049Sbinkertn@umich.edu    def __sub__(self, other):
2441049Sbinkertn@umich.edu        f = FormulaStat()
2451049Sbinkertn@umich.edu        f.value = binaryop(operator.sub, self, other)
2461049Sbinkertn@umich.edu        return f
2471049Sbinkertn@umich.edu    def __mul__(self, other):
2481049Sbinkertn@umich.edu        f = FormulaStat()
2491049Sbinkertn@umich.edu        f.value = binaryop(operator.mul, self, other)
2501049Sbinkertn@umich.edu        return f
2511049Sbinkertn@umich.edu    def __truediv__(self, other):
2521049Sbinkertn@umich.edu        f = FormulaStat()
2531049Sbinkertn@umich.edu        f.value = binaryop(zerodiv, self, other)
2541049Sbinkertn@umich.edu        return f
2551049Sbinkertn@umich.edu    def __mod__(self, other):
2561049Sbinkertn@umich.edu        f = FormulaStat()
2571049Sbinkertn@umich.edu        f.value = binaryop(operator.mod, self, other)
2581049Sbinkertn@umich.edu        return f
2591049Sbinkertn@umich.edu    def __radd__(self, other):
2601049Sbinkertn@umich.edu        f = FormulaStat()
2611049Sbinkertn@umich.edu        f.value = binaryop(operator.add, other, self)
2621049Sbinkertn@umich.edu        return f
2631049Sbinkertn@umich.edu    def __rsub__(self, other):
2641049Sbinkertn@umich.edu        f = FormulaStat()
2651049Sbinkertn@umich.edu        f.value = binaryop(operator.sub, other, self)
2661049Sbinkertn@umich.edu        return f
2671049Sbinkertn@umich.edu    def __rmul__(self, other):
2681049Sbinkertn@umich.edu        f = FormulaStat()
2691049Sbinkertn@umich.edu        f.value = binaryop(operator.mul, other, self)
2701049Sbinkertn@umich.edu        return f
2711049Sbinkertn@umich.edu    def __rtruediv__(self, other):
2721049Sbinkertn@umich.edu        f = FormulaStat()
2731049Sbinkertn@umich.edu        f.value = binaryop(zerodiv, other, self)
2741049Sbinkertn@umich.edu        return f
2751049Sbinkertn@umich.edu    def __rmod__(self, other):
2761049Sbinkertn@umich.edu        f = FormulaStat()
2771049Sbinkertn@umich.edu        f.value = binaryop(operator.mod, other, self)
2781049Sbinkertn@umich.edu        return f
2791049Sbinkertn@umich.edu    def __neg__(self):
2801049Sbinkertn@umich.edu        f = FormulaStat()
2811049Sbinkertn@umich.edu        f.value = unaryop(operator.neg, self)
2821049Sbinkertn@umich.edu        return f
2831049Sbinkertn@umich.edu    def __getitem__(self, idx):
2841049Sbinkertn@umich.edu        f = FormulaStat()
2851049Sbinkertn@umich.edu        f.value = {}
2861049Sbinkertn@umich.edu        for key in self.value.keys():
2871049Sbinkertn@umich.edu            f.value[key] = {}
2881049Sbinkertn@umich.edu            f.value[key][0] = {}
2891049Sbinkertn@umich.edu            f.value[key][0][0] = self.value[key][idx][0]
2901049Sbinkertn@umich.edu        return f
2911049Sbinkertn@umich.edu
2921049Sbinkertn@umich.edu    def __float__(self):
2931049Sbinkertn@umich.edu        if isinstance(self.value, FormulaStat):
2941049Sbinkertn@umich.edu            return float(self.value)
2951049Sbinkertn@umich.edu        if not self.value.has_key(display_run):
2961049Sbinkertn@umich.edu            return (1e300*1e300)
2971049Sbinkertn@umich.edu        if len(self.value[display_run]) == 1:
2981049Sbinkertn@umich.edu            return self.value[display_run][0][0]
2991049Sbinkertn@umich.edu        else:
3001049Sbinkertn@umich.edu            #print self.value[display_run]
3011049Sbinkertn@umich.edu            return self.value[display_run][4][0]
3021049Sbinkertn@umich.edu            #raise ValueError
3031049Sbinkertn@umich.edu
3041049Sbinkertn@umich.edu    def display(self):
3051049Sbinkertn@umich.edu        import display
3061049Sbinkertn@umich.edu        d = display.VectorDisplay()
3071049Sbinkertn@umich.edu        d.flags = 0
3081049Sbinkertn@umich.edu        d.precision = 1
3091049Sbinkertn@umich.edu        d.name = 'formula'
3101049Sbinkertn@umich.edu        d.desc = 'formula'
3111049Sbinkertn@umich.edu        val = self.value[display_run]
3121049Sbinkertn@umich.edu        d.value = [ val[x][0] for x in val.keys() ]
3131049Sbinkertn@umich.edu        d.display()
3141049Sbinkertn@umich.edu
3151049Sbinkertn@umich.edu
3161049Sbinkertn@umich.educlass Scalar(Statistic,FormulaStat):
3171049Sbinkertn@umich.edu    def getValue(self):
3181301Ssaidi@eecs.umich.edu        return source.data(self, self.bins, self.ticks)
3191049Sbinkertn@umich.edu
3201049Sbinkertn@umich.edu    def display(self):
3211049Sbinkertn@umich.edu        import display
3221049Sbinkertn@umich.edu        p = display.Print()
3231049Sbinkertn@umich.edu        p.name = self.name
3241049Sbinkertn@umich.edu        p.desc = self.desc
3251049Sbinkertn@umich.edu        p.value = float(self)
3261049Sbinkertn@umich.edu        p.flags = self.flags
3271049Sbinkertn@umich.edu        p.precision = self.precision
3281049Sbinkertn@umich.edu        if display.all or (self.flags & flags.printable):
3291049Sbinkertn@umich.edu            p.display()
3301049Sbinkertn@umich.edu
3311049Sbinkertn@umich.edu    def comparable(self, other):
3321049Sbinkertn@umich.edu        return self.name == other.name
3331049Sbinkertn@umich.edu
3341049Sbinkertn@umich.edu    def __eq__(self, other):
3351049Sbinkertn@umich.edu        return self.value == other.value
3361049Sbinkertn@umich.edu
3371049Sbinkertn@umich.edu    def __isub__(self, other):
3381049Sbinkertn@umich.edu        self.value -= other.value
3391049Sbinkertn@umich.edu        return self
3401049Sbinkertn@umich.edu
3411049Sbinkertn@umich.edu    def __iadd__(self, other):
3421049Sbinkertn@umich.edu        self.value += other.value
3431049Sbinkertn@umich.edu        return self
3441049Sbinkertn@umich.edu
3451049Sbinkertn@umich.edu    def __itruediv__(self, other):
3461049Sbinkertn@umich.edu        if not other:
3471049Sbinkertn@umich.edu            return self
3481049Sbinkertn@umich.edu        self.value /= other
3491049Sbinkertn@umich.edu        return self
3501049Sbinkertn@umich.edu
3511049Sbinkertn@umich.educlass Vector(Statistic,FormulaStat):
3521049Sbinkertn@umich.edu    def getValue(self):
3531331Ssaidi@eecs.umich.edu        return source.data(self, self.bins, self.ticks);
3541049Sbinkertn@umich.edu
3551049Sbinkertn@umich.edu    def display(self):
3561049Sbinkertn@umich.edu        import display
3571049Sbinkertn@umich.edu        if not display.all and not (self.flags & flags.printable):
3581049Sbinkertn@umich.edu            return
3591049Sbinkertn@umich.edu
3601049Sbinkertn@umich.edu        d = display.VectorDisplay()
3611049Sbinkertn@umich.edu        d.__dict__.update(self.__dict__)
3621049Sbinkertn@umich.edu        d.display()
3631049Sbinkertn@umich.edu
3641049Sbinkertn@umich.edu    def comparable(self, other):
3651049Sbinkertn@umich.edu        return self.name == other.name and \
3661049Sbinkertn@umich.edu               len(self.value) == len(other.value)
3671049Sbinkertn@umich.edu
3681049Sbinkertn@umich.edu    def __eq__(self, other):
3691547Sbinkertn@umich.edu        if isinstance(self.value, (list, tuple)) != \
3701547Sbinkertn@umich.edu               isinstance(other.value, (list, tuple)):
3711369Sbinkertn@umich.edu            return False
3721049Sbinkertn@umich.edu
3731547Sbinkertn@umich.edu        if isinstance(self.value, (list, tuple)):
3741049Sbinkertn@umich.edu            if len(self.value) != len(other.value):
3751049Sbinkertn@umich.edu                return False
3761049Sbinkertn@umich.edu            else:
3771049Sbinkertn@umich.edu                for v1,v2 in zip(self.value, other.value):
3781049Sbinkertn@umich.edu                    if v1 != v2:
3791049Sbinkertn@umich.edu                        return False
3801049Sbinkertn@umich.edu                return True
3811049Sbinkertn@umich.edu        else:
3821049Sbinkertn@umich.edu            return self.value == other.value
3831049Sbinkertn@umich.edu
3841049Sbinkertn@umich.edu    def __isub__(self, other):
3851049Sbinkertn@umich.edu        self.value = binaryop(operator.sub, self.value, other.value)
3861049Sbinkertn@umich.edu        return self
3871049Sbinkertn@umich.edu
3881049Sbinkertn@umich.edu    def __iadd__(self, other):
3891049Sbinkertn@umich.edu        self.value = binaryop(operator.add, self.value, other.value)
3901049Sbinkertn@umich.edu        return self
3911049Sbinkertn@umich.edu
3921049Sbinkertn@umich.edu    def __itruediv__(self, other):
3931049Sbinkertn@umich.edu        if not other:
3941049Sbinkertn@umich.edu            return self
3951547Sbinkertn@umich.edu        if isinstance(self.value, (list, tuple)):
3961049Sbinkertn@umich.edu            for i in xrange(len(self.value)):
3971049Sbinkertn@umich.edu                self.value[i] /= other
3981049Sbinkertn@umich.edu        else:
3991049Sbinkertn@umich.edu            self.value /= other
4001049Sbinkertn@umich.edu        return self
4011049Sbinkertn@umich.edu
4021049Sbinkertn@umich.educlass Formula(Vector):
4031049Sbinkertn@umich.edu    def getValue(self):
4041049Sbinkertn@umich.edu        formula = re.sub(':', '__', self.formula)
4051049Sbinkertn@umich.edu        x = eval(formula, source.stattop)
4061049Sbinkertn@umich.edu        return x.value
4071049Sbinkertn@umich.edu
4081049Sbinkertn@umich.edu    def comparable(self, other):
4091049Sbinkertn@umich.edu        return self.name == other.name and \
4101049Sbinkertn@umich.edu               compare(self.dist, other.dist)
4111049Sbinkertn@umich.edu
4121049Sbinkertn@umich.edu    def __eq__(self, other):
4131049Sbinkertn@umich.edu        return self.value == other.value
4141049Sbinkertn@umich.edu
4151049Sbinkertn@umich.edu    def __isub__(self, other):
4161049Sbinkertn@umich.edu        return self
4171049Sbinkertn@umich.edu
4181049Sbinkertn@umich.edu    def __iadd__(self, other):
4191049Sbinkertn@umich.edu        return self
4201049Sbinkertn@umich.edu
4211049Sbinkertn@umich.edu    def __itruediv__(self, other):
4221049Sbinkertn@umich.edu        if not other:
4231049Sbinkertn@umich.edu            return self
4241049Sbinkertn@umich.edu        return self
4251049Sbinkertn@umich.edu
4261049Sbinkertn@umich.educlass SimpleDist(object):
4271049Sbinkertn@umich.edu    def __init__(self, sums, squares, samples):
4281049Sbinkertn@umich.edu        self.sums = sums
4291049Sbinkertn@umich.edu        self.squares = squares
4301049Sbinkertn@umich.edu        self.samples = samples
4311049Sbinkertn@umich.edu
4321049Sbinkertn@umich.edu    def getValue(self):
4331049Sbinkertn@umich.edu        return 0.0
4341049Sbinkertn@umich.edu
4351049Sbinkertn@umich.edu    def display(self, name, desc, flags, precision):
4361049Sbinkertn@umich.edu        import display
4371049Sbinkertn@umich.edu        p = display.Print()
4381049Sbinkertn@umich.edu        p.flags = flags
4391049Sbinkertn@umich.edu        p.precision = precision
4401049Sbinkertn@umich.edu
4411049Sbinkertn@umich.edu        if self.samples > 0:
4421049Sbinkertn@umich.edu            p.name = name + ".mean"
4431049Sbinkertn@umich.edu            p.value = self.sums / self.samples
4441049Sbinkertn@umich.edu            p.display()
4451049Sbinkertn@umich.edu
4461049Sbinkertn@umich.edu            p.name = name + ".stdev"
4471049Sbinkertn@umich.edu            if self.samples > 1:
4481049Sbinkertn@umich.edu                var = (self.samples * self.squares - self.sums ** 2) \
4491049Sbinkertn@umich.edu                      / (self.samples * (self.samples - 1))
4501049Sbinkertn@umich.edu                if var >= 0:
4511049Sbinkertn@umich.edu                    p.value = math.sqrt(var)
4521049Sbinkertn@umich.edu                else:
4531049Sbinkertn@umich.edu                    p.value = 'NaN'
4541049Sbinkertn@umich.edu            else:
4551049Sbinkertn@umich.edu                p.value = 0.0
4561049Sbinkertn@umich.edu            p.display()
4571049Sbinkertn@umich.edu
4581049Sbinkertn@umich.edu        p.name = name + ".samples"
4591049Sbinkertn@umich.edu        p.value = self.samples
4601049Sbinkertn@umich.edu        p.display()
4611049Sbinkertn@umich.edu
4621049Sbinkertn@umich.edu    def comparable(self, other):
4631049Sbinkertn@umich.edu        return True
4641049Sbinkertn@umich.edu
4651049Sbinkertn@umich.edu    def __eq__(self, other):
4661049Sbinkertn@umich.edu        return self.sums == other.sums and self.squares == other.squares and \
4671049Sbinkertn@umich.edu               self.samples == other.samples
4681049Sbinkertn@umich.edu
4691049Sbinkertn@umich.edu    def __isub__(self, other):
4701049Sbinkertn@umich.edu        self.sums -= other.sums
4711049Sbinkertn@umich.edu        self.squares -= other.squares
4721049Sbinkertn@umich.edu        self.samples -= other.samples
4731049Sbinkertn@umich.edu        return self
4741049Sbinkertn@umich.edu
4751049Sbinkertn@umich.edu    def __iadd__(self, other):
4761049Sbinkertn@umich.edu        self.sums += other.sums
4771049Sbinkertn@umich.edu        self.squares += other.squares
4781049Sbinkertn@umich.edu        self.samples += other.samples
4791049Sbinkertn@umich.edu        return self
4801049Sbinkertn@umich.edu
4811049Sbinkertn@umich.edu    def __itruediv__(self, other):
4821049Sbinkertn@umich.edu        if not other:
4831049Sbinkertn@umich.edu            return self
4841049Sbinkertn@umich.edu        self.sums /= other
4851049Sbinkertn@umich.edu        self.squares /= other
4861049Sbinkertn@umich.edu        self.samples /= other
4871049Sbinkertn@umich.edu        return self
4881049Sbinkertn@umich.edu
4891049Sbinkertn@umich.educlass FullDist(SimpleDist):
4901049Sbinkertn@umich.edu    def __init__(self, sums, squares, samples, minval, maxval,
4911049Sbinkertn@umich.edu                 under, vec, over, min, max, bsize, size):
4921049Sbinkertn@umich.edu        self.sums = sums
4931049Sbinkertn@umich.edu        self.squares = squares
4941049Sbinkertn@umich.edu        self.samples = samples
4951049Sbinkertn@umich.edu        self.minval = minval
4961049Sbinkertn@umich.edu        self.maxval = maxval
4971049Sbinkertn@umich.edu        self.under = under
4981049Sbinkertn@umich.edu        self.vec = vec
4991049Sbinkertn@umich.edu        self.over = over
5001049Sbinkertn@umich.edu        self.min = min
5011049Sbinkertn@umich.edu        self.max = max
5021049Sbinkertn@umich.edu        self.bsize = bsize
5031049Sbinkertn@umich.edu        self.size = size
5041049Sbinkertn@umich.edu
5051049Sbinkertn@umich.edu    def getValue(self):
5061049Sbinkertn@umich.edu        return 0.0
5071049Sbinkertn@umich.edu
5081049Sbinkertn@umich.edu    def display(self, name, desc, flags, precision):
5091049Sbinkertn@umich.edu        import display
5101049Sbinkertn@umich.edu        p = display.Print()
5111049Sbinkertn@umich.edu        p.flags = flags
5121049Sbinkertn@umich.edu        p.precision = precision
5131049Sbinkertn@umich.edu
5141049Sbinkertn@umich.edu        p.name = name + '.min_val'
5151049Sbinkertn@umich.edu        p.value = self.minval
5161049Sbinkertn@umich.edu        p.display()
5171049Sbinkertn@umich.edu
5181049Sbinkertn@umich.edu        p.name = name + '.max_val'
5191049Sbinkertn@umich.edu        p.value = self.maxval
5201049Sbinkertn@umich.edu        p.display()
5211049Sbinkertn@umich.edu
5221049Sbinkertn@umich.edu        p.name = name + '.underflow'
5231049Sbinkertn@umich.edu        p.value = self.under
5241049Sbinkertn@umich.edu        p.display()
5251049Sbinkertn@umich.edu
5261049Sbinkertn@umich.edu        i = self.min
5271049Sbinkertn@umich.edu        for val in self.vec[:-1]:
5281049Sbinkertn@umich.edu            p.name = name + '[%d:%d]' % (i, i + self.bsize - 1)
5291049Sbinkertn@umich.edu            p.value = val
5301049Sbinkertn@umich.edu            p.display()
5311049Sbinkertn@umich.edu            i += self.bsize
5321049Sbinkertn@umich.edu
5331049Sbinkertn@umich.edu        p.name = name + '[%d:%d]' % (i, self.max)
5341049Sbinkertn@umich.edu        p.value = self.vec[-1]
5351049Sbinkertn@umich.edu        p.display()
5361049Sbinkertn@umich.edu
5371049Sbinkertn@umich.edu
5381049Sbinkertn@umich.edu        p.name = name + '.overflow'
5391049Sbinkertn@umich.edu        p.value = self.over
5401049Sbinkertn@umich.edu        p.display()
5411049Sbinkertn@umich.edu
5421049Sbinkertn@umich.edu        SimpleDist.display(self, name, desc, flags, precision)
5431049Sbinkertn@umich.edu
5441049Sbinkertn@umich.edu    def comparable(self, other):
5451049Sbinkertn@umich.edu        return self.min == other.min and self.max == other.max and \
5461049Sbinkertn@umich.edu               self.bsize == other.bsize and self.size == other.size
5471049Sbinkertn@umich.edu
5481049Sbinkertn@umich.edu    def __eq__(self, other):
5491049Sbinkertn@umich.edu        return self.sums == other.sums and self.squares == other.squares and \
5501049Sbinkertn@umich.edu               self.samples == other.samples
5511049Sbinkertn@umich.edu
5521049Sbinkertn@umich.edu    def __isub__(self, other):
5531049Sbinkertn@umich.edu        self.sums -= other.sums
5541049Sbinkertn@umich.edu        self.squares -= other.squares
5551049Sbinkertn@umich.edu        self.samples -= other.samples
5561049Sbinkertn@umich.edu
5571049Sbinkertn@umich.edu        if other.samples:
5581049Sbinkertn@umich.edu            self.minval = min(self.minval, other.minval)
5591049Sbinkertn@umich.edu            self.maxval = max(self.maxval, other.maxval)
5601049Sbinkertn@umich.edu            self.under -= under
5611049Sbinkertn@umich.edu            self.vec = map(lambda x,y: x - y, self.vec, other.vec)
5621049Sbinkertn@umich.edu            self.over -= over
5631049Sbinkertn@umich.edu        return self
5641049Sbinkertn@umich.edu
5651049Sbinkertn@umich.edu    def __iadd__(self, other):
5661049Sbinkertn@umich.edu        if not self.samples and other.samples:
5671049Sbinkertn@umich.edu            self = other
5681049Sbinkertn@umich.edu            return self
5691049Sbinkertn@umich.edu
5701049Sbinkertn@umich.edu        self.sums += other.sums
5711049Sbinkertn@umich.edu        self.squares += other.squares
5721049Sbinkertn@umich.edu        self.samples += other.samples
5731049Sbinkertn@umich.edu
5741049Sbinkertn@umich.edu        if other.samples:
5751049Sbinkertn@umich.edu            self.minval = min(self.minval, other.minval)
5761049Sbinkertn@umich.edu            self.maxval = max(self.maxval, other.maxval)
5771049Sbinkertn@umich.edu            self.under += other.under
5781049Sbinkertn@umich.edu            self.vec = map(lambda x,y: x + y, self.vec, other.vec)
5791049Sbinkertn@umich.edu            self.over += other.over
5801049Sbinkertn@umich.edu        return self
5811049Sbinkertn@umich.edu
5821049Sbinkertn@umich.edu    def __itruediv__(self, other):
5831049Sbinkertn@umich.edu        if not other:
5841049Sbinkertn@umich.edu            return self
5851049Sbinkertn@umich.edu        self.sums /= other
5861049Sbinkertn@umich.edu        self.squares /= other
5871049Sbinkertn@umich.edu        self.samples /= other
5881049Sbinkertn@umich.edu
5891049Sbinkertn@umich.edu        if self.samples:
5901049Sbinkertn@umich.edu            self.under /= other
5911049Sbinkertn@umich.edu            for i in xrange(len(self.vec)):
5921049Sbinkertn@umich.edu                self.vec[i] /= other
5931049Sbinkertn@umich.edu            self.over /= other
5941049Sbinkertn@umich.edu        return self
5951049Sbinkertn@umich.edu
5961049Sbinkertn@umich.educlass Dist(Statistic):
5971049Sbinkertn@umich.edu    def getValue(self):
5981049Sbinkertn@umich.edu        return 0.0
5991049Sbinkertn@umich.edu
6001049Sbinkertn@umich.edu    def display(self):
6011049Sbinkertn@umich.edu        import display
6021049Sbinkertn@umich.edu        if not display.all and not (self.flags & flags.printable):
6031049Sbinkertn@umich.edu            return
6041049Sbinkertn@umich.edu
6051049Sbinkertn@umich.edu        self.dist.display(self.name, self.desc, self.flags, self.precision)
6061049Sbinkertn@umich.edu
6071049Sbinkertn@umich.edu    def comparable(self, other):
6081049Sbinkertn@umich.edu        return self.name == other.name and \
6091049Sbinkertn@umich.edu               self.dist.compareable(other.dist)
6101049Sbinkertn@umich.edu
6111049Sbinkertn@umich.edu    def __eq__(self, other):
6121049Sbinkertn@umich.edu        return self.dist == other.dist
6131049Sbinkertn@umich.edu
6141049Sbinkertn@umich.edu    def __isub__(self, other):
6151049Sbinkertn@umich.edu        self.dist -= other.dist
6161049Sbinkertn@umich.edu        return self
6171049Sbinkertn@umich.edu
6181049Sbinkertn@umich.edu    def __iadd__(self, other):
6191049Sbinkertn@umich.edu        self.dist += other.dist
6201049Sbinkertn@umich.edu        return self
6211049Sbinkertn@umich.edu
6221049Sbinkertn@umich.edu    def __itruediv__(self, other):
6231049Sbinkertn@umich.edu        if not other:
6241049Sbinkertn@umich.edu            return self
6251049Sbinkertn@umich.edu        self.dist /= other
6261049Sbinkertn@umich.edu        return self
6271049Sbinkertn@umich.edu
6281049Sbinkertn@umich.educlass VectorDist(Statistic):
6291049Sbinkertn@umich.edu    def getValue(self):
6301049Sbinkertn@umich.edu        return 0.0
6311049Sbinkertn@umich.edu
6321049Sbinkertn@umich.edu    def display(self):
6331049Sbinkertn@umich.edu        import display
6341049Sbinkertn@umich.edu        if not display.all and not (self.flags & flags.printable):
6351049Sbinkertn@umich.edu            return
6361049Sbinkertn@umich.edu
6371049Sbinkertn@umich.edu        if isinstance(self.dist, SimpleDist):
6381049Sbinkertn@umich.edu            return
6391049Sbinkertn@umich.edu
6401049Sbinkertn@umich.edu        for dist,sn,sd,i in map(None, self.dist, self.subnames, self.subdescs,
6411049Sbinkertn@umich.edu                                range(len(self.dist))):
6421049Sbinkertn@umich.edu            if len(sn) > 0:
6431049Sbinkertn@umich.edu                name = '%s.%s' % (self.name, sn)
6441049Sbinkertn@umich.edu            else:
6451049Sbinkertn@umich.edu                name = '%s[%d]' % (self.name, i)
6461049Sbinkertn@umich.edu
6471049Sbinkertn@umich.edu            if len(sd) > 0:
6481049Sbinkertn@umich.edu                desc = sd
6491049Sbinkertn@umich.edu            else:
6501049Sbinkertn@umich.edu                desc = self.desc
6511049Sbinkertn@umich.edu
6521049Sbinkertn@umich.edu            dist.display(name, desc, self.flags, self.precision)
6531049Sbinkertn@umich.edu
6541049Sbinkertn@umich.edu        if (self.flags & flags.total) or 1:
6551049Sbinkertn@umich.edu            if isinstance(self.dist[0], SimpleDist):
6561049Sbinkertn@umich.edu                disttotal = SimpleDist( \
6571049Sbinkertn@umich.edu                    reduce(sums, [d.sums for d in self.dist]),
6581049Sbinkertn@umich.edu                    reduce(sums, [d.squares for d in self.dist]),
6591049Sbinkertn@umich.edu                    reduce(sums, [d.samples for d in self.dist]))
6601049Sbinkertn@umich.edu            else:
6611049Sbinkertn@umich.edu                disttotal = FullDist( \
6621049Sbinkertn@umich.edu                    reduce(sums, [d.sums for d in self.dist]),
6631049Sbinkertn@umich.edu                    reduce(sums, [d.squares for d in self.dist]),
6641049Sbinkertn@umich.edu                    reduce(sums, [d.samples for d in self.dist]),
6651049Sbinkertn@umich.edu                    min([d.minval for d in self.dist]),
6661049Sbinkertn@umich.edu                    max([d.maxval for d in self.dist]),
6671049Sbinkertn@umich.edu                    reduce(sums, [d.under for d in self.dist]),
6681049Sbinkertn@umich.edu                    reduce(sums, [d.vec for d in self.dist]),
6691049Sbinkertn@umich.edu                    reduce(sums, [d.over for d in self.dist]),
6701049Sbinkertn@umich.edu                    dist[0].min,
6711049Sbinkertn@umich.edu                    dist[0].max,
6721049Sbinkertn@umich.edu                    dist[0].bsize,
6731049Sbinkertn@umich.edu                    dist[0].size)
6741049Sbinkertn@umich.edu
6751049Sbinkertn@umich.edu            name = '%s.total' % (self.name)
6761049Sbinkertn@umich.edu            desc = self.desc
6771049Sbinkertn@umich.edu            disttotal.display(name, desc, self.flags, self.precision)
6781049Sbinkertn@umich.edu
6791049Sbinkertn@umich.edu    def comparable(self, other):
6801049Sbinkertn@umich.edu        return self.name == other.name and \
6811049Sbinkertn@umich.edu               alltrue(map(lambda x, y : x.comparable(y),
6821049Sbinkertn@umich.edu                           self.dist,
6831049Sbinkertn@umich.edu                           other.dist))
6841049Sbinkertn@umich.edu
6851049Sbinkertn@umich.edu    def __eq__(self, other):
6861049Sbinkertn@umich.edu        return alltrue(map(lambda x, y : x == y, self.dist, other.dist))
6871049Sbinkertn@umich.edu
6881049Sbinkertn@umich.edu    def __isub__(self, other):
6891547Sbinkertn@umich.edu        if isinstance(self.dist, (list, tuple)) and \
6901547Sbinkertn@umich.edu               isinstance(other.dist, (list, tuple)):
6911049Sbinkertn@umich.edu            for sd,od in zip(self.dist, other.dist):
6921049Sbinkertn@umich.edu                sd -= od
6931049Sbinkertn@umich.edu        else:
6941049Sbinkertn@umich.edu            self.dist -= other.dist
6951049Sbinkertn@umich.edu        return self
6961049Sbinkertn@umich.edu
6971049Sbinkertn@umich.edu    def __iadd__(self, other):
6981547Sbinkertn@umich.edu        if isinstance(self.dist, (list, tuple)) and \
6991547Sbinkertn@umich.edu               isinstance(other.dist, (list, tuple)):
7001049Sbinkertn@umich.edu            for sd,od in zip(self.dist, other.dist):
7011049Sbinkertn@umich.edu                sd += od
7021049Sbinkertn@umich.edu        else:
7031049Sbinkertn@umich.edu            self.dist += other.dist
7041049Sbinkertn@umich.edu        return self
7051049Sbinkertn@umich.edu
7061049Sbinkertn@umich.edu    def __itruediv__(self, other):
7071049Sbinkertn@umich.edu        if not other:
7081049Sbinkertn@umich.edu            return self
7091547Sbinkertn@umich.edu        if isinstance(self.dist, (list, tuple)):
7101049Sbinkertn@umich.edu            for dist in self.dist:
7111049Sbinkertn@umich.edu                dist /= other
7121049Sbinkertn@umich.edu        else:
7131049Sbinkertn@umich.edu            self.dist /= other
7141049Sbinkertn@umich.edu        return self
7151049Sbinkertn@umich.edu
7161049Sbinkertn@umich.educlass Vector2d(Statistic):
7171049Sbinkertn@umich.edu    def getValue(self):
7181049Sbinkertn@umich.edu        return 0.0
7191049Sbinkertn@umich.edu
7201049Sbinkertn@umich.edu    def display(self):
7211049Sbinkertn@umich.edu        import display
7221049Sbinkertn@umich.edu        if not display.all and not (self.flags & flags.printable):
7231049Sbinkertn@umich.edu            return
7241049Sbinkertn@umich.edu
7251049Sbinkertn@umich.edu        d = display.VectorDisplay()
7261049Sbinkertn@umich.edu        d.__dict__.update(self.__dict__)
7271049Sbinkertn@umich.edu
7281049Sbinkertn@umich.edu        if self.__dict__.has_key('ysubnames'):
7291049Sbinkertn@umich.edu            ysubnames = list(self.ysubnames)
7301049Sbinkertn@umich.edu            slack = self.x - len(ysubnames)
7311049Sbinkertn@umich.edu            if slack > 0:
7321049Sbinkertn@umich.edu                ysubnames.extend(['']*slack)
7331049Sbinkertn@umich.edu        else:
7341049Sbinkertn@umich.edu            ysubnames = range(self.x)
7351049Sbinkertn@umich.edu
7361049Sbinkertn@umich.edu        for x,sname in enumerate(ysubnames):
7371049Sbinkertn@umich.edu            o = x * self.y
7381049Sbinkertn@umich.edu            d.value = self.value[o:o+self.y]
7391049Sbinkertn@umich.edu            d.name = '%s[%s]' % (self.name, sname)
7401049Sbinkertn@umich.edu            d.display()
7411049Sbinkertn@umich.edu
7421049Sbinkertn@umich.edu        if self.flags & flags.total:
7431049Sbinkertn@umich.edu            d.value = []
7441049Sbinkertn@umich.edu            for y in range(self.y):
7451049Sbinkertn@umich.edu                xtot = 0.0
7461049Sbinkertn@umich.edu                for x in range(self.x):
7471049Sbinkertn@umich.edu                    xtot += self.value[y + x * self.x]
7481049Sbinkertn@umich.edu                d.value.append(xtot)
7491049Sbinkertn@umich.edu
7501049Sbinkertn@umich.edu            d.name = self.name + '.total'
7511049Sbinkertn@umich.edu            d.display()
7521049Sbinkertn@umich.edu
7531049Sbinkertn@umich.edu    def comparable(self, other):
7541049Sbinkertn@umich.edu        return self.name == other.name and self.x == other.x and \
7551049Sbinkertn@umich.edu               self.y == other.y
7561049Sbinkertn@umich.edu
7571049Sbinkertn@umich.edu    def __eq__(self, other):
7581049Sbinkertn@umich.edu        return True
7591049Sbinkertn@umich.edu
7601049Sbinkertn@umich.edu    def __isub__(self, other):
7611049Sbinkertn@umich.edu        return self
7621049Sbinkertn@umich.edu
7631049Sbinkertn@umich.edu    def __iadd__(self, other):
7641049Sbinkertn@umich.edu        return self
7651049Sbinkertn@umich.edu
7661049Sbinkertn@umich.edu    def __itruediv__(self, other):
7671049Sbinkertn@umich.edu        if not other:
7681049Sbinkertn@umich.edu            return self
7691049Sbinkertn@umich.edu        return self
7701049Sbinkertn@umich.edu
7711049Sbinkertn@umich.edudef NewStat(data):
7721049Sbinkertn@umich.edu    stat = None
7731049Sbinkertn@umich.edu    if data.type == 'SCALAR':
7741049Sbinkertn@umich.edu        stat = Scalar(data)
7751049Sbinkertn@umich.edu    elif data.type == 'VECTOR':
7761049Sbinkertn@umich.edu        stat = Vector(data)
7771049Sbinkertn@umich.edu    elif data.type == 'DIST':
7781049Sbinkertn@umich.edu        stat = Dist(data)
7791049Sbinkertn@umich.edu    elif data.type == 'VECTORDIST':
7801049Sbinkertn@umich.edu        stat = VectorDist(data)
7811049Sbinkertn@umich.edu    elif data.type == 'VECTOR2D':
7821049Sbinkertn@umich.edu        stat = Vector2d(data)
7831049Sbinkertn@umich.edu    elif data.type == 'FORMULA':
7841049Sbinkertn@umich.edu        stat = Formula(data)
7851049Sbinkertn@umich.edu
7861049Sbinkertn@umich.edu    return stat
7871049Sbinkertn@umich.edu
788