richvalues 4.2.0__tar.gz → 4.2.1__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
  BSD 3-Clause License
2
2
 
3
- Copyright (c) 2023, Andrés Megías Toledano
3
+ Copyright (c) 2025, Andrés Megías Toledano
4
4
  All rights reserved.
5
5
 
6
6
  Redistribution and use in source and binary forms, with or without
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: richvalues
3
- Version: 4.2.0
3
+ Version: 4.2.1
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.0"
7
+ version = "4.2.1"
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"}]
@@ -6,7 +6,7 @@ Rich Values Library
6
6
  -------------------
7
7
  Version 4.2
8
8
 
9
- Copyright (C) 2024 - Andrés Megías Toledano
9
+ Copyright (C) 2025 - Andrés Megías Toledano
10
10
 
11
11
  Redistribution and use in source and binary forms, with or without
12
12
  modification, are permitted provided that the following conditions are
@@ -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.0'
40
+ __version__ = '4.2.1'
41
41
  __author__ = 'Andrés Megías Toledano'
42
42
 
43
43
  import copy
@@ -592,6 +592,15 @@ class RichValue():
592
592
  x = [x, x]
593
593
  x = list(x)
594
594
  self._unc = x
595
+ global variable_count
596
+ variable_count += 1
597
+ variable = 'x{}'.format(variable_count)
598
+ variables = [variable]
599
+ expression = variable
600
+ self.variables = variables
601
+ self.expression = expression
602
+ global variable_dict
603
+ variable_dict[expression] = self
595
604
 
596
605
  @property
597
606
  def is_lim(self):
@@ -675,14 +684,23 @@ class RichValue():
675
684
  s_a = [np.nan]*2
676
685
  return s_a
677
686
  @property
687
+ def unc_asymmetry(self):
688
+ """Asymmetry of the uncertainties, as its maximum ratio."""
689
+ if self.is_centr:
690
+ s1, s2 = np.abs(self.unc)
691
+ f = max(s1/s2, s2/s1)
692
+ return f
693
+ @property
678
694
  def prop_score(self):
679
- """Minimum of the signals-to-noise and the relative amplitudes."""
695
+ """Propagation score, to determine the non-normal behaviour."""
680
696
  if self.is_exact:
681
697
  ps = np.inf
682
698
  elif self.is_centr:
683
699
  s_n = self.signal_noise
684
700
  a_s = self.rel_ampl
685
701
  ps = np.min([s_n, a_s])
702
+ f = self.unc_asymmetry
703
+ ps /= (1. + 8.*(f-1.))
686
704
  else:
687
705
  ps = 0.
688
706
  return ps
@@ -1388,21 +1406,21 @@ class RichValue():
1388
1406
 
1389
1407
  def __floordiv__(self, other):
1390
1408
  type_other = str(type(other))
1391
- other_ = (RichValue(other, is_int=(type(other) is int))
1409
+ other_ = (RichValue(other, is_int=('int' in str(type(other))))
1392
1410
  if 'int' in type_other or 'float' in type_other else other)
1393
1411
  rvalue = function_with_rich_values('{}//{}', [self, other_])
1394
1412
  return rvalue
1395
1413
 
1396
1414
  def __rfloordiv__(self, other):
1397
1415
  type_other = str(type(other))
1398
- other_ = (RichValue(other, is_int=(type(other) is int))
1416
+ other_ = (RichValue(other, is_int=('int' in str(type(other))))
1399
1417
  if 'int' in type_other or 'float' in type_other else other)
1400
1418
  other_ = RichValue(other) if type(other) is not RichValue else other
1401
1419
  return other_ // self
1402
1420
 
1403
1421
  def __mod__(self, other):
1404
1422
  type_other = str(type(other))
1405
- other_ = (RichValue(other, is_int=(type(other) is int))
1423
+ other_ = (RichValue(other, is_int=('int' in str(type(other))))
1406
1424
  if 'int' in type_other or 'float' in type_other else other)
1407
1425
  domain = other_.interval(6.)
1408
1426
  if domain[0] > 0 and other_.sign() != -1:
@@ -1452,7 +1470,7 @@ class RichValue():
1452
1470
  x = self.main ** other
1453
1471
  dx = (np.abs(x * other * np.array(self.unc) / self.main)
1454
1472
  if (x*other) != 0. else 0.)
1455
- is_int = self.is_int and type(other) is int
1473
+ is_int = self.is_int and 'int' in str(type(other))
1456
1474
  if domain != [-np.inf, np.inf]:
1457
1475
  if domain[0] != 0 or (domain[0] == 0 and other>0):
1458
1476
  x1 = domain[0] ** other
@@ -1519,7 +1537,7 @@ class RichValue():
1519
1537
  main = self.main
1520
1538
  unc = self.unc
1521
1539
  domain = copy.copy(self.domain)
1522
- if type(x) in (int, float):
1540
+ if not hasattr(x, '__iter__'):
1523
1541
  x = [x]
1524
1542
  x = np.array(x)
1525
1543
  y = np.zeros(len(x))
@@ -1694,7 +1712,7 @@ class RichArray(np.ndarray):
1694
1712
 
1695
1713
  def __new__(cls, mains=None, uncs=None, are_lolims=None, are_uplims=None,
1696
1714
  are_ranges=None, domains=None, are_ints=None,
1697
- variables=None, expressions=None, **kwargs):
1715
+ variables=None, expressions=None, pdf_infos=None, **kwargs):
1698
1716
  """
1699
1717
  Parameters
1700
1718
  ----------
@@ -1823,6 +1841,8 @@ class RichArray(np.ndarray):
1823
1841
  if variables is not None and expressions is not None:
1824
1842
  array[i].variables = variables[i]
1825
1843
  array[i].expression = expressions[i]
1844
+ if pdf_infos is not None:
1845
+ array[i].pdf_info = pdf_infos[i]
1826
1846
  array = array.reshape(mains.shape)
1827
1847
  array = array.view(cls)
1828
1848
  return array
@@ -2898,7 +2918,7 @@ class ComplexRichValue():
2898
2918
  is_other_real = (type(other) not in (RichValue, ComplexRichValue)
2899
2919
  and 'complex' not in str(type(other)))
2900
2920
  if is_other_real:
2901
- is_int = type(other) is int
2921
+ is_int = 'int' in str(type(other))
2902
2922
  other_ = RichValue(other, is_int=is_int)
2903
2923
  other_.variables = []
2904
2924
  other_.expression = str(other)
@@ -3489,15 +3509,18 @@ def rich_array(array, domain=None, is_int=None,
3489
3509
  shape = array.shape
3490
3510
  mains, uncs, are_lolims, are_uplims, are_ranges, domains, are_ints = \
3491
3511
  [], [], [], [], [], [], []
3492
- min_exps, extra_sf_lims, variables, expressions = [], [], [], []
3512
+ min_exps, extra_sf_lims, variables, expressions, pdf_infos = \
3513
+ [], [], [], [], []
3493
3514
  for entry in array.flat:
3494
3515
  if type(entry) in (RichValue, ComplexRichValue):
3495
3516
  if domain is not None:
3496
3517
  entry.domain = domain
3497
3518
  if is_int is not None:
3498
3519
  entry.is_int = is_int
3520
+ pdf_info = entry.pdf_info
3499
3521
  else:
3500
3522
  entry = rich_value(entry, domain, is_int, use_default_extra_sf_lim)
3523
+ pdf_info = 'default'
3501
3524
  mains += [entry.main]
3502
3525
  uncs += [entry.unc]
3503
3526
  are_lolims += [entry.is_lolim]
@@ -3509,6 +3532,7 @@ def rich_array(array, domain=None, is_int=None,
3509
3532
  extra_sf_lims += [entry.extra_sf_lim]
3510
3533
  variables += [entry.variables]
3511
3534
  expressions += [entry.expression]
3535
+ pdf_infos += [pdf_info]
3512
3536
  mains = np.array(mains).reshape(shape)
3513
3537
  uncs = np.array(uncs)
3514
3538
  uncs = (np.array([uncs[:,0].reshape(shape).tolist(),
@@ -3523,7 +3547,7 @@ def rich_array(array, domain=None, is_int=None,
3523
3547
  .transpose().reshape((*shape, 2)))
3524
3548
  are_ints = np.array(are_ints).reshape(shape)
3525
3549
  rarray = RichArray(mains, uncs, are_lolims, are_uplims, are_ranges,
3526
- domains, are_ints, variables, expressions)
3550
+ domains, are_ints, variables, expressions, pdf_infos)
3527
3551
  min_exp = round(np.mean(min_exps))
3528
3552
  extra_sf_lim = max(extra_sf_lims)
3529
3553
  rarray.set_params({'min_exp': min_exp, 'extra_sf_lim': extra_sf_lim})
@@ -3608,6 +3632,28 @@ def rich_dataframe(df, domains=None, are_ints=None, ignore_columns=[],
3608
3632
  rdf = RichDataFrame(df)
3609
3633
  return rdf
3610
3634
 
3635
+ def gaussian(x, m=0., s=1.):
3636
+ """
3637
+ Parameters
3638
+ ----------
3639
+ x : array (float)
3640
+ Independent variable.
3641
+ m : float, optional
3642
+ Mean of the curve. The default is 0.
3643
+ s : float, optional
3644
+ Standard deviation of the curve.
3645
+ The default is 1.
3646
+
3647
+ Returns
3648
+ -------
3649
+ y : array (float)
3650
+ Resulting array.
3651
+ """
3652
+ sqrt_tau = 2.50662827
3653
+ y = np.exp(-0.5 * ((x-m) / s)**2)
3654
+ y /= s * sqrt_tau
3655
+ return y
3656
+
3611
3657
  def bounded_gaussian(x, m=0., s=1., a=np.inf):
3612
3658
  """
3613
3659
  Bounded gaussian function.
@@ -3724,7 +3770,7 @@ def qsplitgaussian(x, m=0., s1=1., s2=1., num_points=1200, sigmas=8.,
3724
3770
  Resulting array.
3725
3771
  """
3726
3772
  alpha = 0.15865
3727
- if type(x) in (int, float):
3773
+ if not hasattr(x, '__iter__'):
3728
3774
  x = [x]
3729
3775
  x = np.array(x)
3730
3776
  x_ = np.linspace(m - sigmas*s1, m + sigmas*s2, num_points)
@@ -3772,7 +3818,7 @@ def qgenextreme(x, m=0., s1=1., s2=1., num_points=800, sigmas=12.,
3772
3818
  Resulting array.
3773
3819
  """
3774
3820
  alpha = 0.15865
3775
- if type(x) in (int, float):
3821
+ if not hasattr(x, '__iter__'):
3776
3822
  x = [x]
3777
3823
  x = np.array(x)
3778
3824
  x_ = np.linspace(m - s1*sigmas, m + s2*sigmas, num_points)
@@ -4146,6 +4192,8 @@ def distr_with_rich_values(function, args, len_samples=None,
4146
4192
  """
4147
4193
  Same as function_with_rich_values, but just returns the final distribution.
4148
4194
  """
4195
+ len_samples = (int(len_samples) if len_samples is not None else
4196
+ int(len(args)**0.5 * defaultparams['size of samples']))
4149
4197
  if type(args) not in (tuple, list):
4150
4198
  args = [args]
4151
4199
  args = [rich_value(arg) if type(arg) not in (RichValue, ComplexRichValue)
@@ -4371,8 +4419,16 @@ def evaluate_distr(distr, domain=None, function=None, args=None,
4371
4419
  (RichValue, ComplexRichValue) else arg for arg in args]
4372
4420
  if consider_intervs is None:
4373
4421
  consider_intervs = True
4374
- if args is not None and all([arg.is_centr for arg in args]):
4375
- consider_intervs = False
4422
+ if args is not None:
4423
+ if type(args[0]) is RichValue:
4424
+ all_args = [arg for arg in args]
4425
+ elif type(args[0]) is RichArray:
4426
+ all_args = []
4427
+ for arg in args:
4428
+ for xi in arg:
4429
+ all_args += [xi]
4430
+ if all([arg.is_centr for arg in all_args]):
4431
+ consider_intervs = False
4376
4432
 
4377
4433
  distr = np.array(distr)
4378
4434
 
@@ -5042,6 +5098,7 @@ def distr_with_rich_arrays(function, args, elementwise=False, **kwargs):
5042
5098
  alt_args = []
5043
5099
  for arg in args:
5044
5100
  alt_args += list(arg.flat)
5101
+ distr = []
5045
5102
  output = distr_with_rich_values(alt_function, alt_args, **kwargs)
5046
5103
  return output
5047
5104
 
@@ -5156,7 +5213,7 @@ def errorbar(x, y, lims_factor=None, **kwargs):
5156
5213
  xa, ya = rich_array(x), rich_array(y)
5157
5214
  xc = rich_array([x]) if len(xa.shape) == 0 else xa
5158
5215
  yc = rich_array([y]) if len(ya.shape) == 0 else ya
5159
- if type(lims_factor) in (float, int):
5216
+ if not hasattr(lims_factor, '__iter__'):
5160
5217
  lims_factor_x, lims_factor_y = [lims_factor]*2
5161
5218
  elif type(lims_factor) in (list, tuple):
5162
5219
  lims_factor_x, lims_factor_y = lims_factor
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: richvalues
3
- Version: 4.2.0
3
+ Version: 4.2.1
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.0',
8
+ version = '4.2.1',
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