metrolopy 0.6.5__py3-none-any.whl → 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- metrolopy/__init__.py +5 -4
- metrolopy/budget.py +61 -50
- metrolopy/builtin_constants.py +903 -0
- metrolopy/constant.py +108 -104
- metrolopy/constcom.py +84 -83
- metrolopy/distributions.py +120 -39
- metrolopy/exceptions.py +7 -9
- metrolopy/fit.py +3 -3
- metrolopy/functions.py +4 -4
- metrolopy/gummy.py +554 -514
- metrolopy/indexed.py +69 -20
- metrolopy/logunit.py +1 -1
- metrolopy/mean.py +8 -9
- metrolopy/miscunits.py +21 -6
- metrolopy/nummy.py +208 -158
- metrolopy/offsetunit.py +2 -3
- metrolopy/prefixedunit.py +24 -23
- metrolopy/relunits.py +1 -2
- metrolopy/siunits.py +7 -5
- metrolopy/tests/__init__.py +6 -6
- metrolopy/tests/test_create.py +7 -6
- metrolopy/tests/test_gummy.py +5 -43
- metrolopy/tests/test_misc.py +1 -0
- metrolopy/tests/test_operations.py +3 -2
- metrolopy/tests/test_ubreakdown.py +3 -2
- metrolopy/ummy.py +889 -897
- metrolopy/unit.py +287 -182
- metrolopy/unitparser.py +40 -42
- metrolopy/unitutils.py +183 -159
- metrolopy/usunits.py +14 -13
- metrolopy/version.py +1 -1
- {metrolopy-0.6.5.dist-info → metrolopy-1.0.0.dist-info}/METADATA +20 -2
- metrolopy-1.0.0.dist-info/RECORD +45 -0
- metrolopy-0.6.5.dist-info/RECORD +0 -44
- {metrolopy-0.6.5.dist-info → metrolopy-1.0.0.dist-info}/WHEEL +0 -0
- {metrolopy-0.6.5.dist-info → metrolopy-1.0.0.dist-info}/licenses/LICENSE +0 -0
- {metrolopy-0.6.5.dist-info → metrolopy-1.0.0.dist-info}/top_level.txt +0 -0
- {metrolopy-0.6.5.dist-info → metrolopy-1.0.0.dist-info}/zip-safe +0 -0
metrolopy/nummy.py
CHANGED
|
@@ -27,11 +27,12 @@ class is not intended to be used directly; rather it is utilized by the gummy
|
|
|
27
27
|
class.
|
|
28
28
|
"""
|
|
29
29
|
import numpy as np
|
|
30
|
-
from .ummy import ummy
|
|
30
|
+
from .ummy import ummy,_udict,_isscalar
|
|
31
31
|
from .distributions import (Distribution,TDist,NormalDist,MultivariateElement,
|
|
32
|
-
MultivariateDistribution,
|
|
32
|
+
MultivariateDistribution,Convolution)
|
|
33
33
|
from .exceptions import NoSimulatedDataError
|
|
34
|
-
from math import isinf,
|
|
34
|
+
from math import isinf,isnan,sqrt
|
|
35
|
+
from html import escape
|
|
35
36
|
|
|
36
37
|
def _bop(f,npf,s,b):
|
|
37
38
|
if isinstance(b,nummy):
|
|
@@ -50,6 +51,59 @@ def _uop(f,npf,s):
|
|
|
50
51
|
f._dist = Distribution.apply(npf,s._dist)
|
|
51
52
|
return f
|
|
52
53
|
|
|
54
|
+
def _getnrefs(x,fr):
|
|
55
|
+
if isinstance(x,ummy):
|
|
56
|
+
x = [x]
|
|
57
|
+
ret = set()
|
|
58
|
+
for i in x:
|
|
59
|
+
for r in x._getrefs(fr):
|
|
60
|
+
if r.dist is not None:
|
|
61
|
+
ret.add(r.dist)
|
|
62
|
+
return ret
|
|
63
|
+
|
|
64
|
+
def get_name(name,fmt,norm):
|
|
65
|
+
fmt = fmt.strip().lower()
|
|
66
|
+
if fmt not in {'unicode','html','latex','ascii'}:
|
|
67
|
+
raise ValueError('fmt "' + str(fmt) + '" is not recognized')
|
|
68
|
+
|
|
69
|
+
if name is None:
|
|
70
|
+
return None
|
|
71
|
+
|
|
72
|
+
if isinstance(name,str):
|
|
73
|
+
name = name.strip()
|
|
74
|
+
if fmt == 'html':
|
|
75
|
+
name = escape(name)
|
|
76
|
+
if len(name) == 1:
|
|
77
|
+
name = '<i>' + name + '</i>'
|
|
78
|
+
elif fmt == 'latex':
|
|
79
|
+
sc = {
|
|
80
|
+
'&': r'\&',
|
|
81
|
+
'%': r'\%',
|
|
82
|
+
'$': r'\$',
|
|
83
|
+
'#': r'\#',
|
|
84
|
+
'_': r'\_',
|
|
85
|
+
'{': r'\{',
|
|
86
|
+
'}': r'\}',
|
|
87
|
+
'~': r'\_',
|
|
88
|
+
'^': r'\_',
|
|
89
|
+
'\\': r'\_'
|
|
90
|
+
}
|
|
91
|
+
name = ''.join(sc[c] if c in sc else c for c in name)
|
|
92
|
+
if len(name) > 1:
|
|
93
|
+
name = norm(name)
|
|
94
|
+
elif fmt == 'ascii':
|
|
95
|
+
name = ''.join(i if ord(i) < 128 else '_' for i in name)
|
|
96
|
+
return name
|
|
97
|
+
|
|
98
|
+
if fmt == 'unicode':
|
|
99
|
+
return name[0]
|
|
100
|
+
if fmt == 'html':
|
|
101
|
+
return name[1]
|
|
102
|
+
if fmt == 'latex':
|
|
103
|
+
return name[2]
|
|
104
|
+
if fmt == 'ascii':
|
|
105
|
+
return name[3]
|
|
106
|
+
|
|
53
107
|
|
|
54
108
|
class nummy(ummy):
|
|
55
109
|
# This class is not intended to be used directly and was created to contain
|
|
@@ -75,37 +129,42 @@ class nummy(ummy):
|
|
|
75
129
|
if isinstance(x,MultivariateElement):
|
|
76
130
|
raise TypeError('a MultivariateElement may not be used in a gummy initializer\nuse the create static method with a MultivariateDistribution')
|
|
77
131
|
|
|
132
|
+
if utype is None:
|
|
133
|
+
utype = x.utype
|
|
134
|
+
else:
|
|
135
|
+
x.utype = utype
|
|
78
136
|
self._dist = x
|
|
79
137
|
|
|
80
138
|
if hasattr(x,'dof'):
|
|
139
|
+
ndof = x.dof
|
|
81
140
|
if nummy._bayesian:
|
|
82
141
|
u = float(x.u())*np.sqrt(x.dof/(x.dof-2))
|
|
83
|
-
dof = float('inf')
|
|
84
142
|
else:
|
|
85
143
|
u = float(x.u())
|
|
86
|
-
dof = x.dof
|
|
87
144
|
else:
|
|
88
|
-
|
|
145
|
+
ndof = float('inf')
|
|
89
146
|
u = float(x.u())
|
|
90
147
|
|
|
91
|
-
super().__init__(x.x(),u=u,dof=
|
|
148
|
+
super().__init__(x.x(),u=u,dof=ndof,utype=utype)
|
|
92
149
|
|
|
93
150
|
else:
|
|
94
151
|
super().__init__(x,u=u,dof=dof,utype=utype)
|
|
95
152
|
x = float(x)
|
|
96
|
-
u = float(self.
|
|
97
|
-
if
|
|
153
|
+
u = float(self.u)
|
|
154
|
+
if u == 0 or isnan(x) or isinf(x) or isnan(u) or isinf(u):
|
|
98
155
|
self._dist = x
|
|
99
156
|
return
|
|
100
|
-
dof
|
|
101
|
-
|
|
102
|
-
self._dist = NormalDist(x,u)
|
|
157
|
+
if isinstance(dof,_udict):
|
|
158
|
+
self._dist = None
|
|
103
159
|
else:
|
|
104
|
-
if
|
|
105
|
-
self._dist =
|
|
106
|
-
self._dof = float('inf')
|
|
160
|
+
if dof is None or dof > self.max_dof:
|
|
161
|
+
self._dist = NormalDist(x,u)
|
|
107
162
|
else:
|
|
108
|
-
|
|
163
|
+
if nummy._bayesian:
|
|
164
|
+
self._dist = TDist(x,u*np.sqrt((dof-2)/dof),dof)
|
|
165
|
+
else:
|
|
166
|
+
self._dist = TDist(x,u,dof)
|
|
167
|
+
self._dist.utype = utype
|
|
109
168
|
|
|
110
169
|
@property
|
|
111
170
|
def distribution(self):
|
|
@@ -116,31 +175,6 @@ class nummy(ummy):
|
|
|
116
175
|
"""
|
|
117
176
|
return self._dist
|
|
118
177
|
|
|
119
|
-
@property
|
|
120
|
-
def dof(self):
|
|
121
|
-
"""
|
|
122
|
-
float, read-only
|
|
123
|
-
|
|
124
|
-
Returns the number or degrees of freedom that the uncertainty of the
|
|
125
|
-
gummy is based on. If `gummy.bayesian` is set to `False`, then the Welch-
|
|
126
|
-
Satterthwaite approximation is used to calculate the effective number
|
|
127
|
-
of degrees of freedom for gummys that result from an operation between
|
|
128
|
-
two or more other gummys. A version of the Welch-Satterthwaite
|
|
129
|
-
approximation that takes into account correlations is used here, see
|
|
130
|
-
[R. Willink, Metrologia, 44, 340 (2007)]. If `gummy.bayesian` is `True`
|
|
131
|
-
then gummys that are the result from an opertaion between other gummys
|
|
132
|
-
will always have dof = float('inf').
|
|
133
|
-
"""
|
|
134
|
-
if isinf(self._dof) and hasattr(self._dist,'dof'):
|
|
135
|
-
dof = self._dist.dof
|
|
136
|
-
else:
|
|
137
|
-
dof = self._dof
|
|
138
|
-
if dof < 1:
|
|
139
|
-
# Occasionally correlations can result in a dof less than 1;
|
|
140
|
-
# see the ummy._get_dof method.
|
|
141
|
-
return 1
|
|
142
|
-
return dof
|
|
143
|
-
|
|
144
178
|
@property
|
|
145
179
|
def name(self):
|
|
146
180
|
if self._name is None:
|
|
@@ -170,31 +204,9 @@ class nummy(ummy):
|
|
|
170
204
|
raise ValueError('the name must be a string or a length 4 tuple of str')
|
|
171
205
|
|
|
172
206
|
def get_name(self,fmt='unicode',norm=None):
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
if self._name is None:
|
|
178
|
-
return None
|
|
179
|
-
|
|
180
|
-
if isinstance(self._name,str):
|
|
181
|
-
name = str(self._name).strip()
|
|
182
|
-
if fmt == 'html' and len(name) == 1:
|
|
183
|
-
return '<i>' + name + '</i>'
|
|
184
|
-
if fmt == 'latex' and len(name) > 1:
|
|
185
|
-
if norm is None:
|
|
186
|
-
norm = type(self).latex_norm
|
|
187
|
-
return norm(self.name)
|
|
188
|
-
return self._name
|
|
189
|
-
|
|
190
|
-
if fmt == 'unicode':
|
|
191
|
-
return self._name[0]
|
|
192
|
-
if fmt == 'html':
|
|
193
|
-
return self._name[1]
|
|
194
|
-
if fmt == 'latex':
|
|
195
|
-
return self._name[2]
|
|
196
|
-
if fmt == 'ascii':
|
|
197
|
-
return self._name[3]
|
|
207
|
+
if norm is None:
|
|
208
|
+
norm = type(self).latex_norm
|
|
209
|
+
return get_name(self._name,fmt,norm)
|
|
198
210
|
|
|
199
211
|
@property
|
|
200
212
|
def bayesian(self):
|
|
@@ -240,12 +252,21 @@ class nummy(ummy):
|
|
|
240
252
|
@staticmethod
|
|
241
253
|
def simulate(nummys,n=100000,ufrom=None):
|
|
242
254
|
if ufrom is not None:
|
|
243
|
-
|
|
255
|
+
if isinstance(ufrom,(nummy,str,Distribution)):
|
|
256
|
+
ufrom = [ufrom]
|
|
257
|
+
ufrom = [g.distribution if isinstance(g,nummy) else g for g in ufrom]
|
|
244
258
|
if isinstance(nummys,nummy):
|
|
245
259
|
nummys = [nummys]
|
|
246
|
-
Distribution.simulate([g.distribution for g in nummys],n,ufrom)
|
|
260
|
+
Distribution.simulate([g.distribution for g in nummys if isinstance(g,nummy)],n=n,ufrom=ufrom)
|
|
247
261
|
nummy._nsim = n
|
|
248
262
|
|
|
263
|
+
def sim(self,n=100000,ufrom=None):
|
|
264
|
+
return nummy.simulate([self],n=n,ufrom=ufrom)
|
|
265
|
+
|
|
266
|
+
def clear(self):
|
|
267
|
+
if isinstance(self._dist,Distribution):
|
|
268
|
+
self._dist.clear()
|
|
269
|
+
|
|
249
270
|
@property
|
|
250
271
|
def simdata(self):
|
|
251
272
|
"""
|
|
@@ -320,7 +341,7 @@ class nummy(ummy):
|
|
|
320
341
|
return 0.5*(self.Usim[0] + self.Usim[1])/self.usim
|
|
321
342
|
|
|
322
343
|
@property
|
|
323
|
-
def
|
|
344
|
+
def isindependent(self):
|
|
324
345
|
"""
|
|
325
346
|
`bool`, read-only
|
|
326
347
|
|
|
@@ -384,7 +405,7 @@ class nummy(ummy):
|
|
|
384
405
|
"""
|
|
385
406
|
returns an ummy representaion of the nummy
|
|
386
407
|
"""
|
|
387
|
-
r = ummy(self.x,u=self.u
|
|
408
|
+
r = ummy(self.x,u=self.u)
|
|
388
409
|
r._ref = self._ref
|
|
389
410
|
r._refs = self._refs
|
|
390
411
|
return r
|
|
@@ -397,9 +418,9 @@ class nummy(ummy):
|
|
|
397
418
|
|
|
398
419
|
|
|
399
420
|
@staticmethod
|
|
400
|
-
def _copy(s,r,formatting=True,
|
|
421
|
+
def _copy(s,r,formatting=True,totype=None):
|
|
401
422
|
# copies attributes of s to r, called from ummy.copy()
|
|
402
|
-
super(nummy,nummy)._copy(s,r,formatting=formatting,
|
|
423
|
+
super(nummy,nummy)._copy(s,r,formatting=formatting,totype=totype)
|
|
403
424
|
if isinstance(s,nummy):
|
|
404
425
|
r._dist = s._dist
|
|
405
426
|
if formatting:
|
|
@@ -409,18 +430,18 @@ class nummy(ummy):
|
|
|
409
430
|
r.name = None
|
|
410
431
|
else:
|
|
411
432
|
r.name = None
|
|
412
|
-
if s.
|
|
413
|
-
r._dist = r.
|
|
433
|
+
if s.u == 0:
|
|
434
|
+
r._dist = r.x
|
|
414
435
|
return
|
|
415
|
-
dof = s.
|
|
436
|
+
dof = s.dof
|
|
416
437
|
if isinf(dof):
|
|
417
|
-
r._dist = NormalDist(s.
|
|
438
|
+
r._dist = NormalDist(s.x,s.u)
|
|
418
439
|
else:
|
|
419
440
|
if r._bayesian:
|
|
420
|
-
r._dist = TDist(s.
|
|
421
|
-
r.
|
|
441
|
+
r._dist = TDist(s.x,s.u*np.sqrt((dof-2)/dof),dof)
|
|
442
|
+
r.dof = float('inf')
|
|
422
443
|
else:
|
|
423
|
-
r._dist = TDist(s.
|
|
444
|
+
r._dist = TDist(s.x,s.u,dof)
|
|
424
445
|
|
|
425
446
|
@classmethod
|
|
426
447
|
def _apply(cls,function,derivative,*args,fxdx=None):
|
|
@@ -452,34 +473,11 @@ class nummy(ummy):
|
|
|
452
473
|
r._dist = Distribution.apply(function,*a)
|
|
453
474
|
return r
|
|
454
475
|
|
|
455
|
-
@staticmethod
|
|
456
|
-
def _set_correlation_matrix(gummys, matrix):
|
|
457
|
-
super(nummy,nummy)._set_correlation_matrix(gummys,matrix)
|
|
458
|
-
cov = nummy.covariance_matrix(gummys)
|
|
459
|
-
mean = [g.x for g in gummys]
|
|
460
|
-
if isfinite(gummys[0].dof) and all([g.dof==gummys[0].dof for g in gummys]):
|
|
461
|
-
mvdist = MultiTDist(mean,cov,gummys[0].dof)
|
|
462
|
-
else:
|
|
463
|
-
mvdist = MultiNormalDist(mean,cov)
|
|
464
|
-
for i,g in enumerate(gummys):
|
|
465
|
-
g._dist = mvdist[i]
|
|
466
|
-
|
|
467
|
-
@staticmethod
|
|
468
|
-
def _set_covariance_matrix(gummys, matrix):
|
|
469
|
-
super(nummy,nummy)._set_covariance_matrix(gummys,matrix)
|
|
470
|
-
mean = [g.x for g in gummys]
|
|
471
|
-
if isfinite(gummys[0].dof) and all([g.dof==gummys[0].dof for g in gummys]):
|
|
472
|
-
mvdist = MultiTDist(mean,matrix,gummys[0].dof)
|
|
473
|
-
else:
|
|
474
|
-
mvdist = MultiNormalDist(mean,matrix)
|
|
475
|
-
for i,g in enumerate(gummys):
|
|
476
|
-
g._dist = mvdist[i]
|
|
477
|
-
|
|
478
476
|
@classmethod
|
|
479
|
-
def create(cls,x,u=0,dof=float('inf'),name=None,
|
|
480
|
-
covariance_matrix=None):
|
|
481
|
-
if name
|
|
482
|
-
name = [
|
|
477
|
+
def create(cls,x,u=0,dof=float('inf'),name=None,utype=None,
|
|
478
|
+
correlation_matrix=None,covariance_matrix=None):
|
|
479
|
+
if _isscalar(name):
|
|
480
|
+
name = [name]*len(x)
|
|
483
481
|
|
|
484
482
|
if isinstance(x,MultivariateDistribution):
|
|
485
483
|
|
|
@@ -497,9 +495,10 @@ class nummy(ummy):
|
|
|
497
495
|
else:
|
|
498
496
|
dof = x.dof
|
|
499
497
|
else:
|
|
500
|
-
dof =
|
|
498
|
+
dof = float('inf')
|
|
501
499
|
|
|
502
|
-
ret = super(nummy,cls).create(x.x(),u=u,dof=dof,
|
|
500
|
+
ret = super(nummy,cls).create(x.x(),u=u,dof=dof,utype=utype,
|
|
501
|
+
covariance_matrix=x.cov)
|
|
503
502
|
|
|
504
503
|
for i,r in enumerate(ret):
|
|
505
504
|
r._dist = x[i]
|
|
@@ -513,6 +512,11 @@ class nummy(ummy):
|
|
|
513
512
|
|
|
514
513
|
if dof is None:
|
|
515
514
|
dof = [float('inf')]*len(x)
|
|
515
|
+
elif _isscalar(dof):
|
|
516
|
+
dof = [dof]*len(x)
|
|
517
|
+
else:
|
|
518
|
+
dof = [float('inf') if i is None else i for i in dof]
|
|
519
|
+
|
|
516
520
|
if u is None:
|
|
517
521
|
u = [0]*len(x)
|
|
518
522
|
d = [None]*len(x)
|
|
@@ -527,7 +531,9 @@ class nummy(ummy):
|
|
|
527
531
|
u[i] = u[i]*np.sqrt(v.dof/(v.dof-2))
|
|
528
532
|
dof[i] = float('inf')
|
|
529
533
|
|
|
530
|
-
ret = super(nummy,cls).create(x,u,dof,
|
|
534
|
+
ret = super(nummy,cls).create(x,u=u,dof=dof,utype=utype,
|
|
535
|
+
correlation_matrix=correlation_matrix,
|
|
536
|
+
covariance_matrix=covariance_matrix)
|
|
531
537
|
for i,r in enumerate(ret):
|
|
532
538
|
r.name = name[i]
|
|
533
539
|
if d[i] is None:
|
|
@@ -538,7 +544,6 @@ class nummy(ummy):
|
|
|
538
544
|
else:
|
|
539
545
|
if nummy._bayesian:
|
|
540
546
|
r._dist = TDist(x,u[i]*np.sqrt((dof[i]-2)/dof[i]),dof[i])
|
|
541
|
-
r._dof = float('inf')
|
|
542
547
|
else:
|
|
543
548
|
r._dist = TDist(x,u[i],dof[i])
|
|
544
549
|
else:
|
|
@@ -546,12 +551,10 @@ class nummy(ummy):
|
|
|
546
551
|
|
|
547
552
|
return ret
|
|
548
553
|
|
|
549
|
-
def hist(self
|
|
550
|
-
if
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
xlabel = '$ ' + xlabel + ' $'
|
|
554
|
-
self.distribution.hist(xlabel=xlabel,title=title,hold=hold,**kwds)
|
|
554
|
+
def hist(self,**kwds):
|
|
555
|
+
if not isinstance(self._dist,Distribution):
|
|
556
|
+
raise TypeError('hist may not be called from a constant nummy')
|
|
557
|
+
self.distribution.hist(**kwds)
|
|
555
558
|
|
|
556
559
|
def covariance_sim(self,g):
|
|
557
560
|
"""
|
|
@@ -561,8 +564,6 @@ class nummy(ummy):
|
|
|
561
564
|
See the method `gummy.covariance(g)` for the corresponding result based
|
|
562
565
|
on first order error propagation.
|
|
563
566
|
"""
|
|
564
|
-
#if self._u == 0 or g._u == 0:
|
|
565
|
-
#return 0
|
|
566
567
|
return self._dist.covsim(g._dist)
|
|
567
568
|
|
|
568
569
|
def correlation_sim(self,g):
|
|
@@ -573,8 +574,6 @@ class nummy(ummy):
|
|
|
573
574
|
See the method `gummy.correlation(g)` for the corresponding result based
|
|
574
575
|
on first order error propagation.
|
|
575
576
|
"""
|
|
576
|
-
#if self._u == 0 or g._u == 0:
|
|
577
|
-
#return 0
|
|
578
577
|
return self.covariance_sim(g)/(self.usim*g.usim)
|
|
579
578
|
|
|
580
579
|
@staticmethod
|
|
@@ -607,59 +606,110 @@ class nummy(ummy):
|
|
|
607
606
|
@staticmethod
|
|
608
607
|
def covplot(x,y,title=None,xlabel=None,ylabel=None,hold=False,**kwds):
|
|
609
608
|
if xlabel is None and x.name is not None:
|
|
610
|
-
xlabel =
|
|
611
|
-
if len(xlabel) == 1:
|
|
612
|
-
xlabel = '$ ' + xlabel + ' $'
|
|
609
|
+
xlabel = x.get_name(fmt='latex')
|
|
613
610
|
if ylabel is None and y.name is not None:
|
|
614
|
-
ylabel =
|
|
615
|
-
if len(ylabel) == 1:
|
|
616
|
-
ylabel = '$ ' + ylabel + ' $'
|
|
611
|
+
ylabel = y.get_name(fmt='latex')
|
|
617
612
|
|
|
618
613
|
Distribution.covplot(x.distribution,y.distribution,xlabel=xlabel,ylabel=ylabel,
|
|
619
614
|
title=title,hold=hold,**kwds)
|
|
620
615
|
|
|
621
|
-
def ufrom(self,x,sim=False):
|
|
622
|
-
"""
|
|
623
|
-
Gets the standard uncertainty contributed from particular gummys
|
|
624
|
-
or utypes if all other free variables are held fixed.
|
|
616
|
+
#def ufrom(self,x,sim=False):
|
|
625
617
|
|
|
618
|
+
#if not sim:
|
|
619
|
+
#return super().ufrom(x)
|
|
620
|
+
|
|
621
|
+
#v = nummy.correlation_matrix_sim(x)
|
|
622
|
+
|
|
623
|
+
#b = [self.correlation(z) for z in x]
|
|
624
|
+
#s = np.linalg.lstsq(v,b,rcond=-1)[0]
|
|
625
|
+
#u = 0
|
|
626
|
+
|
|
627
|
+
#d = [i*self.usim/j.usim for i,j in zip(s,x)]
|
|
628
|
+
#for i in range(len(x)):
|
|
629
|
+
#for j in range(len(x)):
|
|
630
|
+
# u += d[i]*d[j]*x[i].correlation(x[j])*x[i].usim*x[j].usim
|
|
631
|
+
|
|
632
|
+
#return sqrt(u)
|
|
633
|
+
|
|
634
|
+
def ufromsim(self,x):
|
|
635
|
+
"""
|
|
636
|
+
Gets the standard deviation of the Monte-Carlo data only allowing the
|
|
637
|
+
independent variables in `x` to vary. Independent istributions not in
|
|
638
|
+
`x` are held fixed. `sim` or `simulate` must be called to generate
|
|
639
|
+
Monte-Carlo data before calling this method.
|
|
640
|
+
|
|
626
641
|
Parameters
|
|
627
|
-
|
|
628
|
-
x: `
|
|
629
|
-
A
|
|
630
|
-
|
|
631
|
-
|
|
642
|
+
----------
|
|
643
|
+
x: `nummy`, `str`, or array_like
|
|
644
|
+
A nummy, a string referencing a utype or a list containing
|
|
645
|
+
nummys and strings.
|
|
646
|
+
|
|
632
647
|
Returns
|
|
633
648
|
-------
|
|
634
649
|
`float`
|
|
635
|
-
|
|
636
|
-
Example
|
|
637
|
-
-------
|
|
638
|
-
>>> a = gummy(1.2,0.2,utype='A')
|
|
639
|
-
>>> b = gummy(3.2,0.5,utype='A')
|
|
640
|
-
>>> c = gummy(0.9,0.2,utype='B')
|
|
641
|
-
>>> d = a + b + c
|
|
642
|
-
>>> d.ufrom('A')
|
|
643
|
-
0.53851648071345048
|
|
644
650
|
"""
|
|
645
|
-
|
|
646
|
-
|
|
651
|
+
return float(np.std(self.datafrom(x,save=False),ddof=1))
|
|
652
|
+
|
|
653
|
+
def datafrom(self,x,save=True):
|
|
654
|
+
"""
|
|
655
|
+
Recomputes the convolution with only the varaibles in `x` allowed to
|
|
656
|
+
vary. `sim` or `simulate` must be called to generate
|
|
657
|
+
Monte-Carlo data before calling this method. This method cannot be
|
|
658
|
+
called with save == `True` from from a nummy representing an independent
|
|
659
|
+
variable (that is from a nummy not created by by mathematical operations
|
|
660
|
+
between two or more other nummy's).
|
|
647
661
|
|
|
648
|
-
|
|
662
|
+
Parameters
|
|
663
|
+
----------
|
|
664
|
+
x: list containing `nummy` or `str`
|
|
665
|
+
all independent Distributions not in the list or having a utype
|
|
666
|
+
not in the list are held fixed at their `.x()` value
|
|
649
667
|
|
|
650
|
-
|
|
668
|
+
save: If `save` is `True` the recomputed data is stored in the `simdata`
|
|
669
|
+
attribute and `None` is returned. If `save` is `False` then the
|
|
670
|
+
recomputed data is returned and the `simdata` attribute is not
|
|
671
|
+
overwritten.
|
|
672
|
+
|
|
673
|
+
Returns
|
|
674
|
+
-------
|
|
675
|
+
'numpy.array' if `save` is `False`, otherwise returns `None`
|
|
676
|
+
|
|
677
|
+
Raises
|
|
678
|
+
------
|
|
679
|
+
`NoSimulatedDataError`:
|
|
680
|
+
if no simulated data is available from a call to
|
|
681
|
+
`Distribution.simulate`.
|
|
682
|
+
`RuntimeError`:
|
|
683
|
+
if this method is called from an independent `nummy`
|
|
684
|
+
"""
|
|
685
|
+
if not isinstance(self._dist,Distribution):
|
|
686
|
+
if nummy._nsim is None:
|
|
687
|
+
raise NoSimulatedDataError
|
|
688
|
+
return np.full(nummy._nsim,self._dist)
|
|
689
|
+
|
|
690
|
+
if not isinstance(self.distribution,Convolution) and save == 'True':
|
|
691
|
+
raise RuntimeError('datafrom may not be called from an independent nummy with save == True')
|
|
692
|
+
|
|
693
|
+
if self.distribution.simdata is None:
|
|
694
|
+
raise NoSimulatedDataError('no simulated data')
|
|
651
695
|
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
d = [i*self.usim/j.usim for i,j in zip(s,x)]
|
|
657
|
-
for i in range(len(x)):
|
|
658
|
-
for j in range(len(x)):
|
|
659
|
-
u += d[i]*d[j]*x[i].correlation(x[j])*x[i].usim*x[j].usim
|
|
660
|
-
|
|
661
|
-
return sqrt(u)
|
|
696
|
+
if isinstance(x,(nummy,str,Distribution)):
|
|
697
|
+
x = [x]
|
|
698
|
+
x = [i.distribution if isinstance(i,nummy) else i for i in x]
|
|
662
699
|
|
|
700
|
+
if not isinstance(self.distribution,Convolution):
|
|
701
|
+
if self.distribution in x or self.distribution.utype in x:
|
|
702
|
+
ret = self.distribution.simdata
|
|
703
|
+
else:
|
|
704
|
+
ret = np.full(self.distribution.simdata,self.distribution.x())
|
|
705
|
+
else:
|
|
706
|
+
ret = self.distribution.datafrom(x,save=save)
|
|
707
|
+
|
|
708
|
+
if save:
|
|
709
|
+
self.distribution.simdata = ret
|
|
710
|
+
else:
|
|
711
|
+
return ret
|
|
712
|
+
|
|
663
713
|
def __add__(self,b):
|
|
664
714
|
return _bop(super().__add__(b),np.add,self,b)
|
|
665
715
|
|
metrolopy/offsetunit.py
CHANGED
|
@@ -64,8 +64,6 @@ class _IntervalUnit(Unit):
|
|
|
64
64
|
kwds['parent'] = parent
|
|
65
65
|
Unit.__init__(self,params[0] + ' interval',params[1],conversion=conv,**kwds)
|
|
66
66
|
|
|
67
|
-
def _getme(self,ul,e):
|
|
68
|
-
return self.parent
|
|
69
67
|
|
|
70
68
|
class OffsetUnit(NonlinearUnit):
|
|
71
69
|
"""
|
|
@@ -107,4 +105,5 @@ class OffsetUnit(NonlinearUnit):
|
|
|
107
105
|
return (b - a,self.interval_unit)
|
|
108
106
|
raise IncompatibleUnitsError('a quantity with unit ' + self.tostring() + ' may not be subtracted from a quantity with unit ' + bunit.tostring() + '; automatic conversion is disabled with offset unit instances')
|
|
109
107
|
|
|
110
|
-
|
|
108
|
+
def _getme(self,ul,e):
|
|
109
|
+
return self.interval_unit
|
metrolopy/prefixedunit.py
CHANGED
|
@@ -25,6 +25,7 @@ Classes to automatically generate prefixed units from a base unit.
|
|
|
25
25
|
"""
|
|
26
26
|
|
|
27
27
|
from .unit import Unit,Conversion
|
|
28
|
+
from .ummy import MFraction
|
|
28
29
|
|
|
29
30
|
class PrefixedUnit(Unit):
|
|
30
31
|
"""PrefixedUnit(name,symbol,conversion=None,short_name=None,
|
|
@@ -40,26 +41,26 @@ class PrefixedUnit(Unit):
|
|
|
40
41
|
will be generated.
|
|
41
42
|
"""
|
|
42
43
|
prefix_definitions = {
|
|
43
|
-
'yocto':[1e-24,'y',None,None,None],
|
|
44
|
-
'zepto':[1e-21,'z',None,None,None],
|
|
45
|
-
'atto':[1e-18,'a',None,None,None],
|
|
46
|
-
'femto':[1e-15,'f',None,None,None],
|
|
47
|
-
'pico':[1e-12,'p',None,None,None],
|
|
48
|
-
'nano':[1e-9,'n',None,None,None],
|
|
49
|
-
'micro':[1e-6,'\u03BC','μ',None,'u'],
|
|
50
|
-
'milli':[0.001,'m',None,None,None],
|
|
51
|
-
'centi':[0.01,'c',None,None,None],
|
|
52
|
-
'deci':[0.1,'d',None,None,None],
|
|
44
|
+
'yocto':[MFraction('1e-24'),'y',None,None,None],
|
|
45
|
+
'zepto':[MFraction('1e-21'),'z',None,None,None],
|
|
46
|
+
'atto':[MFraction('1e-18'),'a',None,None,None],
|
|
47
|
+
'femto':[MFraction('1e-15'),'f',None,None,None],
|
|
48
|
+
'pico':[MFraction('1e-12'),'p',None,None,None],
|
|
49
|
+
'nano':[MFraction('1e-9'),'n',None,None,None],
|
|
50
|
+
'micro':[MFraction('1e-6'),'\u03BC','μ',None,'u'],
|
|
51
|
+
'milli':[MFraction('0.001'),'m',None,None,None],
|
|
52
|
+
'centi':[MFraction('0.01'),'c',None,None,None],
|
|
53
|
+
'deci':[MFraction('0.1'),'d',None,None,None],
|
|
53
54
|
'deca':[10,'da',None,None,None],
|
|
54
55
|
'hecto':[100,'h',None,None,None],
|
|
55
56
|
'kilo':[1000,'k',None,None,None],
|
|
56
57
|
'mega':[1000000,'M',None,None,None],
|
|
57
|
-
'giga':[
|
|
58
|
-
'tera':[
|
|
59
|
-
'peta':[
|
|
60
|
-
'exa':[
|
|
61
|
-
'zetta':[1e21,'Z',None,None,None],
|
|
62
|
-
'yotta':[1e24,'Y',None,None,None],
|
|
58
|
+
'giga':[1000000000,'G',None,None,None],
|
|
59
|
+
'tera':[1000000000000,'T',None,None,None],
|
|
60
|
+
'peta':[1000000000000000,'P',None,None,None],
|
|
61
|
+
'exa': [1000000000000000000,'E',None,None,None],
|
|
62
|
+
'zetta':[MFraction('1e21'),'Z',None,None,None],
|
|
63
|
+
'yotta':[MFraction('1e24'),'Y',None,None,None],
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
@staticmethod
|
|
@@ -223,13 +224,13 @@ class BinaryPrefixedUnit(PrefixedUnit):
|
|
|
223
224
|
"""
|
|
224
225
|
prefix_definitions = {
|
|
225
226
|
'kilo':[1000,'k',None,None,None],
|
|
226
|
-
'mega':[
|
|
227
|
-
'giga':[
|
|
228
|
-
'tera':[
|
|
229
|
-
'peta':[
|
|
230
|
-
'exa':[
|
|
231
|
-
'zetta':[1e21,'Z',None,None,None],
|
|
232
|
-
'yotta':[1e24,'Y',None,None,None],
|
|
227
|
+
'mega':[1000000,'M',None,None,None],
|
|
228
|
+
'giga':[1000000000,'G',None,None,None],
|
|
229
|
+
'tera':[1000000000000,'T',None,None,None],
|
|
230
|
+
'peta':[1000000000000000,'P',None,None,None],
|
|
231
|
+
'exa':[1000000000000000000,'E',None,None,None],
|
|
232
|
+
'zetta':[MFraction('1e21'),'Z',None,None,None],
|
|
233
|
+
'yotta':[MFraction('1e24'),'Y',None,None,None],
|
|
233
234
|
'kibi':[1024,'Ki',None,None,None],
|
|
234
235
|
'mebi':[1024**2,'Mi',None,None,None],
|
|
235
236
|
'gibi':[1024**3,'Gi',None,None,None],
|
metrolopy/relunits.py
CHANGED
|
@@ -24,8 +24,7 @@
|
|
|
24
24
|
This module is loaded by the gummy.units module and is not intended be be
|
|
25
25
|
imported directly. Dimensionless units are defined here.
|
|
26
26
|
"""
|
|
27
|
-
from .unit import Unit,Conversion,one
|
|
28
|
-
from .ummy import MFraction
|
|
27
|
+
from .unit import Unit,Conversion,one,MFraction
|
|
29
28
|
|
|
30
29
|
class RatioUnit(Unit):
|
|
31
30
|
"""RatioUnit is used for dimensionless units like % where powers, e.g. %**2,
|
metrolopy/siunits.py
CHANGED
|
@@ -28,8 +28,8 @@ The most of the units here are from the SI Brochure, 9th edition.
|
|
|
28
28
|
"""
|
|
29
29
|
|
|
30
30
|
from numpy import pi
|
|
31
|
-
from .ummy import ummy
|
|
32
|
-
from .unit import Conversion,Unit
|
|
31
|
+
from .ummy import ummy
|
|
32
|
+
from .unit import Conversion,Unit,MFraction
|
|
33
33
|
from .prefixedunit import PrefixedUnit
|
|
34
34
|
from .offsetunit import OffsetUnit,OffsetConversion
|
|
35
35
|
|
|
@@ -112,8 +112,9 @@ with Unit._builtin():
|
|
|
112
112
|
_degC = OffsetUnit('degree Celsius','\u00B0C',OffsetConversion(_K,273.15),
|
|
113
113
|
latex_symbol='^{\\circ}C',ascii_symbol = 'degC',add_symbol=True,order=0,
|
|
114
114
|
description='unit of temperature')
|
|
115
|
-
Unit.alias('
|
|
116
|
-
Unit.alias('
|
|
115
|
+
Unit.alias('degreeC',_degC)
|
|
116
|
+
Unit.alias('degree-C',_degC)
|
|
117
|
+
Unit.alias('deg-C',_degC)
|
|
117
118
|
|
|
118
119
|
_lm = PrefixedUnit('lumen','lm',Conversion(_cd*_sr,1),add_symbol=True,order=0,
|
|
119
120
|
description='SI derived unit for luminous flux')
|
|
@@ -151,4 +152,5 @@ with Unit._builtin():
|
|
|
151
152
|
prefixes=['centi','deci','deca','hecto','kilo','mega',
|
|
152
153
|
'giga','tera','peta','exa','zetta','yotta'],
|
|
153
154
|
description='unit of mass')
|
|
154
|
-
Unit.alias('metric ton',_tonne)
|
|
155
|
+
Unit.alias('metric ton',_tonne)
|
|
156
|
+
Unit.alias('metric-ton',_tonne)
|