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/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,MultiNormalDist,MultiTDist)
32
+ MultivariateDistribution,Convolution)
33
33
  from .exceptions import NoSimulatedDataError
34
- from math import isinf,isfinite,isnan,sqrt
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
- dof = float('inf')
145
+ ndof = float('inf')
89
146
  u = float(x.u())
90
147
 
91
- super().__init__(x.x(),u=u,dof=dof,utype=utype)
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._u)
97
- if self._u == 0 or isnan(x) or isinf(x) or isnan(u):
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 = self._dof
101
- if isinf(dof):
102
- self._dist = NormalDist(x,u)
157
+ if isinstance(dof,_udict):
158
+ self._dist = None
103
159
  else:
104
- if nummy._bayesian:
105
- self._dist = TDist(x,u*np.sqrt((dof-2)/dof),dof)
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
- self._dist = TDist(x,u,dof)
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
- fmt = fmt.strip().lower()
174
- if fmt not in {'unicode','html','latex','ascii'}:
175
- raise ValueError('fmt "' + str(fmt) + '" is not recognized')
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
- ufrom = [g._dist for g in ufrom]
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 independent(self):
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,dof=self.dof)
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,tofloat=False):
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,tofloat=tofloat)
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._u == 0:
413
- r._dist = r._x
433
+ if s.u == 0:
434
+ r._dist = r.x
414
435
  return
415
- dof = s._dof
436
+ dof = s.dof
416
437
  if isinf(dof):
417
- r._dist = NormalDist(s._x,s._u)
438
+ r._dist = NormalDist(s.x,s.u)
418
439
  else:
419
440
  if r._bayesian:
420
- r._dist = TDist(s._x,s._u*np.sqrt((dof-2)/dof),dof)
421
- r._dof = float('inf')
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._x,s._u,dof)
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,correlation_matrix=None,
480
- covariance_matrix=None):
481
- if name is None:
482
- name = [None]*len(x)
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 = [float('inf')]*nd
498
+ dof = float('inf')
501
499
 
502
- ret = super(nummy,cls).create(x.x(),u=u,dof=dof,covariance_matrix=x.cov)
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,correlation_matrix,covariance_matrix)
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,xlabel=None,title=None,hold=False,**kwds):
550
- if xlabel is None and self.name is not None:
551
- xlabel = str(self.name)
552
- if len(xlabel) == 1:
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 = str(x.name)
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 = str(y.name)
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: `gummy`, `str`, or array_like
629
- A gummy, a string referencing a utype or a list containing
630
- gummys and strings.
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
- if not sim:
646
- return super().ufrom(x)
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
- x = [g for g in ummy._toummylist(x) if self.correlation(g) != 0]
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
- v = nummy.correlation_matrix_sim(x)
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
- b = [self.correlation(z) for z in x]
653
- s = np.linalg.lstsq(v,b,rcond=-1)[0]
654
- u = 0
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','&mu;',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','&mu;',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':[1e9,'G',None,None,None],
58
- 'tera':[1e12,'T',None,None,None],
59
- 'peta':[1e15,'P',None,None,None],
60
- 'exa':[1e18,'E',None,None,None],
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':[1e6,'M',None,None,None],
227
- 'giga':[1e9,'G',None,None,None],
228
- 'tera':[1e12,'T',None,None,None],
229
- 'peta':[1e15,'P',None,None,None],
230
- 'exa':[1e18,'E',None,None,None],
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,MFraction
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('degree C',_degC)
116
- Unit.alias('deg C',_degC)
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)