diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index c8d8415..3f12fa9 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -29,27 +29,6 @@ jobs: run: | pre-commit run -a - test_code_python3p8: - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.8"] - 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 - pip install .[dev] - - name: Test code - run: | - mkdir test_report - tox - - test_code_and_coverage_report_python3p11: runs-on: ubuntu-latest strategy: diff --git a/.gitignore b/.gitignore index 30a52d2..c12ed68 100644 --- a/.gitignore +++ b/.gitignore @@ -57,7 +57,7 @@ coverage.xml *.cover .hypothesis/ .pytest_cache/ - +test_report/ # Translations *.mo *.pot diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b8fd639..de01789 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,5 @@ # Default image, if not specified -image: "python:3.8" +image: "python:3.11" stages: - Static Analysis @@ -98,23 +98,15 @@ mypy: junit: cov_report.xml expire_in: 1 hour -tox-3.10: - extends: ".tox" - stage: "Test" - image: "python:3.6" - rules: - - if: '$CI_COMMIT_TAG' - when: always - tox-3.11: extends: ".tox" stage: "Test" image: "python:3.11" -tox-3.8: +tox-3.9: extends: ".tox" stage: "Test" - image: "python:3.8" + image: "python:3.9" rules: - if: '$CI_COMMIT_TAG' when: always diff --git a/comet_maths/_version.py b/comet_maths/_version.py index 5becc17..382021f 100644 --- a/comet_maths/_version.py +++ b/comet_maths/_version.py @@ -1 +1 @@ -__version__ = "1.0.0" +__version__ = "1.0.6" diff --git a/comet_maths/generate_sample/generate_sample.py b/comet_maths/generate_sample/generate_sample.py index 57e20e5..92b1b21 100644 --- a/comet_maths/generate_sample/generate_sample.py +++ b/comet_maths/generate_sample/generate_sample.py @@ -212,8 +212,10 @@ def generate_sample_same(MCsteps, param, dtype=None): :return: generated sample :rtype: array """ - tileshape = generate_sample_shape(MCsteps, param) - MC_sample = np.tile(param, tileshape).astype(dtype) + # tileshape = generate_sample_shape(MCsteps, param) + MC_sample = np.repeat(np.array(param)[np.newaxis], MCsteps, axis=0) + if dtype is not None: + MC_sample = MC_sample.astype(dtype) return MC_sample @@ -696,33 +698,39 @@ def correlate_sample_corr( "comet_math.correlate_sample_corr: it is not yet possible to provide a sample with inhomogeneous dimensions." ) - try: - L = np.array(np.linalg.cholesky(corr)) - except: - L = cm.nearestPD_cholesky(corr, corr=True) - - if maintain_sample_unmodified: - sample_out = copy.deepcopy(sample) - else: - sample_out = sample - if iterate_sample: sample_out_iter = np.empty(len(sample), dtype=object) for i in range(len(sample)): - sample_i = np.roll(sample_out, i, axis=0) + sample_i = np.roll(sample, i, axis=0) if mean is not None: mean_i = np.roll(mean, i, axis=0) if std is not None: std_i = np.roll(std, i, axis=0) sample_out_iter[i] = np.roll( correlate_sample_corr( - sample_i, corr, mean_i, std_i, dtype=dtype, iterate_sample=False + sample_i, + corr, + mean_i, + std_i, + dtype=dtype, + iterate_sample=False, + maintain_sample_unmodified=True, ), -i, axis=0, ) return np.mean(sample_out_iter, axis=0) + try: + L = np.array(np.linalg.cholesky(corr)) + except: + L = cm.nearestPD_cholesky(corr, corr=True) + + if maintain_sample_unmodified: + sample_out = copy.deepcopy(sample) + else: + sample_out = sample + if mean is None: mean = np.array( [np.mean(sample[i], axis=0) for i in range(len(sample))], diff --git a/comet_maths/generate_sample/tests/test_generate_sample.py b/comet_maths/generate_sample/tests/test_generate_sample.py index 371c31d..84d4fe7 100644 --- a/comet_maths/generate_sample/tests/test_generate_sample.py +++ b/comet_maths/generate_sample/tests/test_generate_sample.py @@ -112,6 +112,7 @@ def test_generate_sample_same(self): sample = generate_sample_same(100, x0) npt.assert_equal(sample.shape, (100,)) npt.assert_equal(sample[:-1], sample[1:]) + assert sample.dtype == int sample = generate_sample_same(100, x1) npt.assert_equal(sample.shape, (100, 20)) @@ -121,7 +122,13 @@ def test_generate_sample_same(self): npt.assert_equal(sample.shape, (100, 5, 6)) npt.assert_equal(sample[:-1], sample[1:]) + sample = generate_sample_same(100, "test") + npt.assert_equal(sample.shape, (100,)) + npt.assert_equal(sample[:-1], sample[1:]) + assert sample.dtype.type is np.str_ + def test_generate_sample_systematic(self): + np.random.seed(123456) sample = generate_sample_systematic(1000, x0, u_x0) npt.assert_equal(sample.shape, (1000,)) npt.assert_allclose(u_x0, np.std(sample, axis=0), rtol=0.1) diff --git a/comet_maths/interpolation/interpolation.py b/comet_maths/interpolation/interpolation.py index a6def1b..cdd50a7 100644 --- a/comet_maths/interpolation/interpolation.py +++ b/comet_maths/interpolation/interpolation.py @@ -190,7 +190,7 @@ def interpolate_1d( return_corr: Optional[bool] = False, include_model_uncertainties: Optional[bool] = True, add_model_error: Optional[bool] = False, - MCsteps: Optional[int] = 100, + MCsteps: Optional[int] = 50, parallel_cores: Optional[int] = 4, interpolate_axis: Optional[int] = 0, ) -> Union[ @@ -402,14 +402,26 @@ def _redo_extrapolation( :param extrapolate: extrapolation method, which can be set to "extrapolate" (in which case extrapolation is used using interpolation method defined in "method"), "nearest" (in which case nearest values are used for extrapolation), or "linear" (in which case linear extrapolation is used). Defaults to "extrapolate". :return: interpolated values with correct extrapolation """ - if extrapolate == "nearest": - y[x < x_i[0]] = y_i[0] - y[x > x_i[-1]] = y_i[-1] + if hasattr(x, "__len__") and len(x) > 1: + if extrapolate == "nearest": + y[x < x_i[0]] = y_i[0] + y[x > x_i[-1]] = y_i[-1] + + elif extrapolate == "linear": + f_lin = interp1d(x_i, y_i, kind="linear", fill_value="extrapolate") + y[x < x_i[0]] = f_lin(x[x < x_i[0]]) + y[x > x_i[-1]] = f_lin(x[x > x_i[-1]]) + else: + if extrapolate == "nearest": + if x < x_i[0]: + y = y_i[0] + elif x > x_i[-1]: + y = y_i[-1] - elif extrapolate == "linear": - f_lin = interp1d(x_i, y_i, kind="linear", fill_value="extrapolate") - y[x < x_i[0]] = f_lin(x[x < x_i[0]]) - y[x > x_i[-1]] = f_lin(x[x > x_i[-1]]) + elif extrapolate == "linear": + if x < x_i[0] or x > x_i[-1]: + f_lin = interp1d(x_i, y_i, kind="linear", fill_value="extrapolate") + y = f_lin(x) return y @@ -628,7 +640,7 @@ def interpolate_1d_along_example( include_model_uncertainties: Optional[bool] = True, add_model_error: Optional[bool] = False, plot_residuals: Optional[bool] = False, - MCsteps: Optional[int] = 100, + MCsteps: Optional[int] = 50, parallel_cores: Optional[int] = 4, ) -> Union[ np.ndarray, Tuple[np.ndarray, np.ndarray], Tuple[np.ndarray, np.ndarray, np.ndarray] diff --git a/comet_maths/interpolation/tests/test_interpolation.py b/comet_maths/interpolation/tests/test_interpolation.py index 3e7f792..f4f8cbc 100644 --- a/comet_maths/interpolation/tests/test_interpolation.py +++ b/comet_maths/interpolation/tests/test_interpolation.py @@ -145,6 +145,33 @@ def test_interpolation_1d(self): fig2.colorbar(p2) fig2.savefig("interpolation_test_1d_corrs.png", bbox_inches="tight") + def test_interpolation_1d(self): + xi = np.arange(0, 3.0, 0.2) + yi = function1(xi) + u_yi = 0.05 * np.abs(yi) + # yi = cm.generate_sample(1, yi, u_yi, corr_x="rand") + + x = np.array([0.33333, 0.666666, 1, 1.33333, 1.66666, 2.00, 2.3333]) + # t1=time.time() + y = cm.interpolate_1d(xi, yi, x, method="cubic") + y2 = cm.interpolate_1d(xi, yi, x, method="quadratic") + + y, u_y, corr_y = cm.interpolate_1d( + xi, + yi, + x, + u_y_i=u_yi, + corr_y_i="syst", + method="linear", + return_uncertainties=True, + return_corr=True, + MCsteps=20000, + include_model_uncertainties=False, + ) + + print(u_y / y) + print(u_y, u_yi) + def test_interpolation_1d_along_example(self): np.random.seed(1234567) xi = np.arange(0, 3.0, 0.2) @@ -296,7 +323,7 @@ def test_interpolation_1d_along_example_unc(self): # npt.assert_allclose(y_hr_gpr,y_hr_gpr2,atol=0.01) - mcprop = punpy.MCPropagation(100, parallel_cores=4) + mcprop = punpy.MCPropagation(50, parallel_cores=1) inp2 = cm.Interpolator( relative=False, diff --git a/quality_documentation/QualityDocumentation.tex b/quality_documentation/QualityDocumentation.tex index 86b42d2..169cf55 100644 --- a/quality_documentation/QualityDocumentation.tex +++ b/quality_documentation/QualityDocumentation.tex @@ -110,13 +110,14 @@ \section{Test report}\label{testreport} \clearpage } -\part*{User Manual} -\phantomsection -\addcontentsline{toc}{part}{User Manual} -\appendix -\label{UserManual} -\def\maketitle{} -\def\tableofcontents{} -\input{./latex/user_manual.tex} +%\part*{User Manual} +%\usepackage{./latex/sphinxmanual} +%\phantomsection +%\addcontentsline{toc}{part}{User Manual} +%\appendix +%\label{UserManual} +%\def\maketitle{} +%\def\tableofcontents{} +%\input{./latex/user_manual.tex} \end{document} diff --git a/quality_documentation/base/CookiecutterMacros.tex b/quality_documentation/base/CookiecutterMacros.tex index 373bb18..c0d6492 100644 --- a/quality_documentation/base/CookiecutterMacros.tex +++ b/quality_documentation/base/CookiecutterMacros.tex @@ -4,4 +4,5 @@ \verbdef\authorname{Pieter De Vis} \verbdef\authoremail{pieter.de.vis@npl.co.uk} \newcommand{\packagedescription}{Mathematical algorithms and tools to use within CoMet toolkit.} -\newcommand{\sil}{sil3} \ No newline at end of file +\newcommand{\sil}{sil3} +\newcommand{\sphinxAtStartPar}{\hspace{0}} \ No newline at end of file diff --git a/quality_documentation/comet_maths_requirements.docx b/quality_documentation/comet_maths_requirements.docx index b04e3f9..9374e09 100644 Binary files a/quality_documentation/comet_maths_requirements.docx and b/quality_documentation/comet_maths_requirements.docx differ diff --git a/quality_documentation/uml/comet_maths.png b/quality_documentation/uml/comet_maths.png new file mode 100644 index 0000000..3ffa2cf Binary files /dev/null and b/quality_documentation/uml/comet_maths.png differ diff --git a/quality_documentation/uml/comet_maths.uxf b/quality_documentation/uml/comet_maths.uxf new file mode 100644 index 0000000..5ebb554 --- /dev/null +++ b/quality_documentation/uml/comet_maths.uxf @@ -0,0 +1,63 @@ +10UMLPackage010900480comet_maths +-- +bg=orangeUMLPackage1040280440generate_samples +-- +bg=blueUMLPackage30040280440linear_algebra +-- +bg=greenUMLPackage59040290440interpolation +-- +bg=redUMLClass3080250180generate_sample +-- +generate_sample() +generate_error_sample() +generate_sample_shape() +generate_sample_same() +generate_sample_systematic() +generate_sample_random() +generate_sample_correlated() +generate_sample_same() +generate_sample_cov() +correlate_sample_corr()UMLClass30270250180probability_density_function +-- +generate_sample_pdf()UMLClass32080250180matrix_calculation +-- +calculate_Jacobian() +calculate_corr() +nearestPD_cholesky() +isPD()UMLClass320270250180matrix_conversion +-- +calculate_flattened_corr() +separate_flattened_corr() +convert_corr_to_cov() +convert_cov_to_corr() +correlation_from_covariance() +uncertainty_from_covariance() +change_order_errcorr_dims() +expand_errcorr_dims()UMLClass61080260370interpolation +-- +interpolate_1d() +interpolate_1d_along_example() +gaussian_process_regression() +gpr_basics() +default_unc_methods() +model_error_analytical_methods() +UMLClass620220230210Interpolator +-- +relative +method +method_hr +add_model_error +min_scale +extrapolate +plot_residuals +unc_methods +unc_methods_hr +-- +interpolate_1d() +interpolate_1d_along_example() +Relation1016040170lt=<<- +20;150;10;150;10;10;20;10Relation30016040170lt=<<- +20;150;10;150;10;10;20;10Relation59015050170lt=<<- +30;150;10;150;10;10;20;10Relation10150330200lt=<<- +310;180;10;180;10;10;20;10Relation27016036040lt=<<- +10;20;340;20 \ No newline at end of file diff --git a/setup.py b/setup.py index 2c73c44..46dacf7 100644 --- a/setup.py +++ b/setup.py @@ -26,12 +26,12 @@ def read(filename): long_description=read("README.rst"), packages=find_packages(exclude=("tests",)), install_requires=[ - "numpy", - "scikit-learn", + "numpy>=2.2.4", + "scikit-learn>=1.6.1", "numdifftools", - "scipy", - "punpy>=1.0.0", - "matplotlib", + "scipy>=1.15.2", + "punpy>=1.0.4", + "matplotlib>=3.10.1", ], extras_require={ "dev": [ diff --git a/tox.ini b/tox.ini index e6aa000..2aa8cfe 100644 --- a/tox.ini +++ b/tox.ini @@ -8,5 +8,4 @@ deps = pytest-html pytest-cov commands = - pytest --html=test_report/report.html - pytest --cov-report html:test_report/cov_report --cov=comet_maths + pytest --html=test_report/report.html --cov-report html:test_report/cov_report --cov=comet_maths