pyerrors 2.9.0__tar.gz → 2.11.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.
- {pyerrors-2.9.0 → pyerrors-2.11.0}/PKG-INFO +19 -2
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyerrors/__init__.py +1 -0
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyerrors/correlators.py +106 -20
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyerrors/fits.py +4 -4
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyerrors/input/hadrons.py +1 -1
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyerrors/input/openQCD.py +3 -1
- pyerrors-2.11.0/pyerrors/input/sfcf.py +659 -0
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyerrors/input/utils.py +68 -1
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyerrors/linalg.py +6 -0
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyerrors/misc.py +1 -1
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyerrors/obs.py +5 -1
- pyerrors-2.11.0/pyerrors/special.py +23 -0
- pyerrors-2.11.0/pyerrors/version.py +1 -0
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyerrors.egg-info/PKG-INFO +19 -2
- pyerrors-2.11.0/pyerrors.egg-info/SOURCES.txt +32 -0
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyerrors.egg-info/requires.txt +1 -1
- {pyerrors-2.9.0 → pyerrors-2.11.0}/setup.py +2 -1
- pyerrors-2.9.0/.github/CODEOWNERS +0 -4
- pyerrors-2.9.0/.github/ISSUE_TEMPLATE/bug-report.yml +0 -46
- pyerrors-2.9.0/.github/workflows/binder.yml +0 -15
- pyerrors-2.9.0/.github/workflows/codeql.yml +0 -39
- pyerrors-2.9.0/.github/workflows/docs.yml +0 -34
- pyerrors-2.9.0/.github/workflows/examples.yml +0 -42
- pyerrors-2.9.0/.github/workflows/flake8.yml +0 -26
- pyerrors-2.9.0/.github/workflows/pytest.yml +0 -46
- pyerrors-2.9.0/.gitignore +0 -16
- pyerrors-2.9.0/CHANGELOG.md +0 -308
- pyerrors-2.9.0/CITATION.cff +0 -42
- pyerrors-2.9.0/CONTRIBUTING.md +0 -35
- pyerrors-2.9.0/conftest.py +0 -0
- pyerrors-2.9.0/examples/01_basic_example.ipynb +0 -353
- pyerrors-2.9.0/examples/02_correlators.ipynb +0 -472
- pyerrors-2.9.0/examples/03_pcac_example.ipynb +0 -360
- pyerrors-2.9.0/examples/04_fit_example.ipynb +0 -464
- pyerrors-2.9.0/examples/05_matrix_operations.ipynb +0 -408
- pyerrors-2.9.0/examples/06_gevp.ipynb +0 -331
- pyerrors-2.9.0/examples/07_data_management.ipynb +0 -378
- pyerrors-2.9.0/examples/08_combined_fit_example.ipynb +0 -137
- pyerrors-2.9.0/examples/base_style.mplstyle +0 -30
- pyerrors-2.9.0/examples/data/correlator_test.json.gz +0 -0
- pyerrors-2.9.0/examples/data/f_A.json.gz +0 -0
- pyerrors-2.9.0/examples/data/f_P.json.gz +0 -0
- pyerrors-2.9.0/examples/data/matrix_correlator.json.gz +0 -0
- pyerrors-2.9.0/examples/data/matrix_correlator_V1V1.json.gz +0 -0
- pyerrors-2.9.0/examples/data/matrix_correlator_V2V2.json.gz +0 -0
- pyerrors-2.9.0/examples/data/matrix_correlator_V3V3.json.gz +0 -0
- pyerrors-2.9.0/examples/json_schema.json +0 -343
- pyerrors-2.9.0/pyerrors/input/sfcf.py +0 -444
- pyerrors-2.9.0/pyerrors/version.py +0 -1
- pyerrors-2.9.0/pyerrors.egg-info/SOURCES.txt +0 -97
- pyerrors-2.9.0/tests/benchmark_test.py +0 -48
- pyerrors-2.9.0/tests/correlators_test.py +0 -751
- pyerrors-2.9.0/tests/covobs_test.py +0 -110
- pyerrors-2.9.0/tests/data/compute_drho_fails.json.gz +0 -0
- pyerrors-2.9.0/tests/data/openqcd_test/ms5_xsf_T24L16r1.ms5_xsf_dd.dat +0 -0
- pyerrors-2.9.0/tests/data/openqcd_test/ms5_xsf_T24L16r2.ms5_xsf_dd.dat +0 -0
- pyerrors-2.9.0/tests/data/openqcd_test/ms5_xsf_T24L16r3.ms5_xsf_dd.dat +0 -0
- pyerrors-2.9.0/tests/data/openqcd_test/openqcd2r1.ms.dat +0 -0
- pyerrors-2.9.0/tests/data/openqcd_test/openqcd2r1.ms1.dat +0 -0
- pyerrors-2.9.0/tests/data/openqcd_test/sfqcdr1.gfms.dat +0 -0
- pyerrors-2.9.0/tests/data/openqcd_test/sfqcdr1.rwms.dat +0 -0
- pyerrors-2.9.0/tests/data/sfcf_test/broken_data_c/data_c_r0/data_c_r0_n1 +0 -472
- pyerrors-2.9.0/tests/data/sfcf_test/data_a/data_a_r0.F_V0 +0 -1150
- pyerrors-2.9.0/tests/data/sfcf_test/data_a/data_a_r0.f_1 +0 -970
- pyerrors-2.9.0/tests/data/sfcf_test/data_a/data_a_r0.f_A +0 -400
- pyerrors-2.9.0/tests/data/sfcf_test/data_c/data_c_r0/data_c_r0_n1 +0 -476
- pyerrors-2.9.0/tests/data/sfcf_test/data_o/test_r0/cfg1/F_V0 +0 -230
- pyerrors-2.9.0/tests/data/sfcf_test/data_o/test_r0/cfg1/f_1 +0 -194
- pyerrors-2.9.0/tests/data/sfcf_test/data_o/test_r0/cfg1/f_A +0 -80
- pyerrors-2.9.0/tests/data/sfcf_test/param/out.out +0 -3273
- pyerrors-2.9.0/tests/data/sfcf_test/param/parameters_a +0 -102
- pyerrors-2.9.0/tests/data/sfcf_test/param/parameters_c +0 -102
- pyerrors-2.9.0/tests/data/sfcf_test/param/parameters_o +0 -102
- pyerrors-2.9.0/tests/dirac_test.py +0 -63
- pyerrors-2.9.0/tests/fits_test.py +0 -1382
- pyerrors-2.9.0/tests/integrate_test.py +0 -51
- pyerrors-2.9.0/tests/json_io_test.py +0 -411
- pyerrors-2.9.0/tests/linalg_test.py +0 -357
- pyerrors-2.9.0/tests/misc_test.py +0 -24
- pyerrors-2.9.0/tests/mpm_test.py +0 -14
- pyerrors-2.9.0/tests/obs_test.py +0 -1335
- pyerrors-2.9.0/tests/openQCD_in_test.py +0 -209
- pyerrors-2.9.0/tests/pandas_test.py +0 -256
- pyerrors-2.9.0/tests/roots_test.py +0 -54
- pyerrors-2.9.0/tests/sfcf_in_test.py +0 -141
- pyerrors-2.9.0/tests/utils_in_test.py +0 -32
- {pyerrors-2.9.0 → pyerrors-2.11.0}/LICENSE +0 -0
- {pyerrors-2.9.0 → pyerrors-2.11.0}/README.md +0 -0
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyerrors/covobs.py +0 -0
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyerrors/dirac.py +0 -0
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyerrors/input/__init__.py +0 -0
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyerrors/input/bdio.py +0 -0
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyerrors/input/dobs.py +0 -0
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyerrors/input/json.py +0 -0
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyerrors/input/misc.py +0 -0
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyerrors/input/pandas.py +0 -0
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyerrors/integrate.py +0 -0
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyerrors/mpm.py +0 -0
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyerrors/roots.py +0 -0
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyerrors.egg-info/dependency_links.txt +0 -0
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyerrors.egg-info/top_level.txt +0 -0
- {pyerrors-2.9.0 → pyerrors-2.11.0}/pyproject.toml +0 -0
- {pyerrors-2.9.0 → pyerrors-2.11.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pyerrors
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.11.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.8
|
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.9
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
21
|
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
21
22
|
Requires-Python: >=3.8.0
|
|
22
23
|
Description-Content-Type: text/markdown
|
|
23
|
-
Provides-Extra: test
|
|
24
24
|
License-File: LICENSE
|
|
25
|
+
Requires-Dist: numpy<2,>=1.24
|
|
26
|
+
Requires-Dist: autograd>=1.6.2
|
|
27
|
+
Requires-Dist: numdifftools>=0.9.41
|
|
28
|
+
Requires-Dist: matplotlib>=3.7
|
|
29
|
+
Requires-Dist: scipy>=1.10
|
|
30
|
+
Requires-Dist: iminuit>=2.21
|
|
31
|
+
Requires-Dist: h5py>=3.8
|
|
32
|
+
Requires-Dist: lxml>=4.9
|
|
33
|
+
Requires-Dist: python-rapidjson>=1.10
|
|
34
|
+
Requires-Dist: pandas>=2.0
|
|
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
|
[](https://github.com/fjosw/pyerrors/actions/workflows/pytest.yml) [](https://www.python.org/downloads/) [](https://opensource.org/licenses/MIT) [](https://arxiv.org/abs/2209.14371) [](https://doi.org/10.1016/j.cpc.2023.108750)
|
|
27
44
|
# pyerrors
|
|
@@ -8,6 +8,7 @@ from .obs import Obs, reweight, correlate, CObs
|
|
|
8
8
|
from .misc import dump_object, _assert_equal_properties
|
|
9
9
|
from .fits import least_squares
|
|
10
10
|
from .roots import find_root
|
|
11
|
+
from . import linalg
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
class Corr:
|
|
@@ -298,7 +299,7 @@ class Corr:
|
|
|
298
299
|
transposed = [None if _check_for_none(self, G) else G.T for G in self.content]
|
|
299
300
|
return 0.5 * (Corr(transposed) + self)
|
|
300
301
|
|
|
301
|
-
def GEVP(self, t0, ts=None, sort="Eigenvalue", **kwargs):
|
|
302
|
+
def GEVP(self, t0, ts=None, sort="Eigenvalue", vector_obs=False, **kwargs):
|
|
302
303
|
r'''Solve the generalized eigenvalue problem on the correlator matrix and returns the corresponding eigenvectors.
|
|
303
304
|
|
|
304
305
|
The eigenvectors are sorted according to the descending eigenvalues, the zeroth eigenvector(s) correspond to the
|
|
@@ -317,14 +318,21 @@ class Corr:
|
|
|
317
318
|
If sort="Eigenvector" it gives a reference point for the sorting method.
|
|
318
319
|
sort : string
|
|
319
320
|
If this argument is set, a list of self.T vectors per state is returned. If it is set to None, only one vector is returned.
|
|
320
|
-
- "Eigenvalue": The eigenvector is chosen according to which eigenvalue it belongs individually on every timeslice.
|
|
321
|
+
- "Eigenvalue": The eigenvector is chosen according to which eigenvalue it belongs individually on every timeslice. (default)
|
|
321
322
|
- "Eigenvector": Use the method described in arXiv:2004.10472 to find the set of v(t) belonging to the state.
|
|
322
323
|
The reference state is identified by its eigenvalue at $t=t_s$.
|
|
324
|
+
- None: The GEVP is solved only at ts, no sorting is necessary
|
|
325
|
+
vector_obs : bool
|
|
326
|
+
If True, uncertainties are propagated in the eigenvector computation (default False).
|
|
323
327
|
|
|
324
328
|
Other Parameters
|
|
325
329
|
----------------
|
|
326
330
|
state : int
|
|
327
331
|
Returns only the vector(s) for a specified state. The lowest state is zero.
|
|
332
|
+
method : str
|
|
333
|
+
Method used to solve the GEVP.
|
|
334
|
+
- "eigh": Use scipy.linalg.eigh to solve the GEVP. (default for vector_obs=False)
|
|
335
|
+
- "cholesky": Use manually implemented solution via the Cholesky decomposition. Automatically chosen if vector_obs==True.
|
|
328
336
|
'''
|
|
329
337
|
|
|
330
338
|
if self.N == 1:
|
|
@@ -342,16 +350,34 @@ class Corr:
|
|
|
342
350
|
else:
|
|
343
351
|
symmetric_corr = self.matrix_symmetric()
|
|
344
352
|
|
|
345
|
-
|
|
346
|
-
|
|
353
|
+
def _get_mat_at_t(t, vector_obs=vector_obs):
|
|
354
|
+
if vector_obs:
|
|
355
|
+
return symmetric_corr[t]
|
|
356
|
+
else:
|
|
357
|
+
return np.vectorize(lambda x: x.value)(symmetric_corr[t])
|
|
358
|
+
G0 = _get_mat_at_t(t0)
|
|
359
|
+
|
|
360
|
+
method = kwargs.get('method', 'eigh')
|
|
361
|
+
if vector_obs:
|
|
362
|
+
chol = linalg.cholesky(G0)
|
|
363
|
+
chol_inv = linalg.inv(chol)
|
|
364
|
+
method = 'cholesky'
|
|
365
|
+
else:
|
|
366
|
+
chol = np.linalg.cholesky(_get_mat_at_t(t0, vector_obs=False)) # Check if matrix G0 is positive-semidefinite.
|
|
367
|
+
if method == 'cholesky':
|
|
368
|
+
chol_inv = np.linalg.inv(chol)
|
|
369
|
+
else:
|
|
370
|
+
chol_inv = None
|
|
347
371
|
|
|
348
372
|
if sort is None:
|
|
349
373
|
if (ts is None):
|
|
350
374
|
raise Exception("ts is required if sort=None.")
|
|
351
375
|
if (self.content[t0] is None) or (self.content[ts] is None):
|
|
352
376
|
raise Exception("Corr not defined at t0/ts.")
|
|
353
|
-
Gt =
|
|
354
|
-
reordered_vecs = _GEVP_solver(Gt, G0)
|
|
377
|
+
Gt = _get_mat_at_t(ts)
|
|
378
|
+
reordered_vecs = _GEVP_solver(Gt, G0, method=method, chol_inv=chol_inv)
|
|
379
|
+
if kwargs.get('auto_gamma', False) and vector_obs:
|
|
380
|
+
[[o.gm() for o in ev if isinstance(o, Obs)] for ev in reordered_vecs]
|
|
355
381
|
|
|
356
382
|
elif sort in ["Eigenvalue", "Eigenvector"]:
|
|
357
383
|
if sort == "Eigenvalue" and ts is not None:
|
|
@@ -359,8 +385,8 @@ class Corr:
|
|
|
359
385
|
all_vecs = [None] * (t0 + 1)
|
|
360
386
|
for t in range(t0 + 1, self.T):
|
|
361
387
|
try:
|
|
362
|
-
Gt =
|
|
363
|
-
all_vecs.append(_GEVP_solver(Gt, G0))
|
|
388
|
+
Gt = _get_mat_at_t(t)
|
|
389
|
+
all_vecs.append(_GEVP_solver(Gt, G0, method=method, chol_inv=chol_inv))
|
|
364
390
|
except Exception:
|
|
365
391
|
all_vecs.append(None)
|
|
366
392
|
if sort == "Eigenvector":
|
|
@@ -369,15 +395,17 @@ class Corr:
|
|
|
369
395
|
all_vecs = _sort_vectors(all_vecs, ts)
|
|
370
396
|
|
|
371
397
|
reordered_vecs = [[v[s] if v is not None else None for v in all_vecs] for s in range(self.N)]
|
|
398
|
+
if kwargs.get('auto_gamma', False) and vector_obs:
|
|
399
|
+
[[[o.gm() for o in evn] for evn in ev if evn is not None] for ev in reordered_vecs]
|
|
372
400
|
else:
|
|
373
|
-
raise Exception("
|
|
401
|
+
raise Exception("Unknown value for 'sort'. Choose 'Eigenvalue', 'Eigenvector' or None.")
|
|
374
402
|
|
|
375
403
|
if "state" in kwargs:
|
|
376
404
|
return reordered_vecs[kwargs.get("state")]
|
|
377
405
|
else:
|
|
378
406
|
return reordered_vecs
|
|
379
407
|
|
|
380
|
-
def Eigenvalue(self, t0, ts=None, state=0, sort="Eigenvalue"):
|
|
408
|
+
def Eigenvalue(self, t0, ts=None, state=0, sort="Eigenvalue", **kwargs):
|
|
381
409
|
"""Determines the eigenvalue of the GEVP by solving and projecting the correlator
|
|
382
410
|
|
|
383
411
|
Parameters
|
|
@@ -387,7 +415,7 @@ class Corr:
|
|
|
387
415
|
|
|
388
416
|
All other parameters are identical to the ones of Corr.GEVP.
|
|
389
417
|
"""
|
|
390
|
-
vec = self.GEVP(t0, ts=ts, sort=sort)[state]
|
|
418
|
+
vec = self.GEVP(t0, ts=ts, sort=sort, **kwargs)[state]
|
|
391
419
|
return self.projected(vec)
|
|
392
420
|
|
|
393
421
|
def Hankel(self, N, periodic=False):
|
|
@@ -1075,7 +1103,7 @@ class Corr:
|
|
|
1075
1103
|
newcontent.append(self.content[t] + y.content[t])
|
|
1076
1104
|
return Corr(newcontent)
|
|
1077
1105
|
|
|
1078
|
-
elif isinstance(y, (Obs, int, float, CObs)):
|
|
1106
|
+
elif isinstance(y, (Obs, int, float, CObs, complex)):
|
|
1079
1107
|
newcontent = []
|
|
1080
1108
|
for t in range(self.T):
|
|
1081
1109
|
if _check_for_none(self, self.content[t]):
|
|
@@ -1103,7 +1131,7 @@ class Corr:
|
|
|
1103
1131
|
newcontent.append(self.content[t] * y.content[t])
|
|
1104
1132
|
return Corr(newcontent)
|
|
1105
1133
|
|
|
1106
|
-
elif isinstance(y, (Obs, int, float, CObs)):
|
|
1134
|
+
elif isinstance(y, (Obs, int, float, CObs, complex)):
|
|
1107
1135
|
newcontent = []
|
|
1108
1136
|
for t in range(self.T):
|
|
1109
1137
|
if _check_for_none(self, self.content[t]):
|
|
@@ -1386,8 +1414,13 @@ class Corr:
|
|
|
1386
1414
|
return Corr(newcontent)
|
|
1387
1415
|
|
|
1388
1416
|
|
|
1389
|
-
def _sort_vectors(
|
|
1417
|
+
def _sort_vectors(vec_set_in, ts):
|
|
1390
1418
|
"""Helper function used to find a set of Eigenvectors consistent over all timeslices"""
|
|
1419
|
+
|
|
1420
|
+
if isinstance(vec_set_in[ts][0][0], Obs):
|
|
1421
|
+
vec_set = [anp.vectorize(lambda x: float(x))(vi) if vi is not None else vi for vi in vec_set_in]
|
|
1422
|
+
else:
|
|
1423
|
+
vec_set = vec_set_in
|
|
1391
1424
|
reference_sorting = np.array(vec_set[ts])
|
|
1392
1425
|
N = reference_sorting.shape[0]
|
|
1393
1426
|
sorted_vec_set = []
|
|
@@ -1406,9 +1439,9 @@ def _sort_vectors(vec_set, ts):
|
|
|
1406
1439
|
if current_score > best_score:
|
|
1407
1440
|
best_score = current_score
|
|
1408
1441
|
best_perm = perm
|
|
1409
|
-
sorted_vec_set.append([
|
|
1442
|
+
sorted_vec_set.append([vec_set_in[t][k] for k in best_perm])
|
|
1410
1443
|
else:
|
|
1411
|
-
sorted_vec_set.append(
|
|
1444
|
+
sorted_vec_set.append(vec_set_in[t])
|
|
1412
1445
|
|
|
1413
1446
|
return sorted_vec_set
|
|
1414
1447
|
|
|
@@ -1418,10 +1451,63 @@ def _check_for_none(corr, entry):
|
|
|
1418
1451
|
return len(list(filter(None, np.asarray(entry).flatten()))) < corr.N ** 2
|
|
1419
1452
|
|
|
1420
1453
|
|
|
1421
|
-
def _GEVP_solver(Gt, G0):
|
|
1422
|
-
"""Helper function for solving the GEVP and sorting the eigenvectors.
|
|
1454
|
+
def _GEVP_solver(Gt, G0, method='eigh', chol_inv=None):
|
|
1455
|
+
r"""Helper function for solving the GEVP and sorting the eigenvectors.
|
|
1456
|
+
|
|
1457
|
+
Solves $G(t)v_i=\lambda_i G(t_0)v_i$ and returns the eigenvectors v_i
|
|
1423
1458
|
|
|
1424
1459
|
The helper function assumes that both provided matrices are symmetric and
|
|
1425
1460
|
only processes the lower triangular part of both matrices. In case the matrices
|
|
1426
|
-
are not symmetric the upper triangular parts are effectively discarded.
|
|
1427
|
-
|
|
1461
|
+
are not symmetric the upper triangular parts are effectively discarded.
|
|
1462
|
+
|
|
1463
|
+
Parameters
|
|
1464
|
+
----------
|
|
1465
|
+
Gt : array
|
|
1466
|
+
The correlator at time t for the left hand side of the GEVP
|
|
1467
|
+
G0 : array
|
|
1468
|
+
The correlator at time t0 for the right hand side of the GEVP
|
|
1469
|
+
Method used to solve the GEVP.
|
|
1470
|
+
- "eigh": Use scipy.linalg.eigh to solve the GEVP.
|
|
1471
|
+
- "cholesky": Use manually implemented solution via the Cholesky decomposition.
|
|
1472
|
+
chol_inv : array, optional
|
|
1473
|
+
Inverse of the Cholesky decomposition of G0. May be provided to
|
|
1474
|
+
speed up the computation in the case of method=='cholesky'
|
|
1475
|
+
|
|
1476
|
+
"""
|
|
1477
|
+
if isinstance(G0[0][0], Obs):
|
|
1478
|
+
vector_obs = True
|
|
1479
|
+
else:
|
|
1480
|
+
vector_obs = False
|
|
1481
|
+
|
|
1482
|
+
if method == 'cholesky':
|
|
1483
|
+
if vector_obs:
|
|
1484
|
+
cholesky = linalg.cholesky
|
|
1485
|
+
inv = linalg.inv
|
|
1486
|
+
eigv = linalg.eigv
|
|
1487
|
+
matmul = linalg.matmul
|
|
1488
|
+
else:
|
|
1489
|
+
cholesky = np.linalg.cholesky
|
|
1490
|
+
inv = np.linalg.inv
|
|
1491
|
+
|
|
1492
|
+
def eigv(x, **kwargs):
|
|
1493
|
+
return np.linalg.eigh(x)[1]
|
|
1494
|
+
|
|
1495
|
+
def matmul(*operands):
|
|
1496
|
+
return np.linalg.multi_dot(operands)
|
|
1497
|
+
N = Gt.shape[0]
|
|
1498
|
+
output = [[] for j in range(N)]
|
|
1499
|
+
if chol_inv is None:
|
|
1500
|
+
chol = cholesky(G0) # This will automatically report if the matrix is not pos-def
|
|
1501
|
+
chol_inv = inv(chol)
|
|
1502
|
+
|
|
1503
|
+
try:
|
|
1504
|
+
new_matrix = matmul(chol_inv, Gt, chol_inv.T)
|
|
1505
|
+
ev = eigv(new_matrix)
|
|
1506
|
+
ev = matmul(chol_inv.T, ev)
|
|
1507
|
+
output = np.flip(ev, axis=1).T
|
|
1508
|
+
except (np.linalg.LinAlgError, TypeError, ValueError): # The above code can fail because of linalg-errors or because the entry of the corr is None
|
|
1509
|
+
for s in range(N):
|
|
1510
|
+
output[s] = None
|
|
1511
|
+
return output
|
|
1512
|
+
elif method == 'eigh':
|
|
1513
|
+
return scipy.linalg.eigh(Gt, G0, lower=True)[1].T[::-1]
|
|
@@ -168,12 +168,12 @@ def least_squares(x, y, func, priors=None, silent=False, **kwargs):
|
|
|
168
168
|
'''
|
|
169
169
|
output = Fit_result()
|
|
170
170
|
|
|
171
|
-
if (
|
|
171
|
+
if (isinstance(x, dict) and isinstance(y, dict) and isinstance(func, dict)):
|
|
172
172
|
xd = {key: anp.asarray(x[key]) for key in x}
|
|
173
173
|
yd = y
|
|
174
174
|
funcd = func
|
|
175
175
|
output.fit_function = func
|
|
176
|
-
elif (
|
|
176
|
+
elif (isinstance(x, dict) or isinstance(y, dict) or isinstance(func, dict)):
|
|
177
177
|
raise TypeError("All arguments have to be dictionaries in order to perform a combined fit.")
|
|
178
178
|
else:
|
|
179
179
|
x = np.asarray(x)
|
|
@@ -365,7 +365,7 @@ def least_squares(x, y, func, priors=None, silent=False, **kwargs):
|
|
|
365
365
|
raise Exception('The minimization procedure did not converge.')
|
|
366
366
|
|
|
367
367
|
output.chisquare = chisquare
|
|
368
|
-
output.dof =
|
|
368
|
+
output.dof = y_all.shape[-1] - n_parms + len(loc_priors)
|
|
369
369
|
output.p_value = 1 - scipy.stats.chi2.cdf(output.chisquare, output.dof)
|
|
370
370
|
if output.dof > 0:
|
|
371
371
|
output.chisquare_by_dof = output.chisquare / output.dof
|
|
@@ -393,7 +393,7 @@ def least_squares(x, y, func, priors=None, silent=False, **kwargs):
|
|
|
393
393
|
hat_vector = prepare_hat_matrix()
|
|
394
394
|
A = W @ hat_vector
|
|
395
395
|
P_phi = A @ np.linalg.pinv(A.T @ A) @ A.T
|
|
396
|
-
expected_chisquare = np.trace((np.identity(
|
|
396
|
+
expected_chisquare = np.trace((np.identity(y_all.shape[-1]) - P_phi) @ W @ cov @ W)
|
|
397
397
|
output.chisquare_by_expected_chisquare = output.chisquare / expected_chisquare
|
|
398
398
|
if not silent:
|
|
399
399
|
print('chisquare/expected_chisquare:', output.chisquare_by_expected_chisquare)
|
|
@@ -1286,7 +1286,9 @@ def read_ms5_xsf(path, prefix, qc, corr, sep="r", **kwargs):
|
|
|
1286
1286
|
imagsamples[repnum][t].append(corrres[1][t])
|
|
1287
1287
|
if 'idl' in kwargs:
|
|
1288
1288
|
left_idl = list(left_idl)
|
|
1289
|
-
if
|
|
1289
|
+
if expected_idl[repnum] == left_idl:
|
|
1290
|
+
raise ValueError("None of the idls searched for were found in replikum of file " + file)
|
|
1291
|
+
elif len(left_idl) > 0:
|
|
1290
1292
|
warnings.warn('Could not find idls ' + str(left_idl) + ' in replikum of file ' + file, UserWarning)
|
|
1291
1293
|
repnum += 1
|
|
1292
1294
|
s = "Read correlator " + corr + " from " + str(repnum) + " replika with idls" + str(realsamples[0][t])
|