richvalues 4.0.5__tar.gz → 4.0.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.0.5
3
+ Version: 4.0.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
@@ -15,7 +15,7 @@ License-File: LICENSE
15
15
 
16
16
  RichValues is a Python 3 library for working with numeric values with uncertainties, upper/lower limits and finite intervals, which may be called _rich values_.
17
17
 
18
- With it, one can import rich values written in plain text documents in an easily readable format, operate with them propagating the uncertainties automatically, and export them in the same formatting style as the import. It also allows to easily plot rich values and to make fits to any function, taking into account the uncertainties and the upper/limits or finite intervals. Moreover, correlations between variables are taken into account when performing calculations with rich values.
18
+ With it, one can import rich values written in plain text documents in an easily readable format, operate with them propagating the uncertainties automatically, and export them in the same formatting style as the import. It also allows to easily plot rich values and to make fits to any function, taking into account the uncertainties and the upper/lower limits or finite intervals. Moreover, correlations between variables are taken into account when performing calculations with rich values.
19
19
 
20
20
  The libraries NumPy, Pandas, SciPy and Matplotlib are required by RichValues. A user guide and a quick tutorial are available on GitHub: https://github.com/andresmegias/richvalues/.
21
21
 
@@ -1,5 +1,5 @@
1
1
  RichValues is a Python 3 library for working with numeric values with uncertainties, upper/lower limits and finite intervals, which may be called _rich values_.
2
2
 
3
- With it, one can import rich values written in plain text documents in an easily readable format, operate with them propagating the uncertainties automatically, and export them in the same formatting style as the import. It also allows to easily plot rich values and to make fits to any function, taking into account the uncertainties and the upper/limits or finite intervals. Moreover, correlations between variables are taken into account when performing calculations with rich values.
3
+ With it, one can import rich values written in plain text documents in an easily readable format, operate with them propagating the uncertainties automatically, and export them in the same formatting style as the import. It also allows to easily plot rich values and to make fits to any function, taking into account the uncertainties and the upper/lower limits or finite intervals. Moreover, correlations between variables are taken into account when performing calculations with rich values.
4
4
 
5
5
  The libraries NumPy, Pandas, SciPy and Matplotlib are required by RichValues. A user guide and a quick tutorial are available on GitHub: https://github.com/andresmegias/richvalues/.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "richvalues"
7
- version = "4.0.5"
7
+ version = "4.0.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"}]
@@ -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.0.5'
40
+ __version__ = '4.0.6'
41
41
  __author__ = 'Andrés Megías Toledano'
42
42
 
43
43
  import copy
@@ -238,7 +238,8 @@ def round_sf_unc(x, dx, n=None, min_exp=None, extra_sf_lim=None):
238
238
  num_digits_x = len(str(x).split('.')[0])
239
239
  if num_digits_y > num_digits_x:
240
240
  m -= 1
241
- if float(dy[0]) <= extra_sf_lim:
241
+ base_dy = '{:e}'.format(float(dy)).split('e')[0]
242
+ if float(base_dy) <= extra_sf_lim:
242
243
  m += 1
243
244
  y = round_sf(x, m, min_exp, extra_sf_lim=1-1e-8)
244
245
  else:
@@ -339,8 +340,10 @@ def round_sf_uncs(x, dx, n=None, min_exp=None, extra_sf_lim=None):
339
340
  diff = num_dec_1 - num_dec_2
340
341
  off1, off2 = 0, 0
341
342
  if num_dec_1 == 0 == num_dec_2:
342
- b1 = float(str(dy1)[0]) if np.isfinite(dx1) else 10.
343
- b2 = float(str(dy2)[0]) if np.isfinite(dx2) else 10.
343
+ base_dy1 = '{:e}'.format(dx1).split('e')[0]
344
+ base_dy2 = '{:e}'.format(dx2).split('e')[0]
345
+ b1 = float(base_dy1) if np.isfinite(dx1) else 10.
346
+ b2 = float(base_dy2) if np.isfinite(dx2) else 10.
344
347
  if dx2 > dx1 and b1 <= extra_sf_lim and b2 > extra_sf_lim:
345
348
  off2 = 1
346
349
  if dx1 > dx2 and b2 <= extra_sf_lim and b1 > extra_sf_lim:
@@ -945,13 +948,13 @@ class RichValue():
945
948
  elif is_uplim:
946
949
  symbol = '<'
947
950
  y = int(np.ceil(x)) if is_int else x
948
- min_exp = 0
949
951
  y = round_sf(y, n, min_exp, extra_sf_lim)
950
- y, a = y.split('e')
951
- a = str(int(a))
952
+ if 'e' in y:
953
+ y, a = y.split('e')
954
+ else:
955
+ a = '0'
952
956
  text = ('${} {} {}'.format(symbol, y, mult_symbol)
953
957
  + ' 10^{'+a+'}$')
954
- text = text.replace('e-0', 'e-').replace('e+','e')
955
958
  a = int(text.split('10^{')[1].split('}')[0])
956
959
  if abs(a) < min_exp:
957
960
  y = RichValue(x, dx, is_lolim, is_uplim,
@@ -962,7 +965,8 @@ class RichValue():
962
965
  text = y.latex(*kwargs)
963
966
  if (not use_extra_sf_in_exacts and omit_ones_in_sci_notation
964
967
  and dx[0] == dx[1] and dx[0] == 0 or np.isnan(dx[0])):
965
- text = text.replace('1 {} '.format(mult_symbol), '')
968
+ if '.' not in text:
969
+ text = text.replace('1 {} '.format(mult_symbol), '')
966
970
  else:
967
971
  x1 = RichValue(main - unc[0], domain=domain)
968
972
  x2 = RichValue(main + unc[1], domain=domain)
@@ -2663,7 +2667,7 @@ def add_rich_values(x, y):
2663
2667
  is_int = x.is_int and y.is_int
2664
2668
  domain = [x.domain[0] + y.domain[0], x.domain[1] + y.domain[1]]
2665
2669
  sigmas = defaultparams['sigmas to use approximate uncertainty propagation']
2666
- if x.is_exact or y.is_exact:
2670
+ if (x.is_exact or y.is_exact) and (x.is_interv or y.is_interv):
2667
2671
  z = list(np.array(x.interval()) + np.array(y.interval()))
2668
2672
  z = RichValue(z, domain=domain, is_int=is_int)
2669
2673
  elif (not (x.is_interv or y.is_interv)
@@ -2687,7 +2691,7 @@ def multiply_rich_values(x, y):
2687
2691
  is_int = x.is_int and y.is_int
2688
2692
  domain = propagate_domain(x.domain, y.domain, lambda a,b: a*b)
2689
2693
  sigmas = defaultparams['sigmas to use approximate uncertainty propagation']
2690
- if x.is_exact or y.is_exact:
2694
+ if (x.is_exact or y.is_exact) and (x.is_interv or y.is_interv):
2691
2695
  z = list(np.array(x.interval()) * np.array(y.interval()))
2692
2696
  z = RichValue(z, domain=domain, is_int=is_int)
2693
2697
  elif (not (x.is_interv or y.is_interv)
@@ -3070,7 +3074,7 @@ def rich_value(text=None, domain=None, is_int=None, pdf=None,
3070
3074
  unc = 0
3071
3075
  is_lolim, is_uplim, is_range = False, False, True
3072
3076
  min_exp = round(np.mean([me1, me2]))
3073
- extra_sf_lim = min(el1, el2)
3077
+ extra_sf_lim = max(el1, el2)
3074
3078
  return (main, unc, is_lolim, is_uplim, is_range, domain,
3075
3079
  min_exp, extra_sf_lim)
3076
3080
 
@@ -3203,7 +3207,7 @@ def rich_array(array, domain=None, is_int=None,
3203
3207
  rarray = RichArray(mains, uncs, are_lolims, are_uplims, are_ranges,
3204
3208
  domains, are_ints, variables, expressions)
3205
3209
  min_exp = round(np.mean(min_exps))
3206
- extra_sf_lim = min(extra_sf_lims)
3210
+ extra_sf_lim = max(extra_sf_lims)
3207
3211
  rarray.set_params({'min_exp': min_exp, 'extra_sf_lim': extra_sf_lim})
3208
3212
  return rarray
3209
3213
 
@@ -3582,7 +3586,7 @@ def loguniform_distribution(low=-1, high=1, size=1,
3582
3586
  return distr
3583
3587
 
3584
3588
  def distr_with_rich_values(function, args, len_samples=None,
3585
- is_vectorizable=False):
3589
+ is_vectorizable=False, **kwargs):
3586
3590
  """
3587
3591
  Same as function_with_rich_values, but just returns the final distribution.
3588
3592
  """
@@ -3688,7 +3692,7 @@ def remove_zero_infs(interval, zero_log, inf_log):
3688
3692
  return new_interval
3689
3693
 
3690
3694
  def evaluate_distr(distr, domain=None, function=None, args=None,
3691
- len_samples=None, is_vectorizable=False, consider_intervs=True,
3695
+ len_samples=None, is_vectorizable=False, consider_intervs=None,
3692
3696
  is_domain_cyclic=False, lims_fraction=None, num_reps_lims=None,
3693
3697
  save_pdf=None, **kwargs):
3694
3698
  """
@@ -3776,8 +3780,13 @@ def evaluate_distr(distr, domain=None, function=None, args=None,
3776
3780
  if args is not None:
3777
3781
  if type(args) not in (tuple, list):
3778
3782
  args = [args]
3779
- args = [rich_value(arg) if type(arg) not in
3780
- (RichValue, ComplexRichValue) else arg for arg in args]
3783
+ if type(args[0]) is not RichArray:
3784
+ args = [rich_value(arg) if type(arg) not in
3785
+ (RichValue, ComplexRichValue) else arg for arg in args]
3786
+ if consider_intervs is None:
3787
+ consider_intervs = True
3788
+ if args is not None and all([arg.is_centr for arg in args]):
3789
+ consider_intervs = False
3781
3790
 
3782
3791
  distr = np.array(distr)
3783
3792
 
@@ -4076,6 +4085,7 @@ def function_with_rich_values(function, args, unc_function=None,
4076
4085
  args = [args]
4077
4086
  args = [rich_value(arg) if type(arg) not in (RichValue, ComplexRichValue)
4078
4087
  else arg for arg in args]
4088
+ args_copy = copy.copy(args)
4079
4089
 
4080
4090
  input_function = copy.copy(function)
4081
4091
  if type(function) is str:
@@ -4119,7 +4129,7 @@ def function_with_rich_values(function, args, unc_function=None,
4119
4129
 
4120
4130
  if len_samples is None:
4121
4131
  len_samples = int(len(args)**0.5 * defaultparams['size of samples'])
4122
- num_sf = min([arg.num_sf for arg in args])
4132
+ num_sf = int(np.median([arg.num_sf for arg in args]))
4123
4133
  min_exp = round(np.mean([arg.min_exp for arg in args]))
4124
4134
  extra_sf_lim = max([arg.extra_sf_lim for arg in args])
4125
4135
 
@@ -4136,9 +4146,6 @@ def function_with_rich_values(function, args, unc_function=None,
4136
4146
  use_analytic_propagation = False
4137
4147
 
4138
4148
  args_main = np.array([arg.main for arg in args])
4139
- # print()
4140
- # print(args)
4141
- # print(args[0].expression)
4142
4149
  with np.errstate(divide='ignore', invalid='ignore'):
4143
4150
  main = function(*args_main)
4144
4151
  output_size = np.array(main).size
@@ -4224,16 +4231,14 @@ def function_with_rich_values(function, args, unc_function=None,
4224
4231
 
4225
4232
  mains = [main] if output_size == 1 else main
4226
4233
  if unc_function is not None:
4227
- args_unc = [np.array(arg.unc) for arg in args]
4228
- uncs = unc_function(*args_main, *args_unc)
4234
+ uncs = []
4235
+ args_main = np.array([arg.main for arg in args_copy])
4236
+ for i in (0,1):
4237
+ args_unc = [arg.unc[i] for arg in args_copy]
4238
+ uncs += [unc_function(*args_main, *args_unc)]
4229
4239
  uncs = [uncs] if output_size == 1 else uncs
4230
- if output_size > 1:
4231
- for k in range(output_size):
4232
- if not hasattr(uncs[k], '__iter__'):
4233
- uncs[k] = [uncs[k]]*2
4234
- uncs[k][1] = abs(uncs[k][1])
4235
- if not hasattr(uncs,'__iter__'):
4236
- uncs = [uncs]*output_size
4240
+ for k in range(output_size):
4241
+ uncs[k][1] = abs(uncs[k][1])
4237
4242
  else:
4238
4243
  inds_combs = list(itertools.product(*[[0,1,2]]*len(args)))
4239
4244
  comb_main = tuple([1]*len(args))
@@ -4261,6 +4266,9 @@ def function_with_rich_values(function, args, unc_function=None,
4261
4266
  real_k = RichValue(main_k.real, unc_k.real, domain=domain_k)
4262
4267
  imag_k = RichValue(main_k.imag, unc_k.imag, domain=domain_k)
4263
4268
  rval_k = ComplexRichValue(real_k, imag_k)
4269
+ rval_k.num_sf = num_sf
4270
+ rval_k.min_exp = min_exp
4271
+ rval_k.extra_sf_lim = extra_sf_lim
4264
4272
  output += [rval_k]
4265
4273
 
4266
4274
  else:
@@ -4336,6 +4344,37 @@ def function_with_rich_arrays(function, args, elementwise=False, **kwargs):
4336
4344
  output : rich array / rich value
4337
4345
  Result of the function.
4338
4346
  """
4347
+ if 'domain' in kwargs:
4348
+ domain = kwargs['domain']
4349
+ del kwargs['domain']
4350
+ else:
4351
+ domain = None
4352
+ distr = distr_with_rich_arrays(function, args, elementwise, **kwargs)
4353
+ if len(distr.shape) == 1:
4354
+ output = evaluate_distr(distr, domain, function, args, **kwargs)
4355
+ else:
4356
+ output_size = distr.shape[1]
4357
+ output = []
4358
+ for k in range(output_size):
4359
+ function_k = lambda *args: function(args)[k]
4360
+ rval_k = evaluate_distr(distr[:,k], domain, function_k, args,
4361
+ **kwargs)
4362
+ output += [rval_k]
4363
+ args_main = np.array([arg.main for arg in args])
4364
+ with np.errstate(divide='ignore', invalid='ignore'):
4365
+ main = function(*args_main)
4366
+ output_size = np.array(main).size
4367
+ output_type = RichArray if type(main) is np.ndarray else type(main)
4368
+ if output_type is tuple and output_size > 1:
4369
+ output = tuple(output)
4370
+ elif output_type is RichArray:
4371
+ output = np.array(output).view(RichArray)
4372
+ return output
4373
+
4374
+ def distr_with_rich_arrays(function, args, elementwise=False, **kwargs):
4375
+ """
4376
+ Same as function_with_rich_arrays, but just returns the final distribution.
4377
+ """
4339
4378
  if type(args) not in (tuple, list):
4340
4379
  args = [args]
4341
4380
  args = [rich_array(arg) if type(arg) != RichArray else arg
@@ -4351,6 +4390,8 @@ def function_with_rich_arrays(function, args, elementwise=False, **kwargs):
4351
4390
  if 'len_samples' not in kwargs:
4352
4391
  kwargs['len_samples'] = int(len(args)**0.5
4353
4392
  * defaultparams['size of samples'])
4393
+ if 'consider_intervs' in kwargs:
4394
+ del kwargs['consider_intervs']
4354
4395
  if elementwise:
4355
4396
  same_shapes = True
4356
4397
  for arg in args[1:]:
@@ -4359,15 +4400,14 @@ def function_with_rich_arrays(function, args, elementwise=False, **kwargs):
4359
4400
  break
4360
4401
  if not same_shapes:
4361
4402
  raise Exception('Input arrays have different shapes.')
4362
- array = np.empty(0, RichValue)
4403
+ array = np.empty(0, float)
4363
4404
  args_flat = np.array([arg.flatten() for arg in args])
4364
4405
  for i in range(args[0].size):
4365
4406
  args_i = np.array(args_flat)[:,i].tolist()
4366
- rvalue = function_with_rich_values(function, args_i, **kwargs)
4407
+ rvalue = distr_with_rich_values(function, args_i, **kwargs)
4367
4408
  array = np.append(array, rvalue)
4368
4409
  if shape == ():
4369
4410
  array = np.array(array[0])
4370
- array = array.view(RichArray)
4371
4411
  output = array
4372
4412
  else:
4373
4413
  if type(function) is str:
@@ -4410,7 +4450,7 @@ def function_with_rich_arrays(function, args, elementwise=False, **kwargs):
4410
4450
  alt_args = []
4411
4451
  for arg in args:
4412
4452
  alt_args += list(arg.flat)
4413
- output = function_with_rich_values(alt_function, alt_args, **kwargs)
4453
+ output = distr_with_rich_values(alt_function, alt_args, **kwargs)
4414
4454
  return output
4415
4455
 
4416
4456
  def fmean(array, function='None', inverse_function='None',
@@ -4524,12 +4564,12 @@ def errorbar(x, y, lims_factor=None, **kwargs):
4524
4564
  xa, ya = rich_array(x), rich_array(y)
4525
4565
  xc = rich_array([x]) if len(xa.shape) == 0 else xa
4526
4566
  yc = rich_array([y]) if len(ya.shape) == 0 else ya
4527
- if lims_factor is None:
4528
- lims_factor_x, lims_factor_y = None, None
4529
- elif type(lims_factor) in (float, int):
4567
+ if type(lims_factor) in (float, int):
4530
4568
  lims_factor_x, lims_factor_y = [lims_factor]*2
4531
4569
  elif type(lims_factor) in (list, tuple):
4532
4570
  lims_factor_x, lims_factor_y = lims_factor
4571
+ else:
4572
+ lims_factor_x, lims_factor_y = None, None
4533
4573
  if lims_factor_x is None:
4534
4574
  lims_factor_x = lim_factor(xc)
4535
4575
  if lims_factor_y is None:
@@ -4979,6 +5019,7 @@ rich_df = rdataframe = rich_dataframe
4979
5019
  function = function_with_rich_values
4980
5020
  array_function = function_with_rich_arrays
4981
5021
  distribution = distr_with_rich_values
5022
+ array_distribution = distr_with_rich_arrays
4982
5023
  evaluate_distribution = evaluate_distr
4983
5024
  center_and_uncertainties = center_and_uncs
4984
5025
  is_not_a_number = is_nan = isnan
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: richvalues
3
- Version: 4.0.5
3
+ Version: 4.0.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
@@ -15,7 +15,7 @@ License-File: LICENSE
15
15
 
16
16
  RichValues is a Python 3 library for working with numeric values with uncertainties, upper/lower limits and finite intervals, which may be called _rich values_.
17
17
 
18
- With it, one can import rich values written in plain text documents in an easily readable format, operate with them propagating the uncertainties automatically, and export them in the same formatting style as the import. It also allows to easily plot rich values and to make fits to any function, taking into account the uncertainties and the upper/limits or finite intervals. Moreover, correlations between variables are taken into account when performing calculations with rich values.
18
+ With it, one can import rich values written in plain text documents in an easily readable format, operate with them propagating the uncertainties automatically, and export them in the same formatting style as the import. It also allows to easily plot rich values and to make fits to any function, taking into account the uncertainties and the upper/lower limits or finite intervals. Moreover, correlations between variables are taken into account when performing calculations with rich values.
19
19
 
20
20
  The libraries NumPy, Pandas, SciPy and Matplotlib are required by RichValues. A user guide and a quick tutorial are available on GitHub: https://github.com/andresmegias/richvalues/.
21
21
 
@@ -3,7 +3,6 @@ README.md
3
3
  pyproject.toml
4
4
  setup.py
5
5
  richvalues/__init__.py
6
- richvalues.egg-info/.DS_Store
7
6
  richvalues.egg-info/PKG-INFO
8
7
  richvalues.egg-info/SOURCES.txt
9
8
  richvalues.egg-info/dependency_links.txt
@@ -5,7 +5,7 @@ with open('README.md', 'r') as file:
5
5
 
6
6
  setuptools.setup(
7
7
  name = 'richvalues',
8
- version = '4.0.5',
8
+ version = '4.0.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