pyerrors 2.12.0__tar.gz → 2.13.0__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.
Files changed (35) hide show
  1. {pyerrors-2.12.0 → pyerrors-2.13.0}/PKG-INFO +19 -2
  2. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors/fits.py +74 -12
  3. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors/obs.py +86 -0
  4. pyerrors-2.13.0/pyerrors/version.py +1 -0
  5. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors.egg-info/PKG-INFO +19 -2
  6. {pyerrors-2.12.0 → pyerrors-2.13.0}/setup.py +1 -0
  7. pyerrors-2.12.0/pyerrors/version.py +0 -1
  8. {pyerrors-2.12.0 → pyerrors-2.13.0}/LICENSE +0 -0
  9. {pyerrors-2.12.0 → pyerrors-2.13.0}/README.md +0 -0
  10. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors/__init__.py +0 -0
  11. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors/correlators.py +0 -0
  12. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors/covobs.py +0 -0
  13. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors/dirac.py +0 -0
  14. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors/input/__init__.py +0 -0
  15. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors/input/bdio.py +0 -0
  16. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors/input/dobs.py +0 -0
  17. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors/input/hadrons.py +0 -0
  18. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors/input/json.py +0 -0
  19. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors/input/misc.py +0 -0
  20. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors/input/openQCD.py +0 -0
  21. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors/input/pandas.py +0 -0
  22. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors/input/sfcf.py +0 -0
  23. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors/input/utils.py +0 -0
  24. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors/integrate.py +0 -0
  25. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors/linalg.py +0 -0
  26. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors/misc.py +0 -0
  27. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors/mpm.py +0 -0
  28. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors/roots.py +0 -0
  29. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors/special.py +0 -0
  30. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors.egg-info/SOURCES.txt +0 -0
  31. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors.egg-info/dependency_links.txt +0 -0
  32. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors.egg-info/requires.txt +0 -0
  33. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyerrors.egg-info/top_level.txt +0 -0
  34. {pyerrors-2.12.0 → pyerrors-2.13.0}/pyproject.toml +0 -0
  35. {pyerrors-2.12.0 → pyerrors-2.13.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyerrors
3
- Version: 2.12.0
3
+ Version: 2.13.0
4
4
  Summary: Error propagation and statistical analysis for Monte Carlo simulations
5
5
  Home-page: https://github.com/fjosw/pyerrors
6
6
  Author: Fabian Joswig
@@ -17,11 +17,28 @@ Classifier: Programming Language :: Python :: 3.9
17
17
  Classifier: Programming Language :: Python :: 3.10
18
18
  Classifier: Programming Language :: Python :: 3.11
19
19
  Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
20
21
  Classifier: Topic :: Scientific/Engineering :: Physics
21
22
  Requires-Python: >=3.9.0
22
23
  Description-Content-Type: text/markdown
23
- Provides-Extra: test
24
24
  License-File: LICENSE
25
+ Requires-Dist: numpy>=2.0
26
+ Requires-Dist: autograd>=1.7.0
27
+ Requires-Dist: numdifftools>=0.9.41
28
+ Requires-Dist: matplotlib>=3.9
29
+ Requires-Dist: scipy>=1.13
30
+ Requires-Dist: iminuit>=2.28
31
+ Requires-Dist: h5py>=3.11
32
+ Requires-Dist: lxml>=5.0
33
+ Requires-Dist: python-rapidjson>=1.20
34
+ Requires-Dist: pandas>=2.2
35
+ Provides-Extra: test
36
+ Requires-Dist: pytest; extra == "test"
37
+ Requires-Dist: pytest-cov; extra == "test"
38
+ Requires-Dist: pytest-benchmark; extra == "test"
39
+ Requires-Dist: hypothesis; extra == "test"
40
+ Requires-Dist: nbmake; extra == "test"
41
+ Requires-Dist: flake8; extra == "test"
25
42
 
26
43
  [![pytest](https://github.com/fjosw/pyerrors/actions/workflows/pytest.yml/badge.svg)](https://github.com/fjosw/pyerrors/actions/workflows/pytest.yml) [![](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![arXiv](https://img.shields.io/badge/arXiv-2209.14371-b31b1b.svg)](https://arxiv.org/abs/2209.14371) [![DOI](https://img.shields.io/badge/DOI-10.1016%2Fj.cpc.2023.108750-blue)](https://doi.org/10.1016/j.cpc.2023.108750)
27
44
  # pyerrors
@@ -14,7 +14,7 @@ from autograd import hessian as auto_hessian
14
14
  from autograd import elementwise_grad as egrad
15
15
  from numdifftools import Jacobian as num_jacobian
16
16
  from numdifftools import Hessian as num_hessian
17
- from .obs import Obs, derived_observable, covariance, cov_Obs
17
+ from .obs import Obs, derived_observable, covariance, cov_Obs, invert_corr_cov_cholesky
18
18
 
19
19
 
20
20
  class Fit_result(Sequence):
@@ -151,6 +151,14 @@ def least_squares(x, y, func, priors=None, silent=False, **kwargs):
151
151
  For details about how the covariance matrix is estimated see `pyerrors.obs.covariance`.
152
152
  In practice the correlation matrix is Cholesky decomposed and inverted (instead of the covariance matrix).
153
153
  This procedure should be numerically more stable as the correlation matrix is typically better conditioned (Jacobi preconditioning).
154
+ inv_chol_cov_matrix [array,list], optional
155
+ array: shape = (no of y values) X (no of y values)
156
+ list: for an uncombined fit: [""]
157
+ for a combined fit: list of keys belonging to the corr_matrix saved in the array, must be the same as the keys of the y dict in alphabetical order
158
+ If correlated_fit=True is set as well, can provide an inverse covariance matrix (y errors, dy_f included!) of your own choosing for a correlated fit.
159
+ The matrix must be a lower triangular matrix constructed from a Cholesky decomposition: The function invert_corr_cov_cholesky(corr, inverrdiag) can be
160
+ used to construct it from a correlation matrix (corr) and the errors dy_f of the data points (inverrdiag = np.diag(1 / np.asarray(dy_f))). For the correct
161
+ ordering the correlation matrix (corr) can be sorted via the function sort_corr(corr, kl, yd) where kl is the list of keys and yd the y dict.
154
162
  expected_chisquare : bool
155
163
  If True estimates the expected chisquare which is
156
164
  corrected by effects caused by correlated input data (default False).
@@ -165,6 +173,57 @@ def least_squares(x, y, func, priors=None, silent=False, **kwargs):
165
173
  -------
166
174
  output : Fit_result
167
175
  Parameters and information on the fitted result.
176
+ Examples
177
+ ------
178
+ >>> # Example of a correlated (correlated_fit = True, inv_chol_cov_matrix handed over) combined fit, based on a randomly generated data set
179
+ >>> import numpy as np
180
+ >>> from scipy.stats import norm
181
+ >>> from scipy.linalg import cholesky
182
+ >>> import pyerrors as pe
183
+ >>> # generating the random data set
184
+ >>> num_samples = 400
185
+ >>> N = 3
186
+ >>> x = np.arange(N)
187
+ >>> x1 = norm.rvs(size=(N, num_samples)) # generate random numbers
188
+ >>> x2 = norm.rvs(size=(N, num_samples)) # generate random numbers
189
+ >>> r = r1 = r2 = np.zeros((N, N))
190
+ >>> y = {}
191
+ >>> for i in range(N):
192
+ >>> for j in range(N):
193
+ >>> r[i, j] = np.exp(-0.8 * np.fabs(i - j)) # element in correlation matrix
194
+ >>> errl = np.sqrt([3.4, 2.5, 3.6]) # set y errors
195
+ >>> for i in range(N):
196
+ >>> for j in range(N):
197
+ >>> r[i, j] *= errl[i] * errl[j] # element in covariance matrix
198
+ >>> c = cholesky(r, lower=True)
199
+ >>> y = {'a': np.dot(c, x1), 'b': np.dot(c, x2)} # generate y data with the covariance matrix defined
200
+ >>> # random data set has been generated, now the dictionaries and the inverse covariance matrix to be handed over are built
201
+ >>> x_dict = {}
202
+ >>> y_dict = {}
203
+ >>> chol_inv_dict = {}
204
+ >>> data = []
205
+ >>> for key in y.keys():
206
+ >>> x_dict[key] = x
207
+ >>> for i in range(N):
208
+ >>> data.append(pe.Obs([[i + 1 + o for o in y[key][i]]], ['ens'])) # generate y Obs from the y data
209
+ >>> [o.gamma_method() for o in data]
210
+ >>> corr = pe.covariance(data, correlation=True)
211
+ >>> inverrdiag = np.diag(1 / np.asarray([o.dvalue for o in data]))
212
+ >>> chol_inv = pe.obs.invert_corr_cov_cholesky(corr, inverrdiag) # gives form of the inverse covariance matrix needed for the combined correlated fit below
213
+ >>> y_dict = {'a': data[:3], 'b': data[3:]}
214
+ >>> # common fit parameter p[0] in combined fit
215
+ >>> def fit1(p, x):
216
+ >>> return p[0] + p[1] * x
217
+ >>> def fit2(p, x):
218
+ >>> return p[0] + p[2] * x
219
+ >>> fitf_dict = {'a': fit1, 'b':fit2}
220
+ >>> fitp_inv_cov_combined_fit = pe.least_squares(x_dict,y_dict, fitf_dict, correlated_fit = True, inv_chol_cov_matrix = [chol_inv,['a','b']])
221
+ Fit with 3 parameters
222
+ Method: Levenberg-Marquardt
223
+ `ftol` termination condition is satisfied.
224
+ chisquare/d.o.f.: 0.5388013574561786 # random
225
+ fit parameters [1.11897846 0.96361162 0.92325319] # random
226
+
168
227
  '''
169
228
  output = Fit_result()
170
229
 
@@ -197,7 +256,7 @@ def least_squares(x, y, func, priors=None, silent=False, **kwargs):
197
256
  if sorted(list(funcd.keys())) != key_ls:
198
257
  raise ValueError('x and func dictionaries do not contain the same keys.')
199
258
 
200
- x_all = np.concatenate([np.array(xd[key]) for key in key_ls])
259
+ x_all = np.concatenate([np.array(xd[key]).transpose() for key in key_ls]).transpose()
201
260
  y_all = np.concatenate([np.array(yd[key]) for key in key_ls])
202
261
 
203
262
  y_f = [o.value for o in y_all]
@@ -297,15 +356,19 @@ def least_squares(x, y, func, priors=None, silent=False, **kwargs):
297
356
  return anp.sum(general_chisqfunc_uncorr(p, y_f, p_f) ** 2)
298
357
 
299
358
  if kwargs.get('correlated_fit') is True:
300
- corr = covariance(y_all, correlation=True, **kwargs)
301
- covdiag = np.diag(1 / np.asarray(dy_f))
302
- condn = np.linalg.cond(corr)
303
- if condn > 0.1 / np.finfo(float).eps:
304
- raise Exception(f"Cannot invert correlation matrix as its condition number exceeds machine precision ({condn:1.2e})")
305
- if condn > 1e13:
306
- warnings.warn("Correlation matrix may be ill-conditioned, condition number: {%1.2e}" % (condn), RuntimeWarning)
307
- chol = np.linalg.cholesky(corr)
308
- chol_inv = scipy.linalg.solve_triangular(chol, covdiag, lower=True)
359
+ if 'inv_chol_cov_matrix' in kwargs:
360
+ chol_inv = kwargs.get('inv_chol_cov_matrix')
361
+ if (chol_inv[0].shape[0] != len(dy_f)):
362
+ raise TypeError('The number of columns of the inverse covariance matrix handed over needs to be equal to the number of y errors.')
363
+ if (chol_inv[0].shape[0] != chol_inv[0].shape[1]):
364
+ raise TypeError('The inverse covariance matrix handed over needs to have the same number of rows as columns.')
365
+ if (chol_inv[1] != key_ls):
366
+ raise ValueError('The keys of inverse covariance matrix are not the same or do not appear in the same order as the x and y values.')
367
+ chol_inv = chol_inv[0]
368
+ else:
369
+ corr = covariance(y_all, correlation=True, **kwargs)
370
+ inverrdiag = np.diag(1 / np.asarray(dy_f))
371
+ chol_inv = invert_corr_cov_cholesky(corr, inverrdiag)
309
372
 
310
373
  def general_chisqfunc(p, ivars, pr):
311
374
  model = anp.concatenate([anp.array(funcd[key](p, xd[key])).reshape(-1) for key in key_ls])
@@ -350,7 +413,6 @@ def least_squares(x, y, func, priors=None, silent=False, **kwargs):
350
413
 
351
414
  fit_result = scipy.optimize.least_squares(chisqfunc_residuals_uncorr, x0, method='lm', ftol=1e-15, gtol=1e-15, xtol=1e-15)
352
415
  if kwargs.get('correlated_fit') is True:
353
-
354
416
  def chisqfunc_residuals(p):
355
417
  return general_chisqfunc(p, y_f, p_f)
356
418
 
@@ -1544,6 +1544,92 @@ def covariance(obs, visualize=False, correlation=False, smooth=None, **kwargs):
1544
1544
  return cov
1545
1545
 
1546
1546
 
1547
+ def invert_corr_cov_cholesky(corr, inverrdiag):
1548
+ """Constructs a lower triangular matrix `chol` via the Cholesky decomposition of the correlation matrix `corr`
1549
+ and then returns the inverse covariance matrix `chol_inv` as a lower triangular matrix by solving `chol * x = inverrdiag`.
1550
+
1551
+ Parameters
1552
+ ----------
1553
+ corr : np.ndarray
1554
+ correlation matrix
1555
+ inverrdiag : np.ndarray
1556
+ diagonal matrix, the entries are the inverse errors of the data points considered
1557
+ """
1558
+
1559
+ condn = np.linalg.cond(corr)
1560
+ if condn > 0.1 / np.finfo(float).eps:
1561
+ raise Exception(f"Cannot invert correlation matrix as its condition number exceeds machine precision ({condn:1.2e})")
1562
+ if condn > 1e13:
1563
+ warnings.warn("Correlation matrix may be ill-conditioned, condition number: {%1.2e}" % (condn), RuntimeWarning)
1564
+ chol = np.linalg.cholesky(corr)
1565
+ chol_inv = scipy.linalg.solve_triangular(chol, inverrdiag, lower=True)
1566
+
1567
+ return chol_inv
1568
+
1569
+
1570
+ def sort_corr(corr, kl, yd):
1571
+ """ Reorders a correlation matrix to match the alphabetical order of its underlying y data.
1572
+
1573
+ The ordering of the input correlation matrix `corr` is given by the list of keys `kl`.
1574
+ The input dictionary `yd` (with the same keys `kl`) must contain the corresponding y data
1575
+ that the correlation matrix is based on.
1576
+ This function sorts the list of keys `kl` alphabetically and sorts the matrix `corr`
1577
+ according to this alphabetical order such that the sorted matrix `corr_sorted` corresponds
1578
+ to the y data `yd` when arranged in an alphabetical order by its keys.
1579
+
1580
+ Parameters
1581
+ ----------
1582
+ corr : np.ndarray
1583
+ A square correlation matrix constructed using the order of the y data specified by `kl`.
1584
+ The dimensions of `corr` should match the total number of y data points in `yd` combined.
1585
+ kl : list of str
1586
+ A list of keys that denotes the order in which the y data from `yd` was used to build the
1587
+ input correlation matrix `corr`.
1588
+ yd : dict of list
1589
+ A dictionary where each key corresponds to a unique identifier, and its value is a list of
1590
+ y data points. The total number of y data points across all keys must match the dimensions
1591
+ of `corr`. The lists in the dictionary can be lists of Obs.
1592
+
1593
+ Returns
1594
+ -------
1595
+ np.ndarray
1596
+ A new, sorted correlation matrix that corresponds to the y data from `yd` when arranged alphabetically by its keys.
1597
+
1598
+ Example
1599
+ -------
1600
+ >>> import numpy as np
1601
+ >>> import pyerrors as pe
1602
+ >>> corr = np.array([[1, 0.2, 0.3], [0.2, 1, 0.4], [0.3, 0.4, 1]])
1603
+ >>> kl = ['b', 'a']
1604
+ >>> yd = {'a': [1, 2], 'b': [3]}
1605
+ >>> sorted_corr = pe.obs.sort_corr(corr, kl, yd)
1606
+ >>> print(sorted_corr)
1607
+ array([[1. , 0.3, 0.4],
1608
+ [0.3, 1. , 0.2],
1609
+ [0.4, 0.2, 1. ]])
1610
+
1611
+ """
1612
+ kl_sorted = sorted(kl)
1613
+
1614
+ posd = {}
1615
+ ofs = 0
1616
+ for ki, k in enumerate(kl):
1617
+ posd[k] = [i + ofs for i in range(len(yd[k]))]
1618
+ ofs += len(posd[k])
1619
+
1620
+ mapping = []
1621
+ for k in kl_sorted:
1622
+ for i in range(len(yd[k])):
1623
+ mapping.append(posd[k][i])
1624
+
1625
+ corr_sorted = np.zeros_like(corr)
1626
+ for i in range(corr.shape[0]):
1627
+ for j in range(corr.shape[0]):
1628
+ corr_sorted[i][j] = corr[mapping[i]][mapping[j]]
1629
+
1630
+ return corr_sorted
1631
+
1632
+
1547
1633
  def _smooth_eigenvalues(corr, E):
1548
1634
  """Eigenvalue smoothing as described in hep-lat/9412087
1549
1635
 
@@ -0,0 +1 @@
1
+ __version__ = "2.13.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyerrors
3
- Version: 2.12.0
3
+ Version: 2.13.0
4
4
  Summary: Error propagation and statistical analysis for Monte Carlo simulations
5
5
  Home-page: https://github.com/fjosw/pyerrors
6
6
  Author: Fabian Joswig
@@ -17,11 +17,28 @@ Classifier: Programming Language :: Python :: 3.9
17
17
  Classifier: Programming Language :: Python :: 3.10
18
18
  Classifier: Programming Language :: Python :: 3.11
19
19
  Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
20
21
  Classifier: Topic :: Scientific/Engineering :: Physics
21
22
  Requires-Python: >=3.9.0
22
23
  Description-Content-Type: text/markdown
23
- Provides-Extra: test
24
24
  License-File: LICENSE
25
+ Requires-Dist: numpy>=2.0
26
+ Requires-Dist: autograd>=1.7.0
27
+ Requires-Dist: numdifftools>=0.9.41
28
+ Requires-Dist: matplotlib>=3.9
29
+ Requires-Dist: scipy>=1.13
30
+ Requires-Dist: iminuit>=2.28
31
+ Requires-Dist: h5py>=3.11
32
+ Requires-Dist: lxml>=5.0
33
+ Requires-Dist: python-rapidjson>=1.20
34
+ Requires-Dist: pandas>=2.2
35
+ Provides-Extra: test
36
+ Requires-Dist: pytest; extra == "test"
37
+ Requires-Dist: pytest-cov; extra == "test"
38
+ Requires-Dist: pytest-benchmark; extra == "test"
39
+ Requires-Dist: hypothesis; extra == "test"
40
+ Requires-Dist: nbmake; extra == "test"
41
+ Requires-Dist: flake8; extra == "test"
25
42
 
26
43
  [![pytest](https://github.com/fjosw/pyerrors/actions/workflows/pytest.yml/badge.svg)](https://github.com/fjosw/pyerrors/actions/workflows/pytest.yml) [![](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![arXiv](https://img.shields.io/badge/arXiv-2209.14371-b31b1b.svg)](https://arxiv.org/abs/2209.14371) [![DOI](https://img.shields.io/badge/DOI-10.1016%2Fj.cpc.2023.108750-blue)](https://doi.org/10.1016/j.cpc.2023.108750)
27
44
  # pyerrors
@@ -36,6 +36,7 @@ setup(name='pyerrors',
36
36
  'Programming Language :: Python :: 3.10',
37
37
  'Programming Language :: Python :: 3.11',
38
38
  'Programming Language :: Python :: 3.12',
39
+ 'Programming Language :: Python :: 3.13',
39
40
  'Topic :: Scientific/Engineering :: Physics'
40
41
  ],
41
42
  )
@@ -1 +0,0 @@
1
- __version__ = "2.12.0"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes