diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 5e6baf48..c0649da6 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,5 +2,3 @@ /pyerrors/covobs.py @s-kuberski /pyerrors/input/json.py @s-kuberski /pyerrors/input/dobs.py @s-kuberski -/pyerrors/input/sfcf.py @jkuhl-uni -/tests/sfcf_in_test.py @jkuhl-uni diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000..33f1b1ee --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,39 @@ +name: "CodeQL" + +on: + push: + branches: + - master + - develop + pull_request: + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'python' ] + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 03ca7c23..9b204da6 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -11,10 +11,10 @@ jobs: steps: - name: Set up Python environment - uses: actions/setup-python@v5 + uses: actions/setup-python@v4 with: python-version: "3.10" - - uses: actions/checkout@v4 + - uses: actions/checkout@v3 - name: Updated documentation run: | git config --global user.email "${{ github.actor }}@users.noreply.github.com" diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index 51322b2c..473e77d0 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -6,7 +6,6 @@ on: - master - develop pull_request: - workflow_dispatch: schedule: - cron: '0 4 1 * *' @@ -17,27 +16,27 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python-version: ["3.10", "3.12"] + python-version: ["3.8", "3.10"] steps: - name: Checkout source - uses: actions/checkout@v4 + uses: actions/checkout@v3 - name: Setup python - uses: actions/setup-python@v5 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - - name: uv - uses: astral-sh/setup-uv@v5 - name: Install run: | sudo apt-get update sudo apt-get install dvipng texlive-latex-extra texlive-fonts-recommended cm-super - uv pip install wheel --system - uv pip install . --system - uv pip install pytest nbmake --system - uv pip install -U matplotlib!=3.7.0 --system # Exclude version 3.7.0 of matplotlib as this breaks local imports of style files. + python -m pip install --upgrade pip + pip install wheel + pip install . + pip install pytest + pip install nbmake + pip install -U matplotlib!=3.7.0 # Exclude version 3.7.0 of matplotlib as this breaks local imports of style files. - name: Run tests run: pytest -vv --nbmake examples/*.ipynb diff --git a/.github/workflows/flake8.yml b/.github/workflows/flake8.yml index c6625b37..d931f241 100644 --- a/.github/workflows/flake8.yml +++ b/.github/workflows/flake8.yml @@ -13,9 +13,9 @@ jobs: name: Lint steps: - name: Check out source repository - uses: actions/checkout@v4 + uses: actions/checkout@v3 - name: Set up Python environment - uses: actions/setup-python@v5 + uses: actions/setup-python@v4 with: python-version: "3.10" - name: flake8 Lint diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index af98e210..d4abcfc3 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -6,7 +6,6 @@ on: - master - develop pull_request: - workflow_dispatch: schedule: - cron: '0 4 1 * *' @@ -17,30 +16,31 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.8", "3.9", "3.10", "3.11"] include: - os: macos-latest - python-version: "3.12" - - os: ubuntu-24.04-arm - python-version: "3.12" + python-version: "3.10" steps: - name: Checkout source - uses: actions/checkout@v4 + uses: actions/checkout@v3 - name: Setup python - uses: actions/setup-python@v5 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - - name: uv - uses: astral-sh/setup-uv@v5 - name: Install run: | - uv pip install wheel --system - uv pip install . --system - uv pip install pytest pytest-cov pytest-benchmark hypothesis --system - uv pip freeze --system + python -m pip install --upgrade pip + pip install wheel + pip install . + pip install pytest + pip install pytest-cov + pip install pytest-benchmark + pip install hypothesis + pip install py + pip freeze - name: Run tests run: pytest --cov=pyerrors -vv -Werror diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 2548255f..00000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: Release - -on: - workflow_dispatch: - release: - types: [published] - -jobs: - build: - name: Build sdist and wheel - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - name: Checkout repository - - - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install pypa/build - run: >- - python3 -m - pip install - build - --user - - - name: Build wheel and source tarball - run: python3 -m build - - - name: Upload artifacts - uses: actions/upload-artifact@v4 - with: - name: python-package-distributions - path: dist/ - if-no-files-found: error - - publish: - needs: [build] - name: Upload to PyPI - runs-on: ubuntu-latest - environment: - name: pypi - url: https://pypi.org/p/pyerrors - permissions: - id-token: write - - steps: - - name: Download artifacts - uses: actions/download-artifact@v4 - with: - name: python-package-distributions - path: dist/ - - - name: Sanity check - run: ls -la dist/ - - - name: Publish to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.github/workflows/ruff.yml b/.github/workflows/ruff.yml deleted file mode 100644 index 2288bd3c..00000000 --- a/.github/workflows/ruff.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: ruff -on: - push: - branches: - - master - - develop - pull_request: -jobs: - ruff: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: astral-sh/ruff-action@v2 - with: - src: "./pyerrors" diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a61e766..006888a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,64 +2,6 @@ All notable changes to this project will be documented in this file. -## [2.14.0] - 2025-03-09 - -### Added -- Explicit checks of the provided inverse matrix for correlated fits #259 - -### Changed -- Compute derivative for pow explicitly instead of relying on autograd. This results in a ~4x speedup for pow operations #246 -- More explicit exception types #248 - -### Fixed -- Removed the possibility to create an Obs from data on several replica #258 -- Fix range in `set_prange` #247 -- Fix ensemble name handling in sfcf input modules #253 -- Correct error message for fit shape mismatch #257 - -## [2.13.0] - 2024-11-03 - -### Added -- Allow providing lower triangular matrix constructed from a Cholesky decomposition in least squares function for correlated fits. - -### Fixed -- Corrected bug that prevented combined fits with multiple x-obs in some cases. - -## [2.12.0] - 2024-08-22 - -### Changed -- Support for numpy 2 was added via a new autograd release -- Support for python<3.9 was dropped and dependencies were updated. - -### Fixed -- Minor bug fixes in input.sfcf - - -## [2.11.1] - 2024-04-25 - -### Fixed -- Fixed a bug in error computation when combining two Obs from the same ensemble and fluctuations on one replicum are not part of one of the Obs. - - -## [2.11.0] - 2024-04-01 -### Added -- New special function module. - -### Fixed -- Various bug fixes in input module. - -## [2.10.0] - 2023-11-24 -### Added -- More efficient implementation of read_sfcf -- added support for addition and multiplication of complex numbers to Corr objects -- the Corr.GEVP method can now also propagate the errors for the eigenvectors - -### Fixed -- Fixed bug in combined fit with multiple independent variables -- Check for invalid set of configuration numbers added when initializing an Obs object. -- Fixed a bug in hadrons.read_hdf5 - - ## [2.9.0] - 2023-07-20 ### Added - Vectorized `gamma_method` added which can be applied to lists or arrays of pyerrors objects. diff --git a/README.md b/README.md index 7937da4d..93afe409 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![](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) +[![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.8+-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) # pyerrors `pyerrors` is a python framework for error computation and propagation of Markov chain Monte Carlo data from lattice field theory and statistical mechanics simulations. @@ -14,6 +14,11 @@ Install the most recent release using pip and [pypi](https://pypi.org/project/py python -m pip install pyerrors # Fresh install python -m pip install -U pyerrors # Update ``` +Install the most recent release using conda and [conda-forge](https://anaconda.org/conda-forge/pyerrors): +```bash +conda install -c conda-forge pyerrors # Fresh install +conda update -c conda-forge pyerrors # Update +``` ## Contributing We appreciate all contributions to the code, the documentation and the examples. If you want to get involved please have a look at our [contribution guideline](https://github.com/fjosw/pyerrors/blob/develop/CONTRIBUTING.md). diff --git a/examples/01_basic_example.ipynb b/examples/01_basic_example.ipynb index 52fa35f0..1fe60b4d 100644 --- a/examples/01_basic_example.ipynb +++ b/examples/01_basic_example.ipynb @@ -34,7 +34,7 @@ "source": [ "plt.style.use('./base_style.mplstyle')\n", "import shutil\n", - "usetex = shutil.which('latex') not in ('', None)\n", + "usetex = shutil.which('latex') != ''\n", "plt.rc('text', usetex=usetex)" ] }, diff --git a/examples/02_correlators.ipynb b/examples/02_correlators.ipynb index 6f396ff7..b86cb5b9 100644 --- a/examples/02_correlators.ipynb +++ b/examples/02_correlators.ipynb @@ -22,7 +22,7 @@ "source": [ "plt.style.use('./base_style.mplstyle')\n", "import shutil\n", - "usetex = shutil.which('latex') not in ('', None)\n", + "usetex = shutil.which('latex') != ''\n", "plt.rc('text', usetex=usetex)" ] }, diff --git a/examples/03_pcac_example.ipynb b/examples/03_pcac_example.ipynb index 3fc38020..87d081be 100644 --- a/examples/03_pcac_example.ipynb +++ b/examples/03_pcac_example.ipynb @@ -20,7 +20,7 @@ "source": [ "plt.style.use('./base_style.mplstyle')\n", "import shutil\n", - "usetex = shutil.which('latex') not in ('', None)\n", + "usetex = shutil.which('latex') != ''\n", "plt.rc('text', usetex=usetex)" ] }, diff --git a/examples/04_fit_example.ipynb b/examples/04_fit_example.ipynb index e8f3e7af..868de9bf 100644 --- a/examples/04_fit_example.ipynb +++ b/examples/04_fit_example.ipynb @@ -9,10 +9,7 @@ "import numpy as np\n", "import matplotlib\n", "import matplotlib.pyplot as plt\n", - "import pyerrors as pe\n", - "import scipy.optimize\n", - "from scipy.linalg import cholesky\n", - "from scipy.stats import norm" + "import pyerrors as pe" ] }, { @@ -23,7 +20,7 @@ "source": [ "plt.style.use('./base_style.mplstyle')\n", "import shutil\n", - "usetex = shutil.which('latex') not in ('', None)\n", + "usetex = shutil.which('latex') != ''\n", "plt.rc('text', usetex=usetex)" ] }, @@ -60,7 +57,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We can now define a custom fit function, in this case a single exponential. __Here we need to use the autograd wrapped version of np__ (imported as anp) to use automatic differentiation." + "We can now define a custom fit function, in this case a single exponential. __Here we need to use the autograd wrapped version of numpy__ (imported as anp) to use automatic differentiation." ] }, { @@ -94,8 +91,7 @@ "Fit with 2 parameters\n", "Method: Levenberg-Marquardt\n", "`xtol` termination condition is satisfied.\n", - "chisquare/d.o.f.: 0.0023324250917750268\n", - "fit parameters [ 0.20362603 16.25660947]\n", + "chisquare/d.o.f.: 0.0023324250917749687\n", "\n", " Goodness of fit:\n", "χ²/d.o.f. = 0.002332\n", @@ -108,12 +104,14 @@ }, { "data": { - "image/png": "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YPXq1Wzfvr3FtjFjxpCVlcXmzZt5/fXXW2wbOnQo4XCY0aNHt/tzhUIh0tPT+ec//9ni9iOOOILDDz+caDTaKnwMHjyYSZMmAfDCCy+0Ci4TJ05kyJAhbNiwgS1btrTYNnLkSI488kjeeeedFn81ABgwYADHHXccAP/617/YtWtXi+25ubkMGzaMN954g02bNrXYlpWVxZgxY9i+fTurV69u9TOeeOKJANx1110UFxe3eDP54Q9/yO233855553Hm2++2WLf4cOHM378eHbu3MmqVata/f6OP/54UlNTiUQibNu2rcW2o446ihEjRrBlyxY2bNjQYtuQIUOYOHEiQKvfPcCkSZMYPHgwr732GnV1dS225eTkMGrUKLZu3cratWtbbBs0aBDHHnssAC+99FKrcbrhcJihQ4dSUlLCN77xjTZ/DxdddNF+f4evvPJKi+MaYNy4cWRkZLBx40beeuutFtvS09M5+uij2bFjBy+//HKrn/WEE04gJSWF6upq3n333RbbRo8eTXZ2NrW1tdTU1LTYdthhhzFhwgQaGxt58cUXWz3usccey6BBg1i3bl38/16TUaNG7TdENYWs/R3fNTU11NbWttg2YsQIjjrqKLZt29bqNSM1NZXjjz8egJdffpkdO3a02D5+/HiGDx/OW2+9xcaNG1ts6+7XiOLiYr7yla+0GtteVFREbm4ua9euZevWrS327WuvEfv78NHY2Mill17K22+/3edfI0KhULth88tf/jKnnHIKRxxxRJ9/jdhf2ATiYbOvv0b861//arc50djYyLp16wD6xWvEiy++yM033wzQ4n3zxhtv5KqrriIzM7PHXiP2vV+7Yp30ne98Z7/bH3rooc4+dIdUVFTE2io/HA7HSkpK2tzna1/7Wgw44OXiiy+O1dTUxJ5++uk2t9fU1MRqampieXl5rbbdddddsZqamti3vvWtVtvOPvvsWE1NTexPf/pTu8+dkpISO/PMM1vd/tWvfjVWU1MTu+eee1ptO/HEE+M1DRo0qNX2pUuXxmpqamKXXXZZq23XXXddrKamJlZWVtZq2xFHHBF/3COOOKLV9rKyslhNTU3suuuua7Xtsssui9XU1MSWLl3aatugQYNiNTU1saeeemq/v4e2Hjc/Pz9WU1MTW7lyZZv7rVq1KlZTUxM7++yzW2371re+FaupqYnddddd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", + "image/png": "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wKJFi2oElyFDhtClSxdWrFjB2rVrq+zr3bs3+++/Pxs3bmTp0qr/OTt06MAhhxwCwL///W927NhRZf+gQYPo1q0b77zzDqtWraqyr0ePHvTr14/NmzezePHiGn/H4cOHA3DHHXcwderUKh8mP/7xj7n55pv5yEc+wrvvvlvlsd27d2fgwIFs376dV199tcbv79BDDyU3N5eSkhI2bdpUZd8BBxxAr169WLt2LStWrKiyr0uXLgwZMgSgxu8eYOjQoXTu3Jm33nqLdeuqLsZaVFREnz592LBhA8uWLauyr1OnThx00EEAvPLKKzXm6RYXF9O1a1emTZvGd77znVp/D+ecc84ef4evv/46W7durbJ/wIABFBQUsHLlSt57770q+/Lz8znwwAPZtm0br732Wo2/62GHHUZOTg5Llizhgw8+qLKvb9++9OzZkzVr1lBaWlpl3z777MPgwYMpLy/n5ZdfrnHegw46iE6dOvHmm2+yfn3VKW99+vTZY4iqCFl7en2XlpayZs2aKvt69erFAQccwKZNmygpKamyLzc3l0MPPRSA1157jW3btlXZP3DgQLp37857773HypUrq+xr7veIqVOn8o1vfKPG3PYpU6YwaNAgli1bxoYNG6o8tq29R+zpy0d5eTkXXngh77//fpt/jwgh1Bk2v/71r3PMMcew3377tfn3iD2FTWBX2Gzr7xH//ve/6xycKC8v58033wRoF+8RL7/8Mtdem8x8rvy5ec0113D55ZdTWFjYIu8ROTk55OXl1ThPrWKMDboB1+5l/3kNPXeazz8mKb/G9iXAxDoe8y0g7u123nnnxdLS0vj000/Xur+0tDSWlpbGESNG1Nh3xx13xNLS0vi9732vxr5TTjkllpaWxkcffbTO587JyYknnnhije3f/OY3Y2lpabz77rtr7Bs+fPiumjp16lRj/9y5c2NpaWm86KKLauy76qqrYmlpaZw5c2aNffvtt9+u8+6333419s+cOTOWlpbGq666qsa+iy66KJaWlsa5c+fW2NepU6dYWloan3rqqT3+Hmo779ixY2NpaWl88cUXa33cq6++GktLS+Mpp5xSY9/3vve9WFpaGu+4444a+0aMGLHr71rbeZ9++ulYWloazzvvvBr7vva1r8XS0tJ433331dg3cODAXeft2bNnjf0PP/zwXn8P99xzT43t3bp1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", "text/plain": [ "
" ] }, - "metadata": {}, + "metadata": { + "needs_background": "light" + }, "output_type": "display_data" } ], @@ -142,8 +140,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "Covariance: 0.009831165600263978\n", - "Normalized covariance: 0.8384671240792649\n" + "Covariance: 0.009831165592706342\n", + "Normalized covariance: 0.8384671239654656\n" ] } ], @@ -193,11 +191,10 @@ "name": "stdout", "output_type": "stream", "text": [ - "Fit with 1 parameter\n", + "Fit with 1 parameters\n", "Method: Levenberg-Marquardt\n", "`ftol` termination condition is satisfied.\n", - "chisquare/d.o.f.: 0.13241808096938082\n", - "fit parameters [0.20567587]\n", + "chisquare/d.o.f.: 0.13241808096937788\n", "\n", "Effective mass:\t 0.2057(68)\n", "Fitted mass:\t 0.2036(92)\n" @@ -227,12 +224,14 @@ "outputs": [ { "data": { - "image/png": "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", + "image/png": "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", "text/plain": [ "
" ] }, - "metadata": {}, + "metadata": { + "needs_background": "light" + }, "output_type": "display_data" } ], @@ -263,11 +262,11 @@ "name": "stdout", "output_type": "stream", "text": [ - "(Obs[-0.47(35)], Obs[-0.26(25)])\n", - "(Obs[2.44(35)], Obs[1.15(25)])\n", - "(Obs[3.68(35)], Obs[-1.23(25)])\n", - "(Obs[6.50(35)], Obs[-1.86(25)])\n", - "(Obs[7.91(35)], Obs[-0.32(25)])\n" + "(Obs[0.53(35)], Obs[0.38(25)])\n", + "(Obs[1.73(35)], Obs[0.59(25)])\n", + "(Obs[3.92(35)], Obs[-1.23(25)])\n", + "(Obs[5.73(35)], Obs[-1.18(25)])\n", + "(Obs[7.74(35)], Obs[-0.40(25)])\n" ] } ], @@ -319,10 +318,10 @@ "Fit with 3 parameters\n", "Method: ODR\n", "Sum of squares convergence\n", - "Residual variance: 0.49296554803718634\n", - "Parameter 1 : 0.72(56)\n", - "Parameter 2 : -0.43(16)\n", - "Parameter 3 : 2.33(84)\n" + "Residual variance: 0.08780824312692749\n", + "Parameter 1 : 0.06(25)\n", + "Parameter 2 : -0.160(47)\n", + "Parameter 3 : 0.80(18)\n" ] } ], @@ -348,12 +347,14 @@ "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkIAAAFyCAYAAAAZNbUwAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAAA8TklEQVR4nO3deXxU1eH+8c8kQMKSSUAICgYlLCqyGUTcRSFS61LUAEXcaiVoFxTaLyntr7W2tdG0RUWrgq07IhBc0aoJCu4IRBTcWIZNEIKEyQQkgSTz++OaYDDLJMydM3Pv83698kommeQ+hjjzzLnnnuMJBoNBRERERFwoznQAEREREVNUhERERMS1VIRERETEtVSERERExLVUhERERMS1VIRERETEtVSERERExLVamQ7QlOrqarZv305SUhIej8d0HBEREYkBwWCQsrIyunXrRlxcw+M+UV+Etm/fTlpamukYIiIiEoO2bt3Kscce2+DXo74IJSUlAdZ/iNfrNZxGREREYkEgECAtLa22RzQk6otQzekwr9erIiQiIiLN0tS0Gk2WFhEREddSERIRERHXUhESERER11IREhEREddSERIRERHXUhESERER11IREhEREddSERIRERHXUhESERER11IREhEREddSERIRERHXivq9xkRsU10Nu9fD16ugbUfokwml26DwNmjdDpLT4Kh0OHao9XET+9WIiEjsURES99n+ESz/L3z5Cny72/rc0IlWEao6AGU7oKIMvlhkfT3BCzmbwBMPJRuhU0+j8UVEJHxUhMQdKvbC/hJI6QElPtjyPpxyDfQ6H44ZZI0IgVVyrl906Pv27rLuHxcP5QH492nQ7RQ4czKc8GOI09llEZFY5gkGg0HTIRoTCARITk6mtLQUr9drOo7EmqqDUPQ4LLkT0obBT+dYp8Q8nuaf6qqqhHWvwXv3WUWqWwZclAdpQ+3JLiIiLRZqf9DLWXGubSth1rnw8m+h90j40Z3W5+PiWjbfJ74VnHgx3PAqXP8KVFfCW/8Ib2YREYkonRoTZyoPwBOjrVNdk5Zap7/C6fizIHsJlJdatze+DXGt4LgzwnscERGxlYqQOEtguzXfJ9EL174ARw+0RnLsEBcP7TpZHy9/GD5fBKP+DsMm6QozEZEYoVNj4hyb3oWHzoY377Bud8+wrwQd7spH4PSb4dUceGky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", + "image/png": "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", "text/plain": [ "
" ] }, - "metadata": {}, + "metadata": { + "needs_background": "light" + }, "output_type": "display_data" } ], @@ -392,7 +393,7 @@ }, { "data": { - "image/png": "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", + "image/png": "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", "text/plain": [ "
" ] @@ -402,7 +403,7 @@ }, { "data": { - "image/png": "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", + "image/png": "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", "text/plain": [ "
" ] @@ -412,7 +413,7 @@ }, { "data": { - "image/png": "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", + "image/png": "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", "text/plain": [ "
" ] @@ -428,276 +429,12 @@ " print()" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Correlated fits with a covariance of your own choosing" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "##### generate a random data set" - ] - }, { "cell_type": "code", - "execution_count": 15, - "metadata": { - "tags": [] - }, + "execution_count": null, + "metadata": {}, "outputs": [], - "source": [ - "def fitf(p, x):\n", - " return p[1] * anp.exp(-p[0] * x)\n", - "\n", - "num_samples = 400\n", - "N = 10\n", - "x_random = norm.rvs(size=(N, num_samples)) # generate random numbers\n", - "\n", - "r = np.zeros((N, N))\n", - "for i in range(N):\n", - " for j in range(N):\n", - " r[i, j] = np.exp(-0.8 * np.fabs(i - j)) # element in correlation matrix\n", - "\n", - "errl = np.sqrt([10.0, 2.5, 25.0, 2.8, 4.2, 4.7, 4.9, 5.1, 3.2, 4.2]) # set y errors\n", - "for i in range(N):\n", - " for j in range(N):\n", - " r[i, j] *= errl[i] * errl[j] # element in covariance matrix\n", - "\n", - "c = cholesky(r, lower=True)\n", - "y = np.dot(c, x_random)\n", - "x = np.arange(N)\n", - "\n", - "\n", - "data = []\n", - "for i in range(N):\n", - " data.append(pe.Obs([[np.exp(-(i + 1)) + np.exp(-(i + 1)) * o for o in y[i]]], ['ens']))\n", - "\n", - "data[2] = data[2]+0.05\n", - "\n", - "[o.gamma_method() for o in data]\n", - "\n", - "corr = pe.covariance(data, correlation=True)\n", - "covdiag = np.diag(1 / np.asarray([o.dvalue for o in data]))\n", - "\n", - "chol_inv = pe.obs.invert_corr_cov_cholesky(corr,covdiag)\n", - "chol_inv_keys = [\"\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.matshow(corr, vmin=-1, vmax=1)\n", - "plt.title('The full correlation matrix')\n", - "plt.set_cmap('RdBu')\n", - "plt.colorbar()\n", - "plt.draw()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### generate a block diagonal covariance matrix" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "e=0\n", - "block_diag_corr_matrix = np.zeros((N,N))\n", - "for k in range(3):\n", - " if(k==0):\n", - " step = 4\n", - " block = pe.covariance(data[:4],correlation=True)\n", - " else:\n", - " step = 3\n", - " block = pe.covariance(data[:3],correlation=True) \n", - " block_diag_corr_matrix[e:e+step,e:e+step] += block\n", - " e+=step\n", - "\n", - "block_diag_chol_inv = pe.obs.invert_corr_cov_cholesky(block_diag_corr_matrix,covdiag)" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.matshow(block_diag_corr_matrix, vmin=-1, vmax=1)\n", - "plt.title('A block diagonal correlation matrix')\n", - "plt.set_cmap('RdBu')\n", - "plt.colorbar()\n", - "plt.draw()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "#### perform a fully correlated fit and a fit with a block diagonal covariance matrix" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Fit with 2 parameters\n", - "Method: Levenberg-Marquardt\n", - "`ftol` termination condition is satisfied.\n", - "chisquare/d.o.f.: 2.3597637233070254\n", - "fit parameters [0.9754457 0.28547338]\n", - "Fit with 2 parameters\n", - "inv_chol_cov_matrix handed over as kwargs.\n", - "Method: Levenberg-Marquardt\n", - "`ftol` termination condition is satisfied.\n", - "chisquare/d.o.f.: 2.3217921000302923\n", - "fit parameters [0.9766841 0.2933594]\n" - ] - } - ], - "source": [ - "fitpc = pe.least_squares(x, data, fitf, correlated_fit=True)\n", - "fitp_inv_block_diag_cov = pe.least_squares(x, data, fitf, correlated_fit = True, inv_chol_cov_matrix = [block_diag_chol_inv,chol_inv_keys])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### generate a block diagonal covariance matrix with modified weights for particular data points + perform the fit again" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Fit with 2 parameters\n", - "inv_chol_cov_matrix handed over as kwargs.\n", - "Method: Levenberg-Marquardt\n", - "`ftol` termination condition is satisfied.\n", - "chisquare/d.o.f.: 0.3401961132842267\n", - "fit parameters [0.99320618 0.33488345]\n" - ] - } - ], - "source": [ - "covdiag[2][2] = covdiag[2][2]/100. # weight the third data point less\n", - "block_diag_chol_inv_weighted = pe.obs.invert_corr_cov_cholesky(block_diag_corr_matrix,covdiag)\n", - "\n", - "fitp_inv_block_diag_cov_weighted = pe.least_squares(x, data, fitf, correlated_fit = True, inv_chol_cov_matrix = [block_diag_chol_inv_weighted,chol_inv_keys])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### compare the fully correlated fit to those with block-diagonal covariance matrices (and modified weights)" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "x_fit = np.arange(min(x) - 1, max(x)+ 1, 0.01)\n", - "y_fit_correlated = fitf([o.value for o in fitpc.fit_parameters], x_fit)\n", - "y_fit = fitf([o.value for o in fitp_inv_block_diag_cov.fit_parameters], x_fit)\n", - "y_fit_weighted = fitf([o.value for o in fitp_inv_block_diag_cov_weighted.fit_parameters], x_fit)\n", - "\n", - "plt.figure()\n", - "plt.errorbar(x,data,yerr=[o.dvalue for o in data])\n", - "plt.plot(x_fit, y_fit_correlated, '--',label = '$\\chi^2/\\mathrm{d.o.f.}$=' + str(round(fitpc.chisquare/fitpc.dof,2)) +': fully correlated')\n", - "plt.plot(x_fit, y_fit, '--',label = '$\\chi^2/\\mathrm{d.o.f.}$=' + str(round(fitp_inv_block_diag_cov.chisquare/fitp_inv_block_diag_cov.dof,2)) +': block-diag. cov matrix')\n", - "plt.plot(x_fit, y_fit_weighted, '--',label = '$\\chi^2/\\mathrm{d.o.f.}$=' +str(round(fitp_inv_block_diag_cov_weighted.chisquare/fitp_inv_block_diag_cov_weighted.dof,2)) + \n", - " ': block-diag. cov matrix + reduced weight 2. point')\n", - "plt.xlim(-0.5,10.0)\n", - "plt.ylim(-0.1,0.6)\n", - "plt.legend(fontsize=11)\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- the fully correlated fit vs. the fit with a block diagonal covariance matrix\n", - " - the fits do not differ significantly $\\rightarrow$ the block diagonal covariance matrix can be a good estimator \n", - " (if a large fraction of the off-diagonal elements are small)\\\n", - " $\\rightarrow$ sparser matrices can be more easily/cheaply inverted/saved \n", - "- the fit with a block diagonal covariance matrix vs. the fit with \" and a decreased weight for the third data point\n", - " - the $\\chi^2/\\mathrm{d.o.f.}$ improves - decreasing/increasing the weights can be used for points that are known to be less/more 'trustworthy'" - ] + "source": [] } ], "metadata": { @@ -719,7 +456,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.13" + "version": "3.8.10" } }, "nbformat": 4, diff --git a/examples/05_matrix_operations.ipynb b/examples/05_matrix_operations.ipynb index 0cd85534..1f08951b 100644 --- a/examples/05_matrix_operations.ipynb +++ b/examples/05_matrix_operations.ipynb @@ -190,7 +190,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "[7.2(1.7) -1.00(46)]\n" + "[7.2(1.7) -1.00(45)]\n" ] } ], @@ -243,7 +243,7 @@ "output_type": "stream", "text": [ "[[2.025(49) 0.0]\n", - " [-0.494(51) 0.870(29)]]\n" + " [-0.494(50) 0.870(29)]]\n" ] } ], @@ -296,7 +296,7 @@ "output_type": "stream", "text": [ "[[0.494(12) 0.0]\n", - " [0.280(40) 1.150(39)]]\n", + " [0.280(40) 1.150(38)]]\n", "Check:\n", "[[1.0 0.0]\n", " [0.0 1.0]]\n" @@ -330,10 +330,10 @@ "output_type": "stream", "text": [ "Eigenvalues:\n", - "[0.705(57) 4.39(19)]\n", + "[0.705(56) 4.39(20)]\n", "Eigenvectors:\n", - "[[-0.283(26) -0.9592(76)]\n", - " [-0.9592(76) 0.283(26)]]\n" + "[[-0.283(26) -0.9592(75)]\n", + " [-0.9592(75) 0.283(26)]]\n" ] } ], @@ -363,13 +363,17 @@ "name": "stdout", "output_type": "stream", "text": [ - "[[ True True]\n", - " [ True True]]\n" + "Check eigenvector 1\n", + "[-5.551115123125783e-17 0.0]\n", + "Check eigenvector 2\n", + "[0.0 -2.220446049250313e-16]\n" ] } ], "source": [ - "print(matrix @ v == e * v)" + "for i in range(2):\n", + " print('Check eigenvector', i + 1)\n", + " print(matrix @ v[:, i] - v[:, i] * e[i])" ] }, { diff --git a/examples/06_gevp.ipynb b/examples/06_gevp.ipynb index 3de14d5e..867237bb 100644 --- a/examples/06_gevp.ipynb +++ b/examples/06_gevp.ipynb @@ -21,7 +21,7 @@ "source": [ "plt.style.use('./base_style.mplstyle')\n", "import shutil\n", - "usetex = shutil.which('latex') not in ('', None)\n", + "usetex = shutil.which('latex') != ''\n", "plt.rc('text', usetex=usetex)" ] }, @@ -151,7 +151,7 @@ "\n", "$$C_{\\textrm{projected}}(t)=v_1^T \\underline{C}(t) v_2$$\n", "\n", - "If we choose the vectors to be $v_1=v_2=(1,0,0,0)$, we should get the same correlator as in the cell above. \n", + "If we choose the vectors to be $v_1=v_2=(0,1,0,0)$, we should get the same correlator as in the cell above. \n", "\n", "Thinking about it this way is usefull in the Context of the generalized eigenvalue problem (GEVP), used to find the source-sink combination, which best describes a certain energy eigenstate.\n", "A good introduction is found in https://arxiv.org/abs/0902.1265." diff --git a/pyerrors/__init__.py b/pyerrors/__init__.py index ca05aff4..731c43cf 100644 --- a/pyerrors/__init__.py +++ b/pyerrors/__init__.py @@ -481,12 +481,11 @@ from .obs import * from .correlators import * from .fits import * from .misc import * -from . import dirac as dirac -from . import input as input -from . import linalg as linalg -from . import mpm as mpm -from . import roots as roots -from . import integrate as integrate -from . import special as special +from . import dirac +from . import input +from . import linalg +from . import mpm +from . import roots +from . import integrate -from .version import __version__ as __version__ +from .version import __version__ diff --git a/pyerrors/correlators.py b/pyerrors/correlators.py index 0375155f..be5c69a6 100644 --- a/pyerrors/correlators.py +++ b/pyerrors/correlators.py @@ -8,7 +8,6 @@ from .obs import Obs, reweight, correlate, CObs from .misc import dump_object, _assert_equal_properties from .fits import least_squares from .roots import find_root -from . import linalg class Corr: @@ -101,7 +100,7 @@ class Corr: self.N = 1 elif all([isinstance(item, np.ndarray) or item is None for item in data_input]) and any([isinstance(item, np.ndarray) for item in data_input]): self.content = data_input - noNull = [a for a in self.content if a is not None] # To check if the matrices are correct for all undefined elements + noNull = [a for a in self.content if not (a is None)] # To check if the matrices are correct for all undefined elements self.N = noNull[0].shape[0] if self.N > 1 and noNull[0].shape[0] != noNull[0].shape[1]: raise ValueError("Smearing matrices are not NxN.") @@ -141,7 +140,7 @@ class Corr: def gamma_method(self, **kwargs): """Apply the gamma method to the content of the Corr.""" for item in self.content: - if item is not None: + if not (item is None): if self.N == 1: item[0].gamma_method(**kwargs) else: @@ -159,7 +158,7 @@ class Corr: By default it will return the lowest source, which usually means unsmeared-unsmeared (0,0), but it does not have to """ if self.N == 1: - raise ValueError("Trying to project a Corr, that already has N=1.") + raise Exception("Trying to project a Corr, that already has N=1.") if vector_l is None: vector_l, vector_r = np.asarray([1.] + (self.N - 1) * [0.]), np.asarray([1.] + (self.N - 1) * [0.]) @@ -167,16 +166,16 @@ class Corr: vector_r = vector_l if isinstance(vector_l, list) and not isinstance(vector_r, list): if len(vector_l) != self.T: - raise ValueError("Length of vector list must be equal to T") + raise Exception("Length of vector list must be equal to T") vector_r = [vector_r] * self.T if isinstance(vector_r, list) and not isinstance(vector_l, list): if len(vector_r) != self.T: - raise ValueError("Length of vector list must be equal to T") + raise Exception("Length of vector list must be equal to T") vector_l = [vector_l] * self.T if not isinstance(vector_l, list): if not vector_l.shape == vector_r.shape == (self.N,): - raise ValueError("Vectors are of wrong shape!") + raise Exception("Vectors are of wrong shape!") if normalize: vector_l, vector_r = vector_l / np.sqrt((vector_l @ vector_l)), vector_r / np.sqrt(vector_r @ vector_r) newcontent = [None if _check_for_none(self, item) else np.asarray([vector_l.T @ item @ vector_r]) for item in self.content] @@ -201,7 +200,7 @@ class Corr: Second index to be picked. """ if self.N == 1: - raise ValueError("Trying to pick item from projected Corr") + raise Exception("Trying to pick item from projected Corr") newcontent = [None if (item is None) else item[i, j] for item in self.content] return Corr(newcontent) @@ -212,8 +211,8 @@ class Corr: timeslice and the error on each timeslice. """ if self.N != 1: - raise ValueError("Can only make Corr[N=1] plottable") - x_list = [x for x in range(self.T) if self.content[x] is not None] + raise Exception("Can only make Corr[N=1] plottable") + x_list = [x for x in range(self.T) if not self.content[x] is None] y_list = [y[0].value for y in self.content if y is not None] y_err_list = [y[0].dvalue for y in self.content if y is not None] @@ -222,9 +221,9 @@ class Corr: def symmetric(self): """ Symmetrize the correlator around x0=0.""" if self.N != 1: - raise ValueError('symmetric cannot be safely applied to multi-dimensional correlators.') + raise Exception('symmetric cannot be safely applied to multi-dimensional correlators.') if self.T % 2 != 0: - raise ValueError("Can not symmetrize odd T") + raise Exception("Can not symmetrize odd T") if self.content[0] is not None: if np.argmax(np.abs([o[0].value if o is not None else 0 for o in self.content])) != 0: @@ -237,7 +236,7 @@ class Corr: else: newcontent.append(0.5 * (self.content[t] + self.content[self.T - t])) if (all([x is None for x in newcontent])): - raise ValueError("Corr could not be symmetrized: No redundant values") + raise Exception("Corr could not be symmetrized: No redundant values") return Corr(newcontent, prange=self.prange) def anti_symmetric(self): @@ -245,7 +244,7 @@ class Corr: if self.N != 1: raise TypeError('anti_symmetric cannot be safely applied to multi-dimensional correlators.') if self.T % 2 != 0: - raise ValueError("Can not symmetrize odd T") + raise Exception("Can not symmetrize odd T") test = 1 * self test.gamma_method() @@ -259,7 +258,7 @@ class Corr: else: newcontent.append(0.5 * (self.content[t] - self.content[self.T - t])) if (all([x is None for x in newcontent])): - raise ValueError("Corr could not be symmetrized: No redundant values") + raise Exception("Corr could not be symmetrized: No redundant values") return Corr(newcontent, prange=self.prange) def is_matrix_symmetric(self): @@ -292,14 +291,14 @@ class Corr: def matrix_symmetric(self): """Symmetrizes the correlator matrices on every timeslice.""" if self.N == 1: - raise ValueError("Trying to symmetrize a correlator matrix, that already has N=1.") + raise Exception("Trying to symmetrize a correlator matrix, that already has N=1.") if self.is_matrix_symmetric(): return 1.0 * self else: transposed = [None if _check_for_none(self, G) else G.T for G in self.content] return 0.5 * (Corr(transposed) + self) - def GEVP(self, t0, ts=None, sort="Eigenvalue", vector_obs=False, **kwargs): + def GEVP(self, t0, ts=None, sort="Eigenvalue", **kwargs): r'''Solve the generalized eigenvalue problem on the correlator matrix and returns the corresponding eigenvectors. The eigenvectors are sorted according to the descending eigenvalues, the zeroth eigenvector(s) correspond to the @@ -318,28 +317,21 @@ class Corr: If sort="Eigenvector" it gives a reference point for the sorting method. sort : string 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. - - "Eigenvalue": The eigenvector is chosen according to which eigenvalue it belongs individually on every timeslice. (default) + - "Eigenvalue": The eigenvector is chosen according to which eigenvalue it belongs individually on every timeslice. - "Eigenvector": Use the method described in arXiv:2004.10472 to find the set of v(t) belonging to the state. The reference state is identified by its eigenvalue at $t=t_s$. - - None: The GEVP is solved only at ts, no sorting is necessary - vector_obs : bool - If True, uncertainties are propagated in the eigenvector computation (default False). Other Parameters ---------------- state : int Returns only the vector(s) for a specified state. The lowest state is zero. - method : str - Method used to solve the GEVP. - - "eigh": Use scipy.linalg.eigh to solve the GEVP. (default for vector_obs=False) - - "cholesky": Use manually implemented solution via the Cholesky decomposition. Automatically chosen if vector_obs==True. ''' if self.N == 1: - raise ValueError("GEVP methods only works on correlator matrices and not single correlators.") + raise Exception("GEVP methods only works on correlator matrices and not single correlators.") if ts is not None: if (ts <= t0): - raise ValueError("ts has to be larger than t0.") + raise Exception("ts has to be larger than t0.") if "sorted_list" in kwargs: warnings.warn("Argument 'sorted_list' is deprecated, use 'sort' instead.", DeprecationWarning) @@ -350,34 +342,16 @@ class Corr: else: symmetric_corr = self.matrix_symmetric() - def _get_mat_at_t(t, vector_obs=vector_obs): - if vector_obs: - return symmetric_corr[t] - else: - return np.vectorize(lambda x: x.value)(symmetric_corr[t]) - G0 = _get_mat_at_t(t0) - - method = kwargs.get('method', 'eigh') - if vector_obs: - chol = linalg.cholesky(G0) - chol_inv = linalg.inv(chol) - method = 'cholesky' - else: - chol = np.linalg.cholesky(_get_mat_at_t(t0, vector_obs=False)) # Check if matrix G0 is positive-semidefinite. - if method == 'cholesky': - chol_inv = np.linalg.inv(chol) - else: - chol_inv = None + G0 = np.vectorize(lambda x: x.value)(symmetric_corr[t0]) + np.linalg.cholesky(G0) # Check if matrix G0 is positive-semidefinite. if sort is None: if (ts is None): - raise ValueError("ts is required if sort=None.") + raise Exception("ts is required if sort=None.") if (self.content[t0] is None) or (self.content[ts] is None): - raise ValueError("Corr not defined at t0/ts.") - Gt = _get_mat_at_t(ts) - reordered_vecs = _GEVP_solver(Gt, G0, method=method, chol_inv=chol_inv) - if kwargs.get('auto_gamma', False) and vector_obs: - [[o.gm() for o in ev if isinstance(o, Obs)] for ev in reordered_vecs] + raise Exception("Corr not defined at t0/ts.") + Gt = np.vectorize(lambda x: x.value)(symmetric_corr[ts]) + reordered_vecs = _GEVP_solver(Gt, G0) elif sort in ["Eigenvalue", "Eigenvector"]: if sort == "Eigenvalue" and ts is not None: @@ -385,27 +359,25 @@ class Corr: all_vecs = [None] * (t0 + 1) for t in range(t0 + 1, self.T): try: - Gt = _get_mat_at_t(t) - all_vecs.append(_GEVP_solver(Gt, G0, method=method, chol_inv=chol_inv)) + Gt = np.vectorize(lambda x: x.value)(symmetric_corr[t]) + all_vecs.append(_GEVP_solver(Gt, G0)) except Exception: all_vecs.append(None) if sort == "Eigenvector": if ts is None: - raise ValueError("ts is required for the Eigenvector sorting method.") + raise Exception("ts is required for the Eigenvector sorting method.") all_vecs = _sort_vectors(all_vecs, ts) reordered_vecs = [[v[s] if v is not None else None for v in all_vecs] for s in range(self.N)] - if kwargs.get('auto_gamma', False) and vector_obs: - [[[o.gm() for o in evn] for evn in ev if evn is not None] for ev in reordered_vecs] else: - raise ValueError("Unknown value for 'sort'. Choose 'Eigenvalue', 'Eigenvector' or None.") + raise Exception("Unkown value for 'sort'.") if "state" in kwargs: return reordered_vecs[kwargs.get("state")] else: return reordered_vecs - def Eigenvalue(self, t0, ts=None, state=0, sort="Eigenvalue", **kwargs): + def Eigenvalue(self, t0, ts=None, state=0, sort="Eigenvalue"): """Determines the eigenvalue of the GEVP by solving and projecting the correlator Parameters @@ -415,7 +387,7 @@ class Corr: All other parameters are identical to the ones of Corr.GEVP. """ - vec = self.GEVP(t0, ts=ts, sort=sort, **kwargs)[state] + vec = self.GEVP(t0, ts=ts, sort=sort)[state] return self.projected(vec) def Hankel(self, N, periodic=False): @@ -435,7 +407,7 @@ class Corr: """ if self.N != 1: - raise NotImplementedError("Multi-operator Prony not implemented!") + raise Exception("Multi-operator Prony not implemented!") array = np.empty([N, N], dtype="object") new_content = [] @@ -502,7 +474,7 @@ class Corr: correlator or a Corr of same length. """ if self.N != 1: - raise ValueError("Only one-dimensional correlators can be safely correlated.") + raise Exception("Only one-dimensional correlators can be safely correlated.") new_content = [] for x0, t_slice in enumerate(self.content): if _check_for_none(self, t_slice): @@ -516,7 +488,7 @@ class Corr: elif isinstance(partner, Obs): # Should this include CObs? new_content.append(np.array([correlate(o, partner) for o in t_slice])) else: - raise TypeError("Can only correlate with an Obs or a Corr.") + raise Exception("Can only correlate with an Obs or a Corr.") return Corr(new_content) @@ -583,7 +555,7 @@ class Corr: Available choice: symmetric, forward, backward, improved, log, default: symmetric """ if self.N != 1: - raise ValueError("deriv only implemented for one-dimensional correlators.") + raise Exception("deriv only implemented for one-dimensional correlators.") if variant == "symmetric": newcontent = [] for t in range(1, self.T - 1): @@ -592,7 +564,7 @@ class Corr: else: newcontent.append(0.5 * (self.content[t + 1] - self.content[t - 1])) if (all([x is None for x in newcontent])): - raise ValueError('Derivative is undefined at all timeslices') + raise Exception('Derivative is undefined at all timeslices') return Corr(newcontent, padding=[1, 1]) elif variant == "forward": newcontent = [] @@ -602,7 +574,7 @@ class Corr: else: newcontent.append(self.content[t + 1] - self.content[t]) if (all([x is None for x in newcontent])): - raise ValueError("Derivative is undefined at all timeslices") + raise Exception("Derivative is undefined at all timeslices") return Corr(newcontent, padding=[0, 1]) elif variant == "backward": newcontent = [] @@ -612,7 +584,7 @@ class Corr: else: newcontent.append(self.content[t] - self.content[t - 1]) if (all([x is None for x in newcontent])): - raise ValueError("Derivative is undefined at all timeslices") + raise Exception("Derivative is undefined at all timeslices") return Corr(newcontent, padding=[1, 0]) elif variant == "improved": newcontent = [] @@ -622,7 +594,7 @@ class Corr: else: newcontent.append((1 / 12) * (self.content[t - 2] - 8 * self.content[t - 1] + 8 * self.content[t + 1] - self.content[t + 2])) if (all([x is None for x in newcontent])): - raise ValueError('Derivative is undefined at all timeslices') + raise Exception('Derivative is undefined at all timeslices') return Corr(newcontent, padding=[2, 2]) elif variant == 'log': newcontent = [] @@ -632,11 +604,11 @@ class Corr: else: newcontent.append(np.log(self.content[t])) if (all([x is None for x in newcontent])): - raise ValueError("Log is undefined at all timeslices") + raise Exception("Log is undefined at all timeslices") logcorr = Corr(newcontent) return self * logcorr.deriv('symmetric') else: - raise ValueError("Unknown variant.") + raise Exception("Unknown variant.") def second_deriv(self, variant="symmetric"): r"""Return the second derivative of the correlator with respect to x0. @@ -656,7 +628,7 @@ class Corr: $$f(x) = \tilde{\partial}^2_0 log(f(x_0))+(\tilde{\partial}_0 log(f(x_0)))^2$$ """ if self.N != 1: - raise ValueError("second_deriv only implemented for one-dimensional correlators.") + raise Exception("second_deriv only implemented for one-dimensional correlators.") if variant == "symmetric": newcontent = [] for t in range(1, self.T - 1): @@ -665,7 +637,7 @@ class Corr: else: newcontent.append((self.content[t + 1] - 2 * self.content[t] + self.content[t - 1])) if (all([x is None for x in newcontent])): - raise ValueError("Derivative is undefined at all timeslices") + raise Exception("Derivative is undefined at all timeslices") return Corr(newcontent, padding=[1, 1]) elif variant == "big_symmetric": newcontent = [] @@ -675,7 +647,7 @@ class Corr: else: newcontent.append((self.content[t + 2] - 2 * self.content[t] + self.content[t - 2]) / 4) if (all([x is None for x in newcontent])): - raise ValueError("Derivative is undefined at all timeslices") + raise Exception("Derivative is undefined at all timeslices") return Corr(newcontent, padding=[2, 2]) elif variant == "improved": newcontent = [] @@ -685,7 +657,7 @@ class Corr: else: newcontent.append((1 / 12) * (-self.content[t + 2] + 16 * self.content[t + 1] - 30 * self.content[t] + 16 * self.content[t - 1] - self.content[t - 2])) if (all([x is None for x in newcontent])): - raise ValueError("Derivative is undefined at all timeslices") + raise Exception("Derivative is undefined at all timeslices") return Corr(newcontent, padding=[2, 2]) elif variant == 'log': newcontent = [] @@ -695,11 +667,11 @@ class Corr: else: newcontent.append(np.log(self.content[t])) if (all([x is None for x in newcontent])): - raise ValueError("Log is undefined at all timeslices") + raise Exception("Log is undefined at all timeslices") logcorr = Corr(newcontent) return self * (logcorr.second_deriv('symmetric') + (logcorr.deriv('symmetric'))**2) else: - raise ValueError("Unknown variant.") + raise Exception("Unknown variant.") def m_eff(self, variant='log', guess=1.0): """Returns the effective mass of the correlator as correlator object @@ -728,7 +700,7 @@ class Corr: else: newcontent.append(self.content[t] / self.content[t + 1]) if (all([x is None for x in newcontent])): - raise ValueError('m_eff is undefined at all timeslices') + raise Exception('m_eff is undefined at all timeslices') return np.log(Corr(newcontent, padding=[0, 1])) @@ -742,7 +714,7 @@ class Corr: else: newcontent.append(self.content[t - 1] / self.content[t + 1]) if (all([x is None for x in newcontent])): - raise ValueError('m_eff is undefined at all timeslices') + raise Exception('m_eff is undefined at all timeslices') return np.log(Corr(newcontent, padding=[1, 1])) / 2 @@ -767,7 +739,7 @@ class Corr: else: newcontent.append(np.abs(find_root(self.content[t][0] / self.content[t + 1][0], root_function, guess=guess))) if (all([x is None for x in newcontent])): - raise ValueError('m_eff is undefined at all timeslices') + raise Exception('m_eff is undefined at all timeslices') return Corr(newcontent, padding=[0, 1]) @@ -779,11 +751,11 @@ class Corr: else: newcontent.append((self.content[t + 1] + self.content[t - 1]) / (2 * self.content[t])) if (all([x is None for x in newcontent])): - raise ValueError("m_eff is undefined at all timeslices") + raise Exception("m_eff is undefined at all timeslices") return np.arccosh(Corr(newcontent, padding=[1, 1])) else: - raise ValueError('Unknown variant.') + raise Exception('Unknown variant.') def fit(self, function, fitrange=None, silent=False, **kwargs): r'''Fits function to the data @@ -801,7 +773,7 @@ class Corr: Decides whether output is printed to the standard output. ''' if self.N != 1: - raise ValueError("Correlator must be projected before fitting") + raise Exception("Correlator must be projected before fitting") if fitrange is None: if self.prange: @@ -810,12 +782,12 @@ class Corr: fitrange = [0, self.T - 1] else: if not isinstance(fitrange, list): - raise TypeError("fitrange has to be a list with two elements") + raise Exception("fitrange has to be a list with two elements") if len(fitrange) != 2: - raise ValueError("fitrange has to have exactly two elements [fit_start, fit_stop]") + raise Exception("fitrange has to have exactly two elements [fit_start, fit_stop]") - xs = np.array([x for x in range(fitrange[0], fitrange[1] + 1) if self.content[x] is not None]) - ys = np.array([self.content[x][0] for x in range(fitrange[0], fitrange[1] + 1) if self.content[x] is not None]) + xs = np.array([x for x in range(fitrange[0], fitrange[1] + 1) if not self.content[x] is None]) + ys = np.array([self.content[x][0] for x in range(fitrange[0], fitrange[1] + 1) if not self.content[x] is None]) result = least_squares(xs, ys, function, silent=silent, **kwargs) return result @@ -840,9 +812,9 @@ class Corr: else: raise Exception("no plateau range provided") if self.N != 1: - raise ValueError("Correlator must be projected before getting a plateau.") + raise Exception("Correlator must be projected before getting a plateau.") if (all([self.content[t] is None for t in range(plateau_range[0], plateau_range[1] + 1)])): - raise ValueError("plateau is undefined at all timeslices in plateaurange.") + raise Exception("plateau is undefined at all timeslices in plateaurange.") if auto_gamma: self.gamma_method() if method == "fit": @@ -854,16 +826,16 @@ class Corr: return returnvalue else: - raise ValueError("Unsupported plateau method: " + method) + raise Exception("Unsupported plateau method: " + method) def set_prange(self, prange): """Sets the attribute prange of the Corr object.""" if not len(prange) == 2: - raise ValueError("prange must be a list or array with two values") + raise Exception("prange must be a list or array with two values") if not ((isinstance(prange[0], int)) and (isinstance(prange[1], int))): - raise TypeError("Start and end point must be integers") - if not (0 <= prange[0] <= self.T and 0 <= prange[1] <= self.T and prange[0] <= prange[1]): - raise ValueError("Start and end point must define a range in the interval 0,T") + raise Exception("Start and end point must be integers") + if not (0 <= prange[0] <= self.T and 0 <= prange[1] <= self.T and prange[0] < prange[1]): + raise Exception("Start and end point must define a range in the interval 0,T") self.prange = prange return @@ -900,7 +872,7 @@ class Corr: Optional title of the figure. """ if self.N != 1: - raise ValueError("Correlator must be projected before plotting") + raise Exception("Correlator must be projected before plotting") if auto_gamma: self.gamma_method() @@ -941,7 +913,7 @@ class Corr: hide_from = None ax1.errorbar(x[:hide_from], y[:hide_from], y_err[:hide_from], label=corr.tag, mfc=plt.rcParams['axes.facecolor']) else: - raise TypeError("'comp' must be a correlator or a list of correlators.") + raise Exception("'comp' must be a correlator or a list of correlators.") if plateau: if isinstance(plateau, Obs): @@ -950,14 +922,14 @@ class Corr: ax1.axhline(y=plateau.value, linewidth=2, color=plt.rcParams['text.color'], alpha=0.6, marker=',', ls='--', label=str(plateau)) ax1.axhspan(plateau.value - plateau.dvalue, plateau.value + plateau.dvalue, alpha=0.25, color=plt.rcParams['text.color'], ls='-') else: - raise TypeError("'plateau' must be an Obs") + raise Exception("'plateau' must be an Obs") if references: if isinstance(references, list): for ref in references: ax1.axhline(y=ref, linewidth=1, color=plt.rcParams['text.color'], alpha=0.6, marker=',', ls='--') else: - raise TypeError("'references' must be a list of floating pint values.") + raise Exception("'references' must be a list of floating pint values.") if self.prange: ax1.axvline(self.prange[0], 0, 1, ls='-', marker=',', color="black", zorder=0) @@ -991,7 +963,7 @@ class Corr: if isinstance(save, str): fig.savefig(save, bbox_inches='tight') else: - raise TypeError("'save' has to be a string.") + raise Exception("'save' has to be a string.") def spaghetti_plot(self, logscale=True): """Produces a spaghetti plot of the correlator suited to monitor exceptional configurations. @@ -1002,7 +974,7 @@ class Corr: Determines whether the scale of the y-axis is logarithmic or standard. """ if self.N != 1: - raise ValueError("Correlator needs to be projected first.") + raise Exception("Correlator needs to be projected first.") mc_names = list(set([item for sublist in [sum(map(o[0].e_content.get, o[0].mc_names), []) for o in self.content if o is not None] for item in sublist])) x0_vals = [n for (n, o) in zip(np.arange(self.T), self.content) if o is not None] @@ -1044,7 +1016,7 @@ class Corr: elif datatype == "pickle": dump_object(self, filename, **kwargs) else: - raise ValueError("Unknown datatype " + str(datatype)) + raise Exception("Unknown datatype " + str(datatype)) def print(self, print_range=None): print(self.__repr__(print_range)) @@ -1094,7 +1066,7 @@ class Corr: def __add__(self, y): if isinstance(y, Corr): if ((self.N != y.N) or (self.T != y.T)): - raise ValueError("Addition of Corrs with different shape") + raise Exception("Addition of Corrs with different shape") newcontent = [] for t in range(self.T): if _check_for_none(self, self.content[t]) or _check_for_none(y, y.content[t]): @@ -1103,7 +1075,7 @@ class Corr: newcontent.append(self.content[t] + y.content[t]) return Corr(newcontent) - elif isinstance(y, (Obs, int, float, CObs, complex)): + elif isinstance(y, (Obs, int, float, CObs)): newcontent = [] for t in range(self.T): if _check_for_none(self, self.content[t]): @@ -1122,7 +1094,7 @@ class Corr: def __mul__(self, y): if isinstance(y, Corr): if not ((self.N == 1 or y.N == 1 or self.N == y.N) and self.T == y.T): - raise ValueError("Multiplication of Corr object requires N=N or N=1 and T=T") + raise Exception("Multiplication of Corr object requires N=N or N=1 and T=T") newcontent = [] for t in range(self.T): if _check_for_none(self, self.content[t]) or _check_for_none(y, y.content[t]): @@ -1131,7 +1103,7 @@ class Corr: newcontent.append(self.content[t] * y.content[t]) return Corr(newcontent) - elif isinstance(y, (Obs, int, float, CObs, complex)): + elif isinstance(y, (Obs, int, float, CObs)): newcontent = [] for t in range(self.T): if _check_for_none(self, self.content[t]): @@ -1193,7 +1165,7 @@ class Corr: def __truediv__(self, y): if isinstance(y, Corr): if not ((self.N == 1 or y.N == 1 or self.N == y.N) and self.T == y.T): - raise ValueError("Multiplication of Corr object requires N=N or N=1 and T=T") + raise Exception("Multiplication of Corr object requires N=N or N=1 and T=T") newcontent = [] for t in range(self.T): if _check_for_none(self, self.content[t]) or _check_for_none(y, y.content[t]): @@ -1207,16 +1179,16 @@ class Corr: newcontent[t] = None if all([item is None for item in newcontent]): - raise ValueError("Division returns completely undefined correlator") + raise Exception("Division returns completely undefined correlator") return Corr(newcontent) elif isinstance(y, (Obs, CObs)): if isinstance(y, Obs): if y.value == 0: - raise ValueError('Division by zero will return undefined correlator') + raise Exception('Division by zero will return undefined correlator') if isinstance(y, CObs): if y.is_zero(): - raise ValueError('Division by zero will return undefined correlator') + raise Exception('Division by zero will return undefined correlator') newcontent = [] for t in range(self.T): @@ -1228,7 +1200,7 @@ class Corr: elif isinstance(y, (int, float)): if y == 0: - raise ValueError('Division by zero will return undefined correlator') + raise Exception('Division by zero will return undefined correlator') newcontent = [] for t in range(self.T): if _check_for_none(self, self.content[t]): @@ -1284,7 +1256,7 @@ class Corr: if np.isnan(tmp_sum.value): newcontent[t] = None if all([item is None for item in newcontent]): - raise ValueError('Operation returns undefined correlator') + raise Exception('Operation returns undefined correlator') return Corr(newcontent) def sin(self): @@ -1392,13 +1364,13 @@ class Corr: ''' if self.N == 1: - raise ValueError('Method cannot be applied to one-dimensional correlators.') + raise Exception('Method cannot be applied to one-dimensional correlators.') if basematrix is None: basematrix = self if Ntrunc >= basematrix.N: - raise ValueError('Cannot truncate using Ntrunc <= %d' % (basematrix.N)) + raise Exception('Cannot truncate using Ntrunc <= %d' % (basematrix.N)) if basematrix.N != self.N: - raise ValueError('basematrix and targetmatrix have to be of the same size.') + raise Exception('basematrix and targetmatrix have to be of the same size.') evecs = basematrix.GEVP(t0proj, tproj, sort=None)[:Ntrunc] @@ -1414,13 +1386,8 @@ class Corr: return Corr(newcontent) -def _sort_vectors(vec_set_in, ts): +def _sort_vectors(vec_set, ts): """Helper function used to find a set of Eigenvectors consistent over all timeslices""" - - if isinstance(vec_set_in[ts][0][0], Obs): - vec_set = [anp.vectorize(lambda x: float(x))(vi) if vi is not None else vi for vi in vec_set_in] - else: - vec_set = vec_set_in reference_sorting = np.array(vec_set[ts]) N = reference_sorting.shape[0] sorted_vec_set = [] @@ -1439,9 +1406,9 @@ def _sort_vectors(vec_set_in, ts): if current_score > best_score: best_score = current_score best_perm = perm - sorted_vec_set.append([vec_set_in[t][k] for k in best_perm]) + sorted_vec_set.append([vec_set[t][k] for k in best_perm]) else: - sorted_vec_set.append(vec_set_in[t]) + sorted_vec_set.append(vec_set[t]) return sorted_vec_set @@ -1451,63 +1418,10 @@ def _check_for_none(corr, entry): return len(list(filter(None, np.asarray(entry).flatten()))) < corr.N ** 2 -def _GEVP_solver(Gt, G0, method='eigh', chol_inv=None): - r"""Helper function for solving the GEVP and sorting the eigenvectors. - - Solves $G(t)v_i=\lambda_i G(t_0)v_i$ and returns the eigenvectors v_i +def _GEVP_solver(Gt, G0): + """Helper function for solving the GEVP and sorting the eigenvectors. The helper function assumes that both provided matrices are symmetric and only processes the lower triangular part of both matrices. In case the matrices - are not symmetric the upper triangular parts are effectively discarded. - - Parameters - ---------- - Gt : array - The correlator at time t for the left hand side of the GEVP - G0 : array - The correlator at time t0 for the right hand side of the GEVP - Method used to solve the GEVP. - - "eigh": Use scipy.linalg.eigh to solve the GEVP. - - "cholesky": Use manually implemented solution via the Cholesky decomposition. - chol_inv : array, optional - Inverse of the Cholesky decomposition of G0. May be provided to - speed up the computation in the case of method=='cholesky' - - """ - if isinstance(G0[0][0], Obs): - vector_obs = True - else: - vector_obs = False - - if method == 'cholesky': - if vector_obs: - cholesky = linalg.cholesky - inv = linalg.inv - eigv = linalg.eigv - matmul = linalg.matmul - else: - cholesky = np.linalg.cholesky - inv = np.linalg.inv - - def eigv(x, **kwargs): - return np.linalg.eigh(x)[1] - - def matmul(*operands): - return np.linalg.multi_dot(operands) - N = Gt.shape[0] - output = [[] for j in range(N)] - if chol_inv is None: - chol = cholesky(G0) # This will automatically report if the matrix is not pos-def - chol_inv = inv(chol) - - try: - new_matrix = matmul(chol_inv, Gt, chol_inv.T) - ev = eigv(new_matrix) - ev = matmul(chol_inv.T, ev) - output = np.flip(ev, axis=1).T - except (np.linalg.LinAlgError, TypeError, ValueError): # The above code can fail because of linalg-errors or because the entry of the corr is None - for s in range(N): - output[s] = None - return output - elif method == 'eigh': - return scipy.linalg.eigh(Gt, G0, lower=True)[1].T[::-1] + are not symmetric the upper triangular parts are effectively discarded.""" + return scipy.linalg.eigh(Gt, G0, lower=True)[1].T[::-1] diff --git a/pyerrors/dirac.py b/pyerrors/dirac.py index 016e4722..48d1b547 100644 --- a/pyerrors/dirac.py +++ b/pyerrors/dirac.py @@ -34,7 +34,7 @@ def epsilon_tensor(i, j, k): """ test_set = set((i, j, k)) if not (test_set <= set((1, 2, 3)) or test_set <= set((0, 1, 2))): - raise ValueError("Unexpected input", i, j, k) + raise Exception("Unexpected input", i, j, k) return (i - j) * (j - k) * (k - i) / 2 @@ -52,7 +52,7 @@ def epsilon_tensor_rank4(i, j, k, o): """ test_set = set((i, j, k, o)) if not (test_set <= set((1, 2, 3, 4)) or test_set <= set((0, 1, 2, 3))): - raise ValueError("Unexpected input", i, j, k, o) + raise Exception("Unexpected input", i, j, k, o) return (i - j) * (j - k) * (k - i) * (i - o) * (j - o) * (o - k) / 12 @@ -92,5 +92,5 @@ def Grid_gamma(gamma_tag): elif gamma_tag == 'SigmaZT': g = 0.5 * (gamma[2] @ gamma[3] - gamma[3] @ gamma[2]) else: - raise ValueError('Unkown gamma structure', gamma_tag) + raise Exception('Unkown gamma structure', gamma_tag) return g diff --git a/pyerrors/fits.py b/pyerrors/fits.py index 675bdca6..5ec857e0 100644 --- a/pyerrors/fits.py +++ b/pyerrors/fits.py @@ -14,7 +14,7 @@ from autograd import hessian as auto_hessian from autograd import elementwise_grad as egrad from numdifftools import Jacobian as num_jacobian from numdifftools import Hessian as num_hessian -from .obs import Obs, derived_observable, covariance, cov_Obs, invert_corr_cov_cholesky +from .obs import Obs, derived_observable, covariance, cov_Obs class Fit_result(Sequence): @@ -151,14 +151,6 @@ def least_squares(x, y, func, priors=None, silent=False, **kwargs): For details about how the covariance matrix is estimated see `pyerrors.obs.covariance`. In practice the correlation matrix is Cholesky decomposed and inverted (instead of the covariance matrix). This procedure should be numerically more stable as the correlation matrix is typically better conditioned (Jacobi preconditioning). - inv_chol_cov_matrix [array,list], optional - array: shape = (no of y values) X (no of y values) - list: for an uncombined fit: [""] - 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 - 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. - The matrix must be a lower triangular matrix constructed from a Cholesky decomposition: The function invert_corr_cov_cholesky(corr, inverrdiag) can be - 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 - 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. expected_chisquare : bool If True estimates the expected chisquare which is corrected by effects caused by correlated input data (default False). @@ -173,66 +165,15 @@ def least_squares(x, y, func, priors=None, silent=False, **kwargs): ------- output : Fit_result Parameters and information on the fitted result. - Examples - ------ - >>> # Example of a correlated (correlated_fit = True, inv_chol_cov_matrix handed over) combined fit, based on a randomly generated data set - >>> import numpy as np - >>> from scipy.stats import norm - >>> from scipy.linalg import cholesky - >>> import pyerrors as pe - >>> # generating the random data set - >>> num_samples = 400 - >>> N = 3 - >>> x = np.arange(N) - >>> x1 = norm.rvs(size=(N, num_samples)) # generate random numbers - >>> x2 = norm.rvs(size=(N, num_samples)) # generate random numbers - >>> r = r1 = r2 = np.zeros((N, N)) - >>> y = {} - >>> for i in range(N): - >>> for j in range(N): - >>> r[i, j] = np.exp(-0.8 * np.fabs(i - j)) # element in correlation matrix - >>> errl = np.sqrt([3.4, 2.5, 3.6]) # set y errors - >>> for i in range(N): - >>> for j in range(N): - >>> r[i, j] *= errl[i] * errl[j] # element in covariance matrix - >>> c = cholesky(r, lower=True) - >>> y = {'a': np.dot(c, x1), 'b': np.dot(c, x2)} # generate y data with the covariance matrix defined - >>> # random data set has been generated, now the dictionaries and the inverse covariance matrix to be handed over are built - >>> x_dict = {} - >>> y_dict = {} - >>> chol_inv_dict = {} - >>> data = [] - >>> for key in y.keys(): - >>> x_dict[key] = x - >>> for i in range(N): - >>> data.append(pe.Obs([[i + 1 + o for o in y[key][i]]], ['ens'])) # generate y Obs from the y data - >>> [o.gamma_method() for o in data] - >>> corr = pe.covariance(data, correlation=True) - >>> inverrdiag = np.diag(1 / np.asarray([o.dvalue for o in data])) - >>> chol_inv = pe.obs.invert_corr_cov_cholesky(corr, inverrdiag) # gives form of the inverse covariance matrix needed for the combined correlated fit below - >>> y_dict = {'a': data[:3], 'b': data[3:]} - >>> # common fit parameter p[0] in combined fit - >>> def fit1(p, x): - >>> return p[0] + p[1] * x - >>> def fit2(p, x): - >>> return p[0] + p[2] * x - >>> fitf_dict = {'a': fit1, 'b':fit2} - >>> 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']]) - Fit with 3 parameters - Method: Levenberg-Marquardt - `ftol` termination condition is satisfied. - chisquare/d.o.f.: 0.5388013574561786 # random - fit parameters [1.11897846 0.96361162 0.92325319] # random - ''' output = Fit_result() - if (isinstance(x, dict) and isinstance(y, dict) and isinstance(func, dict)): + if (type(x) == dict and type(y) == dict and type(func) == dict): xd = {key: anp.asarray(x[key]) for key in x} yd = y funcd = func output.fit_function = func - elif (isinstance(x, dict) or isinstance(y, dict) or isinstance(func, dict)): + elif (type(x) == dict or type(y) == dict or type(func) == dict): raise TypeError("All arguments have to be dictionaries in order to perform a combined fit.") else: x = np.asarray(x) @@ -256,7 +197,7 @@ def least_squares(x, y, func, priors=None, silent=False, **kwargs): if sorted(list(funcd.keys())) != key_ls: raise ValueError('x and func dictionaries do not contain the same keys.') - x_all = np.concatenate([np.array(xd[key]).transpose() for key in key_ls]).transpose() + x_all = np.concatenate([np.array(xd[key]) for key in key_ls]) y_all = np.concatenate([np.array(yd[key]) for key in key_ls]) y_f = [o.value for o in y_all] @@ -293,7 +234,7 @@ def least_squares(x, y, func, priors=None, silent=False, **kwargs): if len(key_ls) > 1: for key in key_ls: if np.asarray(yd[key]).shape != funcd[key](np.arange(n_parms), xd[key]).shape: - raise ValueError(f"Fit function {key} returns the wrong shape ({funcd[key](np.arange(n_parms), xd[key]).shape} instead of {np.asarray(yd[key]).shape})\nIf the fit function is just a constant you could try adding x*0 to get the correct shape.") + raise ValueError(f"Fit function {key} returns the wrong shape ({funcd[key](np.arange(n_parms), xd[key]).shape} instead of {xd[key].shape})\nIf the fit function is just a constant you could try adding x*0 to get the correct shape.") if not silent: print('Fit with', n_parms, 'parameter' + 's' * (n_parms > 1)) @@ -356,21 +297,15 @@ def least_squares(x, y, func, priors=None, silent=False, **kwargs): return anp.sum(general_chisqfunc_uncorr(p, y_f, p_f) ** 2) if kwargs.get('correlated_fit') is True: - if 'inv_chol_cov_matrix' in kwargs: - chol_inv = kwargs.get('inv_chol_cov_matrix') - if (chol_inv[0].shape[0] != len(dy_f)): - raise TypeError('The number of columns of the inverse covariance matrix handed over needs to be equal to the number of y errors.') - if (chol_inv[0].shape[0] != chol_inv[0].shape[1]): - raise TypeError('The inverse covariance matrix handed over needs to have the same number of rows as columns.') - if (chol_inv[1] != key_ls): - 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.') - chol_inv = chol_inv[0] - if np.any(np.diag(chol_inv) <= 0) or (not np.all(chol_inv == np.tril(chol_inv))): - raise ValueError('The inverse covariance matrix inv_chol_cov_matrix[0] has to be a lower triangular matrix constructed from a Cholesky decomposition.') - else: - corr = covariance(y_all, correlation=True, **kwargs) - inverrdiag = np.diag(1 / np.asarray(dy_f)) - chol_inv = invert_corr_cov_cholesky(corr, inverrdiag) + corr = covariance(y_all, correlation=True, **kwargs) + covdiag = np.diag(1 / np.asarray(dy_f)) + condn = np.linalg.cond(corr) + if condn > 0.1 / np.finfo(float).eps: + raise Exception(f"Cannot invert correlation matrix as its condition number exceeds machine precision ({condn:1.2e})") + if condn > 1e13: + warnings.warn("Correlation matrix may be ill-conditioned, condition number: {%1.2e}" % (condn), RuntimeWarning) + chol = np.linalg.cholesky(corr) + chol_inv = scipy.linalg.solve_triangular(chol, covdiag, lower=True) def general_chisqfunc(p, ivars, pr): model = anp.concatenate([anp.array(funcd[key](p, xd[key])).reshape(-1) for key in key_ls]) @@ -415,6 +350,7 @@ def least_squares(x, y, func, priors=None, silent=False, **kwargs): fit_result = scipy.optimize.least_squares(chisqfunc_residuals_uncorr, x0, method='lm', ftol=1e-15, gtol=1e-15, xtol=1e-15) if kwargs.get('correlated_fit') is True: + def chisqfunc_residuals(p): return general_chisqfunc(p, y_f, p_f) @@ -429,7 +365,7 @@ def least_squares(x, y, func, priors=None, silent=False, **kwargs): raise Exception('The minimization procedure did not converge.') output.chisquare = chisquare - output.dof = y_all.shape[-1] - n_parms + len(loc_priors) + output.dof = x_all.shape[-1] - n_parms + len(loc_priors) output.p_value = 1 - scipy.stats.chi2.cdf(output.chisquare, output.dof) if output.dof > 0: output.chisquare_by_dof = output.chisquare / output.dof @@ -457,7 +393,7 @@ def least_squares(x, y, func, priors=None, silent=False, **kwargs): hat_vector = prepare_hat_matrix() A = W @ hat_vector P_phi = A @ np.linalg.pinv(A.T @ A) @ A.T - expected_chisquare = np.trace((np.identity(y_all.shape[-1]) - P_phi) @ W @ cov @ W) + expected_chisquare = np.trace((np.identity(x_all.shape[-1]) - P_phi) @ W @ cov @ W) output.chisquare_by_expected_chisquare = output.chisquare / expected_chisquare if not silent: print('chisquare/expected_chisquare:', output.chisquare_by_expected_chisquare) diff --git a/pyerrors/input/__init__.py b/pyerrors/input/__init__.py index 257c5bd8..6910bd2a 100644 --- a/pyerrors/input/__init__.py +++ b/pyerrors/input/__init__.py @@ -5,11 +5,11 @@ r''' For comparison with other analysis workflows `pyerrors` can also generate jackknife samples from an `Obs` object or import jackknife samples into an `Obs` object. See `pyerrors.obs.Obs.export_jackknife` and `pyerrors.obs.import_jackknife` for details. ''' -from . import bdio as bdio -from . import dobs as dobs -from . import hadrons as hadrons -from . import json as json -from . import misc as misc -from . import openQCD as openQCD -from . import pandas as pandas -from . import sfcf as sfcf +from . import bdio +from . import dobs +from . import hadrons +from . import json +from . import misc +from . import openQCD +from . import pandas +from . import sfcf diff --git a/pyerrors/input/dobs.py b/pyerrors/input/dobs.py index 6907ec3c..b8b005ff 100644 --- a/pyerrors/input/dobs.py +++ b/pyerrors/input/dobs.py @@ -79,7 +79,7 @@ def _dict_to_xmlstring_spaces(d, space=' '): o += space o += li + '\n' if li.startswith('<') and not cm: - if '<%s' % ('/') not in li: + if not '<%s' % ('/') in li: c += 1 cm = False return o @@ -529,8 +529,7 @@ def import_dobs_string(content, full_output=False, separator_insertion=True): deltas.append(repdeltas) idl.append(repidl) - obsmeans = [np.average(deltas[j]) for j in range(len(deltas))] - res.append(Obs([np.array(deltas[j]) - obsmeans[j] for j in range(len(obsmeans))], obs_names, idl=idl, means=obsmeans)) + res.append(Obs(deltas, obs_names, idl=idl)) res[-1]._value = mean[i] _check(len(e_names) == ne) @@ -672,7 +671,7 @@ def _dobsdict_to_xmlstring_spaces(d, space=' '): o += space o += li + '\n' if li.startswith('<') and not cm: - if '<%s' % ('/') not in li: + if not '<%s' % ('/') in li: c += 1 cm = False return o diff --git a/pyerrors/input/hadrons.py b/pyerrors/input/hadrons.py index 525f564a..5b65f3c6 100644 --- a/pyerrors/input/hadrons.py +++ b/pyerrors/input/hadrons.py @@ -88,7 +88,7 @@ def read_hd5(filestem, ens_id, group, attrs=None, idl=None, part="real"): path_obj = Path(filestem) path = path_obj.parent.as_posix() - filestem = path_obj.name + filestem = path_obj.stem files, idx = _get_files(path, filestem, idl) @@ -113,7 +113,7 @@ def read_hd5(filestem, ens_id, group, attrs=None, idl=None, part="real"): infos = [] for hd5_file in files: h5file = h5py.File(path + '/' + hd5_file, "r") - if group + '/' + entry not in h5file: + if not group + '/' + entry in h5file: raise Exception("Entry '" + entry + "' not contained in the files.") raw_data = h5file[group + '/' + entry + '/corr'] real_data = raw_data[:].view("complex") @@ -186,7 +186,7 @@ def _extract_real_arrays(path, files, tree, keys): for hd5_file in files: h5file = h5py.File(path + '/' + hd5_file, "r") for key in keys: - if tree + '/' + key not in h5file: + if not tree + '/' + key in h5file: raise Exception("Entry '" + key + "' not contained in the files.") raw_data = h5file[tree + '/' + key + '/data'] real_data = raw_data[:].astype(np.double) diff --git a/pyerrors/input/json.py b/pyerrors/input/json.py index a2008f9c..ca3fb0d2 100644 --- a/pyerrors/input/json.py +++ b/pyerrors/input/json.py @@ -133,11 +133,10 @@ def create_json_string(ol, description='', indent=1): names = [] idl = [] for key, value in obs.idl.items(): - samples.append(np.array([np.nan] * len(value))) + samples.append([np.nan] * len(value)) names.append(key) idl.append(value) - my_obs = Obs(samples, names, idl, means=[np.nan for n in names]) - my_obs._value = np.nan + my_obs = Obs(samples, names, idl) my_obs._covobs = obs._covobs for name in obs._covobs: my_obs.names.append(name) @@ -332,8 +331,7 @@ def _parse_json_dict(json_dict, verbose=True, full_output=False): cd = _gen_covobsd_from_cdatad(o.get('cdata', {})) if od: - r_offsets = [np.average([ddi[0] for ddi in di]) for di in od['deltas']] - ret = Obs([np.array([ddi[0] for ddi in od['deltas'][i]]) - r_offsets[i] for i in range(len(od['deltas']))], od['names'], idl=od['idl'], means=[ro + values[0] for ro in r_offsets]) + ret = Obs([[ddi[0] + values[0] for ddi in di] for di in od['deltas']], od['names'], idl=od['idl']) ret._value = values[0] else: ret = Obs([], [], means=[]) @@ -358,8 +356,7 @@ def _parse_json_dict(json_dict, verbose=True, full_output=False): taglist = o.get('tag', layout * [None]) for i in range(layout): if od: - r_offsets = np.array([np.average(di[:, i]) for di in od['deltas']]) - ret.append(Obs([od['deltas'][j][:, i] - r_offsets[j] for j in range(len(od['deltas']))], od['names'], idl=od['idl'], means=[ro + values[i] for ro in r_offsets])) + ret.append(Obs([list(di[:, i] + values[i]) for di in od['deltas']], od['names'], idl=od['idl'])) ret[-1]._value = values[i] else: ret.append(Obs([], [], means=[])) @@ -386,8 +383,7 @@ def _parse_json_dict(json_dict, verbose=True, full_output=False): taglist = o.get('tag', N * [None]) for i in range(N): if od: - r_offsets = np.array([np.average(di[:, i]) for di in od['deltas']]) - ret.append(Obs([od['deltas'][j][:, i] - r_offsets[j] for j in range(len(od['deltas']))], od['names'], idl=od['idl'], means=[ro + values[i] for ro in r_offsets])) + ret.append(Obs([di[:, i] + values[i] for di in od['deltas']], od['names'], idl=od['idl'])) ret[-1]._value = values[i] else: ret.append(Obs([], [], means=[])) @@ -571,6 +567,7 @@ def _ol_from_dict(ind, reps='DICTOBS'): counter = 0 def dict_replace_obs(d): + nonlocal ol nonlocal counter x = {} for k, v in d.items(): @@ -591,6 +588,7 @@ def _ol_from_dict(ind, reps='DICTOBS'): return x def list_replace_obs(li): + nonlocal ol nonlocal counter x = [] for e in li: @@ -611,6 +609,7 @@ def _ol_from_dict(ind, reps='DICTOBS'): return x def obslist_replace_obs(li): + nonlocal ol nonlocal counter il = [] for e in li: @@ -691,6 +690,7 @@ def _od_from_list_and_dict(ol, ind, reps='DICTOBS'): def dict_replace_string(d): nonlocal counter + nonlocal ol x = {} for k, v in d.items(): if isinstance(v, dict): @@ -706,6 +706,7 @@ def _od_from_list_and_dict(ol, ind, reps='DICTOBS'): def list_replace_string(li): nonlocal counter + nonlocal ol x = [] for e in li: if isinstance(e, list): diff --git a/pyerrors/input/openQCD.py b/pyerrors/input/openQCD.py index 278977d2..36fa21b6 100644 --- a/pyerrors/input/openQCD.py +++ b/pyerrors/input/openQCD.py @@ -47,7 +47,7 @@ def read_rwms(path, prefix, version='2.0', names=None, **kwargs): Reweighting factors read """ known_oqcd_versions = ['1.4', '1.6', '2.0'] - if version not in known_oqcd_versions: + if not (version in known_oqcd_versions): raise Exception('Unknown openQCD version defined!') print("Working with openQCD version " + version) if 'postfix' in kwargs: @@ -1286,9 +1286,7 @@ def read_ms5_xsf(path, prefix, qc, corr, sep="r", **kwargs): imagsamples[repnum][t].append(corrres[1][t]) if 'idl' in kwargs: left_idl = list(left_idl) - if expected_idl[repnum] == left_idl: - raise ValueError("None of the idls searched for were found in replikum of file " + file) - elif len(left_idl) > 0: + if len(left_idl) > 0: warnings.warn('Could not find idls ' + str(left_idl) + ' in replikum of file ' + file, UserWarning) repnum += 1 s = "Read correlator " + corr + " from " + str(repnum) + " replika with idls" + str(realsamples[0][t]) diff --git a/pyerrors/input/pandas.py b/pyerrors/input/pandas.py index af446cfc..13482983 100644 --- a/pyerrors/input/pandas.py +++ b/pyerrors/input/pandas.py @@ -1,7 +1,6 @@ import warnings import gzip import sqlite3 -from contextlib import closing import pandas as pd from ..obs import Obs from ..correlators import Corr @@ -30,8 +29,9 @@ def to_sql(df, table_name, db, if_exists='fail', gz=True, **kwargs): None """ se_df = _serialize_df(df, gz=gz) - with closing(sqlite3.connect(db)) as con: - se_df.to_sql(table_name, con=con, if_exists=if_exists, index=False, **kwargs) + con = sqlite3.connect(db) + se_df.to_sql(table_name, con, if_exists=if_exists, index=False, **kwargs) + con.close() def read_sql(sql, db, auto_gamma=False, **kwargs): @@ -52,8 +52,9 @@ def read_sql(sql, db, auto_gamma=False, **kwargs): data : pandas.DataFrame Dataframe with the content of the sqlite database. """ - with closing(sqlite3.connect(db)) as con: - extract_df = pd.read_sql(sql, con=con, **kwargs) + con = sqlite3.connect(db) + extract_df = pd.read_sql(sql, con, **kwargs) + con.close() return _deserialize_df(extract_df, auto_gamma=auto_gamma) diff --git a/pyerrors/input/sfcf.py b/pyerrors/input/sfcf.py index 0431788a..e6cb0b49 100644 --- a/pyerrors/input/sfcf.py +++ b/pyerrors/input/sfcf.py @@ -4,13 +4,9 @@ import re import numpy as np # Thinly-wrapped numpy from ..obs import Obs from .utils import sort_names, check_idl -import itertools -sep = "/" - - -def read_sfcf(path, prefix, name, quarks='.*', corr_type="bi", noffset=0, wf=0, wf2=0, version="1.0c", cfg_separator="n", silent=False, **kwargs): +def read_sfcf(path, prefix, name, quarks='.*', corr_type='bi', noffset=0, wf=0, wf2=0, version="1.0c", cfg_separator="n", silent=False, **kwargs): """Read sfcf files from given folder structure. Parameters @@ -69,77 +65,6 @@ def read_sfcf(path, prefix, name, quarks='.*', corr_type="bi", noffset=0, wf=0, list of Observables with length T, observable per timeslice. bb-type correlators have length 1. """ - ret = read_sfcf_multi(path, prefix, [name], quarks_list=[quarks], corr_type_list=[corr_type], - noffset_list=[noffset], wf_list=[wf], wf2_list=[wf2], version=version, - cfg_separator=cfg_separator, silent=silent, **kwargs) - return ret[name][quarks][str(noffset)][str(wf)][str(wf2)] - - -def read_sfcf_multi(path, prefix, name_list, quarks_list=['.*'], corr_type_list=['bi'], noffset_list=[0], wf_list=[0], wf2_list=[0], version="1.0c", cfg_separator="n", silent=False, keyed_out=False, **kwargs): - """Read sfcf files from given folder structure. - - Parameters - ---------- - path : str - Path to the sfcf files. - prefix : str - Prefix of the sfcf files. - name : str - Name of the correlation function to read. - quarks_list : list[str] - Label of the quarks used in the sfcf input file. e.g. "quark quark" - for version 0.0 this does NOT need to be given with the typical " - " - that is present in the output file, - this is done automatically for this version - corr_type_list : list[str] - Type of correlation function to read. Can be - - 'bi' for boundary-inner - - 'bb' for boundary-boundary - - 'bib' for boundary-inner-boundary - noffset_list : list[int] - Offset of the source (only relevant when wavefunctions are used) - wf_list : int - ID of wave function - wf2_list : list[int] - ID of the second wavefunction - (only relevant for boundary-to-boundary correlation functions) - im : bool - if True, read imaginary instead of real part - of the correlation function. - names : list - Alternative labeling for replicas/ensembles. - Has to have the appropriate length - ens_name : str - replaces the name of the ensemble - version: str - version of SFCF, with which the measurement was done. - if the compact output option (-c) was specified, - append a "c" to the version (e.g. "1.0c") - if the append output option (-a) was specified, - append an "a" to the version - cfg_separator : str - String that separates the ensemble identifier from the configuration number (default 'n'). - replica: list - list of replica to be read, default is all - files: list[list[int]] - list of files to be read per replica, default is all. - for non-compact output format, hand the folders to be read here. - check_configs: list[list[int]] - list of list of supposed configs, eg. [range(1,1000)] - for one replicum with 1000 configs - rep_string: str - Separator of ensemble name and replicum. Example: In "ensAr0", "r" would be the separator string. - Returns - ------- - result: dict[list[Obs]] - dict with one of the following properties: - if keyed_out: - dict[key] = list[Obs] - where key has the form name/quarks/offset/wf/wf2 - if not keyed_out: - dict[name][quarks][offset][wf][wf2] = list[Obs] - """ - if kwargs.get('im'): im = 1 part = 'imaginary' @@ -147,6 +72,16 @@ def read_sfcf_multi(path, prefix, name_list, quarks_list=['.*'], corr_type_list= im = 0 part = 'real' + if corr_type == 'bb': + b2b = True + single = True + elif corr_type == 'bib': + b2b = True + single = False + else: + b2b = False + single = False + known_versions = ["0.0", "1.0", "2.0", "1.0c", "2.0c", "1.0a", "2.0a"] if version not in known_versions: @@ -185,10 +120,8 @@ def read_sfcf_multi(path, prefix, name_list, quarks_list=['.*'], corr_type_list= else: replica = len([file.split(".")[-1] for file in ls]) // len(set([file.split(".")[-1] for file in ls])) - if replica == 0: - raise Exception('No replica found in directory') if not silent: - print('Read', part, 'part of', name_list, 'from', prefix[:-1], ',', replica, 'replica') + print('Read', part, 'part of', name, 'from', prefix[:-1], ',', replica, 'replica') if 'names' in kwargs: new_names = kwargs.get('names') @@ -200,66 +133,17 @@ def read_sfcf_multi(path, prefix, name_list, quarks_list=['.*'], corr_type_list= else: ens_name = kwargs.get("ens_name") if not appended: - new_names = _get_rep_names(ls, ens_name, rep_sep=(kwargs.get('rep_string', 'r'))) + new_names = _get_rep_names(ls, ens_name) else: - new_names = _get_appended_rep_names(ls, prefix, name_list[0], ens_name, rep_sep=(kwargs.get('rep_string', 'r'))) + new_names = _get_appended_rep_names(ls, prefix, name, ens_name) new_names = sort_names(new_names) idl = [] - - noffset_list = [str(x) for x in noffset_list] - wf_list = [str(x) for x in wf_list] - wf2_list = [str(x) for x in wf2_list] - - # setup dict structures - intern = {} - for name, corr_type in zip(name_list, corr_type_list): - intern[name] = {} - b2b, single = _extract_corr_type(corr_type) - intern[name]["b2b"] = b2b - intern[name]["single"] = single - intern[name]["spec"] = {} - for quarks in quarks_list: - intern[name]["spec"][quarks] = {} - for off in noffset_list: - intern[name]["spec"][quarks][off] = {} - for w in wf_list: - intern[name]["spec"][quarks][off][w] = {} - if b2b: - for w2 in wf2_list: - intern[name]["spec"][quarks][off][w][w2] = {} - intern[name]["spec"][quarks][off][w][w2]["pattern"] = _make_pattern(version, name, off, w, w2, intern[name]['b2b'], quarks) - else: - intern[name]["spec"][quarks][off][w]["0"] = {} - intern[name]["spec"][quarks][off][w]["0"]["pattern"] = _make_pattern(version, name, off, w, 0, intern[name]['b2b'], quarks) - - internal_ret_dict = {} - needed_keys = [] - for name, corr_type in zip(name_list, corr_type_list): - b2b, single = _extract_corr_type(corr_type) - if b2b: - needed_keys.extend(_lists2key([name], quarks_list, noffset_list, wf_list, wf2_list)) - else: - needed_keys.extend(_lists2key([name], quarks_list, noffset_list, wf_list, ["0"])) - - for key in needed_keys: - internal_ret_dict[key] = [] - if not appended: for i, item in enumerate(ls): rep_path = path + '/' + item if "files" in kwargs: files = kwargs.get("files") - if isinstance(files, list): - if all(isinstance(f, list) for f in files): - files = files[i] - elif all(isinstance(f, str) for f in files): - files = files - else: - raise TypeError("files has to be of type list[list[str]] or list[str]!") - else: - raise TypeError("files has to be of type list[list[str]] or list[str]!") - else: files = [] sub_ls = _find_files(rep_path, prefix, compact, files) @@ -272,7 +156,7 @@ def read_sfcf_multi(path, prefix, name_list, quarks_list=['.*'], corr_type_list= else: rep_idl.append(int(cfg[3:])) except Exception: - raise Exception("Couldn't parse idl from directory, problem with file " + cfg) + raise Exception("Couldn't parse idl from directroy, problem with file " + cfg) rep_idl.sort() # maybe there is a better way to print the idls if not silent: @@ -280,89 +164,67 @@ def read_sfcf_multi(path, prefix, name_list, quarks_list=['.*'], corr_type_list= idl.append(rep_idl) # here we have found all the files we need to look into. if i == 0: - if version != "0.0" and compact: - file = path + '/' + item + '/' + sub_ls[0] - for name_index, name in enumerate(name_list): - if version == "0.0" or not compact: - file = path + '/' + item + '/' + sub_ls[0] + '/' + name - if corr_type_list[name_index] == 'bi': - name_keys = _lists2key(quarks_list, noffset_list, wf_list, ["0"]) + # here, we want to find the place within the file, + # where the correlator we need is stored. + # to do so, the pattern needed is put together + # from the input values + if version == "0.0": + file = path + '/' + item + '/' + sub_ls[0] + '/' + name + else: + if compact: + file = path + '/' + item + '/' + sub_ls[0] else: - name_keys = _lists2key(quarks_list, noffset_list, wf_list, wf2_list) - for key in name_keys: - specs = _key2specs(key) - quarks = specs[0] - off = specs[1] - w = specs[2] - w2 = specs[3] - # here, we want to find the place within the file, - # where the correlator we need is stored. - # to do so, the pattern needed is put together - # from the input values - start_read, T = _find_correlator(file, version, intern[name]["spec"][quarks][str(off)][str(w)][str(w2)]["pattern"], intern[name]['b2b'], silent=silent) - intern[name]["spec"][quarks][str(off)][str(w)][str(w2)]["start"] = start_read - intern[name]["T"] = T - # preparing the datastructure - # the correlators get parsed into... - deltas = [] - for j in range(intern[name]["T"]): - deltas.append([]) - internal_ret_dict[sep.join([name, key])] = deltas + file = path + '/' + item + '/' + sub_ls[0] + '/' + name + + pattern = _make_pattern(version, name, noffset, wf, wf2, b2b, quarks) + start_read, T = _find_correlator(file, version, pattern, b2b, silent=silent) + + # preparing the datastructure + # the correlators get parsed into... + deltas = [] + for j in range(T): + deltas.append([]) if compact: - rep_deltas = _read_compact_rep(path, item, sub_ls, intern, needed_keys, im) - for key in needed_keys: - name = _key2specs(key)[0] - for t in range(intern[name]["T"]): - internal_ret_dict[key][t].append(rep_deltas[key][t]) - else: - for key in needed_keys: - rep_data = [] - name = _key2specs(key)[0] - for subitem in sub_ls: - cfg_path = path + '/' + item + '/' + subitem - file_data = _read_o_file(cfg_path, name, needed_keys, intern, version, im) - rep_data.append(file_data) - for t in range(intern[name]["T"]): - internal_ret_dict[key][t].append([]) - for cfg in range(no_cfg): - internal_ret_dict[key][t][i].append(rep_data[cfg][key][t]) - else: - for key in needed_keys: - specs = _key2specs(key) - name = specs[0] - quarks = specs[1] - off = specs[2] - w = specs[3] - w2 = specs[4] - if "files" in kwargs: - if isinstance(kwargs.get("files"), list) and all(isinstance(f, str) for f in kwargs.get("files")): - name_ls = kwargs.get("files") - else: - raise TypeError("In append mode, files has to be of type list[str]!") - else: - name_ls = ls - for exc in name_ls: - if not fnmatch.fnmatch(exc, prefix + '*.' + name): - name_ls = list(set(name_ls) - set([exc])) - name_ls = sort_names(name_ls) - pattern = intern[name]['spec'][quarks][off][w][w2]['pattern'] - deltas = [] - for rep, file in enumerate(name_ls): - rep_idl = [] - filename = path + '/' + file - T, rep_idl, rep_data = _read_append_rep(filename, pattern, intern[name]['b2b'], cfg_separator, im, intern[name]['single']) - if rep == 0: - intern[name]['T'] = T - for t in range(intern[name]['T']): - deltas.append([]) - for t in range(intern[name]['T']): - deltas[t].append(rep_data[t]) - internal_ret_dict[key] = deltas - if name == name_list[0]: - idl.append(rep_idl) + rep_deltas = _read_compact_rep(path, item, sub_ls, start_read, T, b2b, name, im) - if kwargs.get("check_configs") is True: + for t in range(T): + deltas[t].append(rep_deltas[t]) + else: + for t in range(T): + deltas[t].append(np.zeros(no_cfg)) + for cnfg, subitem in enumerate(sub_ls): + with open(path + '/' + item + '/' + subitem + '/' + name) as fp: + for k, line in enumerate(fp): + if (k >= start_read and k < start_read + T): + floats = list(map(float, line.split())) + if version == "0.0": + deltas[k - start_read][i][cnfg] = floats[im - single] + else: + deltas[k - start_read][i][cnfg] = floats[1 + im - single] + + else: + if "files" in kwargs: + ls = kwargs.get("files") + else: + for exc in ls: + if not fnmatch.fnmatch(exc, prefix + '*.' + name): + ls = list(set(ls) - set([exc])) + ls = sort_names(ls) + pattern = _make_pattern(version, name, noffset, wf, wf2, b2b, quarks) + deltas = [] + for rep, file in enumerate(ls): + rep_idl = [] + filename = path + '/' + file + T, rep_idl, rep_data = _read_append_rep(filename, pattern, b2b, cfg_separator, im, single) + if rep == 0: + for t in range(T): + deltas.append([]) + for t in range(T): + deltas[t].append(rep_data[t]) + idl.append(rep_idl) + + if "check_configs" in kwargs: if not silent: print("Checking for missing configs...") che = kwargs.get("check_configs") @@ -374,91 +236,10 @@ def read_sfcf_multi(path, prefix, name_list, quarks_list=['.*'], corr_type_list= check_idl(idl[r], che[r]) if not silent: print("Done") - - result_dict = {} - if keyed_out: - for key in needed_keys: - name = _key2specs(key)[0] - result = [] - for t in range(intern[name]["T"]): - result.append(Obs(internal_ret_dict[key][t], new_names, idl=idl)) - result_dict[key] = result - else: - for name, corr_type in zip(name_list, corr_type_list): - result_dict[name] = {} - for quarks in quarks_list: - result_dict[name][quarks] = {} - for off in noffset_list: - result_dict[name][quarks][off] = {} - for w in wf_list: - result_dict[name][quarks][off][w] = {} - if corr_type != 'bi': - for w2 in wf2_list: - key = _specs2key(name, quarks, off, w, w2) - result = [] - for t in range(intern[name]["T"]): - result.append(Obs(internal_ret_dict[key][t], new_names, idl=idl)) - result_dict[name][quarks][str(off)][str(w)][str(w2)] = result - else: - key = _specs2key(name, quarks, off, w, "0") - result = [] - for t in range(intern[name]["T"]): - result.append(Obs(internal_ret_dict[key][t], new_names, idl=idl)) - result_dict[name][quarks][str(off)][str(w)][str(0)] = result - return result_dict - - -def _lists2key(*lists): - keys = [] - for tup in itertools.product(*lists): - keys.append(sep.join(tup)) - return keys - - -def _key2specs(key): - return key.split(sep) - - -def _specs2key(*specs): - return sep.join(specs) - - -def _read_o_file(cfg_path, name, needed_keys, intern, version, im): - return_vals = {} - for key in needed_keys: - file = cfg_path + '/' + name - specs = _key2specs(key) - if specs[0] == name: - with open(file) as fp: - lines = fp.readlines() - quarks = specs[1] - off = specs[2] - w = specs[3] - w2 = specs[4] - T = intern[name]["T"] - start_read = intern[name]["spec"][quarks][off][w][w2]["start"] - deltas = [] - for line in lines[start_read:start_read + T]: - floats = list(map(float, line.split())) - if version == "0.0": - deltas.append(floats[im - intern[name]["single"]]) - else: - deltas.append(floats[1 + im - intern[name]["single"]]) - return_vals[key] = deltas - return return_vals - - -def _extract_corr_type(corr_type): - if corr_type == 'bb': - b2b = True - single = True - elif corr_type == 'bib': - b2b = True - single = False - else: - b2b = False - single = False - return b2b, single + result = [] + for t in range(T): + result.append(Obs(deltas[t], new_names, idl=idl)) + return result def _find_files(rep_path, prefix, compact, files=[]): @@ -528,57 +309,38 @@ def _find_correlator(file_name, version, pattern, b2b, silent=False): return start_read, T -def _read_compact_file(rep_path, cfg_file, intern, needed_keys, im): - return_vals = {} - with open(rep_path + cfg_file) as fp: +def _read_compact_file(rep_path, config_file, start_read, T, b2b, name, im): + with open(rep_path + config_file) as fp: lines = fp.readlines() - for key in needed_keys: - keys = _key2specs(key) - name = keys[0] - quarks = keys[1] - off = keys[2] - w = keys[3] - w2 = keys[4] + # check, if the correlator is in fact + # printed completely + if (start_read + T + 1 > len(lines)): + raise Exception("EOF before end of correlator data! Maybe " + rep_path + config_file + " is corrupted?") + corr_lines = lines[start_read - 6: start_read + T] + del lines + t_vals = [] - T = intern[name]["T"] - start_read = intern[name]["spec"][quarks][off][w][w2]["start"] - # check, if the correlator is in fact - # printed completely - if (start_read + T + 1 > len(lines)): - raise Exception("EOF before end of correlator data! Maybe " + rep_path + cfg_file + " is corrupted?") - corr_lines = lines[start_read - 6: start_read + T] - t_vals = [] + if corr_lines[1 - b2b].strip() != 'name ' + name: + raise Exception('Wrong format in file', config_file) - if corr_lines[1 - intern[name]["b2b"]].strip() != 'name ' + name: - raise Exception('Wrong format in file', cfg_file) - - for k in range(6, T + 6): - floats = list(map(float, corr_lines[k].split())) - t_vals.append(floats[-2:][im]) - return_vals[key] = t_vals - return return_vals + for k in range(6, T + 6): + floats = list(map(float, corr_lines[k].split())) + t_vals.append(floats[-2:][im]) + return t_vals -def _read_compact_rep(path, rep, sub_ls, intern, needed_keys, im): +def _read_compact_rep(path, rep, sub_ls, start_read, T, b2b, name, im): rep_path = path + '/' + rep + '/' no_cfg = len(sub_ls) - - return_vals = {} - for key in needed_keys: - name = _key2specs(key)[0] - deltas = [] - for t in range(intern[name]["T"]): - deltas.append(np.zeros(no_cfg)) - return_vals[key] = deltas - + deltas = [] + for t in range(T): + deltas.append(np.zeros(no_cfg)) for cfg in range(no_cfg): cfg_file = sub_ls[cfg] - cfg_data = _read_compact_file(rep_path, cfg_file, intern, needed_keys, im) - for key in needed_keys: - name = _key2specs(key)[0] - for t in range(intern[name]["T"]): - return_vals[key][t][cfg] = cfg_data[key][t] - return return_vals + cfg_data = _read_compact_file(rep_path, cfg_file, start_read, T, b2b, name, im) + for t in range(T): + deltas[t][cfg] = cfg_data[t] + return deltas def _read_chunk(chunk, gauge_line, cfg_sep, start_read, T, corr_line, b2b, pattern, im, single): @@ -647,22 +409,22 @@ def _read_append_rep(filename, pattern, b2b, cfg_separator, im, single): return T, rep_idl, data -def _get_rep_names(ls, ens_name=None, rep_sep='r'): +def _get_rep_names(ls, ens_name=None): new_names = [] for entry in ls: try: - idx = entry.index(rep_sep) + idx = entry.index('r') except Exception: raise Exception("Automatic recognition of replicum failed, please enter the key word 'names'.") if ens_name: - new_names.append(ens_name + '|' + entry[idx:]) + new_names.append('ens_name' + '|' + entry[idx:]) else: new_names.append(entry[:idx] + '|' + entry[idx:]) return new_names -def _get_appended_rep_names(ls, prefix, name, ens_name=None, rep_sep='r'): +def _get_appended_rep_names(ls, prefix, name, ens_name=None): new_names = [] for exc in ls: if not fnmatch.fnmatch(exc, prefix + '*.' + name): @@ -671,12 +433,12 @@ def _get_appended_rep_names(ls, prefix, name, ens_name=None, rep_sep='r'): for entry in ls: myentry = entry[:-len(name) - 1] try: - idx = myentry.index(rep_sep) + idx = myentry.index('r') except Exception: raise Exception("Automatic recognition of replicum failed, please enter the key word 'names'.") if ens_name: - new_names.append(ens_name + '|' + entry[idx:]) + new_names.append('ens_name' + '|' + entry[idx:]) else: new_names.append(myentry[:idx] + '|' + myentry[idx:]) return new_names diff --git a/pyerrors/input/utils.py b/pyerrors/input/utils.py index eaf41f06..f9eedd68 100644 --- a/pyerrors/input/utils.py +++ b/pyerrors/input/utils.py @@ -1,8 +1,5 @@ -"""Utilities for the input""" - import re -import fnmatch -import os +"""Utilities for the input""" def sort_names(ll): @@ -20,7 +17,6 @@ def sort_names(ll): ll: list sorted list """ - if len(ll) > 1: sorted = False r_pattern = r'r(\d+)' @@ -67,7 +63,6 @@ def check_idl(idl, che): miss_str : str string with integers of which idls are missing """ - missing = [] for c in che: if c not in idl: @@ -80,65 +75,3 @@ def check_idl(idl, che): miss_str += "," + str(i) print(miss_str) return miss_str - - -def check_params(path, param_hash, prefix, param_prefix="parameters_"): - """ - Check if, for sfcf, the parameter hashes at the end of the parameter files are in fact the expected one. - - Parameters - ---------- - path: str - measurement path, same as for sfcf read method - param_hash: str - expected parameter hash - prefix: str - data prefix to find the appropriate replicum folders in path - param_prefix: str - prefix of the parameter file. Defaults to 'parameters_' - - Returns - ------- - nums: dict - dictionary of faulty parameter files sorted by the replica paths - """ - - ls = [] - for (dirpath, dirnames, filenames) in os.walk(path): - ls.extend(dirnames) - break - if not ls: - raise Exception('Error, directory not found') - # Exclude folders with different names - for exc in ls: - if not fnmatch.fnmatch(exc, prefix + '*'): - ls = list(set(ls) - set([exc])) - - ls = sort_names(ls) - nums = {} - for rep in ls: - rep_path = path + '/' + rep - # files of replicum - sub_ls = [] - for (dirpath, dirnames, filenames) in os.walk(rep_path): - sub_ls.extend(filenames) - - # filter - param_files = [] - for file in sub_ls: - if fnmatch.fnmatch(file, param_prefix + '*'): - param_files.append(file) - - rep_nums = '' - for file in param_files: - with open(rep_path + '/' + file) as fp: - for line in fp: - pass - last_line = line - if last_line.split()[2] != param_hash: - rep_nums += file.split("_")[1] + ',' - nums[rep_path] = rep_nums - - if not len(rep_nums) == 0: - raise Warning("found differing parameter hash in the param files in " + rep_path) - return nums diff --git a/pyerrors/linalg.py b/pyerrors/linalg.py index 5a489e26..73c93169 100644 --- a/pyerrors/linalg.py +++ b/pyerrors/linalg.py @@ -271,12 +271,6 @@ def eig(obs, **kwargs): return w -def eigv(obs, **kwargs): - """Computes the eigenvectors of a given hermitian matrix of Obs according to np.linalg.eigh.""" - v = derived_observable(lambda x, **kwargs: anp.linalg.eigh(x)[1], obs) - return v - - def pinv(obs, **kwargs): """Computes the Moore-Penrose pseudoinverse of a matrix of Obs.""" return derived_observable(lambda x, **kwargs: anp.linalg.pinv(x), obs) diff --git a/pyerrors/misc.py b/pyerrors/misc.py index 94a7d4c2..d71a2bb5 100644 --- a/pyerrors/misc.py +++ b/pyerrors/misc.py @@ -20,7 +20,7 @@ def print_config(): "pandas": pd.__version__} for key, value in config.items(): - print(f"{key: <10}\t {value}") + print(f"{key : <10}\t {value}") def errorbar(x, y, axes=plt, **kwargs): diff --git a/pyerrors/obs.py b/pyerrors/obs.py index 87591cd9..e9dc20cb 100644 --- a/pyerrors/obs.py +++ b/pyerrors/obs.py @@ -82,8 +82,6 @@ class Obs: raise ValueError('Names are not unique.') if not all(isinstance(x, str) for x in names): raise TypeError('All names have to be strings.') - if len(set([o.split('|')[0] for o in names])) > 1: - raise ValueError('Cannot initialize Obs based on multiple ensembles. Please average separate Obs from each ensemble.') else: if not isinstance(names[0], str): raise TypeError('All names have to be strings.') @@ -106,9 +104,7 @@ class Obs: elif isinstance(idx, (list, np.ndarray)): dc = np.unique(np.diff(idx)) if np.any(dc < 0): - raise ValueError("Unsorted idx for idl[%s] at position %s" % (name, ' '.join(['%s' % (pos + 1) for pos in np.where(np.diff(idx) < 0)[0]]))) - elif np.any(dc == 0): - raise ValueError("Duplicate entries in idx for idl[%s] at position %s" % (name, ' '.join(['%s' % (pos + 1) for pos in np.where(np.diff(idx) == 0)[0]]))) + raise ValueError("Unsorted idx for idl[%s]" % (name)) if len(dc) == 1: self.idl[name] = range(idx[0], idx[-1] + dc[0], dc[0]) else: @@ -224,7 +220,7 @@ class Obs: tmp = kwargs.get(kwarg_name) if isinstance(tmp, (int, float)): if tmp < 0: - raise ValueError(kwarg_name + ' has to be larger or equal to 0.') + raise Exception(kwarg_name + ' has to be larger or equal to 0.') for e, e_name in enumerate(self.e_names): getattr(self, kwarg_name)[e_name] = tmp else: @@ -293,7 +289,7 @@ class Obs: texp = self.tau_exp[e_name] # Critical slowing down analysis if w_max // 2 <= 1: - raise ValueError("Need at least 8 samples for tau_exp error analysis") + raise Exception("Need at least 8 samples for tau_exp error analysis") for n in range(1, w_max // 2): _compute_drho(n + 1) if (self.e_rho[e_name][n] - self.N_sigma[e_name] * self.e_drho[e_name][n]) < 0 or n >= w_max // 2 - 2: @@ -622,7 +618,7 @@ class Obs: if not hasattr(self, 'e_dvalue'): raise Exception('Run the gamma method first.') if np.isclose(0.0, self._dvalue, atol=1e-15): - raise ValueError('Error is 0.0') + raise Exception('Error is 0.0') labels = self.e_names sizes = [self.e_dvalue[name] ** 2 for name in labels] / self._dvalue ** 2 fig1, ax1 = plt.subplots() @@ -661,7 +657,7 @@ class Obs: with open(file_name + '.p', 'wb') as fb: pickle.dump(self, fb) else: - raise TypeError("Unknown datatype " + str(datatype)) + raise Exception("Unknown datatype " + str(datatype)) def export_jackknife(self): """Export jackknife samples from the Obs @@ -678,7 +674,7 @@ class Obs: """ if len(self.names) != 1: - raise ValueError("'export_jackknife' is only implemented for Obs defined on one ensemble and replicum.") + raise Exception("'export_jackknife' is only implemented for Obs defined on one ensemble and replicum.") name = self.names[0] full_data = self.deltas[name] + self.r_values[name] @@ -713,7 +709,7 @@ class Obs: should agree with samples from a full bootstrap analysis up to O(1/N). """ if len(self.names) != 1: - raise ValueError("'export_boostrap' is only implemented for Obs defined on one ensemble and replicum.") + raise Exception("'export_boostrap' is only implemented for Obs defined on one ensemble and replicum.") name = self.names[0] length = self.N @@ -788,8 +784,6 @@ class Obs: else: if isinstance(y, np.ndarray): return np.array([self + o for o in y]) - elif isinstance(y, complex): - return CObs(self, 0) + y elif y.__class__.__name__ in ['Corr', 'CObs']: return NotImplemented else: @@ -858,12 +852,15 @@ class Obs: def __pow__(self, y): if isinstance(y, Obs): - return derived_observable(lambda x, **kwargs: x[0] ** x[1], [self, y], man_grad=[y.value * self.value ** (y.value - 1), self.value ** y.value * np.log(self.value)]) + return derived_observable(lambda x: x[0] ** x[1], [self, y]) else: - return derived_observable(lambda x, **kwargs: x[0] ** y, [self], man_grad=[y * self.value ** (y - 1)]) + return derived_observable(lambda x: x[0] ** y, [self]) def __rpow__(self, y): - return derived_observable(lambda x, **kwargs: y ** x[0], [self], man_grad=[y ** self.value * np.log(y)]) + if isinstance(y, Obs): + return derived_observable(lambda x: x[0] ** x[1], [y, self]) + else: + return derived_observable(lambda x: y ** x[0], [self]) def __abs__(self): return derived_observable(lambda x: anp.abs(x[0]), [self]) @@ -1137,7 +1134,7 @@ def _intersection_idx(idl): return idinter -def _expand_deltas_for_merge(deltas, idx, shape, new_idx, scalefactor): +def _expand_deltas_for_merge(deltas, idx, shape, new_idx): """Expand deltas defined on idx to the list of configs that is defined by new_idx. New, empty entries are filled by 0. If idx and new_idx are of type range, the smallest common divisor of the step sizes is used as new step size. @@ -1153,20 +1150,15 @@ def _expand_deltas_for_merge(deltas, idx, shape, new_idx, scalefactor): Number of configs in idx. new_idx : list List of configs that defines the new range, has to be sorted in ascending order. - scalefactor : float - An additional scaling factor that can be applied to scale the fluctuations, - e.g., when Obs with differing numbers of replica are merged. """ + if type(idx) is range and type(new_idx) is range: if idx == new_idx: - if scalefactor == 1: - return deltas - else: - return deltas * scalefactor + return deltas ret = np.zeros(new_idx[-1] - new_idx[0] + 1) for i in range(shape): ret[idx[i] - new_idx[0]] = deltas[i] - return np.array([ret[new_idx[i] - new_idx[0]] for i in range(len(new_idx))]) * len(new_idx) / len(idx) * scalefactor + return np.array([ret[new_idx[i] - new_idx[0]] for i in range(len(new_idx))]) * len(new_idx) / len(idx) def derived_observable(func, data, array_mode=False, **kwargs): @@ -1247,29 +1239,10 @@ def derived_observable(func, data, array_mode=False, **kwargs): new_r_values[name] = func(tmp_values, **kwargs) new_idl_d[name] = _merge_idx(idl) - def _compute_scalefactor_missing_rep(obs): - """ - Computes the scale factor that is to be multiplied with the deltas - in the case where Obs with different subsets of replica are merged. - Returns a dictionary with the scale factor for each Monte Carlo name. - - Parameters - ---------- - obs : Obs - The observable corresponding to the deltas that are to be scaled - """ - scalef_d = {} - for mc_name in obs.mc_names: - mc_idl_d = [name for name in obs.idl if name.startswith(mc_name + '|')] - new_mc_idl_d = [name for name in new_idl_d if name.startswith(mc_name + '|')] - if len(mc_idl_d) > 0 and len(mc_idl_d) < len(new_mc_idl_d): - scalef_d[mc_name] = sum([len(new_idl_d[name]) for name in new_mc_idl_d]) / sum([len(new_idl_d[name]) for name in mc_idl_d]) - return scalef_d - if 'man_grad' in kwargs: deriv = np.asarray(kwargs.get('man_grad')) if new_values.shape + data.shape != deriv.shape: - raise ValueError('Manual derivative does not have correct shape.') + raise Exception('Manual derivative does not have correct shape.') elif kwargs.get('num_grad') is True: if multi > 0: raise Exception('Multi mode currently not supported for numerical derivative') @@ -1303,7 +1276,7 @@ def derived_observable(func, data, array_mode=False, **kwargs): d_extracted[name] = [] ens_length = len(new_idl_d[name]) for i_dat, dat in enumerate(data): - d_extracted[name].append(np.array([_expand_deltas_for_merge(o.deltas.get(name, np.zeros(ens_length)), o.idl.get(name, new_idl_d[name]), o.shape.get(name, ens_length), new_idl_d[name], _compute_scalefactor_missing_rep(o).get(name.split('|')[0], 1)) for o in dat.reshape(np.prod(dat.shape))]).reshape(dat.shape + (ens_length, ))) + d_extracted[name].append(np.array([_expand_deltas_for_merge(o.deltas.get(name, np.zeros(ens_length)), o.idl.get(name, new_idl_d[name]), o.shape.get(name, ens_length), new_idl_d[name]) for o in dat.reshape(np.prod(dat.shape))]).reshape(dat.shape + (ens_length, ))) for name in new_cov_names: g_extracted[name] = [] zero_grad = _Zero_grad(new_covobs_lengths[name]) @@ -1325,17 +1298,16 @@ def derived_observable(func, data, array_mode=False, **kwargs): new_grad[name] += np.tensordot(deriv[i_val + (i_dat, )], dat) else: for j_obs, obs in np.ndenumerate(data): - scalef_d = _compute_scalefactor_missing_rep(obs) for name in obs.names: if name in obs.cov_names: new_grad[name] = new_grad.get(name, 0) + deriv[i_val + j_obs] * obs.covobs[name].grad else: - new_deltas[name] = new_deltas.get(name, 0) + deriv[i_val + j_obs] * _expand_deltas_for_merge(obs.deltas[name], obs.idl[name], obs.shape[name], new_idl_d[name], scalef_d.get(name.split('|')[0], 1)) + new_deltas[name] = new_deltas.get(name, 0) + deriv[i_val + j_obs] * _expand_deltas_for_merge(obs.deltas[name], obs.idl[name], obs.shape[name], new_idl_d[name]) new_covobs = {name: Covobs(0, allcov[name], name, grad=new_grad[name]) for name in new_grad} if not set(new_covobs.keys()).isdisjoint(new_deltas.keys()): - raise ValueError('The same name has been used for deltas and covobs!') + raise Exception('The same name has been used for deltas and covobs!') new_samples = [] new_means = [] new_idl = [] @@ -1376,7 +1348,7 @@ def _reduce_deltas(deltas, idx_old, idx_new): Has to be a subset of idx_old. """ if not len(deltas) == len(idx_old): - raise ValueError('Length of deltas and idx_old have to be the same: %d != %d' % (len(deltas), len(idx_old))) + raise Exception('Length of deltas and idx_old have to be the same: %d != %d' % (len(deltas), len(idx_old))) if type(idx_old) is range and type(idx_new) is range: if idx_old == idx_new: return deltas @@ -1384,7 +1356,7 @@ def _reduce_deltas(deltas, idx_old, idx_new): return deltas indices = np.intersect1d(idx_old, idx_new, assume_unique=True, return_indices=True)[1] if len(indices) < len(idx_new): - raise ValueError('Error in _reduce_deltas: Config of idx_new not in idx_old') + raise Exception('Error in _reduce_deltas: Config of idx_new not in idx_old') return np.array(deltas)[indices] @@ -1406,14 +1378,12 @@ def reweight(weight, obs, **kwargs): result = [] for i in range(len(obs)): if len(obs[i].cov_names): - raise ValueError('Error: Not possible to reweight an Obs that contains covobs!') + raise Exception('Error: Not possible to reweight an Obs that contains covobs!') if not set(obs[i].names).issubset(weight.names): - raise ValueError('Error: Ensembles do not fit') - if len(obs[i].mc_names) > 1 or len(weight.mc_names) > 1: - raise ValueError('Error: Cannot reweight an Obs that contains multiple ensembles.') + raise Exception('Error: Ensembles do not fit') for name in obs[i].names: if not set(obs[i].idl[name]).issubset(weight.idl[name]): - raise ValueError('obs[%d] has to be defined on a subset of the configs in weight.idl[%s]!' % (i, name)) + raise Exception('obs[%d] has to be defined on a subset of the configs in weight.idl[%s]!' % (i, name)) new_samples = [] w_deltas = {} for name in sorted(obs[i].names): @@ -1446,21 +1416,18 @@ def correlate(obs_a, obs_b): ----- Keep in mind to only correlate primary observables which have not been reweighted yet. The reweighting has to be applied after correlating the observables. - Only works if a single ensemble is present in the Obs. - Currently only works if ensemble content is identical (this is not strictly necessary). + Currently only works if ensembles are identical (this is not strictly necessary). """ - if len(obs_a.mc_names) > 1 or len(obs_b.mc_names) > 1: - raise ValueError('Error: Cannot correlate Obs that contain multiple ensembles.') if sorted(obs_a.names) != sorted(obs_b.names): - raise ValueError(f"Ensembles do not fit {set(sorted(obs_a.names)) ^ set(sorted(obs_b.names))}") + raise Exception(f"Ensembles do not fit {set(sorted(obs_a.names)) ^ set(sorted(obs_b.names))}") if len(obs_a.cov_names) or len(obs_b.cov_names): - raise ValueError('Error: Not possible to correlate Obs that contain covobs!') + raise Exception('Error: Not possible to correlate Obs that contain covobs!') for name in obs_a.names: if obs_a.shape[name] != obs_b.shape[name]: - raise ValueError('Shapes of ensemble', name, 'do not fit') + raise Exception('Shapes of ensemble', name, 'do not fit') if obs_a.idl[name] != obs_b.idl[name]: - raise ValueError('idl of ensemble', name, 'do not fit') + raise Exception('idl of ensemble', name, 'do not fit') if obs_a.reweighted is True: warnings.warn("The first observable is already reweighted.", RuntimeWarning) @@ -1548,92 +1515,6 @@ def covariance(obs, visualize=False, correlation=False, smooth=None, **kwargs): return cov -def invert_corr_cov_cholesky(corr, inverrdiag): - """Constructs a lower triangular matrix `chol` via the Cholesky decomposition of the correlation matrix `corr` - and then returns the inverse covariance matrix `chol_inv` as a lower triangular matrix by solving `chol * x = inverrdiag`. - - Parameters - ---------- - corr : np.ndarray - correlation matrix - inverrdiag : np.ndarray - diagonal matrix, the entries are the inverse errors of the data points considered - """ - - condn = np.linalg.cond(corr) - if condn > 0.1 / np.finfo(float).eps: - raise ValueError(f"Cannot invert correlation matrix as its condition number exceeds machine precision ({condn:1.2e})") - if condn > 1e13: - warnings.warn("Correlation matrix may be ill-conditioned, condition number: {%1.2e}" % (condn), RuntimeWarning) - chol = np.linalg.cholesky(corr) - chol_inv = scipy.linalg.solve_triangular(chol, inverrdiag, lower=True) - - return chol_inv - - -def sort_corr(corr, kl, yd): - """ Reorders a correlation matrix to match the alphabetical order of its underlying y data. - - The ordering of the input correlation matrix `corr` is given by the list of keys `kl`. - The input dictionary `yd` (with the same keys `kl`) must contain the corresponding y data - that the correlation matrix is based on. - This function sorts the list of keys `kl` alphabetically and sorts the matrix `corr` - according to this alphabetical order such that the sorted matrix `corr_sorted` corresponds - to the y data `yd` when arranged in an alphabetical order by its keys. - - Parameters - ---------- - corr : np.ndarray - A square correlation matrix constructed using the order of the y data specified by `kl`. - The dimensions of `corr` should match the total number of y data points in `yd` combined. - kl : list of str - A list of keys that denotes the order in which the y data from `yd` was used to build the - input correlation matrix `corr`. - yd : dict of list - A dictionary where each key corresponds to a unique identifier, and its value is a list of - y data points. The total number of y data points across all keys must match the dimensions - of `corr`. The lists in the dictionary can be lists of Obs. - - Returns - ------- - np.ndarray - A new, sorted correlation matrix that corresponds to the y data from `yd` when arranged alphabetically by its keys. - - Example - ------- - >>> import numpy as np - >>> import pyerrors as pe - >>> corr = np.array([[1, 0.2, 0.3], [0.2, 1, 0.4], [0.3, 0.4, 1]]) - >>> kl = ['b', 'a'] - >>> yd = {'a': [1, 2], 'b': [3]} - >>> sorted_corr = pe.obs.sort_corr(corr, kl, yd) - >>> print(sorted_corr) - array([[1. , 0.3, 0.4], - [0.3, 1. , 0.2], - [0.4, 0.2, 1. ]]) - - """ - kl_sorted = sorted(kl) - - posd = {} - ofs = 0 - for ki, k in enumerate(kl): - posd[k] = [i + ofs for i in range(len(yd[k]))] - ofs += len(posd[k]) - - mapping = [] - for k in kl_sorted: - for i in range(len(yd[k])): - mapping.append(posd[k][i]) - - corr_sorted = np.zeros_like(corr) - for i in range(corr.shape[0]): - for j in range(corr.shape[0]): - corr_sorted[i][j] = corr[mapping[i]][mapping[j]] - - return corr_sorted - - def _smooth_eigenvalues(corr, E): """Eigenvalue smoothing as described in hep-lat/9412087 @@ -1643,7 +1524,7 @@ def _smooth_eigenvalues(corr, E): Number of eigenvalues to be left substantially unchanged """ if not (2 < E < corr.shape[0] - 1): - raise ValueError(f"'E' has to be between 2 and the dimension of the correlation matrix minus 1 ({corr.shape[0] - 1}).") + raise Exception(f"'E' has to be between 2 and the dimension of the correlation matrix minus 1 ({corr.shape[0] - 1}).") vals, vec = np.linalg.eigh(corr) lambda_min = np.mean(vals[:-E]) vals[vals < lambda_min] = lambda_min @@ -1762,11 +1643,7 @@ def import_bootstrap(boots, name, random_numbers): def merge_obs(list_of_obs): - """Combine all observables in list_of_obs into one new observable. - This allows to merge Obs that have been computed on multiple replica - of the same ensemble. - If you like to merge Obs that are based on several ensembles, please - average them yourself. + """Combine all observables in list_of_obs into one new observable Parameters ---------- @@ -1779,9 +1656,9 @@ def merge_obs(list_of_obs): """ replist = [item for obs in list_of_obs for item in obs.names] if (len(replist) == len(set(replist))) is False: - raise ValueError('list_of_obs contains duplicate replica: %s' % (str(replist))) + raise Exception('list_of_obs contains duplicate replica: %s' % (str(replist))) if any([len(o.cov_names) for o in list_of_obs]): - raise ValueError('Not possible to merge data that contains covobs!') + raise Exception('Not possible to merge data that contains covobs!') new_dict = {} idl_dict = {} for o in list_of_obs: @@ -1832,7 +1709,7 @@ def cov_Obs(means, cov, name, grad=None): for i in range(len(means)): ol.append(covobs_to_obs(Covobs(means[i], cov, name, pos=i, grad=grad))) if ol[0].covobs[name].N != len(means): - raise ValueError('You have to provide %d mean values!' % (ol[0].N)) + raise Exception('You have to provide %d mean values!' % (ol[0].N)) if len(ol) == 1: return ol[0] return ol @@ -1848,7 +1725,7 @@ def _determine_gap(o, e_content, e_name): gap = min(gaps) if not np.all([gi % gap == 0 for gi in gaps]): - raise ValueError(f"Replica for ensemble {e_name} do not have a common spacing.", gaps) + raise Exception(f"Replica for ensemble {e_name} do not have a common spacing.", gaps) return gap diff --git a/pyerrors/special.py b/pyerrors/special.py deleted file mode 100644 index 8b36e056..00000000 --- a/pyerrors/special.py +++ /dev/null @@ -1,23 +0,0 @@ -import scipy -import numpy as np -from autograd.extend import primitive, defvjp -from autograd.scipy.special import j0, y0, j1, y1, jn, yn, i0, i1, iv, ive, beta, betainc, betaln -from autograd.scipy.special import polygamma, psi, digamma, gamma, gammaln, gammainc, gammaincc, gammasgn, rgamma, multigammaln -from autograd.scipy.special import erf, erfc, erfinv, erfcinv, logit, expit, logsumexp - - -__all__ = ["beta", "betainc", "betaln", - "polygamma", "psi", "digamma", "gamma", "gammaln", "gammainc", "gammaincc", "gammasgn", "rgamma", "multigammaln", - "kn", "j0", "y0", "j1", "y1", "jn", "yn", "i0", "i1", "iv", "ive", - "erf", "erfc", "erfinv", "erfcinv", "logit", "expit", "logsumexp"] - - -@primitive -def kn(n, x): - """Modified Bessel function of the second kind of integer order n""" - if int(n) != n: - raise TypeError("The order 'n' needs to be an integer.") - return scipy.special.kn(n, x) - - -defvjp(kn, None, lambda ans, n, x: lambda g: - g * 0.5 * (kn(np.abs(n - 1), x) + kn(n + 1, x))) diff --git a/pyerrors/version.py b/pyerrors/version.py index 806254b1..43ce13db 100644 --- a/pyerrors/version.py +++ b/pyerrors/version.py @@ -1 +1 @@ -__version__ = "2.15.0-dev" +__version__ = "2.9.0" diff --git a/pyproject.toml b/pyproject.toml index 657ec5bb..0c4facc3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,3 @@ [build-system] requires = ["setuptools >= 63.0.0", "wheel"] build-backend = "setuptools.build_meta" - -[tool.ruff.lint] -ignore = ["F403"] diff --git a/setup.py b/setup.py index 8c42f4a6..ab038e8d 100644 --- a/setup.py +++ b/setup.py @@ -24,18 +24,18 @@ setup(name='pyerrors', author_email='fabian.joswig@ed.ac.uk', license="MIT", packages=find_packages(), - python_requires='>=3.9.0', - install_requires=['numpy>=2.0', 'autograd>=1.7.0', 'numdifftools>=0.9.41', 'matplotlib>=3.9', 'scipy>=1.13', 'iminuit>=2.28', 'h5py>=3.11', 'lxml>=5.0', 'python-rapidjson>=1.20', 'pandas>=2.2'], + python_requires='>=3.8.0', + install_requires=['numpy>=1.24', 'autograd>=1.6.2', 'numdifftools>=0.9.41', 'matplotlib>=3.7', 'scipy>=1.10', 'iminuit>=2.21', 'h5py>=3.8', 'lxml>=4.9', 'python-rapidjson>=1.10', 'pandas>=2.0'], extras_require={'test': ['pytest', 'pytest-cov', 'pytest-benchmark', 'hypothesis', 'nbmake', 'flake8']}, classifiers=[ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: MIT License', 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'Programming Language :: Python :: 3.13', 'Topic :: Scientific/Engineering :: Physics' ], ) diff --git a/tests/correlators_test.py b/tests/correlators_test.py index fc3528d2..3d49164a 100644 --- a/tests/correlators_test.py +++ b/tests/correlators_test.py @@ -129,7 +129,7 @@ def test_m_eff(): with pytest.warns(RuntimeWarning): my_corr.m_eff('sinh') - with pytest.raises(ValueError): + with pytest.raises(Exception): my_corr.m_eff('unkown_variant') @@ -140,7 +140,7 @@ def test_m_eff_negative_values(): assert m_eff_log[padding + 1] is None m_eff_cosh = my_corr.m_eff('cosh') assert m_eff_cosh[padding + 1] is None - with pytest.raises(ValueError): + with pytest.raises(Exception): my_corr.m_eff('logsym') @@ -155,7 +155,7 @@ def test_correlate(): my_corr = pe.correlators.Corr([pe.pseudo_Obs(10, 0.1, 't'), pe.pseudo_Obs(0, 0.05, 't')]) corr1 = my_corr.correlate(my_corr) corr2 = my_corr.correlate(my_corr[0]) - with pytest.raises(TypeError): + with pytest.raises(Exception): corr3 = my_corr.correlate(7.3) @@ -176,9 +176,9 @@ def test_fit_correlator(): assert fit_res[0] == my_corr[0] assert fit_res[1] == my_corr[1] - my_corr[0] - with pytest.raises(TypeError): + with pytest.raises(Exception): my_corr.fit(f, "from 0 to 3") - with pytest.raises(ValueError): + with pytest.raises(Exception): my_corr.fit(f, [0, 2, 3]) @@ -200,17 +200,17 @@ def test_padded_correlator(): def test_corr_exceptions(): obs_a = pe.Obs([np.random.normal(0.1, 0.1, 100)], ['test']) - obs_b = pe.Obs([np.random.normal(0.1, 0.1, 99)], ['test']) + obs_b= pe.Obs([np.random.normal(0.1, 0.1, 99)], ['test']) with pytest.raises(Exception): pe.Corr([obs_a, obs_b]) obs_a = pe.Obs([np.random.normal(0.1, 0.1, 100)], ['test']) - obs_b = pe.Obs([np.random.normal(0.1, 0.1, 100)], ['test'], idl=[range(1, 200, 2)]) + obs_b= pe.Obs([np.random.normal(0.1, 0.1, 100)], ['test'], idl=[range(1, 200, 2)]) with pytest.raises(Exception): pe.Corr([obs_a, obs_b]) obs_a = pe.Obs([np.random.normal(0.1, 0.1, 100)], ['test']) - obs_b = pe.Obs([np.random.normal(0.1, 0.1, 100)], ['test2']) + obs_b= pe.Obs([np.random.normal(0.1, 0.1, 100)], ['test2']) with pytest.raises(Exception): pe.Corr([obs_a, obs_b]) @@ -256,11 +256,11 @@ def test_prange(): corr = pe.correlators.Corr(corr_content) corr.set_prange([2, 4]) - with pytest.raises(ValueError): + with pytest.raises(Exception): corr.set_prange([2]) - with pytest.raises(TypeError): + with pytest.raises(Exception): corr.set_prange([2, 2.3]) - with pytest.raises(ValueError): + with pytest.raises(Exception): corr.set_prange([4, 1]) @@ -436,7 +436,6 @@ def test_GEVP_solver(): sp_vecs = [v / np.sqrt((v.T @ mat2 @ v)) for v in sp_vecs] assert np.allclose(sp_vecs, pe.correlators._GEVP_solver(mat1, mat2), atol=1e-14) - assert np.allclose(np.abs(sp_vecs), np.abs(pe.correlators._GEVP_solver(mat1, mat2, method='cholesky'))) def test_GEVP_none_entries(): @@ -553,7 +552,7 @@ def test_corr_no_filtering(): li = [-pe.pseudo_Obs(.2, .1, 'a', samples=10) for i in range(96)] for i in range(len(li)): li[i].idl['a'] = range(1, 21, 2) - c = pe.Corr(li) + c= pe.Corr(li) b = pe.pseudo_Obs(1, 1e-11, 'a', samples=30) c *= b assert np.all([c[0].idl == o.idl for o in c]) @@ -573,28 +572,6 @@ def test_corr_symmetric(): assert scorr[0] == corr[0] -def test_error_GEVP(): - corr = pe.input.json.load_json("tests/data/test_matrix_corr.json.gz") - t0, ts, state = 3, 6, 0 - vec_regular = corr.GEVP(t0=t0)[state][ts] - vec_errors = corr.GEVP(t0=t0, vector_obs=True, auto_gamma=True)[state][ts] - vec_regular_chol = corr.GEVP(t0=t0, method='cholesky')[state][ts] - print(vec_errors) - print(type(vec_errors[0])) - assert(np.isclose(np.asarray([e.value for e in vec_errors]), vec_regular).all()) - assert(all([e.dvalue > 0. for e in vec_errors])) - - projected_regular = corr.projected(vec_regular).content[ts + 1][0] - projected_errors = corr.projected(vec_errors).content[ts + 1][0] - projected_regular.gamma_method() - projected_errors.gamma_method() - assert(projected_errors.dvalue > projected_regular.dvalue) - assert(corr.GEVP(t0, vector_obs=True)[state][42] is None) - - assert(np.isclose(vec_regular_chol, vec_regular).all()) - assert(np.isclose(corr.GEVP(t0=t0, state=state)[ts], vec_regular).all()) - - def test_corr_array_ndim1_init(): y = [pe.pseudo_Obs(2 + np.random.normal(0.0, 0.1), .1, 't') for i in np.arange(5)] cc1 = pe.Corr(y) @@ -711,6 +688,7 @@ def test_matrix_trace(): for el in corr.trace(): assert el == 0 + with pytest.raises(ValueError): corr.item(0, 0).trace() @@ -771,13 +749,3 @@ def test_corr_item(): corr_mat = pe.Corr(np.array([[corr_aa, corr_ab], [corr_ab, corr_aa]])) corr_mat.item(0, 0) assert corr_mat[0].item(0, 1) == corr_mat.item(0, 1)[0] - - -def test_complex_add_and_mul(): - o = pe.pseudo_Obs(1.0, 0.3, "my_r345sfg16£$%&$%^%$^$", samples=47) - co = pe.CObs(o, 0.341 * o) - for obs in [o, co]: - cc = pe.Corr([obs for _ in range(4)]) - cc += 2j - cc = cc * 4j - cc.real + cc.imag diff --git a/tests/data/test_matrix_corr.json.gz b/tests/data/test_matrix_corr.json.gz deleted file mode 100644 index d61b3bcf..00000000 Binary files a/tests/data/test_matrix_corr.json.gz and /dev/null differ diff --git a/tests/dirac_test.py b/tests/dirac_test.py index 03605785..44812397 100644 --- a/tests/dirac_test.py +++ b/tests/dirac_test.py @@ -30,7 +30,7 @@ def test_grid_dirac(): 'SigmaYZ', 'SigmaZT']: pe.dirac.Grid_gamma(gamma) - with pytest.raises(ValueError): + with pytest.raises(Exception): pe.dirac.Grid_gamma('Not a gamma matrix') @@ -44,7 +44,7 @@ def test_epsilon_tensor(): (1, 1, 3) : 0.0} for key, value in check.items(): assert pe.dirac.epsilon_tensor(*key) == value - with pytest.raises(ValueError): + with pytest.raises(Exception): pe.dirac.epsilon_tensor(0, 1, 3) @@ -59,5 +59,5 @@ def test_epsilon_tensor_rank4(): (1, 2, 3, 1) : 0.0} for key, value in check.items(): assert pe.dirac.epsilon_tensor_rank4(*key) == value - with pytest.raises(ValueError): + with pytest.raises(Exception): pe.dirac.epsilon_tensor_rank4(0, 1, 3, 4) diff --git a/tests/fits_test.py b/tests/fits_test.py index 283ff6a2..dbc227dc 100644 --- a/tests/fits_test.py +++ b/tests/fits_test.py @@ -152,127 +152,6 @@ def test_alternative_solvers(): chisquare_values = np.array(chisquare_values) assert np.all(np.isclose(chisquare_values, chisquare_values[0])) -def test_inv_cov_matrix_input_least_squares(): - - - num_samples = 400 - N = 10 - - x = norm.rvs(size=(N, num_samples)) # generate random numbers - - r = np.zeros((N, N)) - for i in range(N): - for j in range(N): - r[i, j] = np.exp(-0.8 * np.fabs(i - j)) # element in correlation matrix - - errl = np.sqrt([3.4, 2.5, 3.6, 2.8, 4.2, 4.7, 4.9, 5.1, 3.2, 4.2]) # set y errors - for i in range(N): - for j in range(N): - r[i, j] *= errl[i] * errl[j] # element in covariance matrix - - c = cholesky(r, lower=True) - y = np.dot(c, x) - x = np.arange(N) - x_dict = {} - y_dict = {} - for i,item in enumerate(x): - x_dict[str(item)] = [x[i]] - - for linear in [True, False]: - data = [] - for i in range(N): - if linear: - data.append(pe.Obs([[i + 1 + o for o in y[i]]], ['ens'])) - else: - data.append(pe.Obs([[np.exp(-(i + 1)) + np.exp(-(i + 1)) * o for o in y[i]]], ['ens'])) - - [o.gamma_method() for o in data] - - data_dict = {} - for i,item in enumerate(x): - data_dict[str(item)] = [data[i]] - - corr = pe.covariance(data, correlation=True) - chol = np.linalg.cholesky(corr) - covdiag = np.diag(1 / np.asarray([o.dvalue for o in data])) - chol_inv = scipy.linalg.solve_triangular(chol, covdiag, lower=True) - chol_inv_keys = [""] - chol_inv_keys_combined_fit = [str(item) for i,item in enumerate(x)] - - if linear: - def fitf(p, x): - return p[1] + p[0] * x - fitf_dict = {} - for i,item in enumerate(x): - fitf_dict[str(item)] = fitf - else: - def fitf(p, x): - return p[1] * anp.exp(-p[0] * x) - fitf_dict = {} - for i,item in enumerate(x): - fitf_dict[str(item)] = fitf - - fitpc = pe.least_squares(x, data, fitf, correlated_fit=True) - fitp_inv_cov = pe.least_squares(x, data, fitf, correlated_fit = True, inv_chol_cov_matrix = [chol_inv,chol_inv_keys]) - fitp_inv_cov_combined_fit = pe.least_squares(x_dict, data_dict, fitf_dict, correlated_fit = True, inv_chol_cov_matrix = [chol_inv,chol_inv_keys_combined_fit]) - for i in range(2): - diff_inv_cov = fitp_inv_cov[i] - fitpc[i] - diff_inv_cov.gamma_method() - assert(diff_inv_cov.is_zero(atol=0.0)) - diff_inv_cov_combined_fit = fitp_inv_cov_combined_fit[i] - fitpc[i] - diff_inv_cov_combined_fit.gamma_method() - assert(diff_inv_cov_combined_fit.is_zero(atol=1e-12)) - - with pytest.raises(ValueError): - pe.least_squares(x_dict, data_dict, fitf_dict, correlated_fit = True, inv_chol_cov_matrix = [corr,chol_inv_keys_combined_fit]) - -def test_least_squares_invalid_inv_cov_matrix_input(): - xvals = [] - yvals = [] - err = 0.1 - def func_valid(a,x): - return a[0] + a[1] * x - for x in range(1, 8, 2): - xvals.append(x) - yvals.append(pe.pseudo_Obs(x + np.random.normal(0.0, err), err, 'test1') + pe.pseudo_Obs(0, err / 100, 'test2', samples=87)) - - [o.gamma_method() for o in yvals] - - #dictionaries for a combined fit - xvals_dict = { } - yvals_dict = { } - for i,item in enumerate(np.arange(1, 8, 2)): - xvals_dict[str(item)] = [xvals[i]] - yvals_dict[str(item)] = [yvals[i]] - chol_inv_keys_combined_fit = ['1', '3', '5', '7'] - chol_inv_keys_combined_fit_invalid = ['2', '7', '100', '8'] - func_dict_valid = {"1": func_valid,"3": func_valid,"5": func_valid,"7": func_valid} - - corr_valid = pe.covariance(yvals, correlation = True) - chol = np.linalg.cholesky(corr_valid) - covdiag = np.diag(1 / np.asarray([o.dvalue for o in yvals])) - chol_inv_valid = scipy.linalg.solve_triangular(chol, covdiag, lower=True) - chol_inv_keys = [""] - pe.least_squares(xvals, yvals,func_valid, correlated_fit = True, inv_chol_cov_matrix = [chol_inv_valid,chol_inv_keys]) - pe.least_squares(xvals_dict, yvals_dict,func_dict_valid, correlated_fit = True, inv_chol_cov_matrix = [chol_inv_valid,chol_inv_keys_combined_fit]) - chol_inv_invalid_shape1 = np.zeros((len(yvals),len(yvals)-1)) - chol_inv_invalid_shape2 = np.zeros((len(yvals)+2,len(yvals))) - - # for an uncombined fit - with pytest.raises(TypeError): - pe.least_squares(xvals, yvals, func_valid, correlated_fit = True, inv_chol_cov_matrix = [chol_inv_invalid_shape1,chol_inv_keys]) - with pytest.raises(TypeError): - pe.least_squares(xvals, yvals, func_valid,correlated_fit = True, inv_chol_cov_matrix = [chol_inv_invalid_shape2,chol_inv_keys]) - with pytest.raises(ValueError): - pe.least_squares(xvals, yvals, func_valid,correlated_fit = True, inv_chol_cov_matrix = [chol_inv_valid,chol_inv_keys_combined_fit_invalid]) - - #repeat for a combined fit - with pytest.raises(TypeError): - pe.least_squares(xvals_dict, yvals_dict,func_dict_valid, correlated_fit = True, inv_chol_cov_matrix = [chol_inv_invalid_shape1,chol_inv_keys_combined_fit]) - with pytest.raises(TypeError): - pe.least_squares(xvals_dict, yvals_dict,func_dict_valid, correlated_fit = True, inv_chol_cov_matrix = [chol_inv_invalid_shape2,chol_inv_keys_combined_fit]) - with pytest.raises(ValueError): - pe.least_squares(xvals_dict, yvals_dict,func_dict_valid, correlated_fit = True, inv_chol_cov_matrix = [chol_inv_valid,chol_inv_keys_combined_fit_invalid]) def test_correlated_fit(): num_samples = 400 @@ -1085,20 +964,6 @@ def test_combined_resplot_qqplot(): fr = pe.least_squares(xd, yd, fd, resplot=True, qqplot=True) plt.close('all') -def test_combined_fit_xerr(): - fitd = { - 'a' : lambda p, x: p[0] * x[0] + p[1] * x[1], - 'b' : lambda p, x: p[0] * x[0] + p[2] * x[1], - 'c' : lambda p, x: p[0] * x[0] + p[3] * x[1], - } - yd = { - 'a': [pe.cov_Obs(3 + .1 * np.random.uniform(), .1**2, 'a' + str(i)) for i in range(5)], - 'b': [pe.cov_Obs(1 + .1 * np.random.uniform(), .1**2, 'b' + str(i)) for i in range(6)], - 'c': [pe.cov_Obs(3 + .1 * np.random.uniform(), .1**2, 'c' + str(i)) for i in range(3)], - } - xd = {k: np.transpose([[1 + .01 * np.random.uniform(), 2] for i in range(len(yd[k]))]) for k in fitd} - pe.fits.least_squares(xd, yd, fitd) - def test_x_multidim_fit(): x1 = np.arange(1, 10) @@ -1277,53 +1142,6 @@ def test_fit_dof(): assert cd[0] != cd[0] # Check for nan assert np.all(np.array(cd[1:]) > 0) - N = 5 - - def fitf(a, x): - return a[0] + 0 * x - - def fitf_multi(a, x): - return a[0] + 0 * x[0] + 0*x[1] - - for priors in [None, [pe.cov_Obs(3, 1, 'p')]]: - if priors is None: - lp = 0 - else: - lp = len(priors) - x = [1. for i in range(N)] - y = [pe.cov_Obs(i, .1, '%d' % (i)) for i in range(N)] - [o.gm() for o in y] - res = pe.fits.least_squares(x, y, fitf, expected_chisquare=True, priors=priors) - assert(res.dof == N - 1 + lp) - if priors is None: - assert(np.isclose(res.chisquare_by_expected_chisquare, res.chisquare_by_dof)) - - kl = ['a', 'b'] - x = {k: [1. for i in range(N)] for k in kl} - y = {k: [pe.cov_Obs(i, .1, '%d%s' % (i, k)) for i in range(N)] for k in kl} - [[o.gm() for o in y[k]] for k in y] - res = pe.fits.least_squares(x, y, {k: fitf for k in kl}, expected_chisquare=True, priors=priors) - assert(res.dof == 2 * N - 1 + lp) - if priors is None: - assert(np.isclose(res.chisquare_by_expected_chisquare, res.chisquare_by_dof)) - - x = np.array([[1., 2.] for i in range(N)]).T - y = [pe.cov_Obs(i, .1, '%d' % (i)) for i in range(N)] - [o.gm() for o in y] - res = pe.fits.least_squares(x, y, fitf_multi, expected_chisquare=True, priors=priors) - assert(res.dof == N - 1 + lp) - if priors is None: - assert(np.isclose(res.chisquare_by_expected_chisquare, res.chisquare_by_dof)) - - x = {k: np.array([[1., 2.] for i in range(N)]).T for k in kl} - y = {k: [pe.cov_Obs(i, .1, '%d%s' % (i, k)) for i in range(N)] for k in kl} - [[o.gm() for o in y[k]] for k in y] - res = pe.fits.least_squares(x, y, {k: fitf_multi for k in kl}, expected_chisquare=True, priors=priors) - - assert(res.dof == 2 * N - 1 + lp) - if priors is None: - assert(np.isclose(res.chisquare_by_expected_chisquare, res.chisquare_by_dof)) - def test_combined_fit_constant_shape(): N1 = 16 diff --git a/tests/json_io_test.py b/tests/json_io_test.py index a9263691..dafaaa41 100644 --- a/tests/json_io_test.py +++ b/tests/json_io_test.py @@ -12,7 +12,7 @@ def test_jsonio(): o = pe.pseudo_Obs(1.0, .2, 'one') o2 = pe.pseudo_Obs(0.5, .1, 'two|r1') o3 = pe.pseudo_Obs(0.5, .1, 'two|r2') - o4 = pe.merge_obs([o2, o3, pe.pseudo_Obs(0.5, .1, 'two|r3', samples=3221)]) + o4 = pe.merge_obs([o2, o3]) otag = 'This has been merged!' o4.tag = otag do = o - .2 * o4 @@ -101,8 +101,8 @@ def test_json_string_reconstruction(): def test_json_corr_io(): - my_list = [pe.Obs([np.random.normal(1.0, 0.1, 100), np.random.normal(1.0, 0.1, 321)], ['ens1|r1', 'ens1|r2'], idl=[range(1, 201, 2), range(321)]) for o in range(8)] - rw_list = pe.reweight(pe.Obs([np.random.normal(1.0, 0.1, 100), np.random.normal(1.0, 0.1, 321)], ['ens1|r1', 'ens1|r2'], idl=[range(1, 201, 2), range(321)]), my_list) + my_list = [pe.Obs([np.random.normal(1.0, 0.1, 100)], ['ens1']) for o in range(8)] + rw_list = pe.reweight(pe.Obs([np.random.normal(1.0, 0.1, 100)], ['ens1']), my_list) for obs_list in [my_list, rw_list]: for tag in [None, "test"]: @@ -111,51 +111,40 @@ def test_json_corr_io(): for corr_tag in [None, 'my_Corr_tag']: for prange in [None, [3, 6]]: for gap in [False, True]: - for mult in [1., pe.cov_Obs([12.22, 1.21], [.212**2, .11**2], 'renorm')[0]]: - my_corr = mult * pe.Corr(obs_list, padding=[pad, pad], prange=prange) - my_corr.tag = corr_tag - if gap: - my_corr.content[4] = None - pe.input.json.dump_to_json(my_corr, 'corr') - recover = pe.input.json.load_json('corr') - os.remove('corr.json.gz') - assert np.all([o.is_zero() for o in [x for x in (my_corr - recover) if x is not None]]) - for index, entry in enumerate(my_corr): - if entry is None: - assert recover[index] is None - assert my_corr.tag == recover.tag - assert my_corr.prange == recover.prange - assert my_corr.reweighted == recover.reweighted + my_corr = pe.Corr(obs_list, padding=[pad, pad], prange=prange) + my_corr.tag = corr_tag + if gap: + my_corr.content[4] = None + pe.input.json.dump_to_json(my_corr, 'corr') + recover = pe.input.json.load_json('corr') + os.remove('corr.json.gz') + assert np.all([o.is_zero() for o in [x for x in (my_corr - recover) if x is not None]]) + for index, entry in enumerate(my_corr): + if entry is None: + assert recover[index] is None + assert my_corr.tag == recover.tag + assert my_corr.prange == recover.prange + assert my_corr.reweighted == recover.reweighted def test_json_corr_2d_io(): - obs_list = [np.array([ - [ - pe.merge_obs([pe.pseudo_Obs(1.0 + i, 0.1 * i, 'test|r2'), pe.pseudo_Obs(1.0 + i, 0.1 * i, 'test|r1', samples=321)]), - pe.merge_obs([pe.pseudo_Obs(0.0, 0.1 * i, 'test|r2'), pe.pseudo_Obs(0.0, 0.1 * i, 'test|r1', samples=321)]), - ], - [ - pe.merge_obs([pe.pseudo_Obs(0.0, 0.1 * i, 'test|r2'), pe.pseudo_Obs(0.0, 0.1 * i, 'test|r1', samples=321),]), - pe.merge_obs([pe.pseudo_Obs(1.0 + i, 0.1 * i, 'test|r2'), pe.pseudo_Obs(1.0 + i, 0.1 * i, 'test|r1', samples=321)]), - ], - ]) for i in range(4)] + obs_list = [np.array([[pe.pseudo_Obs(1.0 + i, 0.1 * i, 'test'), pe.pseudo_Obs(0.0, 0.1 * i, 'test')], [pe.pseudo_Obs(0.0, 0.1 * i, 'test'), pe.pseudo_Obs(1.0 + i, 0.1 * i, 'test')]]) for i in range(4)] for tag in [None, "test"]: obs_list[3][0, 1].tag = tag for padding in [0, 1]: for prange in [None, [3, 6]]: - for mult in [1., pe.cov_Obs([12.22, 1.21], [.212**2, .11**2], 'renorm')[0]]: - my_corr = mult * pe.Corr(obs_list, padding=[padding, padding], prange=prange) - my_corr.tag = tag - pe.input.json.dump_to_json(my_corr, 'corr') - recover = pe.input.json.load_json('corr') - os.remove('corr.json.gz') - assert np.all([np.all([o.is_zero() for o in q]) for q in [x.ravel() for x in (my_corr - recover) if x is not None]]) - for index, entry in enumerate(my_corr): - if entry is None: - assert recover[index] is None - assert my_corr.tag == recover.tag - assert my_corr.prange == recover.prange + my_corr = pe.Corr(obs_list, padding=[padding, padding], prange=prange) + my_corr.tag = tag + pe.input.json.dump_to_json(my_corr, 'corr') + recover = pe.input.json.load_json('corr') + os.remove('corr.json.gz') + assert np.all([np.all([o.is_zero() for o in q]) for q in [x.ravel() for x in (my_corr - recover) if x is not None]]) + for index, entry in enumerate(my_corr): + if entry is None: + assert recover[index] is None + assert my_corr.tag == recover.tag + assert my_corr.prange == recover.prange def test_json_dict_io(): @@ -222,7 +211,6 @@ def test_json_dict_io(): 'd': pe.pseudo_Obs(.01, .001, 'testd', samples=10) * pe.cov_Obs(1, .01, 'cov1'), 'se': None, 'sf': 1.2, - 'k': pe.cov_Obs(.1, .001**2, 'cov') * pe.merge_obs([pe.pseudo_Obs(1.0, 0.1, 'test|r2'), pe.pseudo_Obs(1.0, 0.1, 'test|r1', samples=321)]), } } @@ -326,7 +314,7 @@ def test_dobsio(): o2 = pe.pseudo_Obs(0.5, .1, 'two|r1') o3 = pe.pseudo_Obs(0.5, .1, 'two|r2') - o4 = pe.merge_obs([o2, o3, pe.pseudo_Obs(0.5, .1, 'two|r3', samples=3221)]) + o4 = pe.merge_obs([o2, o3]) otag = 'This has been merged!' o4.tag = otag do = o - .2 * o4 @@ -340,7 +328,7 @@ def test_dobsio(): o5 /= co2[0] o5.tag = 2 * otag - tt1 = pe.Obs([np.random.rand(100), np.random.rand(102)], ['t|r1', 't|r2'], idl=[range(2, 202, 2), range(22, 226, 2)]) + tt1 = pe.Obs([np.random.rand(100), np.random.rand(100)], ['t|r1', 't|r2'], idl=[range(2, 202, 2), range(22, 222, 2)]) tt3 = pe.Obs([np.random.rand(102)], ['qe|r1']) tt = tt1 + tt3 @@ -349,7 +337,7 @@ def test_dobsio(): tt4 = pe.Obs([np.random.rand(100), np.random.rand(100)], ['t|r1', 't|r2'], idl=[range(1, 101, 1), range(2, 202, 2)]) - ol = [o2, o3, o4, do, o5, tt, tt4, np.log(tt4 / o5**2), np.exp(o5 + np.log(co3 / tt3 + o4) / tt), o4.reweight(o4)] + ol = [o2, o3, o4, do, o5, tt, tt4, np.log(tt4 / o5**2), np.exp(o5 + np.log(co3 / tt3 + o4) / tt)] print(ol) fname = 'test_rw' @@ -374,12 +362,9 @@ def test_dobsio(): def test_reconstruct_non_linear_r_obs(tmp_path): - to = ( - pe.Obs([np.random.rand(500), np.random.rand(1200)], - ["e|r1", "e|r2", ], - idl=[range(1, 501), range(0, 1200)]) - + pe.Obs([np.random.rand(111)], ["my_new_ensemble_54^£$|8'[@124435%6^7&()~#"], idl=[range(1, 999, 9)]) - ) + to = pe.Obs([np.random.rand(500), np.random.rand(500), np.random.rand(111)], + ["e|r1", "e|r2", "my_new_ensemble_54^£$|8'[@124435%6^7&()~#"], + idl=[range(1, 501), range(0, 500), range(1, 999, 9)]) to = np.log(to ** 2) / to to.dump((tmp_path / "test_equality").as_posix()) ro = pe.input.json.load_json((tmp_path / "test_equality").as_posix()) @@ -387,12 +372,9 @@ def test_reconstruct_non_linear_r_obs(tmp_path): def test_reconstruct_non_linear_r_obs_list(tmp_path): - to = ( - pe.Obs([np.random.rand(500), np.random.rand(1200)], - ["e|r1", "e|r2", ], - idl=[range(1, 501), range(0, 1200)]) - + pe.Obs([np.random.rand(111)], ["my_new_ensemble_54^£$|8'[@124435%6^7&()~#"], idl=[range(1, 999, 9)]) - ) + to = pe.Obs([np.random.rand(500), np.random.rand(500), np.random.rand(111)], + ["e|r1", "e|r2", "my_new_ensemble_54^£$|8'[@124435%6^7&()~#"], + idl=[range(1, 501), range(0, 500), range(1, 999, 9)]) to = np.log(to ** 2) / to for to_list in [[to, to, to], np.array([to, to, to])]: pe.input.json.dump_to_json(to_list, (tmp_path / "test_equality_list").as_posix()) diff --git a/tests/linalg_test.py b/tests/linalg_test.py index 9323cfcf..ec0591ba 100644 --- a/tests/linalg_test.py +++ b/tests/linalg_test.py @@ -34,7 +34,7 @@ def test_matmul(): my_list = [] length = 100 + np.random.randint(200) for i in range(dim ** 2): - my_list.append(pe.Obs([np.random.rand(length)], ['t1']) + pe.Obs([np.random.rand(length + 1)], ['t2'])) + my_list.append(pe.Obs([np.random.rand(length), np.random.rand(length + 1)], ['t1', 't2'])) my_array = const * np.array(my_list).reshape((dim, dim)) tt = pe.linalg.matmul(my_array, my_array) - my_array @ my_array for t, e in np.ndenumerate(tt): @@ -43,8 +43,8 @@ def test_matmul(): my_list = [] length = 100 + np.random.randint(200) for i in range(dim ** 2): - my_list.append(pe.CObs(pe.Obs([np.random.rand(length)], ['t1']) + pe.Obs([np.random.rand(length + 1)], ['t2']), - pe.Obs([np.random.rand(length)], ['t1']) + pe.Obs([np.random.rand(length + 1)], ['t2']))) + my_list.append(pe.CObs(pe.Obs([np.random.rand(length), np.random.rand(length + 1)], ['t1', 't2']), + pe.Obs([np.random.rand(length), np.random.rand(length + 1)], ['t1', 't2']))) my_array = np.array(my_list).reshape((dim, dim)) * const tt = pe.linalg.matmul(my_array, my_array) - my_array @ my_array for t, e in np.ndenumerate(tt): @@ -151,7 +151,7 @@ def test_multi_dot(): my_list = [] length = 1000 + np.random.randint(200) for i in range(dim ** 2): - my_list.append(pe.Obs([np.random.rand(length)], ['t1']) + pe.Obs([np.random.rand(length + 1)], ['t2'])) + my_list.append(pe.Obs([np.random.rand(length), np.random.rand(length + 1)], ['t1', 't2'])) my_array = pe.cov_Obs(1.0, 0.002, 'cov') * np.array(my_list).reshape((dim, dim)) tt = pe.linalg.matmul(my_array, my_array, my_array, my_array) - my_array @ my_array @ my_array @ my_array for t, e in np.ndenumerate(tt): @@ -160,8 +160,8 @@ def test_multi_dot(): my_list = [] length = 1000 + np.random.randint(200) for i in range(dim ** 2): - my_list.append(pe.CObs(pe.Obs([np.random.rand(length)], ['t1']) + pe.Obs([np.random.rand(length + 1)], ['t2']), - pe.Obs([np.random.rand(length)], ['t1']) + pe.Obs([np.random.rand(length + 1)], ['t2']))) + my_list.append(pe.CObs(pe.Obs([np.random.rand(length), np.random.rand(length + 1)], ['t1', 't2']), + pe.Obs([np.random.rand(length), np.random.rand(length + 1)], ['t1', 't2']))) my_array = np.array(my_list).reshape((dim, dim)) * pe.cov_Obs(1.0, 0.002, 'cov') tt = pe.linalg.matmul(my_array, my_array, my_array, my_array) - my_array @ my_array @ my_array @ my_array for t, e in np.ndenumerate(tt): @@ -209,7 +209,7 @@ def test_irregular_matrix_inverse(): for idl in [range(8, 508, 10), range(250, 273), [2, 8, 19, 20, 78, 99, 828, 10548979]]: irregular_array = [] for i in range(dim ** 2): - irregular_array.append(pe.Obs([np.random.normal(1.1, 0.2, len(idl))], ['ens1'], idl=[idl]) + pe.Obs([np.random.normal(0.25, 0.1, 10)], ['ens2'], idl=[range(1, 11)])) + irregular_array.append(pe.Obs([np.random.normal(1.1, 0.2, len(idl)), np.random.normal(0.25, 0.1, 10)], ['ens1', 'ens2'], idl=[idl, range(1, 11)])) irregular_matrix = np.array(irregular_array).reshape((dim, dim)) * pe.cov_Obs(1.0, 0.002, 'cov') * pe.pseudo_Obs(1.0, 0.002, 'ens2|r23') invertible_irregular_matrix = np.identity(dim) + irregular_matrix @ irregular_matrix.T @@ -276,10 +276,10 @@ def test_matrix_functions(): for (i, j), entry in np.ndenumerate(check_inv): entry.gamma_method() if(i == j): - assert math.isclose(entry.value, 1.0, abs_tol=2e-9), 'value ' + str(i) + ',' + str(j) + ' ' + str(entry.value) + assert math.isclose(entry.value, 1.0, abs_tol=1e-9), 'value ' + str(i) + ',' + str(j) + ' ' + str(entry.value) else: - assert math.isclose(entry.value, 0.0, abs_tol=2e-9), 'value ' + str(i) + ',' + str(j) + ' ' + str(entry.value) - assert math.isclose(entry.dvalue, 0.0, abs_tol=2e-9), 'dvalue ' + str(i) + ',' + str(j) + ' ' + str(entry.dvalue) + assert math.isclose(entry.value, 0.0, abs_tol=1e-9), 'value ' + str(i) + ',' + str(j) + ' ' + str(entry.value) + assert math.isclose(entry.dvalue, 0.0, abs_tol=1e-9), 'dvalue ' + str(i) + ',' + str(j) + ' ' + str(entry.dvalue) # Check Cholesky decomposition sym = np.dot(matrix, matrix.T) @@ -297,10 +297,6 @@ def test_matrix_functions(): for j in range(dim): assert tmp[j].is_zero() - # Check eigv - v2 = pe.linalg.eigv(sym) - assert np.sum(v - v2).is_zero() - # Check eig function e2 = pe.linalg.eig(sym) assert np.all(np.sort(e) == np.sort(e2)) diff --git a/tests/obs_test.py b/tests/obs_test.py index 546a4bfd..334521f0 100644 --- a/tests/obs_test.py +++ b/tests/obs_test.py @@ -5,7 +5,6 @@ import copy import matplotlib.pyplot as plt import pyerrors as pe import pytest -import pyerrors.linalg from hypothesis import given, strategies as st np.random.seed(0) @@ -41,10 +40,6 @@ def test_Obs_exceptions(): pe.Obs([np.random.rand(4)], ['name']) with pytest.raises(ValueError): pe.Obs([np.random.rand(5)], ['1'], idl=[[5, 3, 2 ,4 ,1]]) - with pytest.raises(ValueError): - pe.Obs([np.random.rand(5)], ['1'], idl=[[1, 2, 3, 3, 5]]) - with pytest.raises(ValueError): - pe.Obs([np.random.rand(5)], ['1'], idl=[[1, 1, 3, 1, 5]]) with pytest.raises(TypeError): pe.Obs([np.random.rand(5)], ['1'], idl=['t']) with pytest.raises(ValueError): @@ -61,9 +56,9 @@ def test_Obs_exceptions(): my_obs.plot_rep_dist() with pytest.raises(Exception): my_obs.plot_piechart() - with pytest.raises(TypeError): + with pytest.raises(Exception): my_obs.gamma_method(S='2.3') - with pytest.raises(ValueError): + with pytest.raises(Exception): my_obs.gamma_method(tau_exp=2.3) my_obs.gamma_method() my_obs.details() @@ -199,7 +194,7 @@ def test_gamma_method_no_windowing(): assert np.isclose(np.sqrt(np.var(obs.deltas['ens'], ddof=1) / obs.shape['ens']), obs.dvalue) obs.gamma_method(S=1.1) assert obs.e_tauint['ens'] > 0.5 - with pytest.raises(ValueError): + with pytest.raises(Exception): obs.gamma_method(S=-0.2) @@ -333,7 +328,7 @@ def test_derived_observables(): def test_multi_ens(): names = ['A0', 'A1|r001', 'A1|r002'] - test_obs = pe.Obs([np.random.rand(50)], names[:1]) + pe.Obs([np.random.rand(50), np.random.rand(50)], names[1:]) + test_obs = pe.Obs([np.random.rand(50), np.random.rand(50), np.random.rand(50)], names) assert test_obs.e_names == ['A0', 'A1'] assert test_obs.e_content['A0'] == ['A0'] assert test_obs.e_content['A1'] == ['A1|r001', 'A1|r002'] @@ -345,9 +340,6 @@ def test_multi_ens(): ensembles.append(str(i)) assert my_sum.e_names == sorted(ensembles) - with pytest.raises(ValueError): - test_obs = pe.Obs([np.random.rand(50), np.random.rand(50), np.random.rand(50)], names) - def test_multi_ens2(): names = ['ens', 'e', 'en', 'e|r010', 'E|er', 'ens|', 'Ens|34', 'ens|r548984654ez4e3t34terh'] @@ -464,18 +456,6 @@ def test_cobs_overloading(): obs / cobs -def test_pow(): - data = [1, 2.341, pe.pseudo_Obs(4.8, 0.48, "test_obs"), pe.cov_Obs(1.1, 0.3 ** 2, "test_cov_obs")] - - for d in data: - assert d * d == d ** 2 - assert d * d * d == d ** 3 - - for d2 in data: - assert np.log(d ** d2) == d2 * np.log(d) - assert (d ** d2) ** (1 / d2) == d - - def test_reweighting(): my_obs = pe.Obs([np.random.rand(1000)], ['t']) assert not my_obs.reweighted @@ -493,33 +473,26 @@ def test_reweighting(): r_obs2 = r_obs[0] * my_obs assert r_obs2.reweighted my_covobs = pe.cov_Obs(1.0, 0.003, 'cov') - with pytest.raises(ValueError): + with pytest.raises(Exception): pe.reweight(my_obs, [my_covobs]) my_obs2 = pe.Obs([np.random.rand(1000)], ['t2']) - with pytest.raises(ValueError): + with pytest.raises(Exception): pe.reweight(my_obs, [my_obs + my_obs2]) - with pytest.raises(ValueError): + with pytest.raises(Exception): pe.reweight(my_irregular_obs, [my_obs]) - my_merged_obs = my_obs + pe.Obs([np.random.rand(1000)], ['q']) - with pytest.raises(ValueError): - pe.reweight(my_merged_obs, [my_merged_obs]) - def test_merge_obs(): - my_obs1 = pe.Obs([np.random.normal(1, .1, 100)], ['t|1']) - my_obs2 = pe.Obs([np.random.normal(1, .1, 100)], ['t|2'], idl=[range(1, 200, 2)]) + my_obs1 = pe.Obs([np.random.rand(100)], ['t']) + my_obs2 = pe.Obs([np.random.rand(100)], ['q'], idl=[range(1, 200, 2)]) merged = pe.merge_obs([my_obs1, my_obs2]) - diff = merged - (my_obs2 + my_obs1) / 2 - assert np.isclose(0, diff.value, atol=1e-16) - with pytest.raises(ValueError): + diff = merged - my_obs2 - my_obs1 + assert diff == -(my_obs1.value + my_obs2.value) / 2 + with pytest.raises(Exception): pe.merge_obs([my_obs1, my_obs1]) my_covobs = pe.cov_Obs(1.0, 0.003, 'cov') - with pytest.raises(ValueError): + with pytest.raises(Exception): pe.merge_obs([my_obs1, my_covobs]) - my_obs3 = pe.Obs([np.random.rand(100)], ['q|2'], idl=[range(1, 200, 2)]) - with pytest.raises(ValueError): - pe.merge_obs([my_obs1, my_obs3]) @@ -541,26 +514,23 @@ def test_correlate(): assert corr1 == corr2 my_obs3 = pe.Obs([np.random.rand(100)], ['t'], idl=[range(2, 102)]) - with pytest.raises(ValueError): + with pytest.raises(Exception): pe.correlate(my_obs1, my_obs3) my_obs4 = pe.Obs([np.random.rand(99)], ['t']) - with pytest.raises(ValueError): + with pytest.raises(Exception): pe.correlate(my_obs1, my_obs4) my_obs5 = pe.Obs([np.random.rand(100)], ['t'], idl=[range(5, 505, 5)]) my_obs6 = pe.Obs([np.random.rand(100)], ['t'], idl=[range(5, 505, 5)]) corr3 = pe.correlate(my_obs5, my_obs6) assert my_obs5.idl == corr3.idl - my_obs7 = pe.Obs([np.random.rand(99)], ['q']) - with pytest.raises(ValueError): - pe.correlate(my_obs1, my_obs7) my_new_obs = pe.Obs([np.random.rand(100)], ['q3']) - with pytest.raises(ValueError): + with pytest.raises(Exception): pe.correlate(my_obs1, my_new_obs) my_covobs = pe.cov_Obs(1.0, 0.003, 'cov') - with pytest.raises(ValueError): + with pytest.raises(Exception): pe.correlate(my_covobs, my_covobs) r_obs = pe.reweight(my_obs1, [my_obs1])[0] with pytest.warns(RuntimeWarning): @@ -579,11 +549,11 @@ def test_merge_idx(): for j in range(5): idll = [range(1, int(round(np.random.uniform(300, 700))), int(round(np.random.uniform(1, 14)))) for i in range(10)] - assert list(pe.obs._merge_idx(idll)) == sorted(set().union(*idll)) + assert pe.obs._merge_idx(idll) == sorted(set().union(*idll)) for j in range(5): idll = [range(int(round(np.random.uniform(1, 28))), int(round(np.random.uniform(300, 700))), int(round(np.random.uniform(1, 14)))) for i in range(10)] - assert list(pe.obs._merge_idx(idll)) == sorted(set().union(*idll)) + assert pe.obs._merge_idx(idll) == sorted(set().union(*idll)) idl = [list(np.arange(1, 14)) + list(range(16, 100, 4)), range(4, 604, 4), [2, 4, 5, 6, 8, 9, 12, 24], range(1, 20, 1), range(50, 789, 7)] new_idx = pe.obs._merge_idx(idl) @@ -694,14 +664,14 @@ def test_gamma_method_irregular(): assert (a.dvalue - 5 * a.ddvalue < expe and expe < a.dvalue + 5 * a.ddvalue) arr2 = np.random.normal(1, .2, size=N) - afull = pe.Obs([arr], ['a1']) + pe.Obs([arr2], ['a2']) + afull = pe.Obs([arr, arr2], ['a1', 'a2']) configs = np.ones_like(arr2) for i in np.random.uniform(0, len(arr2), size=int(.8*N)): configs[int(i)] = 0 zero_arr2 = [arr2[i] for i in range(len(arr2)) if not configs[i] == 0] idx2 = [i + 1 for i in range(len(configs)) if configs[i] == 1] - a = pe.Obs([zero_arr], ['a1'], idl=[idx]) + pe.Obs([zero_arr2], ['a2'], idl=[idx2]) + a = pe.Obs([zero_arr, zero_arr2], ['a1', 'a2'], idl=[idx, idx2]) afull.gamma_method() a.gamma_method() @@ -787,7 +757,7 @@ def test_gamma_method_irregular(): my_obs.gm() idl += [range(1, 400, 4)] my_obs = pe.Obs([dat for i in range(len(idl))], ['%s|%d' % ('A', i) for i in range(len(idl))], idl=idl) - with pytest.raises(ValueError): + with pytest.raises(Exception): my_obs.gm() # check cases where tau is large compared to the chain length @@ -803,11 +773,11 @@ def test_gamma_method_irregular(): carr = gen_autocorrelated_array(arr, .8) o = pe.Obs([carr], ['test']) o.gamma_method() - no = np.nan * o + no = np.NaN * o no.gamma_method() o.idl['test'] = range(1, 1998, 2) o.gamma_method() - no = np.nan * o + no = np.NaN * o no.gamma_method() @@ -865,7 +835,7 @@ def test_covariance_vs_numpy(): data1 = np.random.normal(2.5, 0.2, N) data2 = np.random.normal(0.5, 0.08, N) data3 = np.random.normal(-178, 5, N) - uncorr = np.vstack([data1, data2, data3]) + uncorr = np.row_stack([data1, data2, data3]) corr = np.random.multivariate_normal([0.0, 17, -0.0487], [[1.0, 0.6, -0.22], [0.6, 0.8, 0.01], [-0.22, 0.01, 1.9]], N).T for X in [uncorr, corr]: @@ -1035,7 +1005,7 @@ def test_correlation_intersection_of_idls(): def test_covariance_non_identical_objects(): - obs1 = pe.Obs([np.random.normal(1.0, 0.1, 1000), np.random.normal(1.0, 0.1, 1000)], ["ens|r1", "ens|r2"]) + pe.Obs([np.random.normal(1.0, 0.1, 732)], ['ens2']) + obs1 = pe.Obs([np.random.normal(1.0, 0.1, 1000), np.random.normal(1.0, 0.1, 1000), np.random.normal(1.0, 0.1, 732)], ["ens|r1", "ens|r2", "ens2"]) obs1.gamma_method() obs2 = obs1 + 1e-18 obs2.gamma_method() @@ -1088,27 +1058,6 @@ def test_covariance_reorder_non_overlapping_data(): assert np.isclose(corr1[0, 1], corr2[0, 1], atol=1e-14) -def test_sort_corr(): - xd = { - 'b': [1, 2, 3], - 'a': [2.2, 4.4], - 'c': [3.7, 5.1] - } - - yd = {k : pe.cov_Obs(xd[k], [.2 * o for o in xd[k]], k) for k in xd} - key_orig = list(yd.keys()) - y_all = np.concatenate([np.array(yd[key]) for key in key_orig]) - [o.gm() for o in y_all] - cov = pe.covariance(y_all) - - key_ls = key_sorted = sorted(key_orig) - y_sorted = np.concatenate([np.array(yd[key]) for key in key_sorted]) - [o.gm() for o in y_sorted] - cov_sorted = pe.covariance(y_sorted) - retcov = pe.obs.sort_corr(cov, key_orig, yd) - assert np.sum(retcov - cov_sorted) == 0 - - def test_empty_obs(): o = pe.Obs([np.random.rand(100)], ['test']) q = o + pe.Obs([], [], means=[]) @@ -1119,9 +1068,6 @@ def test_reweight_method(): obs1 = pe.pseudo_Obs(0.2, 0.01, 'test') rw = pe.pseudo_Obs(0.999, 0.001, 'test') assert obs1.reweight(rw) == pe.reweight(rw, [obs1])[0] - rw2 = pe.pseudo_Obs(0.999, 0.001, 'test2') - with pytest.raises(ValueError): - obs1.reweight(rw2) def test_jackknife(): @@ -1138,7 +1084,7 @@ def test_jackknife(): assert np.allclose(tmp_jacks, my_obs.export_jackknife()) my_new_obs = my_obs + pe.Obs([full_data], ['test2']) - with pytest.raises(ValueError): + with pytest.raises(Exception): my_new_obs.export_jackknife() @@ -1326,7 +1272,7 @@ def test_nan_obs(): no.gamma_method() o.idl['test'] = [1, 5] + list(range(7, 2002, 2)) - no = np.nan * o + no = np.NaN * o no.gamma_method() @@ -1335,9 +1281,9 @@ def test_format_uncertainty(): assert pe.obs._format_uncertainty(0.548, 2.48497, 2) == '0.5(2.5)' assert pe.obs._format_uncertainty(0.548, 2.48497, 4) == '0.548(2.485)' assert pe.obs._format_uncertainty(0.548, 20078.3, 9) == '0.5480(20078.3000)' - pe.obs._format_uncertainty(np.nan, 1) - pe.obs._format_uncertainty(1, np.nan) - pe.obs._format_uncertainty(np.nan, np.inf) + pe.obs._format_uncertainty(np.NaN, 1) + pe.obs._format_uncertainty(1, np.NaN) + pe.obs._format_uncertainty(np.NaN, np.inf) def test_format(): @@ -1387,102 +1333,3 @@ def test_vec_gm(): cc = pe.Corr(obs) pe.gm(cc, S=4.12) assert np.all(np.vectorize(lambda x: x.S["qq"])(cc.content) == 4.12) - - -def test_complex_addition(): - o = pe.pseudo_Obs(34.12, 1e-4, "testens") - r = o + 2j - assert r.real == o - r = r * 1j - assert r.imag == o - - -def test_missing_replica(): - N1 = 3000 - N2 = 2000 - O1 = np.random.normal(1.0, .1, N1 + N2) - O2 = .5 * O1[:N1] - - w1 = N1 / (N1 + N2) - w2 = N2 / (N1 + N2) - m12 = np.mean(O1[N1:]) - m2 = np.mean(O2) - d12 = np.std(O1[N1:]) / np.sqrt(N2) # error of from second rep - d2 = np.std(O2) / np.sqrt(N1) # error of from first rep - dval = np.sqrt((w2 * d12 / m2)**2 + (w2 * m12 * d2 / m2**2)**2) # complete error of / - - # pyerrors version that should give the same result - O1dobs = pe.Obs([O1[:N1], O1[N1:]], names=['E|1', 'E|2']) - O2dobs = pe.Obs([O2], names=['E|1']) - O1O2 = O1dobs / O2dobs - O1O2.gm(S=0) - - # explicit construction with different ensembles - O1a = pe.Obs([O1[:N1]], names=['E|1']) - O1b = pe.Obs([O1[N1:]], names=['F|2']) - O1O2b = (w1 * O1a + w2 * O1b) / O2dobs - O1O2b.gm(S=0) - - # pyerrors version without replica (missing configs) - O1c = pe.Obs([O1], names=['E|1']) - O1O2c = O1c / O2dobs - O1O2c.gm(S=0) - - for o in [O1O2, O1O2b, O1O2c]: - assert(np.isclose(dval, o.dvalue, atol=0, rtol=5e-2)) - - o = O1O2 * O2dobs - O1dobs - o.gm() - assert(o.is_zero()) - - o = O1dobs / O1O2 - O2dobs - o.gm() - assert(o.is_zero()) - - # bring more randomness and complexity into the game - Nl = [int(np.random.uniform(low=500, high=5000)) for i in range(4)] - wl = np.array(Nl) / sum(Nl) - O1 = np.random.normal(1.0, .1, sum(Nl)) - - # pyerrors replica version - datl = [O1[:Nl[0]], O1[Nl[0]:sum(Nl[:2])], O1[sum(Nl[:2]):sum(Nl[:3])], O1[sum(Nl[:3]):sum(Nl[:4])]] - O1dobs = pe.Obs(datl, names=['E|%d' % (d) for d in range(len(Nl))]) - O2dobs = .5 * pe.Obs([datl[0]], names=['E|0']) - O3dobs = 2. / pe.Obs([datl[1]], names=['E|1']) - O1O2 = O1dobs / O2dobs - O1O2.gm(S=0) - O1O2O3 = O1O2 * np.sinh(O3dobs) - O1O2O3.gm(S=0) - - # explicit construction with different ensembles - charl = ['E', 'F', 'G', 'H'] - Ol = [pe.Obs([datl[i]], names=['%s|%d' % (charl[i], i)]) for i in range(len(Nl))] - O1O2b = sum(np.array(Ol) * wl) / O2dobs - O1O2b.gm(S=0) - i = 1 - O3dobsb = 2. / pe.Obs([datl[i]], names=['%s|%d' % (charl[i], i)]) - O1O2O3b = O1O2b * np.sinh(O3dobsb) - O1O2O3b.gm(S=0) - - for op in [[O1O2, O1O2b], [O1O2O3, O1O2O3b]]: - assert np.isclose(op[0].value, op[1].value) - assert np.isclose(op[0].dvalue, op[1].dvalue, atol=0, rtol=5e-2) - - # perform the same test using the array_mode of derived_observable - O1O2 = pyerrors.linalg.matmul(np.diag(np.diag(np.reshape(4 * [O1dobs], (2, 2)))), np.diag(np.diag(np.reshape(4 * [1. / O2dobs], (2, 2))))) - O1O2O3 = pyerrors.linalg.matmul(O1O2, np.diag(np.diag(np.sinh(np.reshape(4 * [O3dobs], (2, 2)))))) - O1O2 = O1O2[0][0] - O1O2.gm(S=0) - O1O2O3 = O1O2O3[0][0] - O1O2O3.gm(S=0) - - O1O2b = pyerrors.linalg.matmul(np.diag(np.diag(np.reshape(4 * [sum(np.array(Ol) * wl)], (2, 2)))), np.diag(np.diag(np.reshape(4 * [1. / O2dobs], (2, 2))))) - O1O2O3b = pyerrors.linalg.matmul(O1O2b, np.diag(np.diag(np.sinh(np.reshape(4 * [O3dobsb], (2, 2)))))) - O1O2b = O1O2b[0][0] - O1O2b.gm(S=0) - O1O2O3b = O1O2O3b[0][0] - O1O2O3b.gm(S=0) - - for op in [[O1O2, O1O2b], [O1O2O3, O1O2O3b]]: - assert np.isclose(op[1].value, op[0].value) - assert np.isclose(op[1].dvalue, op[0].dvalue, atol=0, rtol=5e-2) diff --git a/tests/sfcf_in_test.py b/tests/sfcf_in_test.py index 60a71433..35fb3509 100644 --- a/tests/sfcf_in_test.py +++ b/tests/sfcf_in_test.py @@ -1,6 +1,7 @@ import os import sys import inspect +import pyerrors as pe import pyerrors.input.sfcf as sfin import shutil import pytest @@ -13,348 +14,107 @@ sys.path.insert(0, parent_dir) def build_test_environment(path, env_type, cfgs, reps): shutil.copytree("tests/data/sfcf_test/data_"+env_type, (path + "/data_" + env_type)) if env_type == "o": - for i in range(2, cfgs+1): + for i in range(2,cfgs+1): shutil.copytree(path + "/data_o/test_r0/cfg1", path + "/data_o/test_r0/cfg"+str(i)) - for i in range(1, reps): + for i in range(1,reps): shutil.copytree(path + "/data_o/test_r0", path + "/data_o/test_r"+str(i)) elif env_type == "c": - for i in range(2, cfgs+1): + for i in range(2,cfgs+1): shutil.copy(path + "/data_c/data_c_r0/data_c_r0_n1", path + "/data_c/data_c_r0/data_c_r0_n"+str(i)) - for i in range(1, reps): + for i in range(1,reps): os.mkdir(path + "/data_c/data_c_r"+str(i)) - for j in range(1, cfgs+1): - shutil.copy(path + "/data_c/data_c_r0/data_c_r0_n1", path + "/data_c/data_c_r"+str(i)+"/data_c_r"+str(i)+"_n"+str(j)) + for j in range(1,cfgs+1): + shutil.copy(path + "/data_c/data_c_r0/data_c_r0_n1",path + "/data_c/data_c_r"+str(i)+"/data_c_r"+str(i)+"_n"+str(j)) elif env_type == "a": - for i in range(1, reps): + for i in range(1,reps): for corr in ["f_1", "f_A", "F_V0"]: shutil.copy(path + "/data_a/data_a_r0." + corr, path + "/data_a/data_a_r" + str(i) + "." + corr) def test_o_bb(tmp_path): - build_test_environment(str(tmp_path), "o", 5, 3) - f_1 = sfin.read_sfcf(str(tmp_path) + "/data_o", "test", "f_1", quarks="lquark lquark", wf=0, wf2=0, version="2.0", corr_type="bb") + build_test_environment(str(tmp_path), "o",5,3) + f_1 = sfin.read_sfcf(str(tmp_path) + "/data_o", "test", "f_1",quarks="lquark lquark", wf = 0, wf2=0, version = "2.0", corr_type="bb") print(f_1) assert len(f_1) == 1 - assert list(f_1[0].shape.keys()) == ["test_|r0", "test_|r1", "test_|r2"] + assert list(f_1[0].shape.keys()) == ["test_|r0","test_|r1","test_|r2"] assert f_1[0].value == 351.1941525454502 - def test_o_bi(tmp_path): - build_test_environment(str(tmp_path), "o", 5, 3) - f_A = sfin.read_sfcf(str(tmp_path) + "/data_o", "test", "f_A", quarks="lquark lquark", wf=0, version="2.0") + build_test_environment(str(tmp_path), "o",5,3) + f_A = sfin.read_sfcf(str(tmp_path) + "/data_o", "test", "f_A",quarks="lquark lquark", wf = 0, version = "2.0") print(f_A) assert len(f_A) == 3 - assert list(f_A[0].shape.keys()) == ["test_|r0", "test_|r1", "test_|r2"] + assert list(f_A[0].shape.keys()) == ["test_|r0","test_|r1","test_|r2"] assert f_A[0].value == 65.4711887279723 assert f_A[1].value == 1.0447210336915187 assert f_A[2].value == -41.025094911185185 - -def test_o_bi_files(tmp_path): - build_test_environment(str(tmp_path), "o", 10, 3) - f_A = sfin.read_sfcf(str(tmp_path) + "/data_o", "test", "f_A", quarks="lquark lquark", wf=0, version="2.0", - files=[["cfg" + str(i) for i in range(1, 11, 2)], ["cfg" + str(i) for i in range(2, 11, 2)], ["cfg" + str(i) for i in range(1, 11, 2)]]) - print(f_A) - assert len(f_A) == 3 - assert list(f_A[0].shape.keys()) == ["test_|r0", "test_|r1", "test_|r2"] - assert f_A[0].value == 65.4711887279723 - assert f_A[1].value == 1.0447210336915187 - assert f_A[2].value == -41.025094911185185 - - def test_o_bib(tmp_path): - build_test_environment(str(tmp_path), "o", 5, 3) - f_V0 = sfin.read_sfcf(str(tmp_path) + "/data_o", "test", "F_V0", quarks="lquark lquark", wf=0, wf2=0, version="2.0", corr_type="bib") + build_test_environment(str(tmp_path), "o",5,3) + f_V0 = sfin.read_sfcf(str(tmp_path) + "/data_o", "test", "F_V0",quarks="lquark lquark", wf = 0, wf2 = 0, version = "2.0", corr_type="bib") print(f_V0) assert len(f_V0) == 3 - assert list(f_V0[0].shape.keys()) == ["test_|r0", "test_|r1", "test_|r2"] + assert list(f_V0[0].shape.keys()) == ["test_|r0","test_|r1","test_|r2"] assert f_V0[0] == 683.6776090085115 assert f_V0[1] == 661.3188585582334 assert f_V0[2] == 683.6776090081005 - -def test_simple_multi_o(tmp_path): - build_test_environment(str(tmp_path), "o", 5, 3) - corrs = sfin.read_sfcf_multi(str(tmp_path) + "/data_o", "test", ["F_V0"], quarks_list=["lquark lquark"], wf1_list=[0], wf2_list=[0], version="2.0", corr_type_list=["bib"]) - f_V0 = corrs["F_V0"]['lquark lquark']['0']['0']['0'] - assert len(f_V0) == 3 - assert list(f_V0[0].shape.keys()) == ["test_|r0", "test_|r1", "test_|r2"] - assert f_V0[0] == 683.6776090085115 - assert f_V0[1] == 661.3188585582334 - assert f_V0[2] == 683.6776090081005 - - -def test_dict_multi_o(tmp_path): - build_test_environment(str(tmp_path), "o", 5, 3) - corrs = sfin.read_sfcf_multi(str(tmp_path) + "/data_o", "test", - ["F_V0", "f_A", "f_1"], quarks_list=["lquark lquark"], - wf_list=[0], wf2_list=[0], version="2.0", - corr_type_list=["bib", "bi", "bb"], nice_output=False) - print(corrs) - f_1 = corrs["f_1"]['lquark lquark']['0']['0']['0'] - f_A = corrs["f_A"]['lquark lquark']['0']['0']['0'] - f_V0 = corrs["F_V0"]['lquark lquark']['0']['0']['0'] - - assert len(f_1) == 1 - assert list(f_1[0].shape.keys()) == ["test_|r0", "test_|r1", "test_|r2"] - assert f_1[0].value == 351.1941525454502 - - assert len(f_A) == 3 - assert list(f_A[0].shape.keys()) == ["test_|r0", "test_|r1", "test_|r2"] - assert f_A[0].value == 65.4711887279723 - assert f_A[1].value == 1.0447210336915187 - assert f_A[2].value == -41.025094911185185 - - assert len(f_V0) == 3 - assert list(f_V0[0].shape.keys()) == ["test_|r0", "test_|r1", "test_|r2"] - assert f_V0[0] == 683.6776090085115 - assert f_V0[1] == 661.3188585582334 - assert f_V0[2] == 683.6776090081005 - - def test_c_bb(tmp_path): - build_test_environment(str(tmp_path), "c", 5, 3) - f_1 = sfin.read_sfcf(str(tmp_path) + "/data_c", "data_c", "f_1", quarks="lquark lquark", wf=0, wf2=0, version="2.0c", corr_type="bb") + build_test_environment(str(tmp_path), "c",5,3) + f_1 = sfin.read_sfcf(str(tmp_path) + "/data_c", "data_c", "f_1", quarks="lquark lquark", wf = 0, wf2=0, version = "2.0c", corr_type="bb") print(f_1) assert len(f_1) == 1 - assert list(f_1[0].shape.keys()) == ["data_c_|r0", "data_c_|r1", "data_c_|r2"] + assert list(f_1[0].shape.keys()) == ["data_c_|r0","data_c_|r1","data_c_|r2"] assert f_1[0].value == 351.1941525454502 - def test_c_bi(tmp_path): - build_test_environment(str(tmp_path), "c", 5, 3) - f_A = sfin.read_sfcf(str(tmp_path) + "/data_c", "data_c", "f_A", quarks="lquark lquark", wf=0, version="2.0c") + build_test_environment(str(tmp_path), "c",5,3) + f_A = sfin.read_sfcf(str(tmp_path) + "/data_c", "data_c", "f_A", quarks="lquark lquark", wf = 0, version = "2.0c") print(f_A) assert len(f_A) == 3 - assert list(f_A[0].shape.keys()) == ["data_c_|r0", "data_c_|r1", "data_c_|r2"] + assert list(f_A[0].shape.keys()) == ["data_c_|r0","data_c_|r1","data_c_|r2"] assert f_A[0].value == 65.4711887279723 assert f_A[1].value == 1.0447210336915187 assert f_A[2].value == -41.025094911185185 - -def test_c_bi_files(tmp_path): - build_test_environment(str(tmp_path), "c", 10, 3) - f_A = sfin.read_sfcf(str(tmp_path) + "/data_c", "data_c", "f_A", quarks="lquark lquark", wf=0, version="2.0c", - files=[["data_c_r0_n" + str(i) for i in range(1, 11, 2)], ["data_c_r1_n" + str(i) for i in range(2, 11, 2)], ["data_c_r2_n" + str(i) for i in range(1, 11, 2)]]) - print(f_A) - assert len(f_A) == 3 - assert list(f_A[0].shape.keys()) == ["data_c_|r0", "data_c_|r1", "data_c_|r2"] - assert f_A[0].value == 65.4711887279723 - assert f_A[1].value == 1.0447210336915187 - assert f_A[2].value == -41.025094911185185 - - -def test_c_bi_files_int_fail(tmp_path): - build_test_environment(str(tmp_path), "c", 10, 3) - with pytest.raises(TypeError): - sfin.read_sfcf(str(tmp_path) + "/data_c", "data_c", "f_A", quarks="lquark lquark", wf=0, version="2.0c", - files=[[range(1, 11, 2)], [range(2, 11, 2)], [range(1, 11, 2)]]) - - def test_c_bib(tmp_path): - build_test_environment(str(tmp_path), "c", 5, 3) - f_V0 = sfin.read_sfcf(str(tmp_path) + "/data_c", "data_c", "F_V0", quarks="lquark lquark", wf=0, wf2=0, version="2.0c", corr_type="bib") + build_test_environment(str(tmp_path), "c",5,3) + f_V0 = sfin.read_sfcf(str(tmp_path) + "/data_c", "data_c", "F_V0",quarks="lquark lquark", wf = 0, wf2 = 0, version = "2.0c", corr_type="bib") print(f_V0) assert len(f_V0) == 3 - assert list(f_V0[0].shape.keys()) == ["data_c_|r0", "data_c_|r1", "data_c_|r2"] + assert list(f_V0[0].shape.keys()) == ["data_c_|r0","data_c_|r1","data_c_|r2"] assert f_V0[0] == 683.6776090085115 assert f_V0[1] == 661.3188585582334 assert f_V0[2] == 683.6776090081005 - -def test_simple_multi_c(tmp_path): - build_test_environment(str(tmp_path), "c", 5, 3) - corrs = sfin.read_sfcf_multi(str(tmp_path) + "/data_c", "data_c", ["F_V0"], quarks_list=["lquark lquark"], wf1_list=[0], wf2_list=[0], version="2.0c", corr_type_list=["bib"]) - f_V0 = corrs["F_V0"]['lquark lquark']['0']['0']['0'] - assert len(f_V0) == 3 - assert list(f_V0[0].shape.keys()) == ["data_c_|r0", "data_c_|r1", "data_c_|r2"] - assert f_V0[0] == 683.6776090085115 - assert f_V0[1] == 661.3188585582334 - assert f_V0[2] == 683.6776090081005 - - -def test_dict_multi_c(tmp_path): - build_test_environment(str(tmp_path), "c", 5, 3) - corrs = sfin.read_sfcf_multi(str(tmp_path) + "/data_c", "data_c", - ["F_V0", "f_A", "f_1"], quarks_list=["lquark lquark"], - wf_list=[0], wf2_list=[0], version="2.0c", - corr_type_list=["bib", "bi", "bb"], nice_output=False) - print(corrs) - f_1 = corrs["f_1"]['lquark lquark']['0']['0']['0'] - f_A = corrs["f_A"]['lquark lquark']['0']['0']['0'] - f_V0 = corrs["F_V0"]['lquark lquark']['0']['0']['0'] - - assert len(f_1) == 1 - assert list(f_1[0].shape.keys()) == ["data_c_|r0", "data_c_|r1", "data_c_|r2"] - assert f_1[0].value == 351.1941525454502 - - assert len(f_A) == 3 - assert list(f_A[0].shape.keys()) == ["data_c_|r0", "data_c_|r1", "data_c_|r2"] - assert f_A[0].value == 65.4711887279723 - assert f_A[1].value == 1.0447210336915187 - assert f_A[2].value == -41.025094911185185 - - assert len(f_V0) == 3 - assert list(f_V0[0].shape.keys()) == ["data_c_|r0", "data_c_|r1", "data_c_|r2"] - assert f_V0[0] == 683.6776090085115 - assert f_V0[1] == 661.3188585582334 - assert f_V0[2] == 683.6776090081005 - - -def test_dict_multi_wf_c(tmp_path): - build_test_environment(str(tmp_path), "c", 5, 3) - corrs = sfin.read_sfcf_multi(str(tmp_path) + "/data_c", "data_c", - ["F_V0", "f_A", "f_1"], quarks_list=["lquark lquark"], - wf_list=[0, 1], wf2_list=[0, 1], version="2.0c", - corr_type_list=["bib", "bi", "bb"], nice_output=False) - rep_names = ["data_c_|r0", "data_c_|r1", "data_c_|r2"] - f_1_00 = corrs["f_1"]['lquark lquark']['0']['0']['0'] - f_1_01 = corrs["f_1"]['lquark lquark']['0']['0']['1'] - f_1_10 = corrs["f_1"]['lquark lquark']['0']['1']['0'] - f_1_11 = corrs["f_1"]['lquark lquark']['0']['1']['1'] - - assert len(f_1_00) == 1 - assert list(f_1_00[0].shape.keys()) == rep_names - assert f_1_00[0].value == 351.1941525454502 - - assert len(f_1_01) == 1 - assert list(f_1_01[0].shape.keys()) == rep_names - assert f_1_01[0].value == 351.20703575855345 - - assert len(f_1_10) == 1 - assert list(f_1_10[0].shape.keys()) == rep_names - assert f_1_10[0].value == 351.20703575855515 - - assert len(f_1_11) == 1 - assert list(f_1_11[0].shape.keys()) == rep_names - assert f_1_11[0].value == 351.22001235609065 - - f_A = corrs["f_A"]['lquark lquark']['0']['0']['0'] - - assert len(f_A) == 3 - assert list(f_A[0].shape.keys()) == rep_names - assert f_A[0].value == 65.4711887279723 - assert f_A[1].value == 1.0447210336915187 - assert f_A[2].value == -41.025094911185185 - - f_V0_00 = corrs["F_V0"]['lquark lquark']['0']['0']['0'] - f_V0_01 = corrs["F_V0"]['lquark lquark']['0']['0']['1'] - f_V0_10 = corrs["F_V0"]['lquark lquark']['0']['1']['0'] - f_V0_11 = corrs["F_V0"]['lquark lquark']['0']['1']['1'] - - assert len(f_V0_00) == 3 - assert list(f_V0_00[0].shape.keys()) == rep_names - assert f_V0_00[0].value == 683.6776090085115 - assert f_V0_00[1].value == 661.3188585582334 - assert f_V0_00[2].value == 683.6776090081005 - - assert len(f_V0_01) == 3 - assert list(f_V0_01[0].shape.keys()) == rep_names - assert f_V0_01[0].value == 683.7028316879306 - assert f_V0_01[1].value == 661.3432563640756 - assert f_V0_01[2].value == 683.7028316875197 - - assert len(f_V0_10) == 3 - assert list(f_V0_10[0].shape.keys()) == rep_names - assert f_V0_10[0].value == 683.7028316879289 - assert f_V0_10[1].value == 661.343256364074 - assert f_V0_10[2].value == 683.702831687518 - - assert len(f_V0_11) == 3 - assert list(f_V0_11[0].shape.keys()) == rep_names - assert f_V0_11[0].value == 683.7280552978792 - assert f_V0_11[1].value == 661.3676550700158 - assert f_V0_11[2].value == 683.7280552974681 - - def test_a_bb(tmp_path): - build_test_environment(str(tmp_path), "a", 5, 3) - f_1 = sfin.read_sfcf(str(tmp_path) + "/data_a", "data_a", "f_1", quarks="lquark lquark", wf=0, wf2=0, version="2.0a", corr_type="bb") + build_test_environment(str(tmp_path), "a",5,3) + f_1 = sfin.read_sfcf(str(tmp_path) + "/data_a", "data_a", "f_1", quarks="lquark lquark", wf = 0, wf2=0, version = "2.0a", corr_type="bb") print(f_1) assert len(f_1) == 1 - assert list(f_1[0].shape.keys()) == ["data_a_|r0", "data_a_|r1", "data_a_|r2"] + assert list(f_1[0].shape.keys()) == ["data_a_|r0","data_a_|r1","data_a_|r2"] assert f_1[0].value == 351.1941525454502 - def test_a_bi(tmp_path): - build_test_environment(str(tmp_path), "a", 5, 3) - f_A = sfin.read_sfcf(str(tmp_path) + "/data_a", "data_a", "f_A", quarks="lquark lquark", wf=0, version="2.0a") + build_test_environment(str(tmp_path), "a",5,3) + f_A = sfin.read_sfcf(str(tmp_path) + "/data_a", "data_a", "f_A", quarks="lquark lquark", wf = 0, version = "2.0a") print(f_A) assert len(f_A) == 3 - assert list(f_A[0].shape.keys()) == ["data_a_|r0", "data_a_|r1", "data_a_|r2"] + assert list(f_A[0].shape.keys()) == ["data_a_|r0","data_a_|r1","data_a_|r2"] assert f_A[0].value == 65.4711887279723 assert f_A[1].value == 1.0447210336915187 assert f_A[2].value == -41.025094911185185 - -def test_a_bi_files(tmp_path): - build_test_environment(str(tmp_path), "a", 5, 3) - f_A = sfin.read_sfcf(str(tmp_path) + "/data_a", "data_a", "f_A", quarks="lquark lquark", wf=0, version="2.0a", files=["data_a_r0.f_A", "data_a_r1.f_A", "data_a_r2.f_A"]) - print(f_A) - assert len(f_A) == 3 - assert list(f_A[0].shape.keys()) == ["data_a_|r0", "data_a_|r1", "data_a_|r2"] - assert f_A[0].value == 65.4711887279723 - assert f_A[1].value == 1.0447210336915187 - assert f_A[2].value == -41.025094911185185 - - -def test_a_bi_files_int_fail(tmp_path): - build_test_environment(str(tmp_path), "a", 10, 3) - with pytest.raises(TypeError): - sfin.read_sfcf(str(tmp_path) + "/data_a", "data_a", "f_A", quarks="lquark lquark", wf=0, version="2.0a", - files=[[range(1, 11, 2)], [range(2, 11, 2)], [range(1, 11, 2)]]) - - def test_a_bib(tmp_path): - build_test_environment(str(tmp_path), "a", 5, 3) - f_V0 = sfin.read_sfcf(str(tmp_path) + "/data_a", "data_a", "F_V0", quarks="lquark lquark", wf=0, wf2=0, version="2.0a", corr_type="bib") + build_test_environment(str(tmp_path), "a",5,3) + f_V0 = sfin.read_sfcf(str(tmp_path) + "/data_a", "data_a", "F_V0",quarks="lquark lquark", wf = 0, wf2 = 0, version = "2.0a", corr_type="bib") print(f_V0) assert len(f_V0) == 3 - assert list(f_V0[0].shape.keys()) == ["data_a_|r0", "data_a_|r1", "data_a_|r2"] + assert list(f_V0[0].shape.keys()) == ["data_a_|r0","data_a_|r1","data_a_|r2"] assert f_V0[0] == 683.6776090085115 assert f_V0[1] == 661.3188585582334 assert f_V0[2] == 683.6776090081005 - -def test_simple_multi_a(tmp_path): - build_test_environment(str(tmp_path), "a", 5, 3) - corrs = sfin.read_sfcf_multi(str(tmp_path) + "/data_a", "data_a", ["F_V0"], quarks_list=["lquark lquark"], wf1_list=[0], wf2_list=[0], version="2.0a", corr_type_list=["bib"]) - f_V0 = corrs["F_V0"]['lquark lquark']['0']['0']['0'] - assert len(f_V0) == 3 - assert list(f_V0[0].shape.keys()) == ["data_a_|r0", "data_a_|r1", "data_a_|r2"] - assert f_V0[0] == 683.6776090085115 - assert f_V0[1] == 661.3188585582334 - assert f_V0[2] == 683.6776090081005 - - -def test_dict_multi_a(tmp_path): - build_test_environment(str(tmp_path), "a", 5, 3) - corrs = sfin.read_sfcf_multi(str(tmp_path) + "/data_a", "data_a", - ["F_V0", "f_A", "f_1"], quarks_list=["lquark lquark"], - wf_list=[0], wf2_list=[0], version="2.0a", - corr_type_list=["bib", "bi", "bb"], nice_output=False) - print(corrs) - f_1 = corrs["f_1"]['lquark lquark']['0']['0']['0'] - f_A = corrs["f_A"]['lquark lquark']['0']['0']['0'] - f_V0 = corrs["F_V0"]['lquark lquark']['0']['0']['0'] - - assert len(f_1) == 1 - assert list(f_1[0].shape.keys()) == ["data_a_|r0", "data_a_|r1", "data_a_|r2"] - assert f_1[0].value == 351.1941525454502 - - assert len(f_A) == 3 - assert list(f_A[0].shape.keys()) == ["data_a_|r0", "data_a_|r1", "data_a_|r2"] - assert f_A[0].value == 65.4711887279723 - assert f_A[1].value == 1.0447210336915187 - assert f_A[2].value == -41.025094911185185 - - assert len(f_V0) == 3 - assert list(f_V0[0].shape.keys()) == ["data_a_|r0", "data_a_|r1", "data_a_|r2"] - assert f_V0[0] == 683.6776090085115 - assert f_V0[1] == 661.3188585582334 - assert f_V0[2] == 683.6776090081005 - - def test_find_corr(): pattern = 'name ' + "f_A" + '\nquarks ' + "lquark lquark" + '\noffset ' + str(0) + '\nwf ' + str(0) start_read, T = sfin._find_correlator("tests/data/sfcf_test/data_c/data_c_r0/data_c_r0_n1", "2.0c", pattern, False) @@ -369,8 +129,7 @@ def test_find_corr(): with pytest.raises(ValueError): sfin._find_correlator("tests/data/sfcf_test/broken_data_c/data_c_r0/data_c_r0_n1", "2.0c", pattern, False) - -def test_read_compact_file(): +def test_read_compact_file(tmp_path): rep_path = "tests/data/sfcf_test/broken_data_c/data_c_r0/" config_file = "data_c_r0_n1" start_read = 469 @@ -380,40 +139,3 @@ def test_read_compact_file(): im = False with pytest.raises(Exception): sfin._read_compact_file(rep_path, config_file, start_read, T, b2b, name, im) - - -def test_find_correlator(): - file = "tests/data/sfcf_test/data_c/data_c_r0/data_c_r0_n1" - found_start, found_T = sfin._find_correlator(file, "2.0", "name f_A\nquarks lquark lquark\noffset 0\nwf 0", False, False) - assert found_start == 21 - assert found_T == 3 - - -def test_get_rep_name(): - names = ['data_r0', 'data_r1', 'data_r2'] - new_names = sfin._get_rep_names(names) - assert len(new_names) == 3 - assert new_names[0] == 'data_|r0' - assert new_names[1] == 'data_|r1' - assert new_names[2] == 'data_|r2' - names = ['data_q0', 'data_q1', 'data_q2'] - new_names = sfin._get_rep_names(names, rep_sep='q') - assert len(new_names) == 3 - assert new_names[0] == 'data_|q0' - assert new_names[1] == 'data_|q1' - assert new_names[2] == 'data_|q2' - - -def test_get_appended_rep_name(): - names = ['data_r0.f_1', 'data_r1.f_1', 'data_r2.f_1'] - new_names = sfin._get_appended_rep_names(names, 'data', 'f_1') - assert len(new_names) == 3 - assert new_names[0] == 'data_|r0' - assert new_names[1] == 'data_|r1' - assert new_names[2] == 'data_|r2' - names = ['data_q0.f_1', 'data_q1.f_1', 'data_q2.f_1'] - new_names = sfin._get_appended_rep_names(names, 'data', 'f_1', rep_sep='q') - assert len(new_names) == 3 - assert new_names[0] == 'data_|q0' - assert new_names[1] == 'data_|q1' - assert new_names[2] == 'data_|q2' diff --git a/tests/special_test.py b/tests/special_test.py deleted file mode 100644 index 548e61db..00000000 --- a/tests/special_test.py +++ /dev/null @@ -1,12 +0,0 @@ -import numpy as np -import scipy -import pyerrors as pe -import pytest - -from autograd import jacobian -from numdifftools import Jacobian as num_jacobian - -def test_kn(): - for n in np.arange(0, 10): - for val in np.linspace(0.1, 7.3, 10): - assert np.isclose(num_jacobian(lambda x: scipy.special.kn(n, x))(val), jacobian(lambda x: pe.special.kn(n, x))(val), rtol=1e-10, atol=1e-10)