diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml new file mode 100644 index 0000000..e56abb6 --- /dev/null +++ b/.github/workflows/python-package.yml @@ -0,0 +1,40 @@ +# This workflow will install Python dependencies, run tests and lint with a variety of Python versions +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python + +name: Python package + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build: + + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ["3.9", "3.10", "3.11"] + + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v3 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python -m pip install flake8 pytest + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + - name: Lint with flake8 + run: | + # stop the build if there are Python syntax errors or undefined names + flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + - name: Test with pytest + run: | + pytest diff --git a/doc/pydoc.rst b/doc/pydoc.rst index e701fbf..278766e 100644 --- a/doc/pydoc.rst +++ b/doc/pydoc.rst @@ -4,7 +4,7 @@ Python documentation ==================== -The package `chiexp` can be loaded in python using the +The package `chiexp` can be loaded in Python using the standard import command:: import sys @@ -21,25 +21,26 @@ The chisquare class Examples of usage ----------------- -First we define a new instance of the `chisquare` class; in the -following example we do it for an uncorrelated fit +First, we define a new instance of the `chisquare` class; in the +following example, we do it for an uncorrelated fit .. code-block:: python + import numpy as np + [x, y, dy] = load_your_data_set() # if dy is the error of y we define W for an uncorrelated fit W = [1./e**2 for e in dy] - func = lambda x, a, m: a*exp(-m*x) - dfunc = lambda x, a, m: [exp(-m*x), -a*x*exp(-m*x)] + func = lambda x, a, m: a*np.exp(-m*x) + dfunc = lambda x, a, m: [np.exp(-m*x), -a*x*np.exp(-m*x)] c=chisquare(x,y,W,func,dfunc) -If the minimum of :math:`\chi^2` is not know the user can use the -``fit`` method; otherwise the values of -the parameters at the minimum can be passed to the class +If the minimum of :math:`\chi^2` is not known, the user can use the +``fit`` method; otherwise, the parameter values at the minimum can be passed to the class via the ``chisq`` method .. code-block:: python @@ -53,9 +54,9 @@ via the ``chisq`` method The user can also compute the error of the fitted parameters from the errors (fluctuations) of the input -observables :math:`Y`. To do so the derivatives +observables :math:`Y`. To do so, the derivatives :math:`d p_\alpha / d y_i` (defined at the minimum of -the :math:`\chi^2`) are needed and if the covariance +the :math:`\chi^2`) are needed. If the covariance matrix is known, applying the chain rule returns the wanted errors @@ -73,35 +74,35 @@ method `chiexp` >>> [ce, dce, _] = c.chiexp(cov) >>> # if cov contains the fluctuations of M configs and 2 replica >>> (M, N) = numpy.shape(cov) - >>> nr = [N1 N2] # such that M=N1+N2 + >>> nr = [N1, N2] # such that M=N1+N2 >>> print M - sum(nr) 0 >>> [ce,dce,covest] = c.chiexp(cov,Nrep=nr,Stau=2.5) -.. The input argument `cov` can be either a matrix (`list` +.. The input argument `cov` can be a matrix (`list` or `numpy.ndarray`) of dimensions NxN or a matrix - of dimensions MxN. In the first case the program + of dimensions MxN. In the first case, the program assumes that `cov` corresponds to the covariance matrix - previously estimated by the user. In the second case - the program assumes that `cov` contains the fluctuations + previously estimated by the user. In the second case, + the program assumes `cov` contains the fluctuations of the observable `y` (mean value subtracted from each measurement) over M different configurations: here the programs computes a *derived autocorrelation function* that is used to estimate :math:`\langle\chi^2\rangle` and its error. -Finally the quality of fit is estimated from a Monte-Carlo +Finally, the quality of fit is estimated from a Monte-Carlo chain of length `nmc` .. code-block:: python >>> nmc=10000 - >>> [p, dp, h] = c.pvalue(nmc, plot=True) + >>> [p, dp, h] = c.pvalue('eig', nmc, plot=True) The method `pvalue` returns the quality of fit and its error, `p` and `dp` respectively, and the Monte Carlo history of -:math:`\chi^2` `h`. If the `plot` flag is activated a plot is automatically +:math:`\chi^2` `h`. If the `plot` flag is activated, a plot is automatically generated with the distribution probability, namely a normalized histogram of `h`. diff --git a/lib/python/chiexp.py b/lib/python/chiexp.py index 157f43a..e03256a 100644 --- a/lib/python/chiexp.py +++ b/lib/python/chiexp.py @@ -169,8 +169,8 @@ def __init__(self,x,y,W,f,df,v='x'): self.v = v.rsplit(',') self.f = f self.df = df - args = inspect.getargspec(f)[0] - if args != inspect.getargspec(df)[0]: + args = inspect.getfullargspec(f)[0] + if args != inspect.getfullargspec(df)[0]: raise ChiExpError(f'Unexpected f and df: arguments do not match') self.pars = [] for vn in args: