richvalues 4.2.4__tar.gz → 4.2.6__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: richvalues
3
- Version: 4.2.4
3
+ Version: 4.2.6
4
4
  Summary: Python library for working with uncertainties and upper/lower limits
5
5
  Home-page: https://github.com/andresmegias/richvalues/
6
6
  Author: Andrés Megías Toledano
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "richvalues"
7
- version = "4.2.4"
7
+ version = "4.2.6"
8
8
  description = "Python library for working with uncertainties and upper/lower limits"
9
9
  license = {file="LICENSE"}
10
10
  authors = [{name="Andrés Megías Toledano"}]
@@ -13,12 +13,12 @@ modification, are permitted provided that the following conditions are
13
13
  met:
14
14
 
15
15
  (1) Redistributions of source code must retain the above copyright
16
- notice, this list of conditions and the following disclaimer.
16
+ notice, this list of conditions and the following disclaimer.
17
17
 
18
18
  (2) Redistributions in binary form must reproduce the above copyright
19
19
  notice, this list of conditions and the following disclaimer in
20
20
  the documentation and/or other materials provided with the
21
- distribution.
21
+ distribution.
22
22
 
23
23
  (3) The name of the author may not be used to endorse or promote
24
24
  products derived from this software without specific prior written
@@ -37,7 +37,7 @@ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37
37
  POSSIBILITY OF SUCH DAMAGE.
38
38
  """
39
39
 
40
- __version__ = '4.2.4'
40
+ __version__ = '4.2.6'
41
41
  __author__ = 'Andrés Megías Toledano'
42
42
 
43
43
  import copy
@@ -59,7 +59,7 @@ defaultparams = {
59
59
  'size of samples': int(8e3),
60
60
  'number of significant figures': 1,
61
61
  'minimum exponent for scientific notation': 4,
62
- 'maximum number of decimals': 5,
62
+ 'maximum number of decimals to use parenthesis': 5,
63
63
  'limit for extra significant figure': 2.5,
64
64
  'use extra significant figure for exact values': True,
65
65
  'use extra significant figure for finite intervals': True,
@@ -211,7 +211,7 @@ def round_sf_unc(x, dx, n=None, min_exp=None, max_dec=None, extra_sf_lim=None):
211
211
  """
212
212
  n = set_default_value(n, 'number of significant figures')
213
213
  min_exp = set_default_value(min_exp, 'minimum exponent for scientific notation')
214
- max_dec = set_default_value(max_dec, 'maximum number of decimals')
214
+ max_dec = set_default_value(max_dec, 'maximum number of decimals to use parenthesis')
215
215
  extra_sf_lim = set_default_value(extra_sf_lim, 'limit for extra significant figure')
216
216
  use_exp = True
217
217
  if ((float(x) > float(dx)
@@ -303,20 +303,29 @@ def round_sf_unc(x, dx, n=None, min_exp=None, max_dec=None, extra_sf_lim=None):
303
303
  min_exp = np.inf
304
304
  y, dy = round_sf_unc(x, dx, n, min_exp, max_dec, extra_sf_lim)
305
305
  y = y.replace('e+', 'e').replace('e00', 'e0')
306
- dy = dy.replace('e+','e').replace('e00', 'e0')
307
- d = len(y.split('e')[0].split('.')[-1])
308
- if d > max_dec and ')' not in dy:
306
+ dy = dy.replace('e+','e').replace('e00', 'e0') .replace('(', '').replace(')', '')
307
+ d = len(y.split('e')[0].split('.')[-1]) if '.' in y else 0
308
+ if max_dec == 0 or d > max_dec and ')' not in dy:
309
309
  if 'e' in y:
310
- y, exp = y.split('e')
310
+ y, exp_y = y.split('e')
311
311
  dy, _ = dy.split('e')
312
312
  else:
313
- exp = None
314
- d = len(y.split('.')[-1])
315
- d_ = len(dy.split('.')[-1])
316
- dy_ = round_sf(float(dy)*10**(d-d_), n, 0, extra_sf_lim)
317
- dy = '(' + dy_.split('e')[0] + ')'
318
- if exp is not None:
319
- y = '{}e{}'.format(y, exp)
313
+ exp_y = None
314
+ if dy != '0':
315
+ d = len(y.split('.')[-1]) if '.' in y else 0
316
+ d_ = len(dy.split('.')[-1]) if '.' in dy else 0
317
+ dy_ = round_sf(float(dy)*10**(d-d_), n, 0, extra_sf_lim)
318
+ dy, exp_dy = dy_.split('e')
319
+ exp_y_ = 0 if exp_y is None else exp_y
320
+ if int(exp_y_) > int(exp_dy):
321
+ dy = round_sf(float(dy)*10**int(exp_dy), n, np.inf, extra_sf_lim)
322
+ if '.' in dy:
323
+ dy = dy.split('.')[-1]
324
+ dy = '(' + dy + ')'
325
+ else:
326
+ dy = ''
327
+ if exp_y is not None:
328
+ y = '{}e{}'.format(y, exp_y)
320
329
  return y, dy
321
330
 
322
331
  def round_sf_uncs(x, dx, n=None, min_exp=None, max_dec=None, extra_sf_lim=None):
@@ -351,7 +360,7 @@ def round_sf_uncs(x, dx, n=None, min_exp=None, max_dec=None, extra_sf_lim=None):
351
360
  """
352
361
  n = set_default_value(n, 'number of significant figures')
353
362
  min_exp = set_default_value(min_exp, 'minimum exponent for scientific notation')
354
- max_dec = set_default_value(max_dec, 'maximum number of decimals')
363
+ max_dec = set_default_value(max_dec, 'maximum number of decimals to use parenthesis')
355
364
  extra_sf_lim = set_default_value(extra_sf_lim, 'limit for extra significant figure')
356
365
  dx1, dx2 = dx
357
366
  y1, dy1 = round_sf_unc(x, dx1, n, min_exp, max_dec, extra_sf_lim)
@@ -580,7 +589,7 @@ class RichValue():
580
589
  self.domain = domain
581
590
  self.num_sf = defaultparams['number of significant figures']
582
591
  self.min_exp = defaultparams['minimum exponent for scientific notation']
583
- self.max_dec = defaultparams['maximum number of decimals']
592
+ self.max_dec = defaultparams['maximum number of decimals to use parenthesis']
584
593
  self.extra_sf_lim = defaultparams['limit for extra significant figure']
585
594
  self.pdf_info = 'default'
586
595
  self.variables = variables
@@ -632,11 +641,11 @@ class RichValue():
632
641
  """Constant value."""
633
642
  isconst = self.is_exact and self.domain[0] == self.domain[1]
634
643
  return isconst
635
- @property
644
+ @property
636
645
  def center(self):
637
646
  """Central value."""
638
647
  cent = self.main if self.is_centr else np.nan
639
- return cent
648
+ return cent
640
649
  @property
641
650
  def unc_eb(self):
642
651
  """Uncertainties with shape (2,1)."""
@@ -663,7 +672,7 @@ class RichValue():
663
672
  else:
664
673
  s_n = [np.nan]*2
665
674
  return s_n
666
- @property
675
+ @property
667
676
  def ampl(self):
668
677
  """Amplitudes."""
669
678
  m, b = self.main, self.domain
@@ -784,7 +793,7 @@ class RichValue():
784
793
  m = np.nanmedian(distr)
785
794
  else:
786
795
  m = np.nan
787
- return m
796
+ return m
788
797
 
789
798
  def mean(self, num_points=int(1e4), sigmas=8.):
790
799
  """Mean of the PDF of the rich value."""
@@ -840,7 +849,7 @@ class RichValue():
840
849
  y = self.pdf(x)
841
850
  c = np.trapz(y*x, x) if central or standarized else 0.
842
851
  s = np.sqrt(np.trapz(y*(x-c)**2)) if standarized else 1.
843
- moment = np.trapz((y*(x-c)**n)) / s**n
852
+ moment = np.trapz((y*(x-c)**n)) / s**n
844
853
  else:
845
854
  moment = np.nan
846
855
  return moment
@@ -1094,7 +1103,7 @@ class RichValue():
1094
1103
  else:
1095
1104
  if is_lolim:
1096
1105
  symbol = '>'
1097
- y = int(np.floor(x)) if is_int else x
1106
+ y = int(np.floor(x)) if is_int else x
1098
1107
  elif is_uplim:
1099
1108
  symbol = '<'
1100
1109
  y = int(np.ceil(x)) if is_int else x
@@ -1144,10 +1153,10 @@ class RichValue():
1144
1153
  else:
1145
1154
  if is_lolim:
1146
1155
  symbol = '>'
1147
- y = int(np.floor(x)) if is_int else x
1156
+ y = int(np.floor(x)) if is_int else x
1148
1157
  elif is_uplim:
1149
1158
  symbol = '<'
1150
- y = int(np.ceil(x)) if is_int else x
1159
+ y = int(np.ceil(x)) if is_int else x
1151
1160
  y = round_sf(y, n, min_exp, extra_sf_lim)
1152
1161
  if 'e' in y:
1153
1162
  y, a = y.split('e')
@@ -1215,6 +1224,7 @@ class RichValue():
1215
1224
  rvalue = RichValue(x, dx, domain=domain, is_int=self.is_int)
1216
1225
  rvalue.num_sf = self.num_sf
1217
1226
  rvalue.min_exp = self.min_exp
1227
+ rvalue.max_dec = self.max_dec
1218
1228
  rvalue.extra_sf_lim = self.extra_sf_lim
1219
1229
  rvalue.variables = self.variables
1220
1230
  expression = self.expression
@@ -1253,6 +1263,7 @@ class RichValue():
1253
1263
  rvalue.domain[0] = max(0, rvalue.domain[0])
1254
1264
  rvalue.num_sf = self.num_sf
1255
1265
  rvalue.min_exp = self.min_exp
1266
+ rvalue.max_dec = self.max_dec
1256
1267
  rvalue.extra_sf_lim = self.extra_sf_lim
1257
1268
  rvalue.variables = self.variables
1258
1269
  rvalue.expression = 'abs({})'.format(self.expression)
@@ -1431,7 +1442,7 @@ class RichValue():
1431
1442
  if domain[0] > 0 and other_.sign() != -1:
1432
1443
  domain[0] = 0
1433
1444
  if domain[1] < 0 and other_.sign() != 1:
1434
- domain[1] = 0
1445
+ domain[1] = 0
1435
1446
  rvalue = function_with_rich_values('{}%{}', [self, other_],
1436
1447
  domain=domain, is_domain_cyclic=True)
1437
1448
  return rvalue
@@ -1498,6 +1509,7 @@ class RichValue():
1498
1509
  rvalue = RichValue(np.nan)
1499
1510
  rvalue.num_sf = self.num_sf
1500
1511
  rvalue.min_exp = self.min_exp
1512
+ rvalue.max_dec = self.max_dec
1501
1513
  rvalue.extra_sf_lim = self.extra_sf_lim
1502
1514
  else:
1503
1515
  vars_str = ','.join(variables)
@@ -1546,7 +1558,7 @@ class RichValue():
1546
1558
  x = [x]
1547
1559
  x = np.array(x)
1548
1560
  y = np.zeros(len(x))
1549
- if self.is_exact:
1561
+ if self.is_exact:
1550
1562
  ind = np.argmin(abs(x - main))
1551
1563
  if hasattr(ind, '__iter__'):
1552
1564
  ind = ind[0]
@@ -1607,7 +1619,7 @@ class RichValue():
1607
1619
  if not self.is_lim:
1608
1620
  distr = general_distribution(main, unc, domain, N)
1609
1621
  else:
1610
- x1, x2 = self.interval()
1622
+ x1, x2 = self.interval()
1611
1623
  distr = loguniform_distribution(x1, x2, N)
1612
1624
  elif not is_finite_interv and all(np.isinf(unc)):
1613
1625
  distr = loguniform_distribution(-np.inf, np.inf, N)
@@ -1857,17 +1869,17 @@ class RichArray(np.ndarray):
1857
1869
  return np.array([x.main for x in self.flat]).reshape(self.shape)
1858
1870
  @property
1859
1871
  def uncs(self):
1860
- return np.array([x.unc for x in self.flat]).reshape([*self.shape,2])
1872
+ return np.array([x.unc for x in self.flat]).reshape([*self.shape,2])
1861
1873
  @property
1862
1874
  def are_lolims(self):
1863
1875
  return np.array([x.is_lolim for x in self.flat]).reshape(self.shape)
1864
1876
  @property
1865
1877
  def are_uplims(self):
1866
- return np.array([x.is_uplim for x in self.flat]).reshape(self.shape)
1878
+ return np.array([x.is_uplim for x in self.flat]).reshape(self.shape)
1867
1879
  @property
1868
1880
  def are_ranges(self):
1869
1881
  return np.array([x.is_range for x in self.flat]).reshape(self.shape)
1870
- @property
1882
+ @property
1871
1883
  def domains(self):
1872
1884
  return np.array([x.domain for x in self.flat]).reshape([*self.shape,2])
1873
1885
  @property
@@ -1908,7 +1920,7 @@ class RichArray(np.ndarray):
1908
1920
  return np.array([x.is_inf for x in self.flat]).reshape(self.shape)
1909
1921
  @property
1910
1922
  def centers(self):
1911
- return np.array([x.center for x in self.flat]).reshape(self.shape)
1923
+ return np.array([x.center for x in self.flat]).reshape(self.shape)
1912
1924
  @property
1913
1925
  def rel_uncs(self):
1914
1926
  return (np.array([x.rel_unc for x in self.flat])
@@ -1982,36 +1994,36 @@ class RichArray(np.ndarray):
1982
1994
 
1983
1995
  def medians(self, num_points=None):
1984
1996
  return np.array([x.median(num_points)
1985
- for x in self.flat]).reshape(self.shape)
1997
+ for x in self.flat]).reshape(self.shape)
1986
1998
 
1987
1999
  def means(self, num_points=int(1e4), sigmas=8.):
1988
2000
  return np.array([x.mean(num_points, sigmas)
1989
- for x in self.flat]).reshape(self.shape)
2001
+ for x in self.flat]).reshape(self.shape)
1990
2002
 
1991
2003
  def modes(self, num_points=int(1e4), sigmas=8.):
1992
2004
  return np.array([x.mode(num_points, sigmas)
1993
- for x in self.flat]).reshape(self.shape)
2005
+ for x in self.flat]).reshape(self.shape)
1994
2006
 
1995
2007
  def variances(self, num_points=int(1e4), sigmas=8.):
1996
2008
  return np.array([x.var(num_points, sigmas)
1997
- for x in self.flat]).reshape(self.shape)
2009
+ for x in self.flat]).reshape(self.shape)
1998
2010
 
1999
2011
  def stds(self, num_points=int(1e4), sigmas=8.):
2000
2012
  return np.array([x.std(num_points, sigmas)
2001
- for x in self.flat]).reshape(self.shape)
2013
+ for x in self.flat]).reshape(self.shape)
2002
2014
 
2003
2015
  def moments(self, n, central=True, standarized=False):
2004
2016
  return np.array([x.moments(n, central, standarized)
2005
- for x in self.flat]).reshape(self.shape)
2017
+ for x in self.flat]).reshape(self.shape)
2006
2018
 
2007
2019
  def set_params(self, params):
2008
2020
  """Set the rich value parameters of each entry of the rich array."""
2009
2021
  abbreviations = {'is integer': 'is_int',
2010
2022
  'number of significant figures': 'num_sf',
2011
2023
  'minimum exponent for scientific notation': 'min_exp',
2012
- 'maximum number of decimals': 'max_dec',
2024
+ 'maximum number of decimals to use parenthesis': 'max_dec',
2013
2025
  'limit for extra significant figure': 'extra_sf_lim'}
2014
- attributes = ['domain'] + list(abbreviations.values())
2026
+ attributes = ['domain'] + list(abbreviations.values())
2015
2027
  for entry in abbreviations:
2016
2028
  name = abbreviations[entry]
2017
2029
  if entry in params:
@@ -2163,7 +2175,7 @@ class RichDataFrame(pd.DataFrame):
2163
2175
  exec(code, {**{'self': self}, **globals()}, output)
2164
2176
  return output['df']
2165
2177
 
2166
- @property
2178
+ @property
2167
2179
  def mains(self): return self._property('mains')
2168
2180
  @property
2169
2181
  def uncs(self): return self._property2('uncs')
@@ -2247,7 +2259,7 @@ class RichDataFrame(pd.DataFrame):
2247
2259
  abbreviations = {'is integer': 'is_int',
2248
2260
  'number of significant figures': 'num_sf',
2249
2261
  'minimum exponent for scientific notation': 'min_exp',
2250
- 'maximum number of decimals': 'max_dec',
2262
+ 'maximum number of decimals to use parenthesis': 'max_dec',
2251
2263
  'limit for extra significant figure': 'extra_sf_lim'}
2252
2264
  attributes = ['domain'] + list(abbreviations.values())
2253
2265
  for entry in abbreviations:
@@ -2595,7 +2607,7 @@ class ComplexRichValue():
2595
2607
  Parameters
2596
2608
  ----------
2597
2609
  real : rich value
2598
- Real part of the complex rich value.
2610
+ Real part of the complex rich value.
2599
2611
  imag : rich value
2600
2612
  Imaginary part of the complex rich value
2601
2613
  """
@@ -2676,14 +2688,14 @@ class ComplexRichValue():
2676
2688
  self.imag.num_sf = x
2677
2689
 
2678
2690
  @property
2679
- def min_exp(self): return round(np.mean([self.real.min_exp, self.imag.min_exp]))
2691
+ def min_exp(self): return round(np.mean([self.real.min_exp, self.imag.min_exp]))
2680
2692
  @min_exp.setter
2681
2693
  def min_exp(self, x):
2682
2694
  self.real.min_exp = x
2683
2695
  self.imag.min_exp = x
2684
2696
 
2685
2697
  @property
2686
- def max_dec(self): return min(self.real.max_dec, self.imag.max_dec)
2698
+ def max_dec(self): return min(self.real.max_dec, self.imag.max_dec)
2687
2699
  @max_dec.setter
2688
2700
  def max_dec(self, x):
2689
2701
  self.real.max_dec = x
@@ -2723,7 +2735,7 @@ class ComplexRichValue():
2723
2735
  def main(self):
2724
2736
  """Main value."""
2725
2737
  x = self.real.main + 1j*self.imag.main
2726
- return x
2738
+ return x
2727
2739
 
2728
2740
  @property
2729
2741
  def unc(self):
@@ -2943,7 +2955,7 @@ class ComplexRichValue():
2943
2955
  """Apply a function to the rich value"""
2944
2956
  return function_with_rich_values(function, self, **kwargs)
2945
2957
 
2946
- # Instance variable acronyms.
2958
+ # Instance variable acronyms.
2947
2959
 
2948
2960
  @property
2949
2961
  def real_part(self): return self.real
@@ -2988,6 +3000,7 @@ def add_rich_values(x, y):
2988
3000
  """Sum two rich values to get a new one."""
2989
3001
  num_sf = min(x.num_sf, y.num_sf)
2990
3002
  min_exp = round(np.mean([x.min_exp, y.min_exp]))
3003
+ max_dec = round(np.mean([x.max_dec, y.max_dec]))
2991
3004
  extra_sf_lim = max(x.extra_sf_lim, y.extra_sf_lim)
2992
3005
  is_int = x.is_int and y.is_int
2993
3006
  domain = [x.domain[0] + y.domain[0], x.domain[1] + y.domain[1]]
@@ -3005,6 +3018,7 @@ def add_rich_values(x, y):
3005
3018
  is_vectorizable=True)
3006
3019
  z.num_sf = num_sf
3007
3020
  z.min_exp = min_exp
3021
+ z.max_dec = max_dec
3008
3022
  z.extra_sf_lim = extra_sf_lim
3009
3023
  return z
3010
3024
 
@@ -3012,6 +3026,7 @@ def multiply_rich_values(x, y):
3012
3026
  """Multiply two rich values to get a new one."""
3013
3027
  num_sf = min(x.num_sf, y.num_sf)
3014
3028
  min_exp = round(np.mean([x.min_exp, y.min_exp]))
3029
+ max_dec = round(np.mean([x.max_dec, y.max_dec]))
3015
3030
  extra_sf_lim = max(x.extra_sf_lim, y.extra_sf_lim)
3016
3031
  is_int = x.is_int and y.is_int
3017
3032
  domain = propagate_domain(x.domain, y.domain, lambda a,b: a*b)
@@ -3030,6 +3045,7 @@ def multiply_rich_values(x, y):
3030
3045
  is_vectorizable=True)
3031
3046
  z.num_sf = num_sf
3032
3047
  z.min_exp = min_exp
3048
+ z.max_dec = max_dec
3033
3049
  z.extra_sf_lim = extra_sf_lim
3034
3050
  return z
3035
3051
 
@@ -3037,6 +3053,7 @@ def divide_rich_values(x, y):
3037
3053
  """Divide two rich values to get a new one."""
3038
3054
  num_sf = min(x.num_sf, y.num_sf)
3039
3055
  min_exp = round(np.mean([x.min_exp, y.min_exp]))
3056
+ max_dec = round(np.mean([x.max_dec, y.max_dec]))
3040
3057
  extra_sf_lim = max(x.extra_sf_lim, y.extra_sf_lim)
3041
3058
  is_int = x.is_int and y.is_int
3042
3059
  domain = propagate_domain(x.domain, y.domain, lambda a,b: a/b)
@@ -3078,6 +3095,7 @@ def divide_rich_values(x, y):
3078
3095
  is_vectorizable=True, sigmas=sigmas)
3079
3096
  z.num_sf = num_sf
3080
3097
  z.min_exp = min_exp
3098
+ z.max_dec = max_dec
3081
3099
  z.extra_sf_lim = extra_sf_lim
3082
3100
  return z
3083
3101
 
@@ -3211,7 +3229,8 @@ def less_equiv(x, y, sigmas_interval=None, sigmas_overlap=None):
3211
3229
  return output
3212
3230
 
3213
3231
  def rich_value(text=None, domain=None, is_int=None, pdf=None,
3214
- consider_intervs=True, use_default_extra_sf_lim=False):
3232
+ consider_intervs=True, use_default_max_dec=False,
3233
+ use_default_extra_sf_lim=False):
3215
3234
  """
3216
3235
  Convert the input text to a rich value.
3217
3236
 
@@ -3233,6 +3252,10 @@ def rich_value(text=None, domain=None, is_int=None, pdf=None,
3233
3252
  If the PDF is given, this variable determines if we consider the
3234
3253
  possibility that the rich value is an upper/lower limit or a finite
3235
3254
  interval of values. By default, it is True.
3255
+ use_default_max_dec : bool, optional
3256
+ If True, the default maximum number of decimals to show uncertainties
3257
+ between parenthesis will be used instead of inferring it from the input
3258
+ text. This will reduce the computation time a little bit.
3236
3259
  use_default_extra_sf_lim : bool, optional
3237
3260
  If True, the default limit for extra significant figure will be used
3238
3261
  instead of inferring it from the input text. This will reduce the
@@ -3258,6 +3281,7 @@ def rich_value(text=None, domain=None, is_int=None, pdf=None,
3258
3281
 
3259
3282
  input_domain = copy.copy(domain)
3260
3283
  default_num_sf = defaultparams['number of significant figures']
3284
+ default_max_dec = defaultparams['maximum number of decimals to use parenthesis']
3261
3285
  default_extra_sf_lim = defaultparams['limit for extra significant figure']
3262
3286
  abbreviations = {'inf': 'np.inf', 'tau': 'math.tau', 'pi': 'np.pi',
3263
3287
  'nan': 'np.nan', 'NaN': 'np.nan', 'none': 'np.nan'}
@@ -3287,7 +3311,7 @@ def rich_value(text=None, domain=None, is_int=None, pdf=None,
3287
3311
  domain = read_domain(text)
3288
3312
  if domain is not None:
3289
3313
  text = text.split('[')[0][:-1]
3290
- if not '--' in text:
3314
+ if not '--' in text:
3291
3315
  if text.startswith('+'):
3292
3316
  text = text[1:]
3293
3317
  if 'e' in text:
@@ -3341,8 +3365,8 @@ def rich_value(text=None, domain=None, is_int=None, pdf=None,
3341
3365
  d = len(x.split('.')[1]) if '.' in x else 0
3342
3366
  d1 = len(dx1.split('.')[1]) if '.' in dx1 else 0
3343
3367
  d2 = len(dx1.split('.')[1]) if '.' in dx2 else 0
3344
- dx1 = '{:f}'.format(float(dx1)*10**(-(d-d1)))
3345
- dx2 = '{:f}'.format(float(dx2)*10**(-(d-d2)))
3368
+ dx1 = str(float(dx1)*10**(-(d-d1)))
3369
+ dx2 = str(float(dx2)*10**(-(d-d2)))
3346
3370
  elif '+/-' in text:
3347
3371
  x, dx = x_dx.split('+/-')
3348
3372
  text = '{}-{}+{} {}'.format(x, dx, dx, e)
@@ -3370,6 +3394,11 @@ def rich_value(text=None, domain=None, is_int=None, pdf=None,
3370
3394
  x = parse_value(x)
3371
3395
  dx1 = parse_value(dx1)
3372
3396
  dx2 = parse_value(dx2)
3397
+ if not use_default_max_dec:
3398
+ num_dec = len(x.split('.')[1].split('e')[0]) if '.' in x else 0
3399
+ max_dec = num_dec - 1
3400
+ else:
3401
+ max_dec = default_max_dec
3373
3402
  if not use_default_extra_sf_lim:
3374
3403
  if (not (is_lolim or is_uplim)
3375
3404
  and not (eval(dx1) == eval(dx2) == 0)):
@@ -3397,11 +3426,11 @@ def rich_value(text=None, domain=None, is_int=None, pdf=None,
3397
3426
  if eval(dx1) == eval(dx2) == 0:
3398
3427
  extra_sf_lim = 1 - 1e-8
3399
3428
  else:
3400
- extra_sf_lim = default_extra_sf_lim
3429
+ extra_sf_lim = default_extra_sf_lim
3401
3430
  base = float('{:e}'.format(eval(val)).split('e')[0])
3402
3431
  if base <= default_extra_sf_lim:
3403
3432
  if num_sf < default_num_sf + 1:
3404
- extra_sf_lim = base - 1e-8
3433
+ extra_sf_lim = base - 1e-8
3405
3434
  else:
3406
3435
  extra_sf_lim = default_extra_sf_lim
3407
3436
  x = x.replace('e0','')
@@ -3409,31 +3438,33 @@ def rich_value(text=None, domain=None, is_int=None, pdf=None,
3409
3438
  unc = [eval(dx1), eval(dx2)]
3410
3439
  is_range = False
3411
3440
  if domain is None and np.isfinite(main) and unc[0] == 0. == unc[1]:
3412
- domain = [main]*2
3441
+ domain = [main]*2
3413
3442
  else:
3414
3443
  text = text.replace(' --','--').replace('-- ','--')
3415
3444
  text1, text2 = text.split('--')
3416
- x1, _, _, _, _, _, me1, el1 = parse_as_rich_value(text1)
3417
- x2, _, _, _, _, _, me2, el2 = parse_as_rich_value(text2)
3445
+ x1, _, _, _, _, _, me1, md1, el1 = parse_as_rich_value(text1)
3446
+ x2, _, _, _, _, _, me2, md2, el2 = parse_as_rich_value(text2)
3418
3447
  main = [x1, x2]
3419
3448
  unc = 0
3420
3449
  is_lolim, is_uplim, is_range = False, False, True
3421
3450
  min_exp = round(np.mean([me1, me2]))
3451
+ max_dec = round(np.mean([md1, md2]))
3422
3452
  extra_sf_lim = max(el1, el2)
3423
3453
  return (main, unc, is_lolim, is_uplim, is_range, domain,
3424
- min_exp, extra_sf_lim)
3454
+ min_exp, max_dec, extra_sf_lim)
3425
3455
 
3426
3456
  if pdf is None:
3427
3457
  text = str(text)
3428
3458
  is_complex = 'j' in text
3429
3459
  if not is_complex:
3430
- (main, unc, is_lolim, is_uplim, is_range, domain,
3431
- min_exp, extra_sf_lim) = parse_as_rich_value(text)
3460
+ (main, unc, is_lolim, is_uplim, is_range, domain, min_exp,
3461
+ max_dec, extra_sf_lim) = parse_as_rich_value(text)
3432
3462
  if input_domain is not None:
3433
3463
  domain = input_domain
3434
3464
  rvalue = RichValue(main, unc, is_lolim, is_uplim,
3435
3465
  is_range, domain, is_int)
3436
3466
  rvalue.min_exp = min_exp
3467
+ rvalue.max_dec = max_dec
3437
3468
  rvalue.extra_sf_lim = extra_sf_lim
3438
3469
  else:
3439
3470
  if '+/-' in text or '-' in text[1:] and '+' in text[1:]:
@@ -3451,12 +3482,13 @@ def rich_value(text=None, domain=None, is_int=None, pdf=None,
3451
3482
  text_imag = text_imag[1:]
3452
3483
  if text_imag[-1] == ')':
3453
3484
  text_imag = text_imag[:-1]
3454
- args = (domain, is_int, pdf, use_default_extra_sf_lim)
3485
+ args = (domain, is_int, pdf,
3486
+ use_default_max_dec, use_default_extra_sf_lim)
3455
3487
  real = rich_value(text_real, *args)
3456
3488
  imag = rich_value(text_imag, *args)
3457
3489
  else:
3458
3490
  text = text.replace(' + ', '+').replace(' - ', '-')
3459
- val = complex(text)
3491
+ val = complex(text)
3460
3492
  real = val.real
3461
3493
  imag = val.imag
3462
3494
  rvalue = ComplexRichValue(real, imag, domain, is_int)
@@ -4173,7 +4205,7 @@ def loguniform_distribution(low=-1, high=1, size=1,
4173
4205
  log_x2 = _log10(abs(x2))
4174
4206
  if log_x1 < zero_log:
4175
4207
  log_x1 = zero_log
4176
- if log_x2 > inf_log:
4208
+ if log_x2 > inf_log:
4177
4209
  log_x2 = inf_log
4178
4210
  if x1 < 0:
4179
4211
  if x2 <= 0:
@@ -4315,7 +4347,7 @@ def add_zero_infs(interval, zero_log, inf_log):
4315
4347
  elif x2 > 0 and x2 > 10**inf_log:
4316
4348
  x2 = np.inf
4317
4349
  new_interval = [x1, x2]
4318
- return new_interval
4350
+ return new_interval
4319
4351
  def remove_zero_infs(interval, zero_log, inf_log):
4320
4352
  """Replace 0 and infinity for the given values in the input interval."""
4321
4353
  x1, x2 = interval
@@ -4782,6 +4814,7 @@ def function_with_rich_values(function, args, unc_function=None,
4782
4814
  len_samples = int(len(args)**0.5 * defaultparams['size of samples'])
4783
4815
  num_sf = int(np.median([arg.num_sf for arg in args]))
4784
4816
  min_exp = round(np.mean([arg.min_exp for arg in args]))
4817
+ max_dec = round(np.mean([arg.max_dec for arg in args]))
4785
4818
  extra_sf_lim = max([arg.extra_sf_lim for arg in args])
4786
4819
 
4787
4820
  if consider_intervs is None:
@@ -4919,6 +4952,7 @@ def function_with_rich_values(function, args, unc_function=None,
4919
4952
  rval_k = ComplexRichValue(real_k, imag_k)
4920
4953
  rval_k.num_sf = num_sf
4921
4954
  rval_k.min_exp = min_exp
4955
+ rval_k.max_dec = max_dec
4922
4956
  rval_k.extra_sf_lim = extra_sf_lim
4923
4957
  output += [rval_k]
4924
4958
 
@@ -4946,6 +4980,7 @@ def function_with_rich_values(function, args, unc_function=None,
4946
4980
  num_reps_lims, save_pdf)
4947
4981
  rval_k.num_sf = num_sf
4948
4982
  rval_k.min_exp = min_exp
4983
+ rval_k.max_dec = max_dec
4949
4984
  rval_k.extra_sf_lim = extra_sf_lim
4950
4985
  if type(input_function) is str:
4951
4986
  if type(rval_k) is RichValue:
@@ -5427,7 +5462,7 @@ def curve_fit(x, y, function, guess, num_samples=3000,
5427
5462
  lim1, lim2 = 0.2, 1.2
5428
5463
  if disp_coef <= lim1:
5429
5464
  frac1 = 1.
5430
- elif disp_coef < lim2:
5465
+ elif disp_coef < lim2:
5431
5466
  frac1 = 1. - disp_coef / (lim2 - lim1)
5432
5467
  else:
5433
5468
  frac1 = 0.
@@ -5440,7 +5475,7 @@ def curve_fit(x, y, function, guess, num_samples=3000,
5440
5475
  result = {'parameters': params_fit, 'dispersion': dispersion, 'loss': loss,
5441
5476
  'parameters samples': samples, 'dispersion sample': dispersions,
5442
5477
  'loss sample': losses, 'number of fails': num_fails}
5443
- return result
5478
+ return result
5444
5479
 
5445
5480
  def point_fit(y, function, guess, num_samples=3000,
5446
5481
  loss=lambda a,b: (a-b)**2, lim_loss_factor=4.,
@@ -5517,7 +5552,7 @@ def point_fit(y, function, guess, num_samples=3000,
5517
5552
  lim1, lim2 = 0.2, 1.2
5518
5553
  if disp_coef <= lim1:
5519
5554
  frac1 = 1.
5520
- elif disp_coef < lim2:
5555
+ elif disp_coef < lim2:
5521
5556
  frac1 = 1. - disp_coef / (lim2 - lim1)
5522
5557
  else:
5523
5558
  frac1 = 0.
@@ -5760,4 +5795,4 @@ evaluate_distribution = evaluate_distr
5760
5795
  center_and_uncertainties = center_and_uncs
5761
5796
  is_not_a_number = is_nan = isnan
5762
5797
  is_infinite = is_inf = isinf
5763
- is_finite = is_finite = isfinite
5798
+ is_finite = is_finite = isfinite
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: richvalues
3
- Version: 4.2.4
3
+ Version: 4.2.6
4
4
  Summary: Python library for working with uncertainties and upper/lower limits
5
5
  Home-page: https://github.com/andresmegias/richvalues/
6
6
  Author: Andrés Megías Toledano
@@ -5,7 +5,7 @@ with open('README.md', 'r') as file:
5
5
 
6
6
  setuptools.setup(
7
7
  name = 'richvalues',
8
- version = '4.2.4',
8
+ version = '4.2.6',
9
9
  license = 'BSD-3-Clause',
10
10
  author = 'Andrés Megías Toledano',
11
11
  description = 'Python library for working with uncertainties and upper/lower limits',
File without changes
File without changes
File without changes