-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserror.py
151 lines (130 loc) · 4.16 KB
/
serror.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
from sfunctions import quad
################################################################################
class Error(object):
def __init__(self, val, err):
self.val = float(val)
self.err = float(err)
def frac(self):
return self.err / self.val
def __add__(self, val):
if isinstance(val, Error):
self.val += val.val
self.err = quad(self.err, val.err)
else:
self.val += val
return self
def __sub__(self, val):
if isinstance(val, Error):
self.val -= val.val
self.err = quad(self.err, val.err)
else:
self.val -= val
return self
def __mul__(self, val):
if isinstance(val, Error):
self.err = quad(self.frac(), val.frac())
self.val *= val.val
self.err *= self.val
else:
self.val *= val
self.err *= val
return self
def __div__(self, val):
if isinstance(val, Error):
self.err = quad(self.frac(), val.frac())
self.val /= val.val
self.err *= self.val
else:
self.val /= val
self.err /= val
return self
def __pow__(self, val):
self.err = self.frac() * abs(val)
self.val = self.val**val
self.err *= self.val
return self
class SError(object):
def __init__(self, centre, err1, err2=None):
self.upper = Error(centre, err1)
self.lower = Error(centre, err2 if err2 is not None else err1)
self.sf = ':.2f'
self.pow = 0
############################################################################
@property
def sigfig(self):
return self.sf
@sigfig.setter
def sigfig(self, sf):
if isinstance(sf, str):
self.sf = sf
if not self.sf.startswith(':'):
self.sf = ':' + self.sf
else:
self.sf = ':.{0}f'.format(sf)
return
@property
def power(self):
return self.pow
@power.setter
def power(self, val):
self.pow = int(val)
self.upper *= 10**self.pow
self.lower *= 10**self.pow
return
############################################################################
def __add__(self, var):
if isinstance(var, SError):
self.upper += var.upper
self.lower += var.lower
else:
self.upper += var
self.lower += var
return self
def __sub__(self, var):
if isinstance(var, SError):
self.upper -= var.upper
self.lower -= var.lower
else:
self.upper -= var
self.lower -= var
return self
def __mul__(self, var):
if isinstance(var, SError):
self.upper *= var.upper
self.lower *= var.lower
else:
self.upper *= var
self.lower *= var
return self
def __div__(self, var):
if isinstance(var, SError):
self.upper /= var.upper
self.lower /= var.lower
else:
self.upper /= var
self.lower /= var
return self
def __pow__(self, var):
self.upper * self.upper ** var
self.lower * self.lower ** var
return self
def __str__(self):
"""Note that {{ and }} are converted to { and } by format()"""
st_cen = ('{0' + self.sf + '}').format(self.upper.val)
st_upper = ('{0' + self.sf + '}').format(self.upper.err)
st_lower = ('{0' + self.sf + '}').format(self.lower.err)
if self.upper.err == self.lower.err:
st = st_cen + ' \pm ' + st_upper
else:
st = st_cen + ' \,^{+' + st_upper + '}_{-' + st_lower + '}'
if self.pow != 0:
st = '({0}) \e{{{1}}}'.format(st, self.pow)
return st
def __radd__(self, other):
return self.__add__(other)
def __repr__(self):
return self.__str__()
############################################################################
################################################################################
if __name__ == "__main__":
"""TEST"""