diff --git a/.github/issue_template.md b/.github/issue_template.md deleted file mode 100644 index 27fd7641..00000000 --- a/.github/issue_template.md +++ /dev/null @@ -1,24 +0,0 @@ -* **This issue is a** [bug report | feature request | support request / question] - - -* **What is the current behaviour?** - - - -* **If the current behaviour is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem** - - - -* **What is the expected behaviour?** - - - -* **Please tell about the environment(s) affected:** - - - Version: [e.g. 1.0.0-beta] - - Python Version [e.g. 3.6] - - Operating System: [e.g. All | Windows (10, 8, 7) | Linux (Ubuntu, Fedora, RedHat etc) | MacOS] - - Platform: [e.g. Name processor and graphics card | IDAaas | Remote Desktop Connection] - - -* **Other information (e.g. detailed explanation, screenshots, stack traces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, gitter, etc):** diff --git a/.github/workflows/build_wheel.yml b/.github/workflows/build_wheel.yml deleted file mode 100644 index 688118ed..00000000 --- a/.github/workflows/build_wheel.yml +++ /dev/null @@ -1,75 +0,0 @@ -name: Build wheel - -on: [workflow_dispatch, workflow_call] - -concurrency: - group: ${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - build: - strategy: - fail-fast: true - matrix: - platform: [windows-latest, ubuntu-latest, macos-15-intel, macos-14] - env: - CIBW_SKIP: 'pp*' - CIBW_ARCHS: 'auto64' - CIBW_MANYLINUX_X86_64_IMAGE: 'manylinux_2_28' - CIBW_PROJECT_REQUIRES_PYTHON: '>=3.10' - CIBW_TEST_REQUIRES: 'pytest' - MACOSX_DEPLOYMENT_TARGET: '14.0' - defaults: - run: - shell: bash -l {0} - - runs-on: ${{ matrix.platform }} - - steps: - - uses: actions/checkout@v5 - with: - submodules: true - - name: Set up Python version - uses: actions/setup-python@v6 - with: - python-version: "3.x" - - name: Install OMP (MacOS Intel) - if: matrix.platform == 'macos-15-intel' - run: | - brew install llvm@20 libomp - echo "export CC=/usr/local/opt/llvm@20/bin/clang" >> ~/.bashrc - echo "export CXX=/usr/local/opt/llvm@20/bin/clang++" >> ~/.bashrc - echo "export CFLAGS=\"$CFLAGS -I/usr/local/opt/libomp/include\"" >> ~/.bashrc - echo "export CXXFLAGS=\"$CXXFLAGS -I/usr/local/opt/libomp/include\"" >> ~/.bashrc - echo "export LDFLAGS=\"$LDFLAGS -Wl,-rpath,/usr/local/opt/libomp/lib -L/usr/local/opt/libomp/lib -lomp\"" >> ~/.bashrc - source ~/.bashrc - - name: Install OMP (MacOS M1) - if: matrix.platform == 'macos-14' - run: | - brew install llvm@20 libomp - echo "export CC=/opt/homebrew/opt/llvm@20/bin/clang" >> ~/.bashrc - echo "export CXX=/opt/homebrew/opt/llvm@20/bin/clang++" >> ~/.bashrc - echo "export CFLAGS=\"$CFLAGS -I/opt/homebrew/opt/libomp/include\"" >> ~/.bashrc - echo "export CXXFLAGS=\"$CXXFLAGS -I/opt/homebrew/opt/libomp/include\"" >> ~/.bashrc - echo "export LDFLAGS=\"$LDFLAGS -Wl,-rpath,/opt/homebrew/opt/libomp/lib -L/opt/homebrew/opt/libomp/lib -lomp\"" >> ~/.bashrc - source ~/.bashrc - - name: Install OMP (Linux) - if: runner.os == 'Linux' - run: | - sudo apt-get update - sudo apt install libomp-dev - - name: Build Wheel - run: | - # Hack to ensure installed RAT package is used for test instead - # of local package. - mkdir tmp - cp -r tests tmp/tests/ - export PATH="$pythonLocation:$PATH" - CIBW_TEST_COMMAND='cd ${pwd}/tmp && python -m pytest tests' - echo "CIBW_TEST_COMMAND=${CIBW_TEST_COMMAND}" >> $GITHUB_ENV - python -m pip install cibuildwheel - python -m cibuildwheel --output-dir ./wheelhouse - - uses: actions/upload-artifact@v4 - with: - name: wheels-${{ runner.os }}-${{ strategy.job-index }} - path: ./wheelhouse/*.whl diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 8ac33f95..00000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: Build and upload to PyPI - -on: - release: - types: - - published - workflow_dispatch: - -jobs: - build_wheels: - uses: RascalSoftware/python-RAT/.github/workflows/build_wheel.yml@main - - build_sdist: - name: Build source distribution - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - submodules: true - - name: Build sdist - run: | - pip install pybind11 - python setup.py sdist - - uses: actions/upload-artifact@v4 - with: - name: sdist - path: dist/*.tar.gz - - upload_pypi: - needs: [build_wheels, build_sdist] - runs-on: ubuntu-latest - environment: release - permissions: - id-token: write - steps: - - uses: actions/download-artifact@v4 - with: - path: dist - merge-multiple: true - - name: Publish to TestPyPi - if: github.event_name == 'workflow_dispatch' - uses: pypa/gh-action-pypi-publish@release/v1 - with: - repository-url: https://test.pypi.org/legacy/ - - name: Publish - if: github.event_name == 'release' - uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.github/workflows/run_ruff.yml b/.github/workflows/run_ruff.yml deleted file mode 100644 index 64637b07..00000000 --- a/.github/workflows/run_ruff.yml +++ /dev/null @@ -1,12 +0,0 @@ -name: Ruff - -on: workflow_call - -jobs: - ruff: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: astral-sh/ruff-action@v3 - - run: ruff format --check - \ No newline at end of file diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml deleted file mode 100644 index 7dce1346..00000000 --- a/.github/workflows/run_tests.yml +++ /dev/null @@ -1,67 +0,0 @@ -name: Run Unit Tests - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -concurrency: - group: ${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - run_ruff: - uses: ./.github/workflows/run_ruff.yml - - test: - needs: [run_ruff] - strategy: - fail-fast: false - matrix: - platform: [windows-latest, ubuntu-latest, macos-15-intel, macos-latest] - version: ["3.10", "3.13"] - defaults: - run: - shell: bash -l {0} - - runs-on: ${{ matrix.platform}} - - steps: - - uses: actions/checkout@v5 - with: - submodules: true - - name: Set up Python version ${{ matrix.version }} - uses: actions/setup-python@v6 - with: - python-version: ${{ matrix.version }} - - name: Install OMP (MacOS Intel) - if: matrix.platform == 'macos-15-intel' - run: | - brew install llvm@20 libomp - echo "export CC=/usr/local/opt/llvm@20/bin/clang" >> ~/.bashrc - echo "export CXX=/usr/local/opt/llvm@20/bin/clang++" >> ~/.bashrc - echo "export CFLAGS=\"$CFLAGS -I/usr/local/opt/libomp/include\"" >> ~/.bashrc - echo "export CXXFLAGS=\"$CXXFLAGS -I/usr/local/opt/libomp/include\"" >> ~/.bashrc - echo "export LDFLAGS=\"$LDFLAGS -Wl,-rpath,/usr/local/opt/libomp/lib -L/usr/local/opt/libomp/lib -lomp\"" >> ~/.bashrc - source ~/.bashrc - - name: Install OMP (MacOS M1) - if: matrix.platform == 'macos-latest' - run: | - brew install llvm@20 libomp - echo "export CC=/opt/homebrew/opt/llvm@20/bin/clang" >> ~/.bashrc - echo "export CXX=/opt/homebrew/opt/llvm@20/bin/clang++" >> ~/.bashrc - echo "export CFLAGS=\"$CFLAGS -I/opt/homebrew/opt/libomp/include\"" >> ~/.bashrc - echo "export CXXFLAGS=\"$CXXFLAGS -I/opt/homebrew/opt/libomp/include\"" >> ~/.bashrc - echo "export LDFLAGS=\"$LDFLAGS -Wl,-rpath,/opt/homebrew/opt/libomp/lib -L/opt/homebrew/opt/libomp/lib -lomp\"" >> ~/.bashrc - source ~/.bashrc - - name: Install OMP (Linux) - if: runner.os == 'Linux' - run: | - sudo apt-get update - sudo apt install libomp-dev - - name: Install and Test with pytest - run: | - export PATH="$pythonLocation:$PATH" - python -m pip install -e .[dev,orso] - pytest tests/ --cov=ratapi --cov-report=term diff --git a/.gitignore b/.gitignore index 51a84ffe..ef5e8370 100644 --- a/.gitignore +++ b/.gitignore @@ -7,21 +7,7 @@ __pycache__/ .idea .vscode -# direnv -.envrc - -# Unit test / coverage reports -htmlcov/ -.coverage -.cache/ - -# Temp files -tmp/ - # Build -_build -docs/.buildinfo -docs/*.inv *.rat.cpp *.so *.dll @@ -35,11 +21,5 @@ build/* dist/* *.whl -# Local pre-commit hooks -.pre-commit-config.yaml - -# Jupyter notebook checkpoints -.ipynb_checkpoints/* - -# Lock file for uv env -uv.lock +# test +.coverage diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 3825e490..00000000 --- a/.gitmodules +++ /dev/null @@ -1,4 +0,0 @@ -[submodule "cpp/RAT"] - path = cpp/RAT - url = https://github.com/RascalSoftware/RAT - branch = generated_source diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 6980c2c2..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -Contributing to Python-RAT -========================== -Everyone is welcome to contribute to the Python-RAT project by either opening an issue (please check that the -issue has not been reported already) or submitting a pull request. - -Create Developer Environment ----------------------------- -This project targets Python 3.10 or later. Install an appropriate version of Python and other dependencies - -Then create a fork of the python-RAT repo, and clone the fork - - git clone --recurse-submodules https://github.com//python-RAT.git - cd python-RAT - -And finally create a separate branch to begin work - - git checkout -b new-feature - -If there are updates to the C++ RAT submodule, run the following command to update the local branch - - git submodule update --remote - -Once complete submit a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork) via GitHub. -Ensure to rebase your branch to include the latest changes on your branch and resolve possible merge conflicts. - -Unit-testing and coverage -------------------------- -Python-RAT uses the **pytest** module for testing. Proper documentation and unit tests are highly recommended. - -To install pytest use - - pip install pytest pytest-cov - -Run the tests and generate a coverage report with - - pytest tests --cov=RAT - -The coverage report can be saved to the directory htmlcov by running the tests with - - pytest tests --cov-report html --cov=RAT - -For information on other coverage report formats, see https://pytest-cov.readthedocs.io/en/latest/reporting.html - -Documentation -------------- -The documentation will be hosted on GitHub pages. - -Style guidelines ----------------- -* Docstrings should be written in the numpydoc format. diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index a4a255ab..00000000 --- a/MANIFEST.in +++ /dev/null @@ -1,5 +0,0 @@ -include README.md -recursive-include cpp * -prune tests -prune */__pycache__ -global-exclude .git diff --git a/README.md b/README.md index 46cc348e..5dc4af5b 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,21 @@ -python-RAT -========== -Python-RAT is the Python interface for the [Reflectivity Algorithm Toolbox](https://github.com/RascalSoftware/RAT) (RAT). +RAT PyBind Demo +=============== +This is a demonstration of using the generated C++ from MATLAB to create a python extension with PyBind11 + +Build +===== +This has been tested using python 3.9, a c++ compiler is required to run the code. Install the requirement then run the example, if the +compiler can be found, the python extension (*.pyd) will be built and the example will run Install ======= To install in local directory: - git clone --recurse-submodules https://github.com/RascalSoftware/python-RAT.git - cd python-RAT pip install -e . -matlabengine is an optional dependency only required for Matlab custom functions. The version of matlabengine should match the version of Matlab installed on the machine. This can be installed as shown below: - - pip install -e .[matlab-2023a] - -Development dependencies can be installed as shown below - - pip install -e .[dev] - To build wheel: - pip install build python -m build --wheel + +matlabengine is an optional dependency only required for Matlab custom functions. The version of matlabengine should match the version of Matlab installed on the machine. This can be installed as shown below: + pip install -e .[Matlab-2023a] diff --git a/_github/workflows/runTests.yml b/_github/workflows/runTests.yml new file mode 100644 index 00000000..325ce20b --- /dev/null +++ b/_github/workflows/runTests.yml @@ -0,0 +1,61 @@ +name: Run Unit Tests + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +concurrency: + group: ${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + test: + strategy: + fail-fast: false + matrix: + platform: [windows-latest, ubuntu-latest, macos-latest] + env: + CIBW_BUILD: 'cp39-*' + CIBW_ARCHS: 'auto64' + + runs-on: ${{ matrix.platform }} + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v4 + with: + python-version: "3.9" + - name: Install (MacOS) + if: runner.os == 'macOS' + run: | + brew install llvm libomp + export CC=/usr/local/opt/llvm/bin/clang + export CFLAGS="$CFLAGS -I/usr/local/opt/libomp/include" + export CXXFLAGS="$CXXFLAGS -I/usr/local/opt/libomp/include" + export LDFLAGS="$LDFLAGS -Wl,-rpath,/usr/local/opt/libomp/lib -L/usr/local/opt/libomp/lib -lomp" + python -m pip install cibuildwheel==2.16.5 + python -m cibuildwheel --output-dir wheelhouse + - name: Install (Linux) + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt install libomp-dev + python -m pip install cibuildwheel==2.16.5 + python -m cibuildwheel --output-dir wheelhouse + - name: Install (Windows) + if: runner.os == 'Windows' + run: | + python -m pip install cibuildwheel==2.16.5 + python -m cibuildwheel --output-dir wheelhouse + - uses: actions/upload-artifact@v4 + with: + name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }} + path: ./wheelhouse/*.whl + - name: Run Example + run: | + python -m pip install --no-index --find-links wheelhouse/ rat + python examples/DSPC_custom_layers_example.py diff --git a/cpp/RAT b/cpp/RAT deleted file mode 160000 index a5d4d80b..00000000 --- a/cpp/RAT +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a5d4d80ba63185846db678c3ebd9a85bdd82921d diff --git a/cpp/RAT/CoderTimeAPI.cpp b/cpp/RAT/CoderTimeAPI.cpp new file mode 100644 index 00000000..6b3135c8 --- /dev/null +++ b/cpp/RAT/CoderTimeAPI.cpp @@ -0,0 +1,25 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// CoderTimeAPI.cpp +// +// Code generation for function 'CoderTimeAPI' +// + +// Include files +#include "CoderTimeAPI.h" +#include "RATMain_data.h" +#include "rt_nonfinite.h" + +// Function Definitions +namespace RAT +{ + void freq_not_empty_init() + { + freq_not_empty = false; + } +} + +// End of code generation (CoderTimeAPI.cpp) diff --git a/cpp/RAT/CoderTimeAPI.h b/cpp/RAT/CoderTimeAPI.h new file mode 100644 index 00000000..1c2dc886 --- /dev/null +++ b/cpp/RAT/CoderTimeAPI.h @@ -0,0 +1,26 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// CoderTimeAPI.h +// +// Code generation for function 'CoderTimeAPI' +// +#ifndef CODERTIMEAPI_H +#define CODERTIMEAPI_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void freq_not_empty_init(); +} + +#endif + +// End of code generation (CoderTimeAPI.h) diff --git a/cpp/RAT/DREAMWrapper.cpp b/cpp/RAT/DREAMWrapper.cpp new file mode 100644 index 00000000..60d62e2b --- /dev/null +++ b/cpp/RAT/DREAMWrapper.cpp @@ -0,0 +1,62 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// DREAMWrapper.cpp +// +// Code generation for function 'DREAMWrapper' +// + +// Include files +#include "DREAMWrapper.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "reflectivityCalculation.h" +#include "rt_nonfinite.h" +#include "unpackParams.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + real_T DREAMWrapper(const ::coder::array &pars, const c_struct_T + *ratInputs_problemStruct, const cell_11 + *ratInputs_problemCells, const struct2_T + *ratInputs_controls) + { + c_struct_T problemStruct; + cell_wrap_9 a__1[6]; + d_struct_T contrastParams; + int32_T loop_ub; + + // Get the inputs for Reflectivity Calculation + problemStruct = *ratInputs_problemStruct; + + // Put the current parameters into problem + problemStruct.fitParams.set_size(1, pars.size(1)); + loop_ub = pars.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + problemStruct.fitParams[problemStruct.fitParams.size(0) * i] = pars[i]; + } + + // Distribute them to the right parts + unpackParams(&problemStruct, ratInputs_controls->checks.fitParam, + ratInputs_controls->checks.fitBackgroundParam, + ratInputs_controls->checks.fitQzshift, + ratInputs_controls->checks.fitScalefactor, + ratInputs_controls->checks.fitBulkIn, + ratInputs_controls->checks.fitBulkOut, + ratInputs_controls->checks.fitResolutionParam, + ratInputs_controls->checks.fitDomainRatio); + + // Calculate.... + reflectivityCalculation(&problemStruct, ratInputs_problemCells, + ratInputs_controls, &contrastParams, a__1); + + // Function value is chi-squared.... + return -contrastParams.calculations.sumChi / 2.0; + } +} + +// End of code generation (DREAMWrapper.cpp) diff --git a/cpp/RAT/DREAMWrapper.h b/cpp/RAT/DREAMWrapper.h new file mode 100644 index 00000000..1450cea8 --- /dev/null +++ b/cpp/RAT/DREAMWrapper.h @@ -0,0 +1,38 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// DREAMWrapper.h +// +// Code generation for function 'DREAMWrapper' +// +#ifndef DREAMWRAPPER_H +#define DREAMWRAPPER_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct c_struct_T; + struct cell_11; + struct struct2_T; +} + +// Function Declarations +namespace RAT +{ + real_T DREAMWrapper(const ::coder::array &pars, const c_struct_T + *ratInputs_problemStruct, const cell_11 + *ratInputs_problemCells, const struct2_T + *ratInputs_controls); +} + +#endif + +// End of code generation (DREAMWrapper.h) diff --git a/cpp/RAT/RATMain.cpp b/cpp/RAT/RATMain.cpp new file mode 100644 index 00000000..106d8b0f --- /dev/null +++ b/cpp/RAT/RATMain.cpp @@ -0,0 +1,1176 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// RATMain.cpp +// +// Code generation for function 'RATMain' +// + +// Include files +#include "RATMain.h" +#include "RATMain_data.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "lower.h" +#include "makeEmptyBayesResultsStruct.h" +#include "reflectivityCalculation.h" +#include "repmat.h" +#include "rt_nonfinite.h" +#include "runDE.h" +#include "runDREAM.h" +#include "runNestedSampler.h" +#include "runSimplex.h" +#include "strcmp.h" +#include "coder_array.h" +#include "coder_bounded_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + static void cast(const c_struct_T *r, struct0_T *r1); + static void cast(const struct0_T *r, c_struct_T *r1); + static void cast(const cell_7 *r, cell_11 *r1); + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_8, 1U> &r1); + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_8, 2U> &r1); + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_8, 2U> &r1); + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_1, 2U> &r1); +} + +// Function Definitions +namespace RAT +{ + static void cast(const c_struct_T *r, struct0_T *r1) + { + int32_T b_loop_ub; + int32_T loop_ub; + r1->contrastBackgrounds.set_size(1, r->contrastBackgrounds.size(1)); + loop_ub = r->contrastBackgrounds.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->contrastBackgrounds[i] = r->contrastBackgrounds[i]; + } + + r1->contrastBackgroundsType.set_size(1, r->contrastBackgroundsType.size(1)); + loop_ub = r->contrastBackgroundsType.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->contrastBackgroundsType[i] = r->contrastBackgroundsType[i]; + } + + r1->TF.size[0] = 1; + r1->TF.size[1] = r->TF.size[1]; + loop_ub = r->TF.size[1]; + if (loop_ub - 1 >= 0) { + std::copy(&r->TF.data[0], &r->TF.data[loop_ub], &r1->TF.data[0]); + } + + r1->resample.set_size(1, r->resample.size(1)); + loop_ub = r->resample.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->resample[i] = r->resample[i]; + } + + r1->dataPresent.set_size(1, r->dataPresent.size(1)); + loop_ub = r->dataPresent.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->dataPresent[i] = r->dataPresent[i]; + } + + r1->oilChiDataPresent.set_size(1, r->oilChiDataPresent.size(1)); + loop_ub = r->oilChiDataPresent.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->oilChiDataPresent[i] = r->oilChiDataPresent[i]; + } + + r1->numberOfContrasts = r->numberOfContrasts; + r1->geometry.size[0] = 1; + r1->geometry.size[1] = r->geometry.size[1]; + loop_ub = r->geometry.size[1]; + if (loop_ub - 1 >= 0) { + std::copy(&r->geometry.data[0], &r->geometry.data[loop_ub], + &r1->geometry.data[0]); + } + + r1->useImaginary = r->useImaginary; + r1->contrastQzshifts.set_size(1, r->contrastQzshifts.size(1)); + loop_ub = r->contrastQzshifts.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->contrastQzshifts[i] = r->contrastQzshifts[i]; + } + + r1->contrastScalefactors.set_size(1, r->contrastScalefactors.size(1)); + loop_ub = r->contrastScalefactors.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->contrastScalefactors[i] = r->contrastScalefactors[i]; + } + + r1->contrastBulkIns.set_size(1, r->contrastBulkIns.size(1)); + loop_ub = r->contrastBulkIns.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->contrastBulkIns[i] = r->contrastBulkIns[i]; + } + + r1->contrastBulkOuts.set_size(1, r->contrastBulkOuts.size(1)); + loop_ub = r->contrastBulkOuts.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->contrastBulkOuts[i] = r->contrastBulkOuts[i]; + } + + r1->contrastResolutions.set_size(1, r->contrastResolutions.size(1)); + loop_ub = r->contrastResolutions.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->contrastResolutions[i] = r->contrastResolutions[i]; + } + + r1->backgroundParams.set_size(1, r->backgroundParams.size(1)); + loop_ub = r->backgroundParams.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->backgroundParams[i] = r->backgroundParams[i]; + } + + r1->qzshifts.set_size(1, r->qzshifts.size(1)); + loop_ub = r->qzshifts.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->qzshifts[i] = r->qzshifts[i]; + } + + r1->scalefactors.set_size(1, r->scalefactors.size(1)); + loop_ub = r->scalefactors.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->scalefactors[i] = r->scalefactors[i]; + } + + r1->bulkIn.set_size(1, r->bulkIn.size(1)); + loop_ub = r->bulkIn.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->bulkIn[i] = r->bulkIn[i]; + } + + r1->bulkOut.set_size(1, r->bulkOut.size(1)); + loop_ub = r->bulkOut.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->bulkOut[i] = r->bulkOut[i]; + } + + r1->resolutionParams.set_size(1, r->resolutionParams.size(1)); + loop_ub = r->resolutionParams.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->resolutionParams[i] = r->resolutionParams[i]; + } + + r1->params.set_size(1, r->params.size(1)); + loop_ub = r->params.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->params[i] = r->params[i]; + } + + r1->numberOfLayers = r->numberOfLayers; + r1->modelType.size[0] = 1; + r1->modelType.size[1] = r->modelType.size[1]; + loop_ub = r->modelType.size[1]; + if (loop_ub - 1 >= 0) { + std::copy(&r->modelType.data[0], &r->modelType.data[loop_ub], + &r1->modelType.data[0]); + } + + r1->contrastCustomFiles.set_size(1, r->contrastCustomFiles.size(1)); + loop_ub = r->contrastCustomFiles.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->contrastCustomFiles[i] = r->contrastCustomFiles[i]; + } + + r1->contrastDomainRatios.set_size(1, r->contrastDomainRatios.size(1)); + loop_ub = r->contrastDomainRatios.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->contrastDomainRatios[i] = r->contrastDomainRatios[i]; + } + + r1->domainRatio.set_size(1, r->domainRatio.size(1)); + loop_ub = r->domainRatio.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->domainRatio[i] = r->domainRatio[i]; + } + + r1->numberOfDomainContrasts = r->numberOfDomainContrasts; + r1->fitParams.set_size(r->fitParams.size(0), r->fitParams.size(1)); + loop_ub = r->fitParams.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = r->fitParams.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + r1->fitParams[i1 + r1->fitParams.size(0) * i] = r->fitParams[i1 + + r->fitParams.size(0) * i]; + } + } + + r1->otherParams.set_size(r->otherParams.size(0), r->otherParams.size(1)); + loop_ub = r->otherParams.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = r->otherParams.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + r1->otherParams[i1 + r1->otherParams.size(0) * i] = r->otherParams[i1 + + r->otherParams.size(0) * i]; + } + } + + r1->fitLimits.set_size(r->fitLimits.size(0), r->fitLimits.size(1)); + loop_ub = r->fitLimits.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = r->fitLimits.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + r1->fitLimits[i1 + r1->fitLimits.size(0) * i] = r->fitLimits[i1 + + r->fitLimits.size(0) * i]; + } + } + + r1->otherLimits.set_size(r->otherLimits.size(0), r->otherLimits.size(1)); + loop_ub = r->otherLimits.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = r->otherLimits.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + r1->otherLimits[i1 + r1->otherLimits.size(0) * i] = r->otherLimits[i1 + + r->otherLimits.size(0) * i]; + } + } + } + + static void cast(const struct0_T *r, c_struct_T *r1) + { + int32_T b_loop_ub; + int32_T loop_ub; + r1->contrastBackgrounds.set_size(1, r->contrastBackgrounds.size(1)); + loop_ub = r->contrastBackgrounds.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->contrastBackgrounds[i] = r->contrastBackgrounds[i]; + } + + r1->contrastBackgroundsType.set_size(1, r->contrastBackgroundsType.size(1)); + loop_ub = r->contrastBackgroundsType.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->contrastBackgroundsType[i] = r->contrastBackgroundsType[i]; + } + + r1->TF.size[0] = 1; + r1->TF.size[1] = r->TF.size[1]; + loop_ub = r->TF.size[1]; + if (loop_ub - 1 >= 0) { + std::copy(&r->TF.data[0], &r->TF.data[loop_ub], &r1->TF.data[0]); + } + + r1->resample.set_size(1, r->resample.size(1)); + loop_ub = r->resample.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->resample[i] = r->resample[i]; + } + + r1->dataPresent.set_size(1, r->dataPresent.size(1)); + loop_ub = r->dataPresent.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->dataPresent[i] = r->dataPresent[i]; + } + + r1->oilChiDataPresent.set_size(1, r->oilChiDataPresent.size(1)); + loop_ub = r->oilChiDataPresent.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->oilChiDataPresent[i] = r->oilChiDataPresent[i]; + } + + r1->numberOfContrasts = r->numberOfContrasts; + r1->geometry.size[0] = 1; + r1->geometry.size[1] = r->geometry.size[1]; + loop_ub = r->geometry.size[1]; + if (loop_ub - 1 >= 0) { + std::copy(&r->geometry.data[0], &r->geometry.data[loop_ub], + &r1->geometry.data[0]); + } + + r1->useImaginary = r->useImaginary; + r1->contrastQzshifts.set_size(1, r->contrastQzshifts.size(1)); + loop_ub = r->contrastQzshifts.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->contrastQzshifts[i] = r->contrastQzshifts[i]; + } + + r1->contrastScalefactors.set_size(1, r->contrastScalefactors.size(1)); + loop_ub = r->contrastScalefactors.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->contrastScalefactors[i] = r->contrastScalefactors[i]; + } + + r1->contrastBulkIns.set_size(1, r->contrastBulkIns.size(1)); + loop_ub = r->contrastBulkIns.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->contrastBulkIns[i] = r->contrastBulkIns[i]; + } + + r1->contrastBulkOuts.set_size(1, r->contrastBulkOuts.size(1)); + loop_ub = r->contrastBulkOuts.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->contrastBulkOuts[i] = r->contrastBulkOuts[i]; + } + + r1->contrastResolutions.set_size(1, r->contrastResolutions.size(1)); + loop_ub = r->contrastResolutions.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->contrastResolutions[i] = r->contrastResolutions[i]; + } + + r1->backgroundParams.set_size(1, r->backgroundParams.size(1)); + loop_ub = r->backgroundParams.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->backgroundParams[i] = r->backgroundParams[i]; + } + + r1->qzshifts.set_size(1, r->qzshifts.size(1)); + loop_ub = r->qzshifts.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->qzshifts[i] = r->qzshifts[i]; + } + + r1->scalefactors.set_size(1, r->scalefactors.size(1)); + loop_ub = r->scalefactors.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->scalefactors[i] = r->scalefactors[i]; + } + + r1->bulkIn.set_size(1, r->bulkIn.size(1)); + loop_ub = r->bulkIn.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->bulkIn[i] = r->bulkIn[i]; + } + + r1->bulkOut.set_size(1, r->bulkOut.size(1)); + loop_ub = r->bulkOut.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->bulkOut[i] = r->bulkOut[i]; + } + + r1->resolutionParams.set_size(1, r->resolutionParams.size(1)); + loop_ub = r->resolutionParams.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->resolutionParams[i] = r->resolutionParams[i]; + } + + r1->params.set_size(1, r->params.size(1)); + loop_ub = r->params.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->params[i] = r->params[i]; + } + + r1->numberOfLayers = r->numberOfLayers; + r1->modelType.size[0] = 1; + r1->modelType.size[1] = r->modelType.size[1]; + loop_ub = r->modelType.size[1]; + if (loop_ub - 1 >= 0) { + std::copy(&r->modelType.data[0], &r->modelType.data[loop_ub], + &r1->modelType.data[0]); + } + + r1->contrastCustomFiles.set_size(1, r->contrastCustomFiles.size(1)); + loop_ub = r->contrastCustomFiles.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->contrastCustomFiles[i] = r->contrastCustomFiles[i]; + } + + r1->contrastDomainRatios.set_size(1, r->contrastDomainRatios.size(1)); + loop_ub = r->contrastDomainRatios.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->contrastDomainRatios[i] = r->contrastDomainRatios[i]; + } + + r1->domainRatio.set_size(1, r->domainRatio.size(1)); + loop_ub = r->domainRatio.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->domainRatio[i] = r->domainRatio[i]; + } + + r1->numberOfDomainContrasts = r->numberOfDomainContrasts; + r1->fitParams.set_size(r->fitParams.size(0), r->fitParams.size(1)); + loop_ub = r->fitParams.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = r->fitParams.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + r1->fitParams[i1 + r1->fitParams.size(0) * i] = r->fitParams[i1 + + r->fitParams.size(0) * i]; + } + } + + r1->otherParams.set_size(r->otherParams.size(0), r->otherParams.size(1)); + loop_ub = r->otherParams.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = r->otherParams.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + r1->otherParams[i1 + r1->otherParams.size(0) * i] = r->otherParams[i1 + + r->otherParams.size(0) * i]; + } + } + + r1->fitLimits.set_size(r->fitLimits.size(0), r->fitLimits.size(1)); + loop_ub = r->fitLimits.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = r->fitLimits.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + r1->fitLimits[i1 + r1->fitLimits.size(0) * i] = r->fitLimits[i1 + + r->fitLimits.size(0) * i]; + } + } + + r1->otherLimits.set_size(r->otherLimits.size(0), r->otherLimits.size(1)); + loop_ub = r->otherLimits.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = r->otherLimits.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + r1->otherLimits[i1 + r1->otherLimits.size(0) * i] = r->otherLimits[i1 + + r->otherLimits.size(0) * i]; + } + } + } + + static void cast(const cell_7 *r, cell_11 *r1) + { + int32_T loop_ub; + r1->f1.set_size(1, r->f1.size(1)); + loop_ub = r->f1.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->f1[i] = r->f1[i]; + } + + cast(r->f2, r1->f2); + r1->f3.set_size(1, r->f3.size(1)); + loop_ub = r->f3.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->f3[i] = r->f3[i]; + } + + r1->f4.set_size(1, r->f4.size(1)); + loop_ub = r->f4.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->f4[i] = r->f4[i]; + } + + cast(r->f5, r1->f5); + cast(r->f6, r1->f6); + cast(r->f7, r1->f7); + cast(r->f8, r1->f8); + cast(r->f9, r1->f9); + cast(r->f10, r1->f10); + cast(r->f11, r1->f11); + cast(r->f12, r1->f12); + cast(r->f13, r1->f13); + cast(r->f14, r1->f14); + cast(r->f15, r1->f15); + cast(r->f16, r1->f16); + cast(r->f17, r1->f17); + r1->f18.set_size(1, r->f18.size(1)); + loop_ub = r->f18.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + r1->f18[i] = r->f18[i]; + } + + cast(r->f19, r1->f19); + cast(r->f20, r1->f20); + } + + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_8, 1U> &r1) + { + int32_T i; + r1.set_size(r.size(0)); + i = r.size(0); + for (int32_T i1{0}; i1 < i; i1++) { + int32_T loop_ub; + loop_ub = r[i1].f1.size[1]; + r1[i1].f1.set_size(r[i1].f1.size[0], r[i1].f1.size[1]); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + int32_T b_loop_ub; + b_loop_ub = r[i1].f1.size[0]; + for (int32_T i3{0}; i3 < b_loop_ub; i3++) { + r1[i1].f1[r1[i1].f1.size(0) * i2] = r[i1].f1.data[r[i1].f1.size[0] * + i2]; + } + } + } + } + + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_8, 2U> &r1) + { + int32_T i; + r1.set_size(1, r.size(1)); + i = r.size(1) - 1; + for (int32_T i1{0}; i1 <= i; i1++) { + int32_T loop_ub; + loop_ub = r[i1].f1.size(1); + r1[r1.size(0) * i1].f1.set_size(r[r.size(0) * i1].f1.size(0), r[r.size(0) * + i1].f1.size(1)); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + int32_T b_loop_ub; + b_loop_ub = r[i1].f1.size(0); + for (int32_T i3{0}; i3 < b_loop_ub; i3++) { + r1[i1].f1[i3 + r1[i1].f1.size(0) * i2] = r[i1].f1[i3 + r[i1].f1.size(0) + * i2]; + } + } + } + } + + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_8, 2U> &r1) + { + int32_T i; + r1.set_size(1, r.size(1)); + i = r.size(1) - 1; + for (int32_T i1{0}; i1 <= i; i1++) { + int32_T loop_ub; + loop_ub = r[i1].f1.size(1); + r1[r1.size(0) * i1].f1.set_size(r[r.size(0) * i1].f1.size(0), r[r.size(0) * + i1].f1.size(1)); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + int32_T b_loop_ub; + b_loop_ub = r[i1].f1.size(0); + for (int32_T i3{0}; i3 < b_loop_ub; i3++) { + r1[i1].f1[r1[i1].f1.size(0) * i2] = r[i1].f1[r[i1].f1.size(0) * i2]; + } + } + } + } + + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_1, 2U> &r1) + { + int32_T i; + r1.set_size(1, r.size(1)); + i = r.size(1) - 1; + for (int32_T i1{0}; i1 <= i; i1++) { + int32_T loop_ub; + loop_ub = r[i1].f1.size[1]; + r1[r1.size(0) * i1].f1.set_size(1, r[r.size(0) * i1].f1.size[1]); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + r1[i1].f1[i2] = r[i1].f1.data[i2]; + } + } + } + + void RATMain(struct0_T *problemStruct, const cell_7 *problemCells, const + struct1_T *problemLimits, struct2_T *controls, const struct4_T + *priors, struct5_T *contrastParams, cell_wrap_9 resultCells[6], + struct7_T *bayesResults) + { + static c_struct_T b_problemStruct; + static c_struct_T r; + static g_struct_T b_bayesResults; + ::coder::array t19_calculations_allChis; + cell_11 r1; + d_struct_T b_contrastParams; + int32_T switch_expression_size[2]; + int32_T b_loop_ub; + int32_T loop_ub; + int32_T problemStruct_idx_0_tmp; + char_T switch_expression_data[10000]; + coder::repmat(resultCells); + problemStruct_idx_0_tmp = static_cast + (problemStruct->numberOfContrasts); + t19_calculations_allChis.set_size(problemStruct_idx_0_tmp); + contrastParams->ssubs.set_size(problemStruct_idx_0_tmp); + contrastParams->backgroundParams.set_size(problemStruct_idx_0_tmp); + contrastParams->qzshifts.set_size(problemStruct_idx_0_tmp); + contrastParams->scalefactors.set_size(problemStruct_idx_0_tmp); + contrastParams->bulkIn.set_size(problemStruct_idx_0_tmp); + contrastParams->bulkOut.set_size(problemStruct_idx_0_tmp); + contrastParams->resolutionParams.set_size(problemStruct_idx_0_tmp); + for (int32_T i{0}; i < problemStruct_idx_0_tmp; i++) { + t19_calculations_allChis[i] = 0; + contrastParams->ssubs[i] = 0.0; + contrastParams->backgroundParams[i] = 0.0; + contrastParams->qzshifts[i] = 0.0; + contrastParams->scalefactors[i] = 0.0; + contrastParams->bulkIn[i] = 0.0; + contrastParams->bulkOut[i] = 0.0; + contrastParams->resolutionParams[i] = 0.0; + } + + contrastParams->calculations.allChis.set_size(t19_calculations_allChis.size + (0)); + loop_ub = t19_calculations_allChis.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->calculations.allChis[i] = 0.0; + } + + contrastParams->calculations.sumChi = 0.0; + contrastParams->allSubRough.set_size(problemStruct_idx_0_tmp); + contrastParams->resample.set_size(problemStruct_idx_0_tmp, 1); + for (int32_T i{0}; i < problemStruct_idx_0_tmp; i++) { + contrastParams->allSubRough[i] = 0.0; + contrastParams->resample[i] = 0.0; + } + + makeEmptyBayesResultsStruct(problemStruct->numberOfContrasts, coder:: + internal::b_strcmp(problemStruct->TF.data, problemStruct->TF.size), + controls->nChains, bayesResults->bestFitsMean.ref, + bayesResults->bestFitsMean.sld, &bayesResults->bestFitsMean.chi, + bayesResults->bestFitsMean.data, bayesResults->predlims.refPredInts, + bayesResults->predlims.sldPredInts, bayesResults->predlims.refXdata, + bayesResults->predlims.sldXdata, bayesResults->predlims.sampleChi.data, + &bayesResults->predlims.sampleChi.size[0], bayesResults->parConfInts.par95, + bayesResults->parConfInts.par65, bayesResults->parConfInts.mean, + bayesResults->bestPars, &b_bayesResults.bayesRes, bayesResults->chain); + bayesResults->bayesRes.allChains.set_size + (b_bayesResults.bayesRes.allChains.size(0), + b_bayesResults.bayesRes.allChains.size(1), + b_bayesResults.bayesRes.allChains.size(2)); + loop_ub = b_bayesResults.bayesRes.allChains.size(2); + for (int32_T i{0}; i < loop_ub; i++) { + problemStruct_idx_0_tmp = b_bayesResults.bayesRes.allChains.size(1); + for (int32_T i1{0}; i1 < problemStruct_idx_0_tmp; i1++) { + b_loop_ub = b_bayesResults.bayesRes.allChains.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + bayesResults->bayesRes.allChains[(i2 + + bayesResults->bayesRes.allChains.size(0) * i1) + + bayesResults->bayesRes.allChains.size(0) * + bayesResults->bayesRes.allChains.size(1) * i] = + b_bayesResults.bayesRes.allChains[(i2 + + b_bayesResults.bayesRes.allChains.size(0) * i1) + + b_bayesResults.bayesRes.allChains.size(0) * + b_bayesResults.bayesRes.allChains.size(1) * i]; + } + } + } + + bayesResults->bayesRes.dreamOutput = b_bayesResults.bayesRes.dreamOutput; + bayesResults->bayesRes.nestOutput.LogZ = + b_bayesResults.bayesRes.nestOutput.LogZ; + bayesResults->bayesRes.nestOutput.nestSamples.set_size(1, 2); + bayesResults->bayesRes.nestOutput.postSamples.set_size(1, 2); + bayesResults->bayesRes.nestOutput.nestSamples[0] = + b_bayesResults.bayesRes.nestOutput.nestSamples.data[0]; + bayesResults->bayesRes.nestOutput.postSamples[0] = + b_bayesResults.bayesRes.nestOutput.postSamples.data[0]; + bayesResults->bayesRes.nestOutput.nestSamples + [bayesResults->bayesRes.nestOutput.nestSamples.size(0)] = + b_bayesResults.bayesRes.nestOutput.nestSamples.data[1]; + bayesResults->bayesRes.nestOutput.postSamples + [bayesResults->bayesRes.nestOutput.postSamples.size(0)] = + b_bayesResults.bayesRes.nestOutput.postSamples.data[1]; + + // Decide what we are doing.... + coder::lower(controls->procedure.data, controls->procedure.size, + switch_expression_data, switch_expression_size); + if (coder::internal::c_strcmp(switch_expression_data, switch_expression_size)) + { + problemStruct_idx_0_tmp = 0; + } else if (coder::internal::e_strcmp(switch_expression_data, + switch_expression_size)) { + problemStruct_idx_0_tmp = 1; + } else if (coder::internal::f_strcmp(switch_expression_data, + switch_expression_size)) { + problemStruct_idx_0_tmp = 2; + } else if (coder::internal::g_strcmp(switch_expression_data, + switch_expression_size)) { + problemStruct_idx_0_tmp = 3; + } else if (coder::internal::h_strcmp(switch_expression_data, + switch_expression_size)) { + problemStruct_idx_0_tmp = 4; + } else { + problemStruct_idx_0_tmp = -1; + } + + switch (problemStruct_idx_0_tmp) { + case 0: + // Just a single reflectivity calculation + cast(problemStruct, &r); + cast(problemCells, &r1); + reflectivityCalculation(&r, &r1, controls, &b_contrastParams, resultCells); + contrastParams->ssubs.set_size(b_contrastParams.ssubs.size(0)); + loop_ub = b_contrastParams.ssubs.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->ssubs[i] = b_contrastParams.ssubs[i]; + } + + contrastParams->backgroundParams.set_size + (b_contrastParams.backgroundParams.size(0)); + loop_ub = b_contrastParams.backgroundParams.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->backgroundParams[i] = + b_contrastParams.backgroundParams[i]; + } + + contrastParams->qzshifts.set_size(b_contrastParams.qzshifts.size(0)); + loop_ub = b_contrastParams.qzshifts.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->qzshifts[i] = b_contrastParams.qzshifts[i]; + } + + contrastParams->scalefactors.set_size(b_contrastParams.scalefactors.size(0)); + loop_ub = b_contrastParams.scalefactors.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->scalefactors[i] = b_contrastParams.scalefactors[i]; + } + + contrastParams->bulkIn.set_size(b_contrastParams.bulkIn.size(0)); + loop_ub = b_contrastParams.bulkIn.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->bulkIn[i] = b_contrastParams.bulkIn[i]; + } + + contrastParams->bulkOut.set_size(b_contrastParams.bulkOut.size(0)); + loop_ub = b_contrastParams.bulkOut.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->bulkOut[i] = b_contrastParams.bulkOut[i]; + } + + contrastParams->resolutionParams.set_size + (b_contrastParams.resolutionParams.size(0)); + loop_ub = b_contrastParams.resolutionParams.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->resolutionParams[i] = + b_contrastParams.resolutionParams[i]; + } + + contrastParams->calculations = b_contrastParams.calculations; + contrastParams->allSubRough.set_size(b_contrastParams.allSubRough.size(0)); + loop_ub = b_contrastParams.allSubRough.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->allSubRough[i] = b_contrastParams.allSubRough[i]; + } + + contrastParams->resample.set_size(1, b_contrastParams.resample.size(1)); + loop_ub = b_contrastParams.resample.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->resample[contrastParams->resample.size(0) * i] = + b_contrastParams.resample[i]; + } + break; + + case 1: + if (!coder::internal::d_strcmp(controls->display.data, + controls->display.size)) { + printf("\nRunning simplex\n\n"); + fflush(stdout); + } + + cast(problemStruct, &b_problemStruct); + cast(problemCells, &r1); + runSimplex(&b_problemStruct, &r1, problemLimits, controls, + &b_contrastParams, resultCells); + cast(&b_problemStruct, problemStruct); + contrastParams->ssubs.set_size(b_contrastParams.ssubs.size(0)); + loop_ub = b_contrastParams.ssubs.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->ssubs[i] = b_contrastParams.ssubs[i]; + } + + contrastParams->backgroundParams.set_size + (b_contrastParams.backgroundParams.size(0)); + loop_ub = b_contrastParams.backgroundParams.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->backgroundParams[i] = + b_contrastParams.backgroundParams[i]; + } + + contrastParams->qzshifts.set_size(b_contrastParams.qzshifts.size(0)); + loop_ub = b_contrastParams.qzshifts.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->qzshifts[i] = b_contrastParams.qzshifts[i]; + } + + contrastParams->scalefactors.set_size(b_contrastParams.scalefactors.size(0)); + loop_ub = b_contrastParams.scalefactors.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->scalefactors[i] = b_contrastParams.scalefactors[i]; + } + + contrastParams->bulkIn.set_size(b_contrastParams.bulkIn.size(0)); + loop_ub = b_contrastParams.bulkIn.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->bulkIn[i] = b_contrastParams.bulkIn[i]; + } + + contrastParams->bulkOut.set_size(b_contrastParams.bulkOut.size(0)); + loop_ub = b_contrastParams.bulkOut.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->bulkOut[i] = b_contrastParams.bulkOut[i]; + } + + contrastParams->resolutionParams.set_size + (b_contrastParams.resolutionParams.size(0)); + loop_ub = b_contrastParams.resolutionParams.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->resolutionParams[i] = + b_contrastParams.resolutionParams[i]; + } + + contrastParams->calculations = b_contrastParams.calculations; + contrastParams->allSubRough.set_size(b_contrastParams.allSubRough.size(0)); + loop_ub = b_contrastParams.allSubRough.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->allSubRough[i] = b_contrastParams.allSubRough[i]; + } + + contrastParams->resample.set_size(1, b_contrastParams.resample.size(1)); + loop_ub = b_contrastParams.resample.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->resample[contrastParams->resample.size(0) * i] = + b_contrastParams.resample[i]; + } + break; + + case 2: + if (!coder::internal::d_strcmp(controls->display.data, + controls->display.size)) { + printf("\nRunning Differential Evolution\n\n"); + fflush(stdout); + } + + cast(problemStruct, &b_problemStruct); + cast(problemCells, &r1); + runDE(&b_problemStruct, &r1, problemLimits, controls, &b_contrastParams, + resultCells); + cast(&b_problemStruct, problemStruct); + contrastParams->ssubs.set_size(b_contrastParams.ssubs.size(0)); + loop_ub = b_contrastParams.ssubs.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->ssubs[i] = b_contrastParams.ssubs[i]; + } + + contrastParams->backgroundParams.set_size + (b_contrastParams.backgroundParams.size(0)); + loop_ub = b_contrastParams.backgroundParams.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->backgroundParams[i] = + b_contrastParams.backgroundParams[i]; + } + + contrastParams->qzshifts.set_size(b_contrastParams.qzshifts.size(0)); + loop_ub = b_contrastParams.qzshifts.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->qzshifts[i] = b_contrastParams.qzshifts[i]; + } + + contrastParams->scalefactors.set_size(b_contrastParams.scalefactors.size(0)); + loop_ub = b_contrastParams.scalefactors.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->scalefactors[i] = b_contrastParams.scalefactors[i]; + } + + contrastParams->bulkIn.set_size(b_contrastParams.bulkIn.size(0)); + loop_ub = b_contrastParams.bulkIn.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->bulkIn[i] = b_contrastParams.bulkIn[i]; + } + + contrastParams->bulkOut.set_size(b_contrastParams.bulkOut.size(0)); + loop_ub = b_contrastParams.bulkOut.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->bulkOut[i] = b_contrastParams.bulkOut[i]; + } + + contrastParams->resolutionParams.set_size + (b_contrastParams.resolutionParams.size(0)); + loop_ub = b_contrastParams.resolutionParams.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->resolutionParams[i] = + b_contrastParams.resolutionParams[i]; + } + + contrastParams->calculations = b_contrastParams.calculations; + contrastParams->allSubRough.set_size(b_contrastParams.allSubRough.size(0)); + loop_ub = b_contrastParams.allSubRough.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->allSubRough[i] = b_contrastParams.allSubRough[i]; + } + + contrastParams->resample.set_size(1, b_contrastParams.resample.size(1)); + loop_ub = b_contrastParams.resample.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->resample[contrastParams->resample.size(0) * i] = + b_contrastParams.resample[i]; + } + break; + + case 3: + if (!coder::internal::d_strcmp(controls->display.data, + controls->display.size)) { + printf("\nRunning Nested Sampler\n\n"); + fflush(stdout); + } + + cast(problemStruct, &b_problemStruct); + cast(problemCells, &r1); + runNestedSampler(&b_problemStruct, &r1, problemLimits, controls, priors, + &b_contrastParams, resultCells, bayesResults); + cast(&b_problemStruct, problemStruct); + contrastParams->ssubs.set_size(b_contrastParams.ssubs.size(0)); + loop_ub = b_contrastParams.ssubs.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->ssubs[i] = b_contrastParams.ssubs[i]; + } + + contrastParams->backgroundParams.set_size + (b_contrastParams.backgroundParams.size(0)); + loop_ub = b_contrastParams.backgroundParams.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->backgroundParams[i] = + b_contrastParams.backgroundParams[i]; + } + + contrastParams->qzshifts.set_size(b_contrastParams.qzshifts.size(0)); + loop_ub = b_contrastParams.qzshifts.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->qzshifts[i] = b_contrastParams.qzshifts[i]; + } + + contrastParams->scalefactors.set_size(b_contrastParams.scalefactors.size(0)); + loop_ub = b_contrastParams.scalefactors.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->scalefactors[i] = b_contrastParams.scalefactors[i]; + } + + contrastParams->bulkIn.set_size(b_contrastParams.bulkIn.size(0)); + loop_ub = b_contrastParams.bulkIn.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->bulkIn[i] = b_contrastParams.bulkIn[i]; + } + + contrastParams->bulkOut.set_size(b_contrastParams.bulkOut.size(0)); + loop_ub = b_contrastParams.bulkOut.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->bulkOut[i] = b_contrastParams.bulkOut[i]; + } + + contrastParams->resolutionParams.set_size + (b_contrastParams.resolutionParams.size(0)); + loop_ub = b_contrastParams.resolutionParams.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->resolutionParams[i] = + b_contrastParams.resolutionParams[i]; + } + + contrastParams->calculations = b_contrastParams.calculations; + contrastParams->allSubRough.set_size(b_contrastParams.allSubRough.size(0)); + loop_ub = b_contrastParams.allSubRough.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->allSubRough[i] = b_contrastParams.allSubRough[i]; + } + + contrastParams->resample.set_size(1, b_contrastParams.resample.size(1)); + loop_ub = b_contrastParams.resample.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->resample[contrastParams->resample.size(0) * i] = + b_contrastParams.resample[i]; + } + break; + + case 4: + if (!coder::internal::d_strcmp(controls->display.data, + controls->display.size)) { + printf("\nRunning DREAM\n\n"); + fflush(stdout); + } + + cast(problemStruct, &r); + cast(problemCells, &r1); + runDREAM(&r, &r1, problemLimits, controls, priors, &b_problemStruct, + &b_contrastParams, resultCells, &b_bayesResults); + bayesResults->bestFitsMean = b_bayesResults.bestFitsMean; + bayesResults->predlims = b_bayesResults.predlims; + bayesResults->parConfInts = b_bayesResults.parConfInts; + bayesResults->bestPars.set_size(1, b_bayesResults.bestPars.size(1)); + loop_ub = b_bayesResults.bestPars.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + bayesResults->bestPars[i] = b_bayesResults.bestPars[i]; + } + + bayesResults->chain.set_size(b_bayesResults.chain.size(0), + b_bayesResults.chain.size(1)); + loop_ub = b_bayesResults.chain.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + problemStruct_idx_0_tmp = b_bayesResults.chain.size(0); + for (int32_T i1{0}; i1 < problemStruct_idx_0_tmp; i1++) { + bayesResults->chain[i1 + bayesResults->chain.size(0) * i] = + b_bayesResults.chain[i1 + b_bayesResults.chain.size(0) * i]; + } + } + + cast(&b_problemStruct, problemStruct); + contrastParams->ssubs.set_size(b_contrastParams.ssubs.size(0)); + loop_ub = b_contrastParams.ssubs.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->ssubs[i] = b_contrastParams.ssubs[i]; + } + + contrastParams->backgroundParams.set_size + (b_contrastParams.backgroundParams.size(0)); + loop_ub = b_contrastParams.backgroundParams.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->backgroundParams[i] = + b_contrastParams.backgroundParams[i]; + } + + contrastParams->qzshifts.set_size(b_contrastParams.qzshifts.size(0)); + loop_ub = b_contrastParams.qzshifts.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->qzshifts[i] = b_contrastParams.qzshifts[i]; + } + + contrastParams->scalefactors.set_size(b_contrastParams.scalefactors.size(0)); + loop_ub = b_contrastParams.scalefactors.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->scalefactors[i] = b_contrastParams.scalefactors[i]; + } + + contrastParams->bulkIn.set_size(b_contrastParams.bulkIn.size(0)); + loop_ub = b_contrastParams.bulkIn.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->bulkIn[i] = b_contrastParams.bulkIn[i]; + } + + contrastParams->bulkOut.set_size(b_contrastParams.bulkOut.size(0)); + loop_ub = b_contrastParams.bulkOut.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->bulkOut[i] = b_contrastParams.bulkOut[i]; + } + + contrastParams->resolutionParams.set_size + (b_contrastParams.resolutionParams.size(0)); + loop_ub = b_contrastParams.resolutionParams.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->resolutionParams[i] = + b_contrastParams.resolutionParams[i]; + } + + contrastParams->calculations = b_contrastParams.calculations; + contrastParams->allSubRough.set_size(b_contrastParams.allSubRough.size(0)); + loop_ub = b_contrastParams.allSubRough.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->allSubRough[i] = b_contrastParams.allSubRough[i]; + } + + contrastParams->resample.set_size(1, b_contrastParams.resample.size(1)); + loop_ub = b_contrastParams.resample.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->resample[contrastParams->resample.size(0) * i] = + b_contrastParams.resample[i]; + } + + bayesResults->bayesRes.allChains.set_size + (b_bayesResults.bayesRes.allChains.size(0), + b_bayesResults.bayesRes.allChains.size(1), + b_bayesResults.bayesRes.allChains.size(2)); + loop_ub = b_bayesResults.bayesRes.allChains.size(2); + for (int32_T i{0}; i < loop_ub; i++) { + problemStruct_idx_0_tmp = b_bayesResults.bayesRes.allChains.size(1); + for (int32_T i1{0}; i1 < problemStruct_idx_0_tmp; i1++) { + b_loop_ub = b_bayesResults.bayesRes.allChains.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + bayesResults->bayesRes.allChains[(i2 + + bayesResults->bayesRes.allChains.size(0) * i1) + + bayesResults->bayesRes.allChains.size(0) * + bayesResults->bayesRes.allChains.size(1) * i] = + b_bayesResults.bayesRes.allChains[(i2 + + b_bayesResults.bayesRes.allChains.size(0) * i1) + + b_bayesResults.bayesRes.allChains.size(0) * + b_bayesResults.bayesRes.allChains.size(1) * i]; + } + } + } + + bayesResults->bayesRes.dreamOutput = b_bayesResults.bayesRes.dreamOutput; + bayesResults->bayesRes.nestOutput.LogZ = + b_bayesResults.bayesRes.nestOutput.LogZ; + bayesResults->bayesRes.nestOutput.nestSamples.set_size(1, 2); + bayesResults->bayesRes.nestOutput.postSamples.set_size(1, 2); + bayesResults->bayesRes.nestOutput.nestSamples[0] = + b_bayesResults.bayesRes.nestOutput.nestSamples.data[0]; + bayesResults->bayesRes.nestOutput.postSamples[0] = + b_bayesResults.bayesRes.nestOutput.postSamples.data[0]; + bayesResults->bayesRes.nestOutput.nestSamples + [bayesResults->bayesRes.nestOutput.nestSamples.size(0)] = + b_bayesResults.bayesRes.nestOutput.nestSamples.data[1]; + bayesResults->bayesRes.nestOutput.postSamples + [bayesResults->bayesRes.nestOutput.postSamples.size(0)] = + b_bayesResults.bayesRes.nestOutput.postSamples.data[1]; + break; + } + + // Then just do a final calculation to fill in SLD if necessary + // (i.e. if calcSLD is no for fit) + if (!controls->calcSldDuringFit) { + controls->calcSldDuringFit = true; + controls->procedure.size[0] = 1; + controls->procedure.size[1] = 9; + for (int32_T i{0}; i < 9; i++) { + controls->procedure.data[i] = cv1[i]; + } + + cast(problemStruct, &r); + cast(problemCells, &r1); + reflectivityCalculation(&r, &r1, controls, &b_contrastParams, resultCells); + contrastParams->ssubs.set_size(b_contrastParams.ssubs.size(0)); + loop_ub = b_contrastParams.ssubs.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->ssubs[i] = b_contrastParams.ssubs[i]; + } + + contrastParams->backgroundParams.set_size + (b_contrastParams.backgroundParams.size(0)); + loop_ub = b_contrastParams.backgroundParams.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->backgroundParams[i] = + b_contrastParams.backgroundParams[i]; + } + + contrastParams->qzshifts.set_size(b_contrastParams.qzshifts.size(0)); + loop_ub = b_contrastParams.qzshifts.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->qzshifts[i] = b_contrastParams.qzshifts[i]; + } + + contrastParams->scalefactors.set_size(b_contrastParams.scalefactors.size(0)); + loop_ub = b_contrastParams.scalefactors.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->scalefactors[i] = b_contrastParams.scalefactors[i]; + } + + contrastParams->bulkIn.set_size(b_contrastParams.bulkIn.size(0)); + loop_ub = b_contrastParams.bulkIn.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->bulkIn[i] = b_contrastParams.bulkIn[i]; + } + + contrastParams->bulkOut.set_size(b_contrastParams.bulkOut.size(0)); + loop_ub = b_contrastParams.bulkOut.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->bulkOut[i] = b_contrastParams.bulkOut[i]; + } + + contrastParams->resolutionParams.set_size + (b_contrastParams.resolutionParams.size(0)); + loop_ub = b_contrastParams.resolutionParams.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->resolutionParams[i] = + b_contrastParams.resolutionParams[i]; + } + + contrastParams->calculations = b_contrastParams.calculations; + contrastParams->allSubRough.set_size(b_contrastParams.allSubRough.size(0)); + loop_ub = b_contrastParams.allSubRough.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->allSubRough[i] = b_contrastParams.allSubRough[i]; + } + + contrastParams->resample.set_size(1, b_contrastParams.resample.size(1)); + loop_ub = b_contrastParams.resample.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + contrastParams->resample[contrastParams->resample.size(0) * i] = + b_contrastParams.resample[i]; + } + } + } +} + +// End of code generation (RATMain.cpp) diff --git a/cpp/RAT/RATMain.h b/cpp/RAT/RATMain.h new file mode 100644 index 00000000..3907ecfd --- /dev/null +++ b/cpp/RAT/RATMain.h @@ -0,0 +1,30 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// RATMain.h +// +// Code generation for function 'RATMain' +// +#ifndef RATMAIN_H +#define RATMAIN_H + +// Include files +#include "RATMain_types.h" +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + extern void RATMain(struct0_T *problemStruct, const cell_7 *problemCells, + const struct1_T *problemLimits, struct2_T *controls, const + struct4_T *priors, struct5_T *contrastParams, cell_wrap_9 + resultCells[6], struct7_T *bayesResults); +} + +#endif + +// End of code generation (RATMain.h) diff --git a/cpp/RAT/RATMain_data.cpp b/cpp/RAT/RATMain_data.cpp new file mode 100644 index 00000000..64bc66a1 --- /dev/null +++ b/cpp/RAT/RATMain_data.cpp @@ -0,0 +1,177 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// RATMain_data.cpp +// +// Code generation for function 'RATMain_data' +// + +// Include files +#include "RATMain_data.h" +#include "rt_nonfinite.h" + +// Variable Definitions +namespace RAT +{ + uint32_T state[625]; + real_T verbose; + real_T DEBUG; + real_T lastNchar; + boolean_T lastNchar_not_empty; + real_T freq; + boolean_T freq_not_empty; + omp_nest_lock_t RATMain_nestLockGlobal; + const char_T cv[128]{ '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', + '\x07', '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', + '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', '\x18', + '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', ' ', '!', '\"', '#', + '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', + '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'a', + 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', + 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '[', '\\', ']', '^', '_', + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', + '~', '\x7f' }; + + const real_T dv[257]{ 0.0, 0.215241895984875, 0.286174591792068, + 0.335737519214422, 0.375121332878378, 0.408389134611989, 0.43751840220787, + 0.46363433679088, 0.487443966139235, 0.50942332960209, 0.529909720661557, + 0.549151702327164, 0.567338257053817, 0.584616766106378, 0.601104617755991, + 0.61689699000775, 0.63207223638606, 0.646695714894993, 0.660822574244419, + 0.674499822837293, 0.687767892795788, 0.700661841106814, 0.713212285190975, + 0.725446140909999, 0.737387211434295, 0.749056662017815, 0.760473406430107, + 0.771654424224568, 0.782615023307232, 0.793369058840623, 0.80392911698997, + 0.814306670135215, 0.824512208752291, 0.834555354086381, 0.844444954909153, + 0.854189171008163, 0.863795545553308, 0.87327106808886, 0.882622229585165, + 0.891855070732941, 0.900975224461221, 0.909987953496718, 0.91889818364959, + 0.927710533401999, 0.936429340286575, 0.945058684468165, 0.953602409881086, + 0.96206414322304, 0.970447311064224, 0.978755155294224, 0.986990747099062, + 0.99515699963509, 1.00325667954467, 1.01129241744, 1.01926671746548, + 1.02718196603564, 1.03504043983344, 1.04284431314415, 1.05059566459093, + 1.05829648333067, 1.06594867476212, 1.07355406579244, 1.0811144097034, + 1.08863139065398, 1.09610662785202, 1.10354167942464, 1.11093804601357, + 1.11829717411934, 1.12562045921553, 1.13290924865253, 1.14016484436815, + 1.14738850542085, 1.15458145035993, 1.16174485944561, 1.16887987673083, + 1.17598761201545, 1.18306914268269, 1.19012551542669, 1.19715774787944, + 1.20416683014438, 1.2111537262437, 1.21811937548548, 1.22506469375653, + 1.23199057474614, 1.23889789110569, 1.24578749554863, 1.2526602218949, + 1.25951688606371, 1.26635828701823, 1.27318520766536, 1.27999841571382, + 1.28679866449324, 1.29358669373695, 1.30036323033084, 1.30712898903073, + 1.31388467315022, 1.32063097522106, 1.32736857762793, 1.33409815321936, + 1.3408203658964, 1.34753587118059, 1.35424531676263, 1.36094934303328, + 1.36764858359748, 1.37434366577317, 1.38103521107586, 1.38772383568998, + 1.39441015092814, 1.40109476367925, 1.4077782768464, 1.41446128977547, + 1.42114439867531, 1.42782819703026, 1.43451327600589, 1.44120022484872, + 1.44788963128058, 1.45458208188841, 1.46127816251028, 1.46797845861808, + 1.47468355569786, 1.48139403962819, 1.48811049705745, 1.49483351578049, + 1.50156368511546, 1.50830159628131, 1.51504784277671, 1.521803020761, + 1.52856772943771, 1.53534257144151, 1.542128153229, 1.54892508547417, + 1.55573398346918, 1.56255546753104, 1.56939016341512, 1.57623870273591, + 1.58310172339603, 1.58997987002419, 1.59687379442279, 1.60378415602609, + 1.61071162236983, 1.61765686957301, 1.62462058283303, 1.63160345693487, + 1.63860619677555, 1.64562951790478, 1.65267414708306, 1.65974082285818, + 1.66683029616166, 1.67394333092612, 1.68108070472517, 1.68824320943719, + 1.69543165193456, 1.70264685479992, 1.7098896570713, 1.71716091501782, + 1.72446150294804, 1.73179231405296, 1.73915426128591, 1.74654827828172, + 1.75397532031767, 1.76143636531891, 1.76893241491127, 1.77646449552452, + 1.78403365954944, 1.79164098655216, 1.79928758454972, 1.80697459135082, + 1.81470317596628, 1.82247454009388, 1.83028991968276, 1.83815058658281, + 1.84605785028518, 1.8540130597602, 1.86201760539967, 1.87007292107127, + 1.878180486293, 1.88634182853678, 1.8945585256707, 1.90283220855043, + 1.91116456377125, 1.91955733659319, 1.92801233405266, 1.93653142827569, + 1.94511656000868, 1.95376974238465, 1.96249306494436, 1.97128869793366, + 1.98015889690048, 1.98910600761744, 1.99813247135842, 2.00724083056053, + 2.0164337349062, 2.02571394786385, 2.03508435372962, 2.04454796521753, + 2.05410793165065, 2.06376754781173, 2.07353026351874, 2.0833996939983, + 2.09337963113879, 2.10347405571488, 2.11368715068665, 2.12402331568952, + 2.13448718284602, 2.14508363404789, 2.15581781987674, 2.16669518035431, + 2.17772146774029, 2.18890277162636, 2.20024554661128, 2.21175664288416, + 2.22344334009251, 2.23531338492992, 2.24737503294739, 2.25963709517379, + 2.27210899022838, 2.28480080272449, 2.29772334890286, 2.31088825060137, + 2.32430801887113, 2.33799614879653, 2.35196722737914, 2.36623705671729, + 2.38082279517208, 2.39574311978193, 2.41101841390112, 2.42667098493715, + 2.44272531820036, 2.4592083743347, 2.47614993967052, 2.49358304127105, + 2.51154444162669, 2.53007523215985, 2.54922155032478, 2.56903545268184, + 2.58957598670829, 2.61091051848882, 2.63311639363158, 2.65628303757674, + 2.68051464328574, 2.70593365612306, 2.73268535904401, 2.76094400527999, + 2.79092117400193, 2.82287739682644, 2.85713873087322, 2.89412105361341, + 2.93436686720889, 2.97860327988184, 3.02783779176959, 3.08352613200214, + 3.147889289518, 3.2245750520478, 3.32024473383983, 3.44927829856143, + 3.65415288536101, 3.91075795952492 }; + + const real_T dv1[257]{ 1.0, 0.977101701267673, 0.959879091800108, + 0.9451989534423, 0.932060075959231, 0.919991505039348, 0.908726440052131, + 0.898095921898344, 0.887984660755834, 0.878309655808918, 0.869008688036857, + 0.860033621196332, 0.851346258458678, 0.842915653112205, 0.834716292986884, + 0.826726833946222, 0.818929191603703, 0.811307874312656, 0.803849483170964, + 0.796542330422959, 0.789376143566025, 0.782341832654803, 0.775431304981187, + 0.768637315798486, 0.761953346836795, 0.755373506507096, 0.748892447219157, + 0.742505296340151, 0.736207598126863, 0.729995264561476, 0.72386453346863, + 0.717811932630722, 0.711834248878248, 0.705928501332754, 0.700091918136512, + 0.694321916126117, 0.688616083004672, 0.682972161644995, 0.677388036218774, + 0.671861719897082, 0.66639134390875, 0.660975147776663, 0.655611470579697, + 0.650298743110817, 0.645035480820822, 0.639820277453057, 0.634651799287624, + 0.629528779924837, 0.624450015547027, 0.619414360605834, 0.614420723888914, + 0.609468064925773, 0.604555390697468, 0.599681752619125, 0.594846243767987, + 0.590047996332826, 0.585286179263371, 0.580559996100791, 0.575868682972354, + 0.571211506735253, 0.566587763256165, 0.561996775814525, 0.557437893618766, + 0.552910490425833, 0.548413963255266, 0.543947731190026, 0.539511234256952, + 0.535103932380458, 0.530725304403662, 0.526374847171684, 0.522052074672322, + 0.517756517229756, 0.513487720747327, 0.509245245995748, 0.505028667943468, + 0.500837575126149, 0.49667156905249, 0.492530263643869, 0.488413284705458, + 0.484320269426683, 0.480250865909047, 0.476204732719506, 0.47218153846773, + 0.468180961405694, 0.464202689048174, 0.460246417812843, 0.456311852678716, + 0.452398706861849, 0.448506701507203, 0.444635565395739, 0.440785034665804, + 0.436954852547985, 0.433144769112652, 0.429354541029442, 0.425583931338022, + 0.421832709229496, 0.418100649837848, 0.414387534040891, 0.410693148270188, + 0.407017284329473, 0.403359739221114, 0.399720314980197, 0.396098818515832, + 0.392495061459315, 0.388908860018789, 0.385340034840077, 0.381788410873393, + 0.378253817245619, 0.374736087137891, 0.371235057668239, 0.367750569779032, + 0.364282468129004, 0.360830600989648, 0.357394820145781, 0.353974980800077, + 0.350570941481406, 0.347182563956794, 0.343809713146851, 0.340452257044522, + 0.337110066637006, 0.333783015830718, 0.330470981379163, 0.327173842813601, + 0.323891482376391, 0.320623784956905, 0.317370638029914, 0.314131931596337, + 0.310907558126286, 0.307697412504292, 0.30450139197665, 0.301319396100803, + 0.298151326696685, 0.294997087799962, 0.291856585617095, 0.288729728482183, + 0.285616426815502, 0.282516593083708, 0.279430141761638, 0.276356989295668, + 0.273297054068577, 0.270250256365875, 0.267216518343561, 0.264195763997261, + 0.261187919132721, 0.258192911337619, 0.255210669954662, 0.252241126055942, + 0.249284212418529, 0.246339863501264, 0.24340801542275, 0.240488605940501, + 0.237581574431238, 0.23468686187233, 0.231804410824339, 0.228934165414681, + 0.226076071322381, 0.223230075763918, 0.220396127480152, 0.217574176724331, + 0.214764175251174, 0.211966076307031, 0.209179834621125, 0.206405406397881, + 0.203642749310335, 0.200891822494657, 0.198152586545776, 0.195425003514135, + 0.192709036903589, 0.190004651670465, 0.187311814223801, 0.1846304924268, + 0.181960655599523, 0.179302274522848, 0.176655321443735, 0.174019770081839, + 0.171395595637506, 0.168782774801212, 0.166181285764482, 0.163591108232366, + 0.161012223437511, 0.158444614155925, 0.15588826472448, 0.153343161060263, + 0.150809290681846, 0.148286642732575, 0.145775208005994, 0.143274978973514, + 0.140785949814445, 0.138308116448551, 0.135841476571254, 0.133386029691669, + 0.130941777173644, 0.12850872228, 0.126086870220186, 0.123676228201597, + 0.12127680548479, 0.11888861344291, 0.116511665625611, 0.114145977827839, + 0.111791568163838, 0.109448457146812, 0.107116667774684, 0.104796225622487, + 0.102487158941935, 0.10018949876881, 0.0979032790388625, 0.095628536713009, + 0.093365311912691, 0.0911136480663738, 0.0888735920682759, + 0.0866451944505581, 0.0844285095703535, 0.082223595813203, + 0.0800305158146631, 0.0778493367020961, 0.0756801303589272, + 0.0735229737139814, 0.0713779490588905, 0.0692451443970068, + 0.0671246538277886, 0.065016577971243, 0.0629210244377582, 0.06083810834954, + 0.0587679529209339, 0.0567106901062031, 0.0546664613248891, + 0.0526354182767924, 0.0506177238609479, 0.0486135532158687, + 0.0466230949019305, 0.0446465522512946, 0.0426841449164746, + 0.0407361106559411, 0.0388027074045262, 0.0368842156885674, + 0.0349809414617162, 0.0330932194585786, 0.0312214171919203, + 0.0293659397581334, 0.0275272356696031, 0.0257058040085489, + 0.0239022033057959, 0.0221170627073089, 0.0203510962300445, + 0.0186051212757247, 0.0168800831525432, 0.0151770883079353, + 0.0134974506017399, 0.0118427578579079, 0.0102149714397015, + 0.00861658276939875, 0.00705087547137324, 0.00552240329925101, + 0.00403797259336304, 0.00260907274610216, 0.0012602859304986, + 0.000477467764609386 }; + + const char_T cv1[9]{ 'c', 'a', 'l', 'c', 'u', 'l', 'a', 't', 'e' }; +} + +// End of code generation (RATMain_data.cpp) diff --git a/cpp/RAT/RATMain_data.h b/cpp/RAT/RATMain_data.h new file mode 100644 index 00000000..9ad8933d --- /dev/null +++ b/cpp/RAT/RATMain_data.h @@ -0,0 +1,38 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// RATMain_data.h +// +// Code generation for function 'RATMain_data' +// +#ifndef RATMAIN_DATA_H +#define RATMAIN_DATA_H + +// Include files +#include "rtwtypes.h" +#include "omp.h" +#include +#include + +// Variable Declarations +namespace RAT +{ + extern uint32_T state[625]; + extern real_T verbose; + extern real_T DEBUG; + extern real_T lastNchar; + extern boolean_T lastNchar_not_empty; + extern real_T freq; + extern boolean_T freq_not_empty; + extern omp_nest_lock_t RATMain_nestLockGlobal; + extern const char_T cv[128]; + extern const real_T dv[257]; + extern const real_T dv1[257]; + extern const char_T cv1[9]; +} + +#endif + +// End of code generation (RATMain_data.h) diff --git a/cpp/RAT/RATMain_initialize.cpp b/cpp/RAT/RATMain_initialize.cpp new file mode 100644 index 00000000..b8312c33 --- /dev/null +++ b/cpp/RAT/RATMain_initialize.cpp @@ -0,0 +1,43 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// RATMain_initialize.cpp +// +// Code generation for function 'RATMain_initialize' +// + +// Include files +#include "RATMain_initialize.h" +#include "CoderTimeAPI.h" +#include "RATMain_data.h" +#include "RATMain_rtwutil.h" +#include "eml_rand_mt19937ar_stateful.h" +#include "fileManager.h" +#include "rt_nonfinite.h" +#include "textProgressBar.h" +#include "timeKeeper.h" +#include "triggerEvent.h" +#include "omp.h" + +// Function Definitions +namespace RAT +{ + void RATMain_initialize() + { + omp_init_nest_lock(&RATMain_nestLockGlobal); + savedTime_not_empty_init(); + freq_not_empty_init(); + lastNchar_not_empty_init(); + DEBUG = 0.0; + verbose = 1.0; + helper_not_empty_init(); + triggerEvent_init(); + eml_rand_mt19937ar_stateful_init(); + filedata_init(); + emlrtInitThreadStackData(); + } +} + +// End of code generation (RATMain_initialize.cpp) diff --git a/cpp/RAT/RATMain_initialize.h b/cpp/RAT/RATMain_initialize.h new file mode 100644 index 00000000..903aca7d --- /dev/null +++ b/cpp/RAT/RATMain_initialize.h @@ -0,0 +1,26 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// RATMain_initialize.h +// +// Code generation for function 'RATMain_initialize' +// +#ifndef RATMAIN_INITIALIZE_H +#define RATMAIN_INITIALIZE_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + extern void RATMain_initialize(); +} + +#endif + +// End of code generation (RATMain_initialize.h) diff --git a/cpp/RAT/RATMain_internal_types.h b/cpp/RAT/RATMain_internal_types.h new file mode 100644 index 00000000..88ccad69 --- /dev/null +++ b/cpp/RAT/RATMain_internal_types.h @@ -0,0 +1,212 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// RATMain_internal_types.h +// +// Code generation for function 'RATMain' +// +#ifndef RATMAIN_INTERNAL_TYPES_H +#define RATMAIN_INTERNAL_TYPES_H + +// Include files +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include "coder_bounded_array.h" + +// Type Definitions +namespace RAT +{ + struct struct_T + { + real_T LogZ; + ::coder::bounded_array nestSamples; + ::coder::bounded_array postSamples; + }; + + struct b_struct_T + { + ::coder::array allChains; + struct12_T dreamOutput; + struct_T nestOutput; + }; + + struct cell_wrap_12 + { + ::coder::array f1; + }; + + struct cell_wrap_14 + { + ::coder::array f1; + }; + + struct c_struct_T + { + ::coder::array contrastBackgrounds; + ::coder::array contrastBackgroundsType; + ::coder::bounded_array TF; + ::coder::array resample; + ::coder::array dataPresent; + ::coder::array oilChiDataPresent; + real_T numberOfContrasts; + ::coder::bounded_array geometry; + boolean_T useImaginary; + ::coder::array contrastQzshifts; + ::coder::array contrastScalefactors; + ::coder::array contrastBulkIns; + ::coder::array contrastBulkOuts; + ::coder::array contrastResolutions; + ::coder::array backgroundParams; + ::coder::array qzshifts; + ::coder::array scalefactors; + ::coder::array bulkIn; + ::coder::array bulkOut; + ::coder::array resolutionParams; + ::coder::array params; + real_T numberOfLayers; + ::coder::bounded_array modelType; + ::coder::array contrastCustomFiles; + ::coder::array contrastDomainRatios; + ::coder::array domainRatio; + real_T numberOfDomainContrasts; + ::coder::array fitParams; + ::coder::array otherParams; + ::coder::array fitLimits; + ::coder::array otherLimits; + }; + + struct cell_11 + { + ::coder::array f1; + ::coder::array f2; + ::coder::array f3; + ::coder::array f4; + ::coder::array f5; + ::coder::array f6; + ::coder::array f7; + ::coder::array f8; + ::coder::array f9; + ::coder::array f10; + ::coder::array f11; + ::coder::array f12; + ::coder::array f13; + ::coder::array f14; + ::coder::array f15; + ::coder::array f16; + ::coder::array f17; + ::coder::array f18; + ::coder::array f19; + ::coder::array f20; + }; + + struct d_struct_T + { + ::coder::array ssubs; + ::coder::array backgroundParams; + ::coder::array qzshifts; + ::coder::array scalefactors; + ::coder::array bulkIn; + ::coder::array bulkOut; + ::coder::array resolutionParams; + struct6_T calculations; + ::coder::array allSubRough; + ::coder::array resample; + }; + + struct cell_wrap_34 + { + ::coder::array f1; + }; + + struct cell_wrap_20 + { + ::coder::array f1; + }; + + struct cell_wrap_35 + { + cell_wrap_8 f1[2]; + }; + + struct e_struct_T + { + ::coder::array ref; + ::coder::array sld; + real_T chi; + ::coder::array data; + }; + + struct f_struct_T + { + ::coder::array refPredInts; + ::coder::array sldPredInts; + ::coder::array refXdata; + ::coder::array sldXdata; + real_T sampleChi[1000]; + }; + + struct g_struct_T + { + struct8_T bestFitsMean; + struct9_T predlims; + struct10_T parConfInts; + ::coder::array bestPars; + b_struct_T bayesRes; + ::coder::array chain; + }; + + struct i_struct_T + { + real_T iterations; + real_T funcCount; + char_T algorithm[33]; + ::coder::array message; + }; + + struct j_struct_T + { + ::coder::bounded_array I_lentol; + ::coder::bounded_array FVr_x; + ::coder::bounded_array FVr_lim_up; + ::coder::bounded_array FVr_lim_lo; + real_T I_NP; + real_T fWeight; + real_T F_CR; + real_T I_D; + ::coder::array FVr_minbound; + ::coder::array FVr_maxbound; + real_T I_bnd_constr; + real_T I_itermax; + real_T F_VTR; + real_T I_strategy; + real_T I_refresh; + real_T I_plotting; + ::coder::array FM_pop; + ::coder::array FVr_bestmem; + }; + + struct cell_25 + { + ::coder::array f1; + }; + + struct k_struct_T + { + ::coder::array LB; + ::coder::array UB; + ::coder::array BoundClass; + }; + + struct l_struct_T + { + real_T I_no; + real_T FVr_oa; + }; +} + +#endif + +// End of code generation (RATMain_internal_types.h) diff --git a/cpp/RAT/RATMain_rtwutil.cpp b/cpp/RAT/RATMain_rtwutil.cpp new file mode 100644 index 00000000..d8967461 --- /dev/null +++ b/cpp/RAT/RATMain_rtwutil.cpp @@ -0,0 +1,228 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// RATMain_rtwutil.cpp +// +// Code generation for function 'RATMain_rtwutil' +// + +// Include files +#include "RATMain_rtwutil.h" +#include "RATMain_types.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include "omp.h" +#include +#include +#include + +// Variable Definitions +namespace RAT +{ + static RATMainTLS *RATMainTLSGlobal; + +#pragma omp threadprivate (RATMainTLSGlobal) + +} + +// Function Definitions +namespace RAT +{ + void cast(const ::coder::array &r, ::coder::array< + cell_wrap_8, 1U> &r1) + { + int32_T i; + r1.set_size(r.size(0)); + i = r.size(0); + for (int32_T i1{0}; i1 < i; i1++) { + int32_T loop_ub; + loop_ub = r[i1].f1.size(1); + r1[i1].f1.set_size(5, r[i1].f1.size(1)); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + for (int32_T i3{0}; i3 < 5; i3++) { + r1[i1].f1[i3 + r1[i1].f1.size(0) * i2] = r[i1].f1[i3 + 5 * i2]; + } + } + } + } + + void cast(const ::coder::array &r, ::coder::array< + cell_wrap_8, 2U> &r1) + { + int32_T i; + r1.set_size(r.size(0), r.size(1)); + i = r.size(0) * r.size(1); + for (int32_T i1{0}; i1 < i; i1++) { + int32_T loop_ub; + loop_ub = r[i1].f1.size(1); + r1[i1].f1.set_size(5, r[i1].f1.size(1)); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + for (int32_T i3{0}; i3 < 5; i3++) { + r1[i1].f1[i3 + r1[i1].f1.size(0) * i2] = r[i1].f1[i3 + 5 * i2]; + } + } + } + } + + void cast(const ::coder::array &r, ::coder::array< + cell_wrap_8, 2U> &r1) + { + int32_T i; + r1.set_size(r.size(0), r.size(1)); + i = r.size(0) * r.size(1); + for (int32_T i1{0}; i1 < i; i1++) { + int32_T loop_ub; + loop_ub = r[i1].f1.size(1); + r1[i1].f1.set_size(1, r[i1].f1.size(1)); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + r1[i1].f1[r1[i1].f1.size(0) * i2] = r[i1].f1[i2]; + } + } + } + + void cast(const ::coder::array &r, ::coder::array< + cell_wrap_8, 2U> &r1) + { + int32_T i; + r1.set_size(r.size(0), 2); + i = r.size(0) << 1; + for (int32_T i1{0}; i1 < i; i1++) { + int32_T loop_ub; + loop_ub = r[i1].f1.size(1); + r1[i1].f1.set_size(r[i1].f1.size(0), r[i1].f1.size(1)); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + int32_T b_loop_ub; + b_loop_ub = r[i1].f1.size(0); + for (int32_T i3{0}; i3 < b_loop_ub; i3++) { + r1[i1].f1[i3 + r1[i1].f1.size(0) * i2] = r[i1].f1[i3 + r[i1].f1.size(0) + * i2]; + } + } + } + } + + void emlrtFreeThreadStackData() + { + int32_T b; + b = omp_get_max_threads(); + +#pragma omp parallel for schedule(static)\ + num_threads(omp_get_max_threads()) + + for (int32_T i = 1; i <= b; i++) { + delete RATMainTLSGlobal; + } + } + + RATMainTLS *emlrtGetThreadStackData() + { + return RATMainTLSGlobal; + } + + void emlrtInitThreadStackData() + { + int32_T b; + b = omp_get_max_threads(); + +#pragma omp parallel for schedule(static)\ + num_threads(omp_get_max_threads()) + + for (int32_T i = 1; i <= b; i++) { + RATMainTLSGlobal = static_cast(new RATMainTLS); + } + } + + real_T rt_hypotd_snf(real_T u0, real_T u1) + { + real_T a; + real_T b; + real_T y; + a = std::abs(u0); + b = std::abs(u1); + if (a < b) { + a /= b; + y = b * std::sqrt(a * a + 1.0); + } else if (a > b) { + b /= a; + y = a * std::sqrt(b * b + 1.0); + } else if (std::isnan(b)) { + y = rtNaN; + } else { + y = a * 1.4142135623730951; + } + + return y; + } + + real_T rt_powd_snf(real_T u0, real_T u1) + { + real_T y; + if (std::isnan(u0) || std::isnan(u1)) { + y = rtNaN; + } else { + real_T d; + real_T d1; + d = std::abs(u0); + d1 = std::abs(u1); + if (std::isinf(u1)) { + if (d == 1.0) { + y = 1.0; + } else if (d > 1.0) { + if (u1 > 0.0) { + y = rtInf; + } else { + y = 0.0; + } + } else if (u1 > 0.0) { + y = 0.0; + } else { + y = rtInf; + } + } else if (d1 == 0.0) { + y = 1.0; + } else if (d1 == 1.0) { + if (u1 > 0.0) { + y = u0; + } else { + y = 1.0 / u0; + } + } else if (u1 == 2.0) { + y = u0 * u0; + } else if ((u1 == 0.5) && (u0 >= 0.0)) { + y = std::sqrt(u0); + } else if ((u0 < 0.0) && (u1 > std::floor(u1))) { + y = rtNaN; + } else { + y = std::pow(u0, u1); + } + } + + return y; + } + + real_T rt_remd_snf(real_T u0, real_T u1) + { + real_T y; + if (std::isnan(u0) || std::isnan(u1) || std::isinf(u0)) { + y = rtNaN; + } else if (std::isinf(u1)) { + y = u0; + } else if ((u1 != 0.0) && (u1 != std::trunc(u1))) { + real_T q; + q = std::abs(u0 / u1); + if (!(std::abs(q - std::floor(q + 0.5)) > DBL_EPSILON * q)) { + y = 0.0 * u0; + } else { + y = std::fmod(u0, u1); + } + } else { + y = std::fmod(u0, u1); + } + + return y; + } +} + +// End of code generation (RATMain_rtwutil.cpp) diff --git a/cpp/RAT/RATMain_rtwutil.h b/cpp/RAT/RATMain_rtwutil.h new file mode 100644 index 00000000..b0747c4d --- /dev/null +++ b/cpp/RAT/RATMain_rtwutil.h @@ -0,0 +1,41 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// RATMain_rtwutil.h +// +// Code generation for function 'RATMain_rtwutil' +// +#ifndef RATMAIN_RTWUTIL_H +#define RATMAIN_RTWUTIL_H + +// Include files +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + extern void cast(const ::coder::array &r, ::coder::array< + cell_wrap_8, 1U> &r1); + extern void cast(const ::coder::array &r, ::coder::array< + cell_wrap_8, 2U> &r1); + extern void cast(const ::coder::array &r, ::coder::array< + cell_wrap_8, 2U> &r1); + extern void cast(const ::coder::array &r, ::coder::array< + cell_wrap_8, 2U> &r1); + extern void emlrtFreeThreadStackData(); + extern RATMainTLS *emlrtGetThreadStackData(); + extern void emlrtInitThreadStackData(); + extern real_T rt_hypotd_snf(real_T u0, real_T u1); + extern real_T rt_powd_snf(real_T u0, real_T u1); + extern real_T rt_remd_snf(real_T u0, real_T u1); +} + +#endif + +// End of code generation (RATMain_rtwutil.h) diff --git a/cpp/RAT/RATMain_terminate.cpp b/cpp/RAT/RATMain_terminate.cpp new file mode 100644 index 00000000..73060f92 --- /dev/null +++ b/cpp/RAT/RATMain_terminate.cpp @@ -0,0 +1,28 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// RATMain_terminate.cpp +// +// Code generation for function 'RATMain_terminate' +// + +// Include files +#include "RATMain_terminate.h" +#include "RATMain_data.h" +#include "RATMain_rtwutil.h" +#include "rt_nonfinite.h" +#include "omp.h" + +// Function Definitions +namespace RAT +{ + void RATMain_terminate() + { + emlrtFreeThreadStackData(); + omp_destroy_nest_lock(&RATMain_nestLockGlobal); + } +} + +// End of code generation (RATMain_terminate.cpp) diff --git a/cpp/RAT/RATMain_terminate.h b/cpp/RAT/RATMain_terminate.h new file mode 100644 index 00000000..321b33aa --- /dev/null +++ b/cpp/RAT/RATMain_terminate.h @@ -0,0 +1,26 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// RATMain_terminate.h +// +// Code generation for function 'RATMain_terminate' +// +#ifndef RATMAIN_TERMINATE_H +#define RATMAIN_TERMINATE_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + extern void RATMain_terminate(); +} + +#endif + +// End of code generation (RATMain_terminate.h) diff --git a/cpp/RAT/RATMain_types.h b/cpp/RAT/RATMain_types.h new file mode 100644 index 00000000..3310a603 --- /dev/null +++ b/cpp/RAT/RATMain_types.h @@ -0,0 +1,353 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// RATMain_types.h +// +// Code generation for function 'RATMain' +// +#ifndef RATMAIN_TYPES_H +#define RATMAIN_TYPES_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include "coder_bounded_array.h" +#define MAX_THREADS omp_get_max_threads() + +// Type Definitions +namespace RAT +{ + struct struct14_T + { + real_T Y; + real_T N; + }; + + struct cell_wrap_2 + { + real_T f1[2]; + }; + + struct cell_wrap_8 + { + ::coder::array f1; + }; + + struct cell_wrap_9 + { + ::coder::array f1; + }; + + struct struct13_T + { + real_T d; + real_T N; + real_T T; + boolean_T parallel; + real_T CPU; + real_T lambda; + real_T pUnitGamma; + real_T nCR; + real_T delta; + real_T steps; + real_T zeta; + char_T outlier[3]; + boolean_T adaptPCR; + real_T thinning; + real_T epsilon; + boolean_T ABC; + boolean_T IO; + boolean_T modout; + boolean_T restart; + boolean_T save; + ::coder::array R; + }; + + struct struct12_T + { + ::coder::bounded_array outlier; + real_T RunTime; + struct13_T DREAMPar; + struct14_T Meas_info; + real_T iteration; + real_T iloc; + real_T fx; + ::coder::bounded_array AR; + ::coder::array R_stat; + ::coder::array CR; + }; + + struct cell_wrap_1 + { + ::coder::array f1; + }; + + struct struct3_T + { + ::coder::array fitParam; + ::coder::array fitBackgroundParam; + ::coder::array fitQzshift; + ::coder::array fitScalefactor; + ::coder::array fitBulkIn; + ::coder::array fitBulkOut; + ::coder::array fitResolutionParam; + ::coder::array fitDomainRatio; + }; + + struct struct2_T + { + ::coder::bounded_array procedure; + ::coder::bounded_array parallel; + real_T resamPars[2]; + boolean_T calcSldDuringFit; + ::coder::bounded_array display; + real_T tolX; + real_T tolFun; + real_T maxFunEvals; + real_T maxIter; + real_T updateFreq; + real_T updatePlotFreq; + real_T populationSize; + real_T fWeight; + real_T crossoverProbability; + real_T strategy; + real_T targetValue; + real_T numGenerations; + real_T Nlive; + real_T Nmcmc; + real_T propScale; + real_T nsTolerance; + real_T nSamples; + real_T nChains; + real_T jumpProbability; + real_T pUnitGamma; + ::coder::bounded_array boundHandling; + boolean_T adaptPCR; + struct3_T checks; + }; + + struct struct6_T + { + ::coder::array allChis; + real_T sumChi; + }; + + struct cell_wrap_18 + { + ::coder::array f1; + }; + + struct cell_wrap_22 + { + ::coder::array f1; + }; + + struct cell_wrap_48 + { + ::coder::array f1; + }; + + struct struct10_T + { + ::coder::array par95; + ::coder::array par65; + ::coder::array mean; + }; + + struct struct1_T + { + ::coder::array param; + ::coder::array backgroundParam; + ::coder::array scalefactor; + ::coder::array qzshift; + ::coder::array bulkIn; + ::coder::array bulkOut; + ::coder::array resolutionParam; + ::coder::array domainRatio; + }; + + struct cell_0 + { + ::coder::array f1; + ::coder::array f2; + real_T f3; + real_T f4; + }; + + struct struct4_T + { + ::coder::array param; + ::coder::array backgroundParam; + ::coder::array resolutionParam; + ::coder::array bulkIn; + ::coder::array bulkOut; + ::coder::array qzshift; + ::coder::array scalefactor; + ::coder::array domainRatio; + ::coder::array priorNames; + ::coder::array priorValues; + }; + + struct struct8_T + { + ::coder::array ref; + ::coder::array sld; + real_T chi; + ::coder::array data; + }; + + struct struct9_T + { + ::coder::array refPredInts; + ::coder::array sldPredInts; + ::coder::array refXdata; + ::coder::array sldXdata; + ::coder::bounded_array sampleChi; + }; + + struct cell_wrap_3 + { + ::coder::array f1; + }; + + struct cell_wrap_4 + { + ::coder::array f1; + }; + + struct cell_wrap_5 + { + ::coder::bounded_array f1; + }; + + struct cell_wrap_6 + { + ::coder::bounded_array f1; + }; + + struct cell_7 + { + ::coder::array f1; + ::coder::array f2; + ::coder::array f3; + ::coder::array f4; + ::coder::array f5; + ::coder::array f6; + ::coder::array f7; + ::coder::array f8; + ::coder::array f9; + ::coder::array f10; + ::coder::array f11; + ::coder::array f12; + ::coder::array f13; + ::coder::array f14; + ::coder::array f15; + ::coder::array f16; + ::coder::array f17; + ::coder::array f18; + ::coder::array f19; + ::coder::array f20; + }; + + struct struct0_T + { + ::coder::array contrastBackgrounds; + ::coder::array contrastBackgroundsType; + ::coder::bounded_array TF; + ::coder::array resample; + ::coder::array dataPresent; + ::coder::array oilChiDataPresent; + real_T numberOfContrasts; + ::coder::bounded_array geometry; + boolean_T useImaginary; + ::coder::array contrastQzshifts; + ::coder::array contrastScalefactors; + ::coder::array contrastBulkIns; + ::coder::array contrastBulkOuts; + ::coder::array contrastResolutions; + ::coder::array backgroundParams; + ::coder::array qzshifts; + ::coder::array scalefactors; + ::coder::array bulkIn; + ::coder::array bulkOut; + ::coder::array resolutionParams; + ::coder::array params; + real_T numberOfLayers; + ::coder::bounded_array modelType; + ::coder::array contrastCustomFiles; + ::coder::array contrastDomainRatios; + ::coder::array domainRatio; + real_T numberOfDomainContrasts; + ::coder::array fitParams; + ::coder::array otherParams; + ::coder::array fitLimits; + ::coder::array otherLimits; + }; + + struct struct5_T + { + ::coder::array ssubs; + ::coder::array backgroundParams; + ::coder::array qzshifts; + ::coder::array scalefactors; + ::coder::array bulkIn; + ::coder::array bulkOut; + ::coder::array resolutionParams; + struct6_T calculations; + ::coder::array allSubRough; + ::coder::array resample; + }; + + struct struct15_T + { + real_T LogZ; + ::coder::array nestSamples; + ::coder::array postSamples; + }; + + struct struct11_T + { + ::coder::array allChains; + struct12_T dreamOutput; + struct15_T nestOutput; + }; + + struct struct7_T + { + struct8_T bestFitsMean; + struct9_T predlims; + struct10_T parConfInts; + ::coder::array bestPars; + struct11_T bayesRes; + ::coder::array chain; + }; + + struct SLDFunction + { + int32_T belowVals_data[10000]; + }; + + struct parallelContrasts + { + real_T thisContrastLayers2_data[6000]; + real_T thisContrastLayers1_data[6000]; + }; + + struct b_parallelContrasts + { + real_T thisContrastLayers_data[6000]; + }; + + struct RATMainTLS + { + SLDFunction f0; + parallelContrasts f1; + b_parallelContrasts f2; + }; +} + +#endif + +// End of code generation (RATMain_types.h) diff --git a/cpp/RAT/SLDFunction.cpp b/cpp/RAT/SLDFunction.cpp new file mode 100644 index 00000000..20778a0f --- /dev/null +++ b/cpp/RAT/SLDFunction.cpp @@ -0,0 +1,147 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// SLDFunction.cpp +// +// Code generation for function 'SLDFunction' +// + +// Include files +#include "SLDFunction.h" +#include "RATMain_rtwutil.h" +#include "RATMain_types.h" +#include "find.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + void b_SLDFunction(real_T x, const ::coder::array &SLD, ::coder:: + array &sldVal) + { + ::coder::array b_i; + ::coder::array c_i; + ::coder::array r; + ::coder::array b_SLD_data; + ::coder::array c_SLD_data; + ::coder::array d_SLD_data; + ::coder::array e_SLD_data; + ::coder::array f_SLD_data; + RATMainTLS *RATMainTLSThread; + int32_T SLD_size; + int32_T loop_ub; + boolean_T SLD_data[10000]; + RATMainTLSThread = emlrtGetThreadStackData(); + + // sldVal = SLDFunction(x,SLD) + // SLD = [x rho;....xn rho] + // x = value in Angstrom. + // + // This function returns the SLD (y) value associated with the + // supplied value of x. SLD is a two column, XY array defining an + // SLD profile. This function interpolates the SLD profile + // to return the SLD at the specific value of X. X can be a vector of + // multiple points. + // + // (c) Arwel Hughes 2019. + // Last modified - AVH, 26/11/19. + // global sldProfile + // + // SLD = sldProfile; + // SLD = getappdata(0,'SLDFunctionSLD'); + SLD_size = SLD.size(0); + loop_ub = SLD.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + SLD_data[i] = (SLD[i] == x); + } + + b_SLD_data.set(&SLD_data[0], SLD_size); + coder::eml_find(b_SLD_data, r); + b_i.set_size(r.size(0)); + loop_ub = r.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + b_i[i] = r[i]; + } + + if (b_i.size(0) != 0) { + sldVal.set_size(b_i.size(0)); + loop_ub = b_i.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + sldVal[i] = SLD[(b_i[i] + SLD.size(0)) - 1]; + } + } else { + real_T deltaY; + int32_T belowVals_size; + SLD_size = SLD.size(0); + loop_ub = SLD.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + SLD_data[i] = (x > SLD[i]); + } + + c_SLD_data.set(&SLD_data[0], SLD_size); + coder::eml_find(c_SLD_data, r); + b_i.set_size(r.size(0)); + loop_ub = r.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + b_i[i] = r[i]; + } + + SLD_size = SLD.size(0); + loop_ub = SLD.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + SLD_data[i] = (x > SLD[i]); + } + + d_SLD_data.set(&SLD_data[0], SLD_size); + coder::eml_find(d_SLD_data, r); + belowVals_size = r.size(0); + loop_ub = r.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + RATMainTLSThread->f0.belowVals_data[i] = r[i]; + } + + SLD_size = SLD.size(0); + loop_ub = SLD.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + SLD_data[i] = (x < SLD[i]); + } + + e_SLD_data.set(&SLD_data[0], SLD_size); + coder::eml_find(e_SLD_data, r); + c_i.set_size(r.size(0)); + loop_ub = r.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + c_i[i] = r[i]; + } + + SLD_size = SLD.size(0); + loop_ub = SLD.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + SLD_data[i] = (x < SLD[i]); + } + + f_SLD_data.set(&SLD_data[0], SLD_size); + coder::eml_find(f_SLD_data, r); + deltaY = (x - SLD[b_i[b_i.size(0) - 1] - 1]) * (std::abs(SLD[(r[0] + + SLD.size(0)) - 1] - SLD[(RATMainTLSThread-> + f0.belowVals_data[belowVals_size - 1] + SLD.size(0)) - 1]) / (SLD[r[0] - + 1] - SLD[RATMainTLSThread->f0.belowVals_data[belowVals_size - 1] - 1])); + if (SLD[(b_i[b_i.size(0) - 1] + SLD.size(0)) - 1] < SLD[(c_i[0] + SLD.size + (0)) - 1]) { + sldVal.set_size(1); + sldVal[0] = SLD[(b_i[b_i.size(0) - 1] + SLD.size(0)) - 1] + deltaY; + } else { + sldVal.set_size(1); + sldVal[0] = SLD[(b_i[b_i.size(0) - 1] + SLD.size(0)) - 1] - deltaY; + } + + // sldVal = interp1(z,rho,x); + } + } +} + +// End of code generation (SLDFunction.cpp) diff --git a/cpp/RAT/SLDFunction.h b/cpp/RAT/SLDFunction.h new file mode 100644 index 00000000..d77c1b72 --- /dev/null +++ b/cpp/RAT/SLDFunction.h @@ -0,0 +1,28 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// SLDFunction.h +// +// Code generation for function 'SLDFunction' +// +#ifndef SLDFUNCTION_H +#define SLDFUNCTION_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void b_SLDFunction(real_T x, const ::coder::array &SLD, ::coder:: + array &sldVal); +} + +#endif + +// End of code generation (SLDFunction.h) diff --git a/cpp/RAT/abelesParallelPoints.cpp b/cpp/RAT/abelesParallelPoints.cpp new file mode 100644 index 00000000..b5b9035d --- /dev/null +++ b/cpp/RAT/abelesParallelPoints.cpp @@ -0,0 +1,404 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// abelesParallelPoints.cpp +// +// Code generation for function 'abelesParallelPoints' +// + +// Include files +#include "abelesParallelPoints.h" +#include "RATMain_data.h" +#include "RATMain_rtwutil.h" +#include "exp.h" +#include "rt_nonfinite.h" +#include "sqrt.h" +#include "coder_array.h" +#include "omp.h" +#include + +// Function Declarations +namespace RAT +{ + static creal_T findkn(real_T k0, const creal_T sld); +} + +// Function Definitions +namespace RAT +{ + static creal_T findkn(real_T k0, const creal_T sld) + { + creal_T dc; + creal_T dc1; + creal_T kn; + real_T k0_im; + real_T k0_re; + real_T re; + + // sqrt function with branch cut in zarg from 0 to infinity along a ray + // at angle theta (in radians) measured from the +x axis in the usual way, + // with -pi<=theta<=pi. theta = pi is the usual square root. + // for zarg on the +x axis, sqrt behavior is conserved, + // i.e. sqrtbc(theta,zarg) is positive and real for any theta. + // + // y = sqrtbc(theta,zarg) + dc.re = 0.0; + dc.im = -0.78539816339744828; + coder::b_exp(&dc); + dc1.re = 0.0; + dc1.im = 1.5707963267948966; + coder::b_exp(&dc1); + k0_re = k0 * k0 - 12.566370614359172 * sld.re; + k0_im = 0.0 - 12.566370614359172 * sld.im; + re = k0_re * dc1.re - k0_im * dc1.im; + k0_re = k0_re * dc1.im + k0_im * dc1.re; + dc1.re = re; + dc1.im = k0_re; + coder::internal::scalar::d_sqrt(&dc1); + kn.re = dc.re * dc1.re - dc.im * dc1.im; + kn.im = dc.re * dc1.im + dc.im * dc1.re; + + // translations: sqrtbc(theta, z-b) has branch cut in the z plane from + // branch point z = b out to infinity, along a ray at angle theta. + // + // for the usual square root with branch cut along -x, + // the real part of sqrt(z) is positive (or 0) for all z. + // for the modified square root with branch cut along +x, + // the imaginary part of sqrt(z) is positive (or 0) for all z. + return kn; + } + + void abelesParallelPoints(const ::coder::array &q, real_T N, const + ::coder::array &layers_thick, const ::coder::array + &layers_rho, const ::coder::array &layers_sig, ::coder::array< + real_T, 1U> &ref) + { + creal_T M_n[2][2]; + creal_T M_res[2][2]; + creal_T M_tot[2][2]; + creal_T M_n_tmp; + creal_T beta; + creal_T bulk_in_SLD; + creal_T denom1; + creal_T denom_n; + creal_T err1; + creal_T err_n; + creal_T k1; + creal_T kn_ptr; + creal_T knp1; + creal_T nom1; + creal_T nom_n; + creal_T r01; + creal_T r_n_np1; + creal_T sld_1; + creal_T sld_np1; + real_T M_tot_re_tmp; + real_T R; + real_T b_M_tot_re_tmp; + real_T brm; + real_T c_M_tot_re_tmp; + real_T d; + real_T d1; + real_T d_M_tot_re_tmp; + real_T im; + real_T k0; + real_T nom_n_re; + real_T sigmasqrd; + real_T sigmasqrd_tmp; + int32_T i1; + int32_T i2; + int32_T loop_ub; + int32_T n; + ref.set_size(q.size(0)); + loop_ub = q.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + ref[i] = 0.0; + } + + loop_ub = q.size(0) - 1; + +#pragma omp parallel for \ + num_threads(omp_get_max_threads()) \ + private(beta,r_n_np1,err_n,sigmasqrd,denom_n,nom_n,knp1,sld_np1,r01,err1,denom1,nom1,k1,sld_1,R,k0,bulk_in_SLD,kn_ptr,M_res,M_n,M_tot,i1,n,nom_n_re,sigmasqrd_tmp,brm,im,M_n_tmp,d,d1,i2,M_tot_re_tmp,b_M_tot_re_tmp,c_M_tot_re_tmp,d_M_tot_re_tmp) + + for (int32_T points = 0; points <= loop_ub; points++) { + M_tot[0][0].re = 0.0; + M_tot[0][0].im = 0.0; + M_res[0][0].re = 0.0; + M_res[0][0].im = 0.0; + M_tot[0][1].re = 0.0; + M_tot[0][1].im = 0.0; + M_res[0][1].re = 0.0; + M_res[0][1].im = 0.0; + M_tot[1][0].re = 0.0; + M_tot[1][0].im = 0.0; + M_tot[1][1].re = 0.0; + M_tot[1][1].im = 0.0; + kn_ptr.re = 0.0; + kn_ptr.im = 0.0; + bulk_in_SLD.re = layers_rho[0].re; + bulk_in_SLD.im = layers_rho[0].im + 1.0E-30; + k0 = q[points] / 2.0; + i1 = static_cast(N - 1.0); + for (n = 0; n < i1; n++) { + if (static_cast(n) + 1U == 1U) { + // Find k1.. + sld_1.re = layers_rho[1].re - bulk_in_SLD.re; + sld_1.im = layers_rho[1].im - bulk_in_SLD.im; + k1 = findkn(k0, sld_1); + + // Find r01 + nom1.re = k0 - k1.re; + denom1.re = k0 + k1.re; + sigmasqrd = layers_sig[1] * layers_sig[1]; + err1.re = sigmasqrd * (k0 * (-2.0 * k1.re)); + err1.im = sigmasqrd * (k0 * (-2.0 * k1.im)); + coder::b_exp(&err1); + if (k1.im == 0.0) { + nom_n_re = nom1.re / denom1.re; + sigmasqrd_tmp = 0.0; + } else if (denom1.re == 0.0) { + if (nom1.re == 0.0) { + nom_n_re = (0.0 - k1.im) / k1.im; + sigmasqrd_tmp = 0.0; + } else if (0.0 - k1.im == 0.0) { + nom_n_re = 0.0; + sigmasqrd_tmp = -(nom1.re / k1.im); + } else { + nom_n_re = (0.0 - k1.im) / k1.im; + sigmasqrd_tmp = -(nom1.re / k1.im); + } + } else { + brm = std::abs(denom1.re); + sigmasqrd_tmp = std::abs(k1.im); + if (brm > sigmasqrd_tmp) { + sigmasqrd_tmp = k1.im / denom1.re; + im = denom1.re + sigmasqrd_tmp * k1.im; + nom_n_re = (nom1.re + sigmasqrd_tmp * (0.0 - k1.im)) / im; + sigmasqrd_tmp = ((0.0 - k1.im) - sigmasqrd_tmp * nom1.re) / im; + } else if (sigmasqrd_tmp == brm) { + if (denom1.re > 0.0) { + sigmasqrd_tmp = 0.5; + } else { + sigmasqrd_tmp = -0.5; + } + + if (k1.im > 0.0) { + im = 0.5; + } else { + im = -0.5; + } + + nom_n_re = (nom1.re * sigmasqrd_tmp + (0.0 - k1.im) * im) / brm; + sigmasqrd_tmp = ((0.0 - k1.im) * sigmasqrd_tmp - nom1.re * im) / + brm; + } else { + sigmasqrd_tmp = denom1.re / k1.im; + im = k1.im + sigmasqrd_tmp * denom1.re; + nom_n_re = (sigmasqrd_tmp * nom1.re + (0.0 - k1.im)) / im; + sigmasqrd_tmp = (sigmasqrd_tmp * (0.0 - k1.im) - nom1.re) / im; + } + } + + r01.re = nom_n_re * err1.re - sigmasqrd_tmp * err1.im; + r01.im = nom_n_re * err1.im + sigmasqrd_tmp * err1.re; + + // Generate the M1 matrix: + M_tot[0][0].re = 1.0; + M_tot[0][0].im = 0.0; + M_tot[1][0] = r01; + M_tot[0][1] = r01; + M_tot[1][1].re = 1.0; + M_tot[1][1].im = 0.0; + kn_ptr = k1; + } else { + // Find kn and k_n+1 (ex. k1 and k2 for n=1): _/ + sld_np1.re = layers_rho[n + 1].re - bulk_in_SLD.re; + sld_np1.im = layers_rho[n + 1].im - bulk_in_SLD.im; + knp1 = findkn(k0, sld_np1); + + // Find r_n,n+1: + nom_n.re = kn_ptr.re - knp1.re; + nom_n.im = kn_ptr.im - knp1.im; + denom_n.re = kn_ptr.re + knp1.re; + denom_n.im = kn_ptr.im + knp1.im; + sigmasqrd_tmp = layers_sig[n + 1]; + sigmasqrd = sigmasqrd_tmp * sigmasqrd_tmp; + sigmasqrd_tmp = -2.0 * kn_ptr.re; + im = -2.0 * kn_ptr.im; + err_n.re = sigmasqrd * (sigmasqrd_tmp * knp1.re - im * knp1.im); + err_n.im = sigmasqrd * (sigmasqrd_tmp * knp1.im + im * knp1.re); + coder::b_exp(&err_n); + if (denom_n.im == 0.0) { + if (nom_n.im == 0.0) { + nom_n_re = nom_n.re / denom_n.re; + sigmasqrd_tmp = 0.0; + } else if (nom_n.re == 0.0) { + nom_n_re = 0.0; + sigmasqrd_tmp = nom_n.im / denom_n.re; + } else { + nom_n_re = nom_n.re / denom_n.re; + sigmasqrd_tmp = nom_n.im / denom_n.re; + } + } else if (denom_n.re == 0.0) { + if (nom_n.re == 0.0) { + nom_n_re = nom_n.im / denom_n.im; + sigmasqrd_tmp = 0.0; + } else if (nom_n.im == 0.0) { + nom_n_re = 0.0; + sigmasqrd_tmp = -(nom_n.re / denom_n.im); + } else { + nom_n_re = nom_n.im / denom_n.im; + sigmasqrd_tmp = -(nom_n.re / denom_n.im); + } + } else { + brm = std::abs(denom_n.re); + sigmasqrd_tmp = std::abs(denom_n.im); + if (brm > sigmasqrd_tmp) { + sigmasqrd_tmp = denom_n.im / denom_n.re; + im = denom_n.re + sigmasqrd_tmp * denom_n.im; + nom_n_re = (nom_n.re + sigmasqrd_tmp * nom_n.im) / im; + sigmasqrd_tmp = (nom_n.im - sigmasqrd_tmp * nom_n.re) / im; + } else if (sigmasqrd_tmp == brm) { + if (denom_n.re > 0.0) { + sigmasqrd_tmp = 0.5; + } else { + sigmasqrd_tmp = -0.5; + } + + if (denom_n.im > 0.0) { + im = 0.5; + } else { + im = -0.5; + } + + nom_n_re = (nom_n.re * sigmasqrd_tmp + nom_n.im * im) / brm; + sigmasqrd_tmp = (nom_n.im * sigmasqrd_tmp - nom_n.re * im) / brm; + } else { + sigmasqrd_tmp = denom_n.re / denom_n.im; + im = denom_n.im + sigmasqrd_tmp * denom_n.re; + nom_n_re = (sigmasqrd_tmp * nom_n.re + nom_n.im) / im; + sigmasqrd_tmp = (sigmasqrd_tmp * nom_n.im - nom_n.re) / im; + } + } + + r_n_np1.re = nom_n_re * err_n.re - sigmasqrd_tmp * err_n.im; + r_n_np1.im = nom_n_re * err_n.im + sigmasqrd_tmp * err_n.re; + + // Find the Phase Factor = (k_n * d_n) + sigmasqrd_tmp = layers_thick[n] * kn_ptr.re; + im = layers_thick[n] * kn_ptr.im; + beta.re = sigmasqrd_tmp * 0.0 - im; + beta.im = sigmasqrd_tmp + im * 0.0; + + // Create the M_n matrix: _/ + M_n_tmp = beta; + coder::b_exp(&M_n_tmp); + M_n[0][0] = M_n_tmp; + M_n[1][0].re = r_n_np1.re * M_n_tmp.re - r_n_np1.im * M_n_tmp.im; + M_n[1][0].im = r_n_np1.re * M_n_tmp.im + r_n_np1.im * M_n_tmp.re; + M_n_tmp.re = -beta.re; + M_n_tmp.im = -beta.im; + coder::b_exp(&M_n_tmp); + M_n[0][1].re = r_n_np1.re * M_n_tmp.re - r_n_np1.im * M_n_tmp.im; + M_n[0][1].im = r_n_np1.re * M_n_tmp.im + r_n_np1.im * M_n_tmp.re; + + // Multiply the matrices + sigmasqrd_tmp = M_n[0][0].re; + im = M_n[0][0].im; + brm = M_n[0][1].re; + nom_n_re = M_n[0][1].im; + d = M_n[1][0].re; + d1 = M_n[1][0].im; + for (i2 = 0; i2 < 2; i2++) { + M_tot_re_tmp = M_tot[0][i2].re; + b_M_tot_re_tmp = M_tot[0][i2].im; + c_M_tot_re_tmp = M_tot[1][i2].re; + d_M_tot_re_tmp = M_tot[1][i2].im; + M_res[0][i2].re = (M_tot_re_tmp * sigmasqrd_tmp - b_M_tot_re_tmp * + im) + (c_M_tot_re_tmp * brm - d_M_tot_re_tmp * + nom_n_re); + M_res[0][i2].im = (M_tot_re_tmp * im + b_M_tot_re_tmp * + sigmasqrd_tmp) + (c_M_tot_re_tmp * nom_n_re + + d_M_tot_re_tmp * brm); + M_res[1][i2].re = (M_tot_re_tmp * d - b_M_tot_re_tmp * d1) + + (c_M_tot_re_tmp * M_n_tmp.re - d_M_tot_re_tmp * M_n_tmp.im); + M_res[1][i2].im = (M_tot_re_tmp * d1 + b_M_tot_re_tmp * d) + + (c_M_tot_re_tmp * M_n_tmp.im + d_M_tot_re_tmp * M_n_tmp.re); + } + + // Reassign the values back to M_tot: + M_tot[0][0] = M_res[0][0]; + M_tot[0][1] = M_res[0][1]; + M_tot[1][0] = M_res[1][0]; + M_tot[1][1] = M_res[1][1]; + + // Point to k_n+1 and sld_n+1 via kn_ptr sld_n_ptr: + kn_ptr = knp1; + } + } + + if (M_res[0][0].im == 0.0) { + if (M_res[0][1].im == 0.0) { + M_n_tmp.re = M_res[0][1].re / M_res[0][0].re; + M_n_tmp.im = 0.0; + } else if (M_res[0][1].re == 0.0) { + M_n_tmp.re = 0.0; + M_n_tmp.im = M_res[0][1].im / M_res[0][0].re; + } else { + M_n_tmp.re = M_res[0][1].re / M_res[0][0].re; + M_n_tmp.im = M_res[0][1].im / M_res[0][0].re; + } + } else if (M_res[0][0].re == 0.0) { + if (M_res[0][1].re == 0.0) { + M_n_tmp.re = M_res[0][1].im / M_res[0][0].im; + M_n_tmp.im = 0.0; + } else if (M_res[0][1].im == 0.0) { + M_n_tmp.re = 0.0; + M_n_tmp.im = -(M_res[0][1].re / M_res[0][0].im); + } else { + M_n_tmp.re = M_res[0][1].im / M_res[0][0].im; + M_n_tmp.im = -(M_res[0][1].re / M_res[0][0].im); + } + } else { + brm = std::abs(M_res[0][0].re); + sigmasqrd_tmp = std::abs(M_res[0][0].im); + if (brm > sigmasqrd_tmp) { + sigmasqrd_tmp = M_res[0][0].im / M_res[0][0].re; + im = M_res[0][0].re + sigmasqrd_tmp * M_res[0][0].im; + M_n_tmp.re = (M_res[0][1].re + sigmasqrd_tmp * M_res[0][1].im) / im; + M_n_tmp.im = (M_res[0][1].im - sigmasqrd_tmp * M_res[0][1].re) / im; + } else if (sigmasqrd_tmp == brm) { + if (M_res[0][0].re > 0.0) { + sigmasqrd_tmp = 0.5; + } else { + sigmasqrd_tmp = -0.5; + } + + if (M_res[0][0].im > 0.0) { + im = 0.5; + } else { + im = -0.5; + } + + M_n_tmp.re = (M_res[0][1].re * sigmasqrd_tmp + M_res[0][1].im * im) / + brm; + M_n_tmp.im = (M_res[0][1].im * sigmasqrd_tmp - M_res[0][1].re * im) / + brm; + } else { + sigmasqrd_tmp = M_res[0][0].re / M_res[0][0].im; + im = M_res[0][0].im + sigmasqrd_tmp * M_res[0][0].re; + M_n_tmp.re = (sigmasqrd_tmp * M_res[0][1].re + M_res[0][1].im) / im; + M_n_tmp.im = (sigmasqrd_tmp * M_res[0][1].im - M_res[0][1].re) / im; + } + } + + R = rt_hypotd_snf(M_n_tmp.re, M_n_tmp.im); + ref[points] = R * R; + } + } +} + +// End of code generation (abelesParallelPoints.cpp) diff --git a/cpp/RAT/abelesParallelPoints.h b/cpp/RAT/abelesParallelPoints.h new file mode 100644 index 00000000..6784ab81 --- /dev/null +++ b/cpp/RAT/abelesParallelPoints.h @@ -0,0 +1,30 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// abelesParallelPoints.h +// +// Code generation for function 'abelesParallelPoints' +// +#ifndef ABELESPARALLELPOINTS_H +#define ABELESPARALLELPOINTS_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void abelesParallelPoints(const ::coder::array &q, real_T N, const + ::coder::array &layers_thick, const ::coder::array + &layers_rho, const ::coder::array &layers_sig, ::coder::array< + real_T, 1U> &ref); +} + +#endif + +// End of code generation (abelesParallelPoints.h) diff --git a/cpp/RAT/abelesSingle.cpp b/cpp/RAT/abelesSingle.cpp new file mode 100644 index 00000000..043a3f53 --- /dev/null +++ b/cpp/RAT/abelesSingle.cpp @@ -0,0 +1,408 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// abelesSingle.cpp +// +// Code generation for function 'abelesSingle' +// + +// Include files +#include "abelesSingle.h" +#include "RATMain_data.h" +#include "RATMain_rtwutil.h" +#include "exp.h" +#include "rt_nonfinite.h" +#include "sqrt.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + void abelesSingle(const ::coder::array &q, real_T N, const ::coder:: + array &layers_thick, const ::coder::array< + creal_T, 1U> &layers_rho, const ::coder::array + &layers_sig, ::coder::array &ref) + { + creal_T M_n[2][2]; + creal_T M_res[2][2]; + creal_T M_tot[2][2]; + creal_T M_n_tmp; + creal_T dc; + real_T kn_ptr_im; + real_T kn_ptr_re; + int32_T i; + int32_T loop_ub; + + // New Matlab version of reflectivity + // with complex rho... + // Pre-allocation + M_tot[0][0].re = 0.0; + M_tot[0][0].im = 0.0; + M_res[0][0].re = 0.0; + M_res[0][0].im = 0.0; + M_tot[0][1].re = 0.0; + M_tot[0][1].im = 0.0; + M_res[0][1].re = 0.0; + M_res[0][1].im = 0.0; + M_tot[1][0].re = 0.0; + M_tot[1][0].im = 0.0; + M_tot[1][1].re = 0.0; + M_tot[1][1].im = 0.0; + kn_ptr_re = 0.0; + kn_ptr_im = 0.0; + ref.set_size(q.size(0)); + loop_ub = q.size(0); + for (i = 0; i < loop_ub; i++) { + ref[i] = 0.0; + } + + i = q.size(0); + for (int32_T points{0}; points < i; points++) { + real_T brm; + real_T bulk_in_SLD_im; + real_T bulk_in_SLD_re; + real_T k0; + real_T k0_im; + real_T sgnbr; + bulk_in_SLD_re = layers_rho[0].re; + bulk_in_SLD_im = layers_rho[0].im + 1.0E-30; + k0 = q[points] / 2.0; + loop_ub = static_cast(N - 1.0); + for (int32_T n{0}; n < loop_ub; n++) { + if (static_cast(n) + 1U == 1U) { + real_T ar; + real_T br; + real_T d; + real_T k0_re; + real_T k1_im; + real_T k1_re; + real_T r01_im; + real_T r01_re; + real_T re; + + // Find k1.. + // sqrt function with branch cut in zarg from 0 to infinity along a ray + // at angle theta (in radians) measured from the +x axis in the usual way, + // with -pi<=theta<=pi. theta = pi is the usual square root. + // for zarg on the +x axis, sqrt behavior is conserved, + // i.e. sqrtbc(theta,zarg) is positive and real for any theta. + // + // y = sqrtbc(theta,zarg) + dc.re = 0.0; + dc.im = -0.78539816339744828; + coder::b_exp(&dc); + M_n_tmp.re = 0.0; + M_n_tmp.im = 1.5707963267948966; + coder::b_exp(&M_n_tmp); + k0_re = k0 * k0 - 12.566370614359172 * (layers_rho[1].re - + bulk_in_SLD_re); + k0_im = 0.0 - 12.566370614359172 * (layers_rho[1].im - bulk_in_SLD_im); + re = k0_re * M_n_tmp.re - k0_im * M_n_tmp.im; + k0_im = k0_re * M_n_tmp.im + k0_im * M_n_tmp.re; + M_n_tmp.re = re; + M_n_tmp.im = k0_im; + coder::internal::scalar::d_sqrt(&M_n_tmp); + k1_re = dc.re * M_n_tmp.re - dc.im * M_n_tmp.im; + k1_im = dc.re * M_n_tmp.im + dc.im * M_n_tmp.re; + + // translations: sqrtbc(theta, z-b) has branch cut in the z plane from + // branch point z = b out to infinity, along a ray at angle theta. + // + // for the usual square root with branch cut along -x, + // the real part of sqrt(z) is positive (or 0) for all z. + // for the modified square root with branch cut along +x, + // the imaginary part of sqrt(z) is positive (or 0) for all z. + // Find r01 + d = layers_sig[1] * layers_sig[1]; + dc.re = d * (k0 * (-2.0 * k1_re)); + dc.im = d * (k0 * (-2.0 * k1_im)); + coder::b_exp(&dc); + ar = k0 - k1_re; + br = k0 + k1_re; + if (k1_im == 0.0) { + k0_re = ar / br; + k0_im = 0.0; + } else if (br == 0.0) { + if (ar == 0.0) { + k0_re = (0.0 - k1_im) / k1_im; + k0_im = 0.0; + } else if (0.0 - k1_im == 0.0) { + k0_re = 0.0; + k0_im = -(ar / k1_im); + } else { + k0_re = (0.0 - k1_im) / k1_im; + k0_im = -(ar / k1_im); + } + } else { + brm = std::abs(br); + k0_im = std::abs(k1_im); + if (brm > k0_im) { + brm = k1_im / br; + k0_im = br + brm * k1_im; + k0_re = (ar + brm * (0.0 - k1_im)) / k0_im; + k0_im = ((0.0 - k1_im) - brm * ar) / k0_im; + } else if (k0_im == brm) { + if (br > 0.0) { + sgnbr = 0.5; + } else { + sgnbr = -0.5; + } + + if (k1_im > 0.0) { + k0_im = 0.5; + } else { + k0_im = -0.5; + } + + k0_re = (ar * sgnbr + (0.0 - k1_im) * k0_im) / brm; + k0_im = ((0.0 - k1_im) * sgnbr - ar * k0_im) / brm; + } else { + brm = br / k1_im; + k0_im = k1_im + brm * br; + k0_re = (brm * ar + (0.0 - k1_im)) / k0_im; + k0_im = (brm * (0.0 - k1_im) - ar) / k0_im; + } + } + + r01_re = k0_re * dc.re - k0_im * dc.im; + r01_im = k0_re * dc.im + k0_im * dc.re; + + // Generate the M1 matrix: + M_tot[0][0].re = 1.0; + M_tot[0][0].im = 0.0; + M_tot[1][0].re = r01_re; + M_tot[1][0].im = r01_im; + M_tot[0][1].re = r01_re; + M_tot[0][1].im = r01_im; + M_tot[1][1].re = 1.0; + M_tot[1][1].im = 0.0; + kn_ptr_re = k1_re; + kn_ptr_im = k1_im; + } else { + real_T ai; + real_T ar; + real_T beta_im; + real_T beta_re; + real_T br; + real_T d; + real_T d1; + real_T k0_re; + real_T knp1_im; + real_T knp1_re; + real_T r_n_np1_im; + real_T r_n_np1_re; + real_T re; + + // Find kn and k_n+1 (ex. k1 and k2 for n=1): _/ + // sqrt function with branch cut in zarg from 0 to infinity along a ray + // at angle theta (in radians) measured from the +x axis in the usual way, + // with -pi<=theta<=pi. theta = pi is the usual square root. + // for zarg on the +x axis, sqrt behavior is conserved, + // i.e. sqrtbc(theta,zarg) is positive and real for any theta. + // + // y = sqrtbc(theta,zarg) + dc.re = 0.0; + dc.im = -0.78539816339744828; + coder::b_exp(&dc); + M_n_tmp.re = 0.0; + M_n_tmp.im = 1.5707963267948966; + coder::b_exp(&M_n_tmp); + k0_re = k0 * k0 - 12.566370614359172 * (layers_rho[n + 1].re - + bulk_in_SLD_re); + k0_im = 0.0 - 12.566370614359172 * (layers_rho[n + 1].im - + bulk_in_SLD_im); + re = k0_re * M_n_tmp.re - k0_im * M_n_tmp.im; + k0_im = k0_re * M_n_tmp.im + k0_im * M_n_tmp.re; + M_n_tmp.re = re; + M_n_tmp.im = k0_im; + coder::internal::scalar::d_sqrt(&M_n_tmp); + knp1_re = dc.re * M_n_tmp.re - dc.im * M_n_tmp.im; + knp1_im = dc.re * M_n_tmp.im + dc.im * M_n_tmp.re; + + // translations: sqrtbc(theta, z-b) has branch cut in the z plane from + // branch point z = b out to infinity, along a ray at angle theta. + // + // for the usual square root with branch cut along -x, + // the real part of sqrt(z) is positive (or 0) for all z. + // for the modified square root with branch cut along +x, + // the imaginary part of sqrt(z) is positive (or 0) for all z. + // Find r_n,n+1: + re = -2.0 * kn_ptr_re; + k0_im = -2.0 * kn_ptr_im; + d = layers_sig[n + 1]; + d *= d; + dc.re = d * (re * knp1_re - k0_im * knp1_im); + dc.im = d * (re * knp1_im + k0_im * knp1_re); + coder::b_exp(&dc); + ar = kn_ptr_re - knp1_re; + ai = kn_ptr_im - knp1_im; + br = kn_ptr_re + knp1_re; + re = kn_ptr_im + knp1_im; + if (re == 0.0) { + if (ai == 0.0) { + k0_re = ar / br; + k0_im = 0.0; + } else if (ar == 0.0) { + k0_re = 0.0; + k0_im = ai / br; + } else { + k0_re = ar / br; + k0_im = ai / br; + } + } else if (br == 0.0) { + if (ar == 0.0) { + k0_re = ai / re; + k0_im = 0.0; + } else if (ai == 0.0) { + k0_re = 0.0; + k0_im = -(ar / re); + } else { + k0_re = ai / re; + k0_im = -(ar / re); + } + } else { + brm = std::abs(br); + k0_im = std::abs(re); + if (brm > k0_im) { + brm = re / br; + k0_im = br + brm * re; + k0_re = (ar + brm * ai) / k0_im; + k0_im = (ai - brm * ar) / k0_im; + } else if (k0_im == brm) { + if (br > 0.0) { + sgnbr = 0.5; + } else { + sgnbr = -0.5; + } + + if (re > 0.0) { + k0_im = 0.5; + } else { + k0_im = -0.5; + } + + k0_re = (ar * sgnbr + ai * k0_im) / brm; + k0_im = (ai * sgnbr - ar * k0_im) / brm; + } else { + brm = br / re; + k0_im = re + brm * br; + k0_re = (brm * ar + ai) / k0_im; + k0_im = (brm * ai - ar) / k0_im; + } + } + + r_n_np1_re = k0_re * dc.re - k0_im * dc.im; + r_n_np1_im = k0_re * dc.im + k0_im * dc.re; + + // Find the Phase Factor = (k_n * d_n) + kn_ptr_re *= layers_thick[n]; + kn_ptr_im *= layers_thick[n]; + beta_re = kn_ptr_re * 0.0 - kn_ptr_im; + beta_im = kn_ptr_re + kn_ptr_im * 0.0; + + // Create the M_n matrix: _/ + M_n_tmp.re = beta_re; + M_n_tmp.im = beta_im; + coder::b_exp(&M_n_tmp); + M_n[0][0] = M_n_tmp; + M_n[1][0].re = r_n_np1_re * M_n_tmp.re - r_n_np1_im * M_n_tmp.im; + M_n[1][0].im = r_n_np1_re * M_n_tmp.im + r_n_np1_im * M_n_tmp.re; + M_n_tmp.re = -beta_re; + M_n_tmp.im = -beta_im; + coder::b_exp(&M_n_tmp); + + // Multiply the matrices + d = M_n[0][0].re; + ar = M_n[0][0].im; + d1 = r_n_np1_re * M_n_tmp.re - r_n_np1_im * M_n_tmp.im; + k0_im = r_n_np1_re * M_n_tmp.im + r_n_np1_im * M_n_tmp.re; + re = M_n[1][0].re; + k0_re = M_n[1][0].im; + for (int32_T i1{0}; i1 < 2; i1++) { + br = M_tot[0][i1].re; + brm = M_tot[0][i1].im; + sgnbr = M_tot[1][i1].re; + ai = M_tot[1][i1].im; + M_res[0][i1].re = (br * d - brm * ar) + (sgnbr * d1 - ai * k0_im); + M_res[0][i1].im = (br * ar + brm * d) + (sgnbr * k0_im + ai * d1); + M_res[1][i1].re = (br * re - brm * k0_re) + (sgnbr * M_n_tmp.re - ai + * M_n_tmp.im); + M_res[1][i1].im = (br * k0_re + brm * re) + (sgnbr * M_n_tmp.im + ai + * M_n_tmp.re); + } + + // Reassign the values back to M_tot: + M_tot[0][0] = M_res[0][0]; + M_tot[0][1] = M_res[0][1]; + M_tot[1][0] = M_res[1][0]; + M_tot[1][1] = M_res[1][1]; + + // Point to k_n+1 and sld_n+1 via kn_ptr sld_n_ptr: + kn_ptr_re = knp1_re; + kn_ptr_im = knp1_im; + } + } + + if (M_res[0][0].im == 0.0) { + if (M_res[0][1].im == 0.0) { + M_n_tmp.re = M_res[0][1].re / M_res[0][0].re; + M_n_tmp.im = 0.0; + } else if (M_res[0][1].re == 0.0) { + M_n_tmp.re = 0.0; + M_n_tmp.im = M_res[0][1].im / M_res[0][0].re; + } else { + M_n_tmp.re = M_res[0][1].re / M_res[0][0].re; + M_n_tmp.im = M_res[0][1].im / M_res[0][0].re; + } + } else if (M_res[0][0].re == 0.0) { + if (M_res[0][1].re == 0.0) { + M_n_tmp.re = M_res[0][1].im / M_res[0][0].im; + M_n_tmp.im = 0.0; + } else if (M_res[0][1].im == 0.0) { + M_n_tmp.re = 0.0; + M_n_tmp.im = -(M_res[0][1].re / M_res[0][0].im); + } else { + M_n_tmp.re = M_res[0][1].im / M_res[0][0].im; + M_n_tmp.im = -(M_res[0][1].re / M_res[0][0].im); + } + } else { + brm = std::abs(M_res[0][0].re); + k0_im = std::abs(M_res[0][0].im); + if (brm > k0_im) { + brm = M_res[0][0].im / M_res[0][0].re; + k0_im = M_res[0][0].re + brm * M_res[0][0].im; + M_n_tmp.re = (M_res[0][1].re + brm * M_res[0][1].im) / k0_im; + M_n_tmp.im = (M_res[0][1].im - brm * M_res[0][1].re) / k0_im; + } else if (k0_im == brm) { + if (M_res[0][0].re > 0.0) { + sgnbr = 0.5; + } else { + sgnbr = -0.5; + } + + if (M_res[0][0].im > 0.0) { + k0_im = 0.5; + } else { + k0_im = -0.5; + } + + M_n_tmp.re = (M_res[0][1].re * sgnbr + M_res[0][1].im * k0_im) / brm; + M_n_tmp.im = (M_res[0][1].im * sgnbr - M_res[0][1].re * k0_im) / brm; + } else { + brm = M_res[0][0].re / M_res[0][0].im; + k0_im = M_res[0][0].im + brm * M_res[0][0].re; + M_n_tmp.re = (brm * M_res[0][1].re + M_res[0][1].im) / k0_im; + M_n_tmp.im = (brm * M_res[0][1].im - M_res[0][1].re) / k0_im; + } + } + + k0_im = rt_hypotd_snf(M_n_tmp.re, M_n_tmp.im); + ref[points] = k0_im * k0_im; + } + } +} + +// End of code generation (abelesSingle.cpp) diff --git a/cpp/RAT/abelesSingle.h b/cpp/RAT/abelesSingle.h new file mode 100644 index 00000000..c1d70ada --- /dev/null +++ b/cpp/RAT/abelesSingle.h @@ -0,0 +1,30 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// abelesSingle.h +// +// Code generation for function 'abelesSingle' +// +#ifndef ABELESSINGLE_H +#define ABELESSINGLE_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void abelesSingle(const ::coder::array &q, real_T N, const ::coder:: + array &layers_thick, const ::coder::array< + creal_T, 1U> &layers_rho, const ::coder::array + &layers_sig, ::coder::array &ref); +} + +#endif + +// End of code generation (abelesSingle.h) diff --git a/cpp/RAT/abs.cpp b/cpp/RAT/abs.cpp new file mode 100644 index 00000000..8bb6e574 --- /dev/null +++ b/cpp/RAT/abs.cpp @@ -0,0 +1,67 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// abs.cpp +// +// Code generation for function 'abs' +// + +// Include files +#include "abs.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + void b_abs(const ::coder::array &x, ::coder::array + &y) + { + y.set_size(1, x.size(1)); + if (x.size(1) != 0) { + int32_T i; + i = x.size(1); + for (int32_T k{0}; k < i; k++) { + y[k] = std::abs(x[k]); + } + } + } + + void b_abs(const ::coder::array &x, ::coder::array + &y) + { + y.set_size(x.size(0)); + if (x.size(0) != 0) { + int32_T i; + i = x.size(0); + for (int32_T k{0}; k < i; k++) { + y[k] = std::abs(x[k]); + } + } + } + + void c_abs(const ::coder::array &x, ::coder::array + &y) + { + y.set_size(x.size(0), x.size(1)); + if ((x.size(0) != 0) && (x.size(1) != 0)) { + int32_T i; + i = x.size(1); + for (int32_T k{0}; k < i; k++) { + int32_T i1; + i1 = y.size(0); + for (int32_T b_k{0}; b_k < i1; b_k++) { + y[b_k + y.size(0) * k] = std::abs(x[b_k + x.size(0) * k]); + } + } + } + } + } +} + +// End of code generation (abs.cpp) diff --git a/cpp/RAT/abs.h b/cpp/RAT/abs.h new file mode 100644 index 00000000..1edafb19 --- /dev/null +++ b/cpp/RAT/abs.h @@ -0,0 +1,35 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// abs.h +// +// Code generation for function 'abs' +// +#ifndef ABS_H +#define ABS_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void b_abs(const ::coder::array &x, ::coder::array + &y); + void b_abs(const ::coder::array &x, ::coder::array + &y); + void c_abs(const ::coder::array &x, ::coder::array + &y); + } +} + +#endif + +// End of code generation (abs.h) diff --git a/cpp/RAT/acos.cpp b/cpp/RAT/acos.cpp new file mode 100644 index 00000000..ff480ee9 --- /dev/null +++ b/cpp/RAT/acos.cpp @@ -0,0 +1,97 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// acos.cpp +// +// Code generation for function 'acos' +// + +// Include files +#include "acos.h" +#include "asinh.h" +#include "complexTimes.h" +#include "rt_nonfinite.h" +#include "sqrt.h" +#include "rt_defines.h" +#include + +// Function Declarations +namespace RAT +{ + static real_T rt_atan2d_snf(real_T u0, real_T u1); +} + +// Function Definitions +namespace RAT +{ + static real_T rt_atan2d_snf(real_T u0, real_T u1) + { + real_T y; + if (std::isnan(u0) || std::isnan(u1)) { + y = rtNaN; + } else if (std::isinf(u0) && std::isinf(u1)) { + int32_T i; + int32_T i1; + if (u0 > 0.0) { + i = 1; + } else { + i = -1; + } + + if (u1 > 0.0) { + i1 = 1; + } else { + i1 = -1; + } + + y = std::atan2(static_cast(i), static_cast(i1)); + } else if (u1 == 0.0) { + if (u0 > 0.0) { + y = RT_PI / 2.0; + } else if (u0 < 0.0) { + y = -(RT_PI / 2.0); + } else { + y = 0.0; + } + } else { + y = std::atan2(u0, u1); + } + + return y; + } + + namespace coder + { + namespace internal + { + namespace scalar + { + void b_acos(creal_T *x) + { + creal_T u; + creal_T v; + real_T d; + if ((x->im == 0.0) && (!(std::abs(x->re) > 1.0))) { + x->re = std::acos(x->re); + x->im = 0.0; + } else { + v.re = x->re + 1.0; + v.im = x->im; + d_sqrt(&v); + u.re = 1.0 - x->re; + u.im = 0.0 - x->im; + d_sqrt(&u); + d = complexTimes(v.re, -v.im, u.re, u.im); + b_asinh(&d); + x->re = 2.0 * rt_atan2d_snf(u.re, v.re); + x->im = d; + } + } + } + } + } +} + +// End of code generation (acos.cpp) diff --git a/cpp/RAT/acos.h b/cpp/RAT/acos.h new file mode 100644 index 00000000..921b0d20 --- /dev/null +++ b/cpp/RAT/acos.h @@ -0,0 +1,35 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// acos.h +// +// Code generation for function 'acos' +// +#ifndef ACOS_H +#define ACOS_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace scalar + { + void b_acos(creal_T *x); + } + } + } +} + +#endif + +// End of code generation (acos.h) diff --git a/cpp/RAT/adaptPCR.cpp b/cpp/RAT/adaptPCR.cpp new file mode 100644 index 00000000..b96e4784 --- /dev/null +++ b/cpp/RAT/adaptPCR.cpp @@ -0,0 +1,68 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// adaptPCR.cpp +// +// Code generation for function 'adaptPCR' +// + +// Include files +#include "adaptPCR.h" +#include "RATMain_types.h" +#include "find.h" +#include "rt_nonfinite.h" +#include "sum.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void adaptPCR(const struct13_T *DREAMPar, const ::coder::array &CR, + const real_T delta_tot_data[], const real_T lCRold_data[], + real_T pCR_data[], int32_T pCR_size[2], real_T lCR_data[], + int32_T lCR_size[2]) + { + ::coder::array y; + ::coder::array r; + ::coder::array c_CR; + real_T b_zz; + int32_T b_CR; + + // Updates the probabilities of the various crossover values + // Make CR to be a single vector + // Determine lCR + lCR_size[0] = 1; + lCR_size[1] = 3; + + // Adapt pCR using information from averaged normalized jumping distance + y.set_size(1, 3); + b_CR = CR.size(0) * CR.size(1); + for (int32_T zz{0}; zz < 3; zz++) { + // Determine how many times a particular CR value is used + // This is used to weight delta_tot + b_zz = (static_cast(zz) + 1.0) / 3.0; + c_CR.set_size(b_CR); + for (int32_T i{0}; i < b_CR; i++) { + c_CR[i] = (CR[i] == b_zz); + } + + coder::eml_find(c_CR, r); + b_zz = lCRold_data[zz] + static_cast(r.size(0)); + lCR_data[zz] = b_zz; + y[zz] = DREAMPar->N * (delta_tot_data[zz] / b_zz); + } + + // / sum(delta_tot); + // Normalize pCR so that selection probabilities add up to 1 + b_zz = coder::sum(y); + pCR_size[0] = 1; + pCR_size[1] = 3; + for (int32_T i{0}; i < 3; i++) { + pCR_data[i] = y[i] / b_zz; + } + } +} + +// End of code generation (adaptPCR.cpp) diff --git a/cpp/RAT/adaptPCR.h b/cpp/RAT/adaptPCR.h new file mode 100644 index 00000000..5cc6f842 --- /dev/null +++ b/cpp/RAT/adaptPCR.h @@ -0,0 +1,36 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// adaptPCR.h +// +// Code generation for function 'adaptPCR' +// +#ifndef ADAPTPCR_H +#define ADAPTPCR_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct struct13_T; +} + +// Function Declarations +namespace RAT +{ + void adaptPCR(const struct13_T *DREAMPar, const ::coder::array &CR, + const real_T delta_tot_data[], const real_T lCRold_data[], + real_T pCR_data[], int32_T pCR_size[2], real_T lCR_data[], + int32_T lCR_size[2]); +} + +#endif + +// End of code generation (adaptPCR.h) diff --git a/cpp/RAT/adaptive.cpp b/cpp/RAT/adaptive.cpp new file mode 100644 index 00000000..235b6213 --- /dev/null +++ b/cpp/RAT/adaptive.cpp @@ -0,0 +1,1097 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// adaptive.cpp +// +// Code generation for function 'adaptive' +// + +// Include files +#include "adaptive.h" +#include "RATMain_internal_types.h" +#include "SLDFunction.h" +#include "acos.h" +#include "allOrAny.h" +#include "eml_mtimes_helper.h" +#include "linspace.h" +#include "minOrMax.h" +#include "repmat.h" +#include "rt_nonfinite.h" +#include "sortrows.h" +#include "coder_array.h" +#include + +// Function Declarations +namespace RAT +{ + static void b_binary_expand_op(::coder::array &in1, const + cell_25 *in2, const ::coder::array &in3, real_T in4); + static void binary_expand_op(const ::coder::array &in1, const :: + coder::array &in2, const ::coder::array &in3, :: + coder::array &in4, ::coder::array &in5, ::coder:: + array &in6); + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, int32_T in3, int32_T in4, int32_T in5, int32_T in6); + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, int32_T in3, int32_T in4, int32_T in5); + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3, const ::coder:: + array &in4, const ::coder::array &in5, const ::coder:: + array &in6); + static void calculateCentralAngles(const ::coder::array &XYdata, + const real_T dataBoxSize[2], ::coder::array &cornerAngle); + static void calculateTrianglesSides(const ::coder::array &XYdata, :: + coder::array &firstStep, ::coder::array &secondStep, + ::coder::array &longStep); + static void increaseSampling(::coder::array &dataPoints, const :: + coder::array &segmentsToSplit, const ::coder::array &sldProfile); + static void normalizeFunction(const ::coder::array &x, const :: + coder::array &sldProfile, ::coder::array &y); + static void times(::coder::array &in1, const ::coder::array &in2, const ::coder::array &in3); +} + +// Function Definitions +namespace RAT +{ + static void b_binary_expand_op(::coder::array &in1, const + cell_25 *in2, const ::coder::array &in3, real_T in4) + { + int32_T i; + int32_T in2_idx_0; + int32_T stride_1_0; + in2_idx_0 = in2->f1.size(0) - 2; + if (in3.size(0) == 1) { + i = in2_idx_0; + } else { + i = in3.size(0); + } + + in1.set_size(i); + stride_1_0 = (in3.size(0) != 1); + if (in3.size(0) != 1) { + in2_idx_0 = in3.size(0); + } + + for (i = 0; i < in2_idx_0; i++) { + in1[i] = (in3[i * stride_1_0] < in4); + } + } + + static void binary_expand_op(const ::coder::array &in1, const :: + coder::array &in2, const ::coder::array &in3, :: + coder::array &in4, ::coder::array &in5, ::coder:: + array &in6) + { + ::coder::array b_in1; + int32_T i; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_1_0; + int32_T stride_2_0; + if (in3.size(0) == 1) { + if (in2.size(0) == 1) { + i = in1.size(0); + } else { + i = in2.size(0); + } + } else { + i = in3.size(0); + } + + b_in1.set_size(i, 2); + stride_0_0 = (in1.size(0) != 1); + stride_1_0 = (in2.size(0) != 1); + stride_2_0 = (in3.size(0) != 1); + if (in3.size(0) == 1) { + if (in2.size(0) == 1) { + loop_ub = in1.size(0); + } else { + loop_ub = in2.size(0); + } + } else { + loop_ub = in3.size(0); + } + + for (i = 0; i < 2; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_in1[i1 + b_in1.size(0) * i] = in1[i1 * stride_0_0 + in1.size(0) * i] / + in2[i1 * stride_1_0 + in2.size(0) * i] - in3[i1 * stride_2_0 + + in3.size(0) * i]; + } + } + + calculateTrianglesSides(b_in1, in4, in5, in6); + } + + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, int32_T in3, int32_T in4, int32_T in5, int32_T in6) + { + int32_T i; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_1_0; + if ((in6 - in5) + 1 == 1) { + i = (in4 - in3) + 1; + } else { + i = (in6 - in5) + 1; + } + + in1.set_size(i, 2); + stride_0_0 = ((in4 - in3) + 1 != 1); + stride_1_0 = ((in6 - in5) + 1 != 1); + if ((in6 - in5) + 1 == 1) { + loop_ub = (in4 - in3) + 1; + } else { + loop_ub = (in6 - in5) + 1; + } + + for (i = 0; i < 2; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + in1[i1 + in1.size(0) * i] = in2[(in3 + i1 * stride_0_0) + in2.size(0) * + i] - in2[(in5 + i1 * stride_1_0) + in2.size(0) * i]; + } + } + } + + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, int32_T in3, int32_T in4, int32_T in5) + { + int32_T i; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_1_0; + if (in5 + 1 == 1) { + i = (in4 - in3) + 1; + } else { + i = in5 + 1; + } + + in1.set_size(i, 2); + stride_0_0 = ((in4 - in3) + 1 != 1); + stride_1_0 = (in5 + 1 != 1); + if (in5 + 1 == 1) { + loop_ub = (in4 - in3) + 1; + } else { + loop_ub = in5 + 1; + } + + for (i = 0; i < 2; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + in1[i1 + in1.size(0) * i] = in2[(in3 + i1 * stride_0_0) + in2.size(0) * + i] - in2[i1 * stride_1_0 + in2.size(0) * i]; + } + } + } + + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3, const ::coder:: + array &in4, const ::coder::array &in5, const ::coder:: + array &in6) + { + int32_T i; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_1_0; + int32_T stride_2_0; + int32_T stride_3_0; + if (in6.size(0) == 1) { + if (in4.size(0) == 1) { + if (in3.size(0) == 1) { + i = in2.size(0); + } else { + i = in3.size(0); + } + } else { + i = in4.size(0); + } + } else { + i = in6.size(0); + } + + in1.set_size(i); + stride_0_0 = (in2.size(0) != 1); + stride_1_0 = (in3.size(0) != 1); + stride_2_0 = (in4.size(0) != 1); + stride_3_0 = (in6.size(0) != 1); + if (in6.size(0) == 1) { + if (in4.size(0) == 1) { + if (in3.size(0) == 1) { + loop_ub = in2.size(0); + } else { + loop_ub = in3.size(0); + } + } else { + loop_ub = in4.size(0); + } + } else { + loop_ub = in6.size(0); + } + + for (i = 0; i < loop_ub; i++) { + int32_T i1; + i1 = i * stride_2_0; + in1[i].re = ((in2[i * stride_0_0] + in3[i * stride_1_0]) - (in4[i1] + + in5[i1])) / 2.0 / in6[i * stride_3_0]; + in1[i].im = 0.0; + } + } + + static void calculateCentralAngles(const ::coder::array &XYdata, + const real_T dataBoxSize[2], ::coder::array &cornerAngle) + { + ::coder::array r4; + ::coder::array b_XYdata; + ::coder::array firstStep; + ::coder::array longStep; + ::coder::array r; + ::coder::array secondStep; + ::coder::array firstStepSquared; + ::coder::array r1; + ::coder::array r2; + ::coder::array r3; + ::coder::array secondStepSquared; + real_T b_dv[2]; + real_T varargin_1; + int32_T i; + int32_T i1; + int32_T k; + + // Calculate the central angle of the triangles formed by data points. + // For input size NxM, the output size is (N-2)xN, because the first and the + // last point are not the central corner of any triangle. + // Normalize data, because angles depend on scaling. + // calculate cosine of central angles + coder::repmat(dataBoxSize, static_cast(XYdata.size(0)), b_XYdata); + coder::internal::minimum(XYdata, b_dv); + coder::repmat(b_dv, static_cast(XYdata.size(0)), r); + if (XYdata.size(0) == 1) { + i = b_XYdata.size(0); + } else { + i = XYdata.size(0); + } + + if ((XYdata.size(0) == b_XYdata.size(0)) && (i == r.size(0))) { + b_XYdata.set_size(XYdata.size(0), 2); + k = XYdata.size(0); + for (i = 0; i < 2; i++) { + for (i1 = 0; i1 < k; i1++) { + b_XYdata[i1 + b_XYdata.size(0) * i] = XYdata[i1 + XYdata.size(0) * i] / + b_XYdata[i1 + b_XYdata.size(0) * i] - r[i1 + r.size(0) * i]; + } + } + + calculateTrianglesSides(b_XYdata, firstStep, secondStep, longStep); + } else { + binary_expand_op(XYdata, b_XYdata, r, firstStep, secondStep, longStep); + } + + // calculate area of squares of length of triangle sides + r1.set_size(firstStep.size(0)); + k = firstStep.size(0); + for (i = 0; i < k; i++) { + varargin_1 = firstStep[i]; + r1[i] = varargin_1 * varargin_1; + } + + r2.set_size(firstStep.size(0)); + k = firstStep.size(0); + for (i = 0; i < k; i++) { + varargin_1 = firstStep[i + firstStep.size(0)]; + r2[i] = varargin_1 * varargin_1; + } + + firstStepSquared.set_size(r1.size(0)); + k = r1.size(0); + for (i = 0; i < k; i++) { + firstStepSquared[i] = r1[i] + r2[i]; + } + + r1.set_size(secondStep.size(0)); + k = secondStep.size(0); + for (i = 0; i < k; i++) { + varargin_1 = secondStep[i]; + r1[i] = varargin_1 * varargin_1; + } + + r2.set_size(secondStep.size(0)); + k = secondStep.size(0); + for (i = 0; i < k; i++) { + varargin_1 = secondStep[i + secondStep.size(0)]; + r2[i] = varargin_1 * varargin_1; + } + + secondStepSquared.set_size(r1.size(0)); + k = r1.size(0); + for (i = 0; i < k; i++) { + secondStepSquared[i] = r1[i] + r2[i]; + } + + r1.set_size(longStep.size(0)); + k = longStep.size(0); + for (i = 0; i < k; i++) { + varargin_1 = longStep[i]; + r1[i] = varargin_1 * varargin_1; + } + + r2.set_size(longStep.size(0)); + k = longStep.size(0); + for (i = 0; i < k; i++) { + varargin_1 = longStep[i + longStep.size(0)]; + r2[i] = varargin_1 * varargin_1; + } + + if (firstStepSquared.size(0) == secondStepSquared.size(0)) { + r3.set_size(firstStepSquared.size(0)); + k = firstStepSquared.size(0); + for (i = 0; i < k; i++) { + r3[i] = firstStepSquared[i] * secondStepSquared[i]; + } + } else { + times(r3, firstStepSquared, secondStepSquared); + } + + i = r3.size(0); + for (k = 0; k < i; k++) { + r3[k] = std::sqrt(r3[k]); + } + + if (firstStepSquared.size(0) == 1) { + i = secondStepSquared.size(0); + } else { + i = firstStepSquared.size(0); + } + + if (firstStepSquared.size(0) == 1) { + i1 = secondStepSquared.size(0); + } else { + i1 = firstStepSquared.size(0); + } + + if (i1 == 1) { + i1 = r1.size(0); + } else if (firstStepSquared.size(0) == 1) { + i1 = secondStepSquared.size(0); + } else { + i1 = firstStepSquared.size(0); + } + + if ((firstStepSquared.size(0) == secondStepSquared.size(0)) && (i == r1.size + (0)) && (i1 == r3.size(0))) { + r4.set_size(firstStepSquared.size(0)); + k = firstStepSquared.size(0); + for (i = 0; i < k; i++) { + r4[i].re = ((firstStepSquared[i] + secondStepSquared[i]) - (r1[i] + r2[i])) + / 2.0 / r3[i]; + r4[i].im = 0.0; + } + } else { + binary_expand_op(r4, firstStepSquared, secondStepSquared, r1, r2, r3); + } + + i = r4.size(0); + for (k = 0; k < i; k++) { + coder::internal::scalar::b_acos(&r4[k]); + } + + cornerAngle.set_size(r4.size(0)); + k = r4.size(0); + for (i = 0; i < k; i++) { + cornerAngle[i] = r4[i].re; + } + } + + static void calculateTrianglesSides(const ::coder::array &XYdata, :: + coder::array &firstStep, ::coder::array &secondStep, + ::coder::array &longStep) + { + int32_T i; + int32_T i1; + int32_T i2; + int32_T i3; + int32_T loop_ub; + + // Return the sides (deltaX, deltaY) of the triangles formed by data points. + // For input size NxM, the output size is (N-2)xN, because the first and the + // last point are not the central corner of any triangle. + if (XYdata.size(0) - 1 < 2) { + i = 0; + i1 = 0; + } else { + i = 1; + i1 = XYdata.size(0) - 1; + } + + if (XYdata.size(0) - 2 < 1) { + i2 = 0; + } else { + i2 = XYdata.size(0) - 2; + } + + loop_ub = i1 - i; + if (loop_ub == i2) { + firstStep.set_size(loop_ub, 2); + for (i1 = 0; i1 < 2; i1++) { + for (i2 = 0; i2 < loop_ub; i2++) { + firstStep[i2 + firstStep.size(0) * i1] = XYdata[(i + i2) + XYdata.size + (0) * i1] - XYdata[i2 + XYdata.size(0) * i1]; + } + } + } else { + binary_expand_op(firstStep, XYdata, i, i1 - 1, i2 - 1); + } + + if (XYdata.size(0) < 3) { + i = 0; + i1 = 0; + i2 = 0; + i3 = 0; + } else { + i = 2; + i1 = XYdata.size(0); + i2 = 1; + i3 = XYdata.size(0) - 1; + } + + loop_ub = i1 - i; + if (loop_ub == i3 - i2) { + secondStep.set_size(loop_ub, 2); + for (i1 = 0; i1 < 2; i1++) { + for (i3 = 0; i3 < loop_ub; i3++) { + secondStep[i3 + secondStep.size(0) * i1] = XYdata[(i + i3) + + XYdata.size(0) * i1] - XYdata[(i2 + i3) + XYdata.size(0) * i1]; + } + } + } else { + binary_expand_op(secondStep, XYdata, i, i1 - 1, i2, i3 - 1); + } + + if (XYdata.size(0) < 3) { + i = 0; + i1 = 0; + } else { + i = 2; + i1 = XYdata.size(0); + } + + if (XYdata.size(0) - 2 < 1) { + i2 = 0; + } else { + i2 = XYdata.size(0) - 2; + } + + loop_ub = i1 - i; + if (loop_ub == i2) { + longStep.set_size(loop_ub, 2); + for (i1 = 0; i1 < 2; i1++) { + for (i2 = 0; i2 < loop_ub; i2++) { + longStep[i2 + longStep.size(0) * i1] = XYdata[(i + i2) + XYdata.size(0) + * i1] - XYdata[i2 + XYdata.size(0) * i1]; + } + } + } else { + binary_expand_op(longStep, XYdata, i, i1 - 1, i2 - 1); + } + } + + static void increaseSampling(::coder::array &dataPoints, const :: + coder::array &segmentsToSplit, const ::coder::array &sldProfile) + { + ::coder::array b_dataPoints; + ::coder::array newDataPoints; + ::coder::array b_newDataPoints; + ::coder::array r4; + ::coder::array r2; + ::coder::array r3; + ::coder::array r; + ::coder::array r1; + int32_T b_i; + int32_T input_sizes_idx_0; + int32_T trueCount; + + // increaseSampling increase the sampling of an input function + input_sizes_idx_0 = segmentsToSplit.size(0); + trueCount = 0; + for (int32_T i{0}; i < input_sizes_idx_0; i++) { + if (segmentsToSplit[i]) { + trueCount++; + } + } + + newDataPoints.set_size(trueCount, 2); + for (int32_T i{0}; i < 2; i++) { + for (b_i = 0; b_i < trueCount; b_i++) { + newDataPoints[b_i + newDataPoints.size(0) * i] = 0.0; + } + } + + r.set_size(segmentsToSplit.size(0) + 1); + trueCount = segmentsToSplit.size(0); + for (int32_T i{0}; i < trueCount; i++) { + r[i] = segmentsToSplit[i]; + } + + r[segmentsToSplit.size(0)] = false; + r1.set_size(segmentsToSplit.size(0) + 1); + r1[0] = false; + trueCount = segmentsToSplit.size(0); + for (int32_T i{0}; i < trueCount; i++) { + r1[i + 1] = segmentsToSplit[i]; + } + + input_sizes_idx_0 = r.size(0) - 1; + trueCount = 0; + for (int32_T i{0}; i <= input_sizes_idx_0; i++) { + if (r[i]) { + trueCount++; + } + } + + r2.set_size(trueCount); + trueCount = 0; + for (int32_T i{0}; i <= input_sizes_idx_0; i++) { + if (r[i]) { + r2[trueCount] = i + 1; + trueCount++; + } + } + + input_sizes_idx_0 = r1.size(0) - 1; + trueCount = 0; + for (int32_T i{0}; i <= input_sizes_idx_0; i++) { + if (r1[i]) { + trueCount++; + } + } + + r3.set_size(trueCount); + trueCount = 0; + for (int32_T i{0}; i <= input_sizes_idx_0; i++) { + if (r1[i]) { + r3[trueCount] = i + 1; + trueCount++; + } + } + + if (r2.size(0) == r3.size(0)) { + trueCount = r2.size(0); + for (int32_T i{0}; i < trueCount; i++) { + newDataPoints[i] = 0.5 * (dataPoints[r2[i] - 1] + dataPoints[r3[i] - 1]); + } + } else { + binary_expand_op(newDataPoints, dataPoints, r2, r3); + } + + b_newDataPoints.set_size(newDataPoints.size(0)); + trueCount = newDataPoints.size(0); + for (int32_T i{0}; i < trueCount; i++) { + b_newDataPoints[i] = newDataPoints[i]; + } + + normalizeFunction(b_newDataPoints, sldProfile, r4); + trueCount = r4.size(0); + for (int32_T i{0}; i < trueCount; i++) { + newDataPoints[i + newDataPoints.size(0)] = r4[i]; + } + + // For simplicity append the new points at the end and then sort. + if (dataPoints.size(0) != 0) { + trueCount = dataPoints.size(0); + } else { + trueCount = 0; + } + + if (newDataPoints.size(0) != 0) { + input_sizes_idx_0 = newDataPoints.size(0); + } else { + input_sizes_idx_0 = 0; + } + + if (newDataPoints.size(0) != 0) { + b_i = newDataPoints.size(0); + } else { + b_i = 0; + } + + b_dataPoints.set_size(trueCount + b_i, 2); + for (int32_T i{0}; i < 2; i++) { + for (b_i = 0; b_i < trueCount; b_i++) { + b_dataPoints[b_i + b_dataPoints.size(0) * i] = dataPoints[b_i + + trueCount * i]; + } + } + + for (int32_T i{0}; i < 2; i++) { + for (b_i = 0; b_i < input_sizes_idx_0; b_i++) { + b_dataPoints[(b_i + trueCount) + b_dataPoints.size(0) * i] = + newDataPoints[b_i + input_sizes_idx_0 * i]; + } + } + + dataPoints.set_size(b_dataPoints.size(0), 2); + trueCount = b_dataPoints.size(0); + for (int32_T i{0}; i < 2; i++) { + for (b_i = 0; b_i < trueCount; b_i++) { + dataPoints[b_i + dataPoints.size(0) * i] = b_dataPoints[b_i + + b_dataPoints.size(0) * i]; + } + } + + coder::sortrows(dataPoints); + } + + static void normalizeFunction(const ::coder::array &x, const :: + coder::array &sldProfile, ::coder::array &y) + { + ::coder::array r; + int32_T i; + + // Subfunctions + // NORMALIZEFUNCTION evaluates a function and returns a NxM array, where N + // is the number of elements of x and M is the number of outputs of func. + // All the outputs of func must be scalar. + // The optional parameter 'vectorizable' (default false) allows to specify + // that the input function can be vectorized. + // Modified by AVH for use with coder + // if (~exist('vectorizable','var') || isempty(vectorizable)) + // end + // abs(nargout(func)); %for anonymous functions nargout<0 + y.set_size(x.size(0)); + + // if vectorizable + // % For uniformity reasons, transform the 'x' array into a column vector. + // % In this way it does not matter if it is given as a column or a row + // % vector. + // [newValues{:}] = func(x(:)); + // y = cell2mat(newValues); + // else + i = x.size(0); + for (int32_T b_i{0}; b_i < i; b_i++) { + // Remove cell array so no need for cell2mat + // which won't compile - AVH + // [newValues{:}] = func(x(i)); + // y(i,:) = cell2mat(newValues); + b_SLDFunction(x[b_i], sldProfile, r); + y[b_i] = r[0]; + } + + // end + } + + static void times(::coder::array &in1, const ::coder::array &in2, const ::coder::array &in3) + { + int32_T i; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_1_0; + if (in3.size(0) == 1) { + i = in2.size(0); + } else { + i = in3.size(0); + } + + in1.set_size(i); + stride_0_0 = (in2.size(0) != 1); + stride_1_0 = (in3.size(0) != 1); + if (in3.size(0) == 1) { + loop_ub = in2.size(0); + } else { + loop_ub = in3.size(0); + } + + for (i = 0; i < loop_ub; i++) { + in1[i] = in2[i * stride_0_0] * in3[i * stride_1_0]; + } + } + + void adaptive(const ::coder::array &sldProfile, const real_T + startDomain[2], real_T minAngle, real_T nPoints, cell_25 *out) + { + ::coder::array b_out; + ::coder::array r; + ::coder::array cornerAngle; + ::coder::array hiVal; + ::coder::array newDomain; + ::coder::array b_trianglesToRefine; + ::coder::array r1; + ::coder::array segmentsToSplit; + ::coder::array trianglesToRefine; + int32_T loop_ub; + int32_T nRefinements; + boolean_T exitg1; + + // adaptive: evaluates a matlab function on a given range + // + // 'adaptive.m' allows to sample a function using a reduced number of + // points. It works iteratively adding new points where needed. + // It is especially useful for functions which are computationally intensive + // (e.g. involve solving a differential equation). + // + // Usage: + // XY = adaptive(func, [xstart, xend]) + // evaluates 'func' in the range [xstart, xend]. Key-value arguments are + // used to control the function evaluation. If the function 'func' returns + // multiple output values, only the first one is used for the refinement + // process, but all of them are calculated and returned as additional + // columns in the output matrix. The output matrix XY contains the new + // domain points in the first column and the output values in the other + // columns. + // [x,yy] = adaptive(func, [xstart, xend]) + // as before but separately returns the array with the domain points and + // the array/matrix with the function output values. + // [x,yy] = adaptive(func, xarray, ...) + // as before but explicitly provide an initial array of domain points. + // + // Methods: + // 'adaptive' provides three methods for refining the function evaluation: + // 1) add more points near the sharp corners, which are found by + // considering the triangles formed by three successive points and + // measuring the central angle. + // 2) measure the area of the same triangles and add more points when the + // area is bigger than a threshold. + // 3) measure the length of the segments formed by pairs of successive + // and split the segments which are longer than a threshold. + // If no methods is explicitly specified, the 'angle' method is used. + // + // Input parameters + // - func: input function (function handle) + // - initialDomain: initial domain points (1D array) + // + // Optional key-value input parameters + // - 'nPoints': (default 20) + // initial number of domain points, only used if an initial domain + // array is not excplitely provided. + // - 'maxRefinements': (default 10) + // Specifies the maximum number of refinement steps. + // - 'minAngle': (default 0.8*pi) + // Refine near the points which forms, together with their left and right + // neighbours, a triangle with central angle smaller than a given value. + // - 'maxArea': (default 5e-4) + // Refine near the points which forms, together with their left and right + // neighbours, a triangle with area larger than a threshold. The threshold + // in normalized to the area enclosing th graph: + // threshold==maxArea*(max(x)-min(x))*(max(f(x))-min(f(x))) + // - 'maxLength': (default Inf) + // Refine all the sements which are longer than a given threshold. The + // threshold is relative to the input and output ranges. Specifically, + // before applying the threshold, the data are normalized so that + // max(x)-min(x)==1 and max(f(x))-min(f(x))==1. + // - 'minLength': (default 0) + // Exclude from the refinement process the segments which are shorter + // than a given threshold. The threshold is relative to the input and + // output ranges. Specifically, before applying the threshold, the + // data are normalized so that max(x)-min(x)==1 and max(f(x))-min(f(x))==1. + // - 'minSignal': (default 0.2) + // Exclude from the refinement process the points where the function is + // below a threshold. The threshold is relative to the output range: In + // this example threshold == 0.01*(max(f(x))-min(f(x))). + // - 'vectorizable': (default false) + // Specifies whether the input function accepts arrays as input + // (e.g. f(x)==x.^2). + // - 'waitbar': (default false) + // Display a waitbar. + // + // Output parameters + // - a NxM array where N is the number of domain points and M is the number + // of output parameters of the input function. + // + // Examples: + // + // % Refine a function near sharp corners. The option 'minAngle' is useful + // % for having more points near the peaks of the function. + // f = @(x) exp(-x.^2/4).*sin(3*x); + // % for test-purpose also evaluate the function directly + // x2 = -10:0.01:10; + // y2 = f(x2); + // y = adaptive(f, [-5,5], 'minAngle',0.8*pi); + // figure(1); plot(x2,f(x2),'k--',y(:,1),y(:,2),'o-'); + // legend('high sampling','adaptive') + // title('y = adaptive(f, [xstart, xend], ''minAngle'',0.8*pi)') + // % as before but starting with an inital array of domain points + // x = -5:5; + // y = adaptive(f, x, 'minAngle',0.8*pi); + // figure(2); plot(x,f(x),'s-',x2,f(x2),'k--',y(:,1),y(:,2),'o-'); + // legend('initial sampling','high sampling','adaptive') + // title('y = adaptive(f, x, ''minAngle'',0.8*pi)') + // + // % Refine a function near sharp corners, but do not split segments which + // % are already shorter than 'minLength'. + // y = adaptive(f, x, 'minAngle',0.8*pi, 'minLength',0.05); + // figure(3); plot(x,f(x),'s-',x2,f(x2),'k--',y(:,1),y(:,2),'o-'); + // legend('initial sampling','high sampling','adaptive') + // title('y = adaptive(f, x, ''minAngle'',0.8*pi, ''minLength'',0.05)'); + // + // % Refine a function until the areas of the triangles formed by + // % triplets of successive points are smaller than 'maxArea'. + // y = adaptive(f, x, 'maxArea',1e-3); + // figure(4); plot(x,f(x),'s-',x2,f(x2),'k--',y(:,1),y(:,2),'o-'); + // legend('initial sampling','high sampling','adaptive') + // title('y = adaptive(f, x, ''maxArea'',1e-3)') + // + // % Refine a function until the segments formed by pairs of successive + // % points are shorter than 'maxLength'. + // y = adaptive(f, x, 'maxLength',0.1); + // figure(5); plot(x,f(x),'s-',x2,f(x2),'k--',y(:,1),y(:,2),'o-'); + // legend('initial sampling','high sampling','adaptive') + // title('y = adaptive(f, x, ''maxLength'',0.1)'); + // Copyright + // 2017, Alberto Comin - LMU Muenchen + // Version changes: + // + // 24/01/2017: 1) new default: when no optional argument is given, use the + // 'angle' method as default 2) it is now possible to provide just the + // start and the end of the function domain, instead of having to + // explicitly provide an initial array 3) a new key-word argument + // 'nPoints' controls the number of initial domain points in the cases when + // the initial array is not explicitly provided. 4) it is now possible to + // return the domain points and the function values either as a single 2D + // array or as two separate arrays. + // 25/01/2017: fixed defaults for the case when no method is specified + // Default settings + // nPoints = 20; + // minAngle = 0.8*pi; + // units normalized to data range + // Test-mode + // The test mode is activated by calling 'adaptive.m' with no input. + // if nargin==0 + // initialDomain = -10:10; + // input_func = @(x) 100*exp(-(x+5.2).^2) + 50*exp(-5*(x-0.5).^2)+ 20*exp(-10*(x-5.8).^2); + // thresholdingAngles = true; + // minAngle = 0.8*pi; + // thresholdingLength = true; + // minLength = 0.02; + // disp('Running adaptive.m in test mode'); + // fprintf('input function: %s\n',func2str(input_func)); + // disp('Plotting the function on a initial set of points'); + // testFigureHandle = figure(); + // plot(initialDomain, input_func(initialDomain),'bs-','LineWidth',1.5); + // grid on; xlabel('x'); ylabel('y'); title('adaptive.m example'); + // end + // Processing input arguments + // assert(isa(input_func,'function_handle'),'adaptiveFunctionEvaluation:ArgChk',... + // 'the first argument must be a function handle'); + // assert(isnumeric(initialDomain) && isvector(initialDomain),... + // 'adaptiveFunctionEvaluation:ArgChk','initial points must be specified as a numeric vector'); + // + // nExtraArgIn = numel(varargin); + // if mod(nExtraArgIn,2)==1 + // error('adaptiveFunctionEvaluation:ArgChk', ... + // 'At least a key or a value is missing in the key-value arguments list.'); + // end + // usingDefaultMethod = true; + // n = 1; + // minAngle = 0.7 * pi; + // thresholdingAngles = true; + // nPoints = 50; + // while n < nExtraArgIn + // switch lower(varargin{n}) + // case 'minangle' + // minAngle = varargin{n+1}; + // n = n+2; + // case 'maxarea' + // maxArea = varargin{n+1}; + // thresholdingArea = true; + // usingDefaultMethod = false; + // n = n+2; + // case 'maxlength' + // maxLength = varargin{n+1}; + // thresholdingLength = true; + // usingDefaultMethod = false; + // n = n+2; + // case 'minlength' + // minLength = varargin{n+1}; + // thresholdingLength = true; + // n = n+2; + // case 'minsignal' + // minSignal = varargin{n+1}; + // thresholdingSignal = true; + // n = n+2; + // case 'npoints' + // nPoints = varargin{n+1}; + // n = n+2; + // case 'vectorize' + // vectorizable = varargin{n+1}; + // n = n+2; + // case 'maxrefinements' + // maxRefinements = varargin{n+1}; + // n = n+2; + // case 'waitbar' + // displayWaitbar = varargin{n+1}; + // n = n+2; + // otherwise + // error('adaptiveFunctionEvaluation:ArgChk',... + // ['unknown keyword argument: ', varargin{n}]); + // end + // end + // if no method is specified use the 'angle' method as default + // if usingDefaultMethod + // thresholdingAngles = true; + // end + // Initial function evaluation + // if initialDomain only contains the start and the end points, create a new + // array with 'nPoints' points. + coder::linspace(startDomain[0], startDomain[1], nPoints, r); + newDomain.set_size(r.size(1)); + loop_ub = r.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + newDomain[i] = r[i]; + } + + // Normalize the input function: This step allows to use the same syntax for + // functions with single or multiple output parameters. + // Remove this syntax for compile - AVH + // func = @(x) normalizeFunction(x,sldProfile,vectorizable); + // Evaluate the input function on the initial set of points. + normalizeFunction(newDomain, sldProfile, hiVal); + + // dataPoints = [initialDomain(:), func(initialDomain(:))]; + out->f1.set_size(newDomain.size(0), 2); + loop_ub = newDomain.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + out->f1[i] = newDomain[i]; + } + + loop_ub = hiVal.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + out->f1[i + out->f1.size(0)] = hiVal[i]; + } + + // Iterative function refinement + // if displayWaitbar + // refinementWaitbar = waitbar(0,['Evaluating function ',func2str(func)],... + // 'CreateCancelBtn','setappdata(gcbf,''canceling'',true)'); + // setappdata(refinementWaitbar,'canceling',false) + // end + nRefinements = 0; + exitg1 = false; + while ((!exitg1) && (nRefinements < 10)) { + real_T b_dv[2]; + real_T b_dv1[2]; + boolean_T y; + + // calculate the box which encloses the current data points: + // Each point is considered as the central corner of the triangle formed + // with its left and right hand side neighbours. The first and the last + // points are not the central corner of any triangle, so for N points + // there are only N-2 triangles. + // if thresholdingArea + // triangleArea = calculateTrianglesArea(dataPoints(:,1:2)); + // bigTriangles = triangleArea > (maxArea * dataBoxArea); + // trianglesToRefine = trianglesToRefine | bigTriangles; + // end + b_out.set_size(out->f1.size(0), 2); + loop_ub = out->f1.size(0); + for (int32_T i{0}; i < 2; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_out[i1 + b_out.size(0) * i] = out->f1[i1 + out->f1.size(0) * i]; + } + } + + coder::internal::maximum(b_out, b_dv); + b_out.set_size(out->f1.size(0), 2); + loop_ub = out->f1.size(0); + for (int32_T i{0}; i < 2; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_out[i1 + b_out.size(0) * i] = out->f1[i1 + out->f1.size(0) * i]; + } + } + + coder::internal::minimum(b_out, b_dv1); + b_out.set_size(out->f1.size(0), 2); + loop_ub = out->f1.size(0); + for (int32_T i{0}; i < 2; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_out[i1 + b_out.size(0) * i] = out->f1[i1 + out->f1.size(0) * i]; + } + + b_dv[i] -= b_dv1[i]; + } + + calculateCentralAngles(b_out, b_dv, cornerAngle); + if (out->f1.size(0) - 2 == cornerAngle.size(0)) { + trianglesToRefine.set_size(out->f1.size(0) - 2); + loop_ub = out->f1.size(0) - 2; + for (int32_T i{0}; i < loop_ub; i++) { + trianglesToRefine[i] = (cornerAngle[i] < minAngle); + } + } else { + b_binary_expand_op(trianglesToRefine, out, cornerAngle, minAngle); + } + + // For N points there are N-2 triangles and N-1 triangle sides. Each + // triangle side is a segment, which can be split or not depending on the + // refinement parameters. + b_trianglesToRefine.set_size(trianglesToRefine.size(0) + 1); + loop_ub = trianglesToRefine.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + b_trianglesToRefine[i] = trianglesToRefine[i]; + } + + b_trianglesToRefine[trianglesToRefine.size(0)] = false; + r1.set_size(trianglesToRefine.size(0) + 1); + r1[0] = false; + loop_ub = trianglesToRefine.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + r1[i + 1] = trianglesToRefine[i]; + } + + segmentsToSplit.set_size(b_trianglesToRefine.size(0)); + loop_ub = b_trianglesToRefine.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + segmentsToSplit[i] = (b_trianglesToRefine[i] || r1[i]); + } + + // if thresholdingLength + // dataSegments = diff(dataPoints(:,1:2)); + // normalizedSegments = bsxfun(@rdivide, dataSegments, dataBoxSize); + // segmentsLengthNormalized = hypot(normalizedSegments(:,1), normalizedSegments(:,2)); + // tooLongSegments = segmentsLengthNormalized > maxLength; + // longEnoughSegments = segmentsLengthNormalized > minLength; + // segmentsToSplit = (segmentsToSplit | tooLongSegments) & longEnoughSegments; + // end + // if thresholdingSignal + // segmentsCenters = (dataPoints(1:end-1,2)+dataPoints(2:end,2))/2; + // centerAboveThreshold = segmentsCenters > minSignal * max(abs(dataPoints(:,2))); + // segmentsToSplit = segmentsToSplit & centerAboveThreshold; + // end + y = coder::internal::allOrAny_anonFcn3(segmentsToSplit.size(0), + segmentsToSplit); + if (y) { + increaseSampling(out->f1, segmentsToSplit, sldProfile); + + // Removed waitbar for compile - AVH + // if displayWaitbar + // if getappdata(refinementWaitbar,'canceling'), break; end + // waitbar(nRefinements/maxRefinements,refinementWaitbar); + // end + nRefinements++; + } else { + exitg1 = true; + } + } + + // if displayWaitbar + // delete(refinementWaitbar); + // end + // Plotting refined function + // Removed for compile - AVH + // if nargin==0 % test mode + // figure(testFigureHandle); + // hold on; + // plot(dataPoints(:,1), dataPoints(:,2),'ro-'); + // legend('initial', 'refiniment'); + // end + // if nargout==1 + // elseif nargout>1 + // out{1} = dataPoints(:,1); + // out{2} = dataPoints(:,2:end); + // end + } +} + +// End of code generation (adaptive.cpp) diff --git a/cpp/RAT/adaptive.h b/cpp/RAT/adaptive.h new file mode 100644 index 00000000..3aaef93b --- /dev/null +++ b/cpp/RAT/adaptive.h @@ -0,0 +1,34 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// adaptive.h +// +// Code generation for function 'adaptive' +// +#ifndef ADAPTIVE_H +#define ADAPTIVE_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct cell_25; +} + +// Function Declarations +namespace RAT +{ + void adaptive(const ::coder::array &sldProfile, const real_T + startDomain[2], real_T minAngle, real_T nPoints, cell_25 *out); +} + +#endif + +// End of code generation (adaptive.h) diff --git a/cpp/RAT/all.cpp b/cpp/RAT/all.cpp new file mode 100644 index 00000000..fbb05473 --- /dev/null +++ b/cpp/RAT/all.cpp @@ -0,0 +1,45 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// all.cpp +// +// Code generation for function 'all' +// + +// Include files +#include "all.h" +#include "allOrAny.h" +#include "rt_nonfinite.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + void all(const boolean_T x_data[], const int32_T x_size[2], boolean_T + y_data[], int32_T y_size[2]) + { + int32_T loop_ub; + y_size[0] = 1; + y_size[1] = static_cast(x_size[1]); + loop_ub = static_cast(x_size[1]); + if (loop_ub - 1 >= 0) { + y_data[0] = false; + } + + loop_ub = x_size[1]; + for (int32_T k{0}; k < loop_ub; k++) { + internal::b_allOrAny_anonFcn2(x_size[0], x_data, y_data); + } + } + + boolean_T b_all(const boolean_T x_data[], const int32_T x_size[2]) + { + return internal::allOrAny_anonFcn2(x_size[1], x_data); + } + } +} + +// End of code generation (all.cpp) diff --git a/cpp/RAT/all.h b/cpp/RAT/all.h new file mode 100644 index 00000000..720f7b5d --- /dev/null +++ b/cpp/RAT/all.h @@ -0,0 +1,31 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// all.h +// +// Code generation for function 'all' +// +#ifndef ALL_H +#define ALL_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void all(const boolean_T x_data[], const int32_T x_size[2], boolean_T + y_data[], int32_T y_size[2]); + boolean_T b_all(const boolean_T x_data[], const int32_T x_size[2]); + } +} + +#endif + +// End of code generation (all.h) diff --git a/cpp/RAT/allOrAny.cpp b/cpp/RAT/allOrAny.cpp new file mode 100644 index 00000000..2b40e675 --- /dev/null +++ b/cpp/RAT/allOrAny.cpp @@ -0,0 +1,85 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// allOrAny.cpp +// +// Code generation for function 'allOrAny' +// + +// Include files +#include "allOrAny.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + boolean_T allOrAny_anonFcn2(int32_T n, const boolean_T X_data[]) + { + int32_T k; + boolean_T exitg1; + boolean_T varargout_1; + varargout_1 = true; + k = 0; + exitg1 = false; + while ((!exitg1) && (k <= static_cast(n) - 1)) { + if (!X_data[0]) { + varargout_1 = false; + exitg1 = true; + } else { + k++; + } + } + + return varargout_1; + } + + boolean_T allOrAny_anonFcn3(int32_T n, const ::coder::array + &X) + { + int32_T k; + boolean_T exitg1; + boolean_T varargout_1; + varargout_1 = false; + k = 0; + exitg1 = false; + while ((!exitg1) && (k <= n - 1)) { + if (X[k]) { + varargout_1 = true; + exitg1 = true; + } else { + k++; + } + } + + return varargout_1; + } + + void b_allOrAny_anonFcn2(int32_T n, const boolean_T X_data[], boolean_T + Y_data[]) + { + int32_T k; + boolean_T exitg1; + Y_data[0] = true; + k = 0; + exitg1 = false; + while ((!exitg1) && (k <= static_cast(n) - 1)) { + if (!X_data[0]) { + Y_data[0] = false; + exitg1 = true; + } else { + k++; + } + } + } + } + } +} + +// End of code generation (allOrAny.cpp) diff --git a/cpp/RAT/allOrAny.h b/cpp/RAT/allOrAny.h new file mode 100644 index 00000000..72a06df4 --- /dev/null +++ b/cpp/RAT/allOrAny.h @@ -0,0 +1,37 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// allOrAny.h +// +// Code generation for function 'allOrAny' +// +#ifndef ALLORANY_H +#define ALLORANY_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + boolean_T allOrAny_anonFcn2(int32_T n, const boolean_T X_data[]); + boolean_T allOrAny_anonFcn3(int32_T n, const ::coder::array + &X); + void b_allOrAny_anonFcn2(int32_T n, const boolean_T X_data[], boolean_T + Y_data[]); + } + } +} + +#endif + +// End of code generation (allOrAny.h) diff --git a/cpp/RAT/allocateLayersForContrast.cpp b/cpp/RAT/allocateLayersForContrast.cpp new file mode 100644 index 00000000..7080b9d8 --- /dev/null +++ b/cpp/RAT/allocateLayersForContrast.cpp @@ -0,0 +1,85 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// allocateLayersForContrast.cpp +// +// Code generation for function 'allocateLayersForContrast' +// + +// Include files +#include "allocateLayersForContrast.h" +#include "RATMain_types.h" +#include "length.h" +#include "nullAssignment.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void allocateLayersForContrast(const ::coder::array + &contrastLayers, const ::coder::array + &outParameterisedLayers, boolean_T useImaginary, real_T + thisContrastLayers_data[], int32_T thisContrastLayers_size[2]) + { + int32_T i; + int32_T n; + + // Decide which layers are needed for a particular contrast. + // This function takes the master array of all layers + // and extracts which parameters are required for + // a particular contrast. + // + // INPUTS: + // outParameterisedLayers - List of all the available layers + // thisContrastLayers - Array detailing which layers are required for this contrast + if (useImaginary) { + n = coder::internal::intlength(contrastLayers.size(0), contrastLayers.size + (1)); + thisContrastLayers_size[0] = n; + thisContrastLayers_size[1] = 6; + for (i = 0; i < 6; i++) { + for (int32_T i1{0}; i1 < n; i1++) { + thisContrastLayers_data[i1 + n * i] = 0.0; + } + } + } else { + n = coder::internal::intlength(contrastLayers.size(0), contrastLayers.size + (1)); + thisContrastLayers_size[0] = n; + thisContrastLayers_size[1] = 5; + for (i = 0; i < 5; i++) { + for (int32_T i1{0}; i1 < n; i1++) { + thisContrastLayers_data[i1 + n * i] = 0.0; + } + } + } + + i = coder::internal::intlength(contrastLayers.size(0), contrastLayers.size(1)); + for (int32_T b_i{0}; b_i < i; b_i++) { + if (contrastLayers[b_i] != 0.0) { + // % Check the length of thisLayer. If it's 6, then we have an + // % imaginary SLD defined. Combile them into one complex number at + // % this point. + // if length(thisLayer) == 6 + // compSLD = complex(thisLayer(2),thisLayer(3)); + // thisLayer = [thisLayer(1) compSLD thisLayer(4:end)]; + // end + n = outParameterisedLayers[static_cast(contrastLayers[b_i]) - 1] + .f1.size(1); + for (int32_T i1{0}; i1 < n; i1++) { + thisContrastLayers_data[b_i + thisContrastLayers_size[0] * i1] = + outParameterisedLayers[static_cast(contrastLayers[b_i]) - 1] + .f1[i1]; + } + } else { + coder::internal::nullAssignment(thisContrastLayers_data, + thisContrastLayers_size); + } + } + } +} + +// End of code generation (allocateLayersForContrast.cpp) diff --git a/cpp/RAT/allocateLayersForContrast.h b/cpp/RAT/allocateLayersForContrast.h new file mode 100644 index 00000000..cb7cbd3d --- /dev/null +++ b/cpp/RAT/allocateLayersForContrast.h @@ -0,0 +1,31 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// allocateLayersForContrast.h +// +// Code generation for function 'allocateLayersForContrast' +// +#ifndef ALLOCATELAYERSFORCONTRAST_H +#define ALLOCATELAYERSFORCONTRAST_H + +// Include files +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void allocateLayersForContrast(const ::coder::array + &contrastLayers, const ::coder::array + &outParameterisedLayers, boolean_T useImaginary, real_T + thisContrastLayers_data[], int32_T thisContrastLayers_size[2]); +} + +#endif + +// End of code generation (allocateLayersForContrast.h) diff --git a/cpp/RAT/allocateParamsToLayers.cpp b/cpp/RAT/allocateParamsToLayers.cpp new file mode 100644 index 00000000..400eeb5a --- /dev/null +++ b/cpp/RAT/allocateParamsToLayers.cpp @@ -0,0 +1,70 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// allocateParamsToLayers.cpp +// +// Code generation for function 'allocateParamsToLayers' +// + +// Include files +#include "allocateParamsToLayers.h" +#include "RATMain_types.h" +#include "length.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include +#include + +// Function Definitions +namespace RAT +{ + void allocateParamsToLayers(const ::coder::array ¶ms, const :: + coder::array &layersDetails, ::coder::array &outLayers) + { + real_T thisOutLayer_data[10]; + int32_T i; + + // Allocates parameters from the parameter array to the correct layers + // + // This function takes the list of all layers in 'layersDetails', + // then loops over all the layers, putting in the correct + // parameter value from the parameters array into each layer in + // the 'outLayers' cell array + i = layersDetails.size(0); + outLayers.set_size(1, layersDetails.size(0)); + for (int32_T b_i{0}; b_i < i; b_i++) { + int32_T i1; + int32_T n; + n = coder::internal::intlength(layersDetails[b_i].f1.size(0), + layersDetails[b_i].f1.size(1)); + if (n - 1 >= 0) { + std::memset(&thisOutLayer_data[0], 0, static_cast(n) * sizeof + (real_T)); + } + + i1 = coder::internal::intlength(layersDetails[b_i].f1.size(0), + layersDetails[b_i].f1.size(1)); + for (int32_T b_n{0}; b_n <= i1 - 2; b_n++) { + if (!std::isnan(layersDetails[b_i].f1[b_n])) { + thisOutLayer_data[b_n] = params[static_cast(layersDetails[b_i] + .f1[b_n]) - 1]; + } else { + thisOutLayer_data[b_n] = rtNaN; + } + } + + thisOutLayer_data[coder::internal::intlength(layersDetails[b_i].f1.size(0), + layersDetails[b_i].f1.size(1)) - 1] = layersDetails[b_i] + .f1[layersDetails[b_i].f1.size(0) * layersDetails[b_i].f1.size(1) - 1]; + outLayers[outLayers.size(0) * b_i].f1.set_size(1, n); + for (i1 = 0; i1 < n; i1++) { + outLayers[b_i].f1[i1] = thisOutLayer_data[i1]; + } + } + } +} + +// End of code generation (allocateParamsToLayers.cpp) diff --git a/cpp/RAT/allocateParamsToLayers.h b/cpp/RAT/allocateParamsToLayers.h new file mode 100644 index 00000000..a618db78 --- /dev/null +++ b/cpp/RAT/allocateParamsToLayers.h @@ -0,0 +1,30 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// allocateParamsToLayers.h +// +// Code generation for function 'allocateParamsToLayers' +// +#ifndef ALLOCATEPARAMSTOLAYERS_H +#define ALLOCATEPARAMSTOLAYERS_H + +// Include files +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void allocateParamsToLayers(const ::coder::array ¶ms, const :: + coder::array &layersDetails, ::coder::array &outLayers); +} + +#endif + +// End of code generation (allocateParamsToLayers.h) diff --git a/cpp/RAT/anyNonFinite.cpp b/cpp/RAT/anyNonFinite.cpp new file mode 100644 index 00000000..d593d06d --- /dev/null +++ b/cpp/RAT/anyNonFinite.cpp @@ -0,0 +1,44 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// anyNonFinite.cpp +// +// Code generation for function 'anyNonFinite' +// + +// Include files +#include "anyNonFinite.h" +#include "rt_nonfinite.h" +#include "vAllOrAny.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + boolean_T anyNonFinite(const ::coder::array &x) + { + int32_T i; + boolean_T p; + p = true; + i = x.size(1); + for (int32_T k{0}; k < i; k++) { + int32_T i1; + i1 = x.size(0); + for (int32_T b_k{0}; b_k < i1; b_k++) { + b_genloops(x, &p, b_k + 1, k + 1); + } + } + + return !p; + } + } + } +} + +// End of code generation (anyNonFinite.cpp) diff --git a/cpp/RAT/anyNonFinite.h b/cpp/RAT/anyNonFinite.h new file mode 100644 index 00000000..baa14c76 --- /dev/null +++ b/cpp/RAT/anyNonFinite.h @@ -0,0 +1,33 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// anyNonFinite.h +// +// Code generation for function 'anyNonFinite' +// +#ifndef ANYNONFINITE_H +#define ANYNONFINITE_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + boolean_T anyNonFinite(const ::coder::array &x); + } + } +} + +#endif + +// End of code generation (anyNonFinite.h) diff --git a/cpp/RAT/applyBackgroundCorrection.cpp b/cpp/RAT/applyBackgroundCorrection.cpp new file mode 100644 index 00000000..6206f76a --- /dev/null +++ b/cpp/RAT/applyBackgroundCorrection.cpp @@ -0,0 +1,77 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// applyBackgroundCorrection.cpp +// +// Code generation for function 'applyBackgroundCorrection' +// + +// Include files +#include "applyBackgroundCorrection.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void applyBackgroundCorrection(::coder::array &reflect, ::coder:: + array &simul, ::coder::array &shiftedData, real_T + backgroundParams, real_T contrastBackgroundsType) + { + ::coder::array b_reflect; + switch (static_cast(contrastBackgroundsType)) { + case 1: + { + int32_T loop_ub; + + // Add background to the simulation + b_reflect.set_size(reflect.size(0)); + loop_ub = reflect.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + b_reflect[i] = reflect[i + reflect.size(0)] + backgroundParams; + } + + loop_ub = b_reflect.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + reflect[i + reflect.size(0)] = b_reflect[i]; + } + + b_reflect.set_size(simul.size(0)); + loop_ub = simul.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + b_reflect[i] = simul[i + simul.size(0)] + backgroundParams; + } + + loop_ub = b_reflect.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + simul[i + simul.size(0)] = b_reflect[i]; + } + } + break; + + case 2: + { + int32_T loop_ub; + + // Subtract the background from the data.. + b_reflect.set_size(shiftedData.size(0)); + loop_ub = shiftedData.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + b_reflect[i] = shiftedData[i + shiftedData.size(0)] - backgroundParams; + } + + loop_ub = b_reflect.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + shiftedData[i + shiftedData.size(0)] = b_reflect[i]; + } + + // shiftedData(:,3) = shiftedData(:,3) - backgroundParams; + } + break; + } + } +} + +// End of code generation (applyBackgroundCorrection.cpp) diff --git a/cpp/RAT/applyBackgroundCorrection.h b/cpp/RAT/applyBackgroundCorrection.h new file mode 100644 index 00000000..01828f5a --- /dev/null +++ b/cpp/RAT/applyBackgroundCorrection.h @@ -0,0 +1,29 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// applyBackgroundCorrection.h +// +// Code generation for function 'applyBackgroundCorrection' +// +#ifndef APPLYBACKGROUNDCORRECTION_H +#define APPLYBACKGROUNDCORRECTION_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void applyBackgroundCorrection(::coder::array &reflect, ::coder:: + array &simul, ::coder::array &shiftedData, real_T + backgroundParams, real_T contrastBackgroundsType); +} + +#endif + +// End of code generation (applyBackgroundCorrection.h) diff --git a/cpp/RAT/applyHydrationImag.cpp b/cpp/RAT/applyHydrationImag.cpp new file mode 100644 index 00000000..bbf85351 --- /dev/null +++ b/cpp/RAT/applyHydrationImag.cpp @@ -0,0 +1,97 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// applyHydrationImag.cpp +// +// Code generation for function 'applyHydrationImag' +// + +// Include files +#include "applyHydrationImag.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void applyHydrationImag(::coder::array &thisContrastLayers, real_T + bulkIn, real_T bulkOut) + { + ::coder::array newOutLayers; + int16_T outSize_idx_0; + + // Applies the hydration correction to real value of layers + // if it is necessary.. (This is for when im(SLD) is used) + // The only guidance we have to whether the user is using hydration + // in their custom model is the number of columns of the output + outSize_idx_0 = static_cast(thisContrastLayers.size(0)); + + // [nlayers x nCols] + if (static_cast(thisContrastLayers.size(1)) == 6) { + int32_T i; + int32_T loop_ub; + + // we need to calculate the hydrated SLD + newOutLayers.set_size(static_cast(outSize_idx_0), 4); + loop_ub = outSize_idx_0; + for (i = 0; i < 4; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + newOutLayers[i1 + newOutLayers.size(0) * i] = 0.0; + } + } + + loop_ub = thisContrastLayers.size(0); + for (i = 0; i < loop_ub; i++) { + newOutLayers[i] = thisContrastLayers[i]; + } + + // Thickness' + loop_ub = thisContrastLayers.size(0); + for (i = 0; i < loop_ub; i++) { + newOutLayers[i + newOutLayers.size(0) * 2] = thisContrastLayers[i + + thisContrastLayers.size(0) * 2]; + } + + // We never hydrate im(SLD) + loop_ub = thisContrastLayers.size(0); + for (i = 0; i < loop_ub; i++) { + newOutLayers[i + newOutLayers.size(0) * 3] = thisContrastLayers[i + + thisContrastLayers.size(0) * 3]; + } + + // Roughness + i = outSize_idx_0; + for (int32_T n{0}; n < i; n++) { + real_T d; + real_T thisHydration; + thisHydration = thisContrastLayers[n + thisContrastLayers.size(0) * 4] / + 100.0; + + // Assume percent for backwards compatability + if (thisContrastLayers[n + thisContrastLayers.size(0) * 5] == 0.0) { + d = bulkIn; + } else { + d = bulkOut; + } + + newOutLayers[n + newOutLayers.size(0)] = thisHydration * d + (1.0 - + thisHydration) * thisContrastLayers[n + thisContrastLayers.size(0)]; + + // Reassignment to keep codegen happy + } + + thisContrastLayers.set_size(newOutLayers.size(0), 4); + loop_ub = newOutLayers.size(0); + for (i = 0; i < 4; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + thisContrastLayers[i1 + thisContrastLayers.size(0) * i] = + newOutLayers[i1 + newOutLayers.size(0) * i]; + } + } + } + } +} + +// End of code generation (applyHydrationImag.cpp) diff --git a/cpp/RAT/applyHydrationImag.h b/cpp/RAT/applyHydrationImag.h new file mode 100644 index 00000000..334d78fd --- /dev/null +++ b/cpp/RAT/applyHydrationImag.h @@ -0,0 +1,28 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// applyHydrationImag.h +// +// Code generation for function 'applyHydrationImag' +// +#ifndef APPLYHYDRATIONIMAG_H +#define APPLYHYDRATIONIMAG_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void applyHydrationImag(::coder::array &thisContrastLayers, real_T + bulkIn, real_T bulkOut); +} + +#endif + +// End of code generation (applyHydrationImag.h) diff --git a/cpp/RAT/applyHydrationReal.cpp b/cpp/RAT/applyHydrationReal.cpp new file mode 100644 index 00000000..c819f885 --- /dev/null +++ b/cpp/RAT/applyHydrationReal.cpp @@ -0,0 +1,90 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// applyHydrationReal.cpp +// +// Code generation for function 'applyHydrationReal' +// + +// Include files +#include "applyHydrationReal.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void applyHydrationReal(::coder::array &thisContrastLayers, real_T + bulkIn, real_T bulkOut) + { + ::coder::array newOutLayers; + int16_T outSize_idx_0; + + // Applies the hydration correction to real value of layers + // if it is necessary.. (This is for when im(SLD) is not used) + // The only guidance we have to whether the user is using hydration + // in their custom model is the numbre of columns of the output + outSize_idx_0 = static_cast(thisContrastLayers.size(0)); + + // [nlayers x nCols] + if (static_cast(thisContrastLayers.size(1)) == 5) { + int32_T i; + int32_T loop_ub; + + // we need to calculate the hydrated SLD + newOutLayers.set_size(static_cast(outSize_idx_0), 3); + loop_ub = outSize_idx_0; + for (i = 0; i < 3; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + newOutLayers[i1 + newOutLayers.size(0) * i] = 0.0; + } + } + + loop_ub = thisContrastLayers.size(0); + for (i = 0; i < loop_ub; i++) { + newOutLayers[i] = thisContrastLayers[i]; + } + + // Thickness' + loop_ub = thisContrastLayers.size(0); + for (i = 0; i < loop_ub; i++) { + newOutLayers[i + newOutLayers.size(0) * 2] = thisContrastLayers[i + + thisContrastLayers.size(0) * 2]; + } + + // Roughness + i = outSize_idx_0; + for (int32_T n{0}; n < i; n++) { + real_T d; + real_T thisHydration; + thisHydration = thisContrastLayers[n + thisContrastLayers.size(0) * 3] / + 100.0; + + // Assume percent for backwards compatability + if (thisContrastLayers[n + thisContrastLayers.size(0) * 4] == 0.0) { + d = bulkIn; + } else { + d = bulkOut; + } + + newOutLayers[n + newOutLayers.size(0)] = thisHydration * d + (1.0 - + thisHydration) * thisContrastLayers[n + thisContrastLayers.size(0)]; + + // Reassignment to keep codegen happy + } + + thisContrastLayers.set_size(newOutLayers.size(0), 3); + loop_ub = newOutLayers.size(0); + for (i = 0; i < 3; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + thisContrastLayers[i1 + thisContrastLayers.size(0) * i] = + newOutLayers[i1 + newOutLayers.size(0) * i]; + } + } + } + } +} + +// End of code generation (applyHydrationReal.cpp) diff --git a/cpp/RAT/applyHydrationReal.h b/cpp/RAT/applyHydrationReal.h new file mode 100644 index 00000000..5a2e41c6 --- /dev/null +++ b/cpp/RAT/applyHydrationReal.h @@ -0,0 +1,28 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// applyHydrationReal.h +// +// Code generation for function 'applyHydrationReal' +// +#ifndef APPLYHYDRATIONREAL_H +#define APPLYHYDRATIONREAL_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void applyHydrationReal(::coder::array &thisContrastLayers, real_T + bulkIn, real_T bulkOut); +} + +#endif + +// End of code generation (applyHydrationReal.h) diff --git a/cpp/RAT/asinh.cpp b/cpp/RAT/asinh.cpp new file mode 100644 index 00000000..23f39b25 --- /dev/null +++ b/cpp/RAT/asinh.cpp @@ -0,0 +1,54 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// asinh.cpp +// +// Code generation for function 'asinh' +// + +// Include files +#include "asinh.h" +#include "log1p.h" +#include "rt_nonfinite.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace scalar + { + void b_asinh(real_T *x) + { + boolean_T xneg; + xneg = (*x < 0.0); + if (xneg) { + *x = -*x; + } + + if (*x >= 2.68435456E+8) { + *x = std::log(*x) + 0.69314718055994529; + } else if (*x > 2.0) { + *x = std::log(2.0 * *x + 1.0 / (std::sqrt(*x * *x + 1.0) + *x)); + } else { + real_T t; + t = *x * *x; + *x += t / (std::sqrt(t + 1.0) + 1.0); + b_log1p(x); + } + + if (xneg) { + *x = -*x; + } + } + } + } + } +} + +// End of code generation (asinh.cpp) diff --git a/cpp/RAT/asinh.h b/cpp/RAT/asinh.h new file mode 100644 index 00000000..c03bcc04 --- /dev/null +++ b/cpp/RAT/asinh.h @@ -0,0 +1,35 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// asinh.h +// +// Code generation for function 'asinh' +// +#ifndef ASINH_H +#define ASINH_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace scalar + { + void b_asinh(real_T *x); + } + } + } +} + +#endif + +// End of code generation (asinh.h) diff --git a/cpp/RAT/asymconvstep.cpp b/cpp/RAT/asymconvstep.cpp new file mode 100644 index 00000000..78b16eb0 --- /dev/null +++ b/cpp/RAT/asymconvstep.cpp @@ -0,0 +1,171 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// asymconvstep.cpp +// +// Code generation for function 'asymconvstep' +// + +// Include files +#include "asymconvstep.h" +#include "eml_mtimes_helper.h" +#include "erf.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void asymconvstep(const ::coder::array &x, real_T xw, real_T xcen, + real_T s1, real_T s2, real_T h, ::coder::array + &f) + { + ::coder::array b_r; + ::coder::array b_x; + ::coder::array r1; + real_T a; + real_T aFactor; + real_T bFactor; + real_T l; + real_T r; + int32_T loop_ub; + + // Produces a step function convoluted with differnt error functions + // on each side. + // Convstep (x,xw,xcen,s1,s2,h) + // x = vector of x values + // xw = Width of step function + // xcen = Centre point of step function + // s1 = Roughness parameter of left side + // s2 = Roughness parameter of right side + // h = Height of step function. + // if length(xw) > 1 + // ME = MException('VerifyOutput:OutOfBounds', ... + // 'xw must be single value'); + // throw(ME); + // end + // + // if length(xcen) > 1 + // ME = MException('VerifyOutput:OutOfBounds', ... + // 'xcen must be single value'); + // throw(ME); + // end + // + // if length(s1) > 1 + // ME = MException('VerifyOutput:OutOfBounds', ... + // 's1 must be single value'); + // throw(ME); + // end + // + // if length(s2) > 1 + // ME = MException('VerifyOutput:OutOfBounds', ... + // 's2 must be single value'); + // throw(ME); + // end + r = xcen + xw / 2.0; + l = xcen - xw / 2.0; + aFactor = 1.4142135623730951 * s1; + bFactor = 1.4142135623730951 * s2; + a = h / 2.0; + b_x.set_size(1, x.size(1)); + loop_ub = x.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_x[i] = (x[i] - l) / aFactor; + } + + coder::b_erf(b_x, b_r); + b_x.set_size(1, x.size(1)); + loop_ub = x.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_x[i] = (x[i] - r) / bFactor; + } + + coder::b_erf(b_x, r1); + if (b_r.size(1) == r1.size(1)) { + f.set_size(1, b_r.size(1)); + loop_ub = b_r.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + f[i] = a * (b_r[i] - r1[i]); + } + } else { + binary_expand_op(f, a, b_r, r1); + } + } + + void asymconvstep(const ::coder::array &x, real_T xw, real_T xcen, + real_T s1, real_T s2, ::coder::array &f) + { + ::coder::array b_r; + ::coder::array b_x; + ::coder::array r1; + real_T aFactor; + real_T bFactor; + real_T l; + real_T r; + int32_T loop_ub; + + // Produces a step function convoluted with differnt error functions + // on each side. + // Convstep (x,xw,xcen,s1,s2,h) + // x = vector of x values + // xw = Width of step function + // xcen = Centre point of step function + // s1 = Roughness parameter of left side + // s2 = Roughness parameter of right side + // h = Height of step function. + // if length(xw) > 1 + // ME = MException('VerifyOutput:OutOfBounds', ... + // 'xw must be single value'); + // throw(ME); + // end + // + // if length(xcen) > 1 + // ME = MException('VerifyOutput:OutOfBounds', ... + // 'xcen must be single value'); + // throw(ME); + // end + // + // if length(s1) > 1 + // ME = MException('VerifyOutput:OutOfBounds', ... + // 's1 must be single value'); + // throw(ME); + // end + // + // if length(s2) > 1 + // ME = MException('VerifyOutput:OutOfBounds', ... + // 's2 must be single value'); + // throw(ME); + // end + r = xcen + xw / 2.0; + l = xcen - xw / 2.0; + aFactor = 1.4142135623730951 * s1; + bFactor = 1.4142135623730951 * s2; + b_x.set_size(1, x.size(1)); + loop_ub = x.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_x[i] = (x[i] - l) / aFactor; + } + + coder::b_erf(b_x, b_r); + b_x.set_size(1, x.size(1)); + loop_ub = x.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_x[i] = (x[i] - r) / bFactor; + } + + coder::b_erf(b_x, r1); + if (b_r.size(1) == r1.size(1)) { + f.set_size(1, b_r.size(1)); + loop_ub = b_r.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + f[i] = 0.0 * (b_r[i] - r1[i]); + } + } else { + binary_expand_op(f, b_r, r1); + } + } +} + +// End of code generation (asymconvstep.cpp) diff --git a/cpp/RAT/asymconvstep.h b/cpp/RAT/asymconvstep.h new file mode 100644 index 00000000..422c2896 --- /dev/null +++ b/cpp/RAT/asymconvstep.h @@ -0,0 +1,31 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// asymconvstep.h +// +// Code generation for function 'asymconvstep' +// +#ifndef ASYMCONVSTEP_H +#define ASYMCONVSTEP_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void asymconvstep(const ::coder::array &x, real_T xw, real_T xcen, + real_T s1, real_T s2, real_T h, ::coder::array + &f); + void asymconvstep(const ::coder::array &x, real_T xw, real_T xcen, + real_T s1, real_T s2, ::coder::array &f); +} + +#endif + +// End of code generation (asymconvstep.h) diff --git a/cpp/RAT/averageReflectivity.cpp b/cpp/RAT/averageReflectivity.cpp new file mode 100644 index 00000000..3d87dd8c --- /dev/null +++ b/cpp/RAT/averageReflectivity.cpp @@ -0,0 +1,67 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// averageReflectivity.cpp +// +// Code generation for function 'averageReflectivity' +// + +// Include files +#include "averageReflectivity.h" +#include "cat.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace domainsTF + { + void averageReflectivity(const ::coder::array &reflect1, const :: + coder::array &reflect2, const ::coder::array + &simul1, const ::coder::array &simul2, real_T domainRatio, :: + coder::array &totReflect, ::coder::array &totSimul) + { + int32_T loop_ub; + + // Calculates the avereaged reflectivity for domains samples (incoherent + // sum) + if (reflect1.size(0) == reflect2.size(0)) { + totReflect.set_size(reflect1.size(0), 2); + loop_ub = reflect1.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + totReflect[i] = reflect1[i]; + } + + loop_ub = reflect1.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + totReflect[i + totReflect.size(0)] = domainRatio * reflect1[i + + reflect1.size(0)] + (1.0 - domainRatio) * reflect2[i + reflect2.size + (0)]; + } + } else { + binary_expand_op(totReflect, reflect1, domainRatio, reflect2); + } + + if (simul1.size(0) == simul2.size(0)) { + totSimul.set_size(simul1.size(0), 2); + loop_ub = simul1.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + totSimul[i] = simul1[i]; + } + + loop_ub = simul1.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + totSimul[i + totSimul.size(0)] = domainRatio * simul1[i + simul1.size + (0)] + (1.0 - domainRatio) * simul2[i + simul2.size(0)]; + } + } else { + binary_expand_op(totSimul, simul1, domainRatio, simul2); + } + } + } +} + +// End of code generation (averageReflectivity.cpp) diff --git a/cpp/RAT/averageReflectivity.h b/cpp/RAT/averageReflectivity.h new file mode 100644 index 00000000..29d82d55 --- /dev/null +++ b/cpp/RAT/averageReflectivity.h @@ -0,0 +1,33 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// averageReflectivity.h +// +// Code generation for function 'averageReflectivity' +// +#ifndef AVERAGEREFLECTIVITY_H +#define AVERAGEREFLECTIVITY_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace domainsTF + { + void averageReflectivity(const ::coder::array &reflect1, const :: + coder::array &reflect2, const ::coder::array + &simul1, const ::coder::array &simul2, real_T domainRatio, :: + coder::array &totReflect, ::coder::array &totSimul); + } +} + +#endif + +// End of code generation (averageReflectivity.h) diff --git a/cpp/RAT/backSort.cpp b/cpp/RAT/backSort.cpp new file mode 100644 index 00000000..813bd48f --- /dev/null +++ b/cpp/RAT/backSort.cpp @@ -0,0 +1,89 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// backSort.cpp +// +// Code generation for function 'backSort' +// + +// Include files +#include "backSort.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void backSort(real_T contrastBackgrounds, real_T contrastQzshifts, real_T + contrastScalefactors, real_T contrastBulkIns, real_T + contrastBulkOuts, real_T contrastResolutions, const ::coder:: + array &backgroundParams, const ::coder::array &qzshifts, const ::coder::array &scalefactors, + const ::coder::array &bulkIn, const ::coder::array< + real_T, 2U> &bulkOut, const ::coder::array + &resolutionParams, real_T *outBackgroundParam, real_T + *outQzshift, real_T *outScalefactor, real_T *outBulkIn, real_T + *outBulkOut, real_T *outResolutionParam) + { + // Distributes the background and shift values among the different contrasts + // + // USAGE:: + // + // [backgroundParams,qzshift,scalefactor,bulkIn,bulkOut,resolutionParams] = backsort(contrastBackgrounds,contrastQzshifts,contrastScalefactors,contrastBulkIns,contrastBulkOuts,contrastResolutions,backs,qzshifts,scalefactor,bulkIn,bulkOut,res) + // + // INPUTS: + // * contrastBackgrounds: Which background value is associated with each contrast + // * contrastQzshifts: Which qz_shift value is associated with each contrast + // * contrastScalefactors: Which scalefactor value is associated with each contrast + // * contrastBulkIns: Which BulkIn value is associated with each contrast + // * contrastBulkOuts: Which BulkOut value is associated with each contrast + // * contrastResolutions: Which resolution value is associated with each contrast + // * backgroundParams: List of all background values. + // * qzshifts: List of all qzshift values + // * scalefactors: List of all scalefactor values + // * bulkIn: List of all bulkIn values + // * bulkOut: List of all bulkOut values + // * resolutionParams: List of all resolution values + // + // OUTPUTS: + // * outBackground: list of actual background values for each contrast + // * outQzshift: list of actual qzshift values for each contrast + // * outScalefactor: list of actual scalefactor values for each contrast + // * outBulkIn: list of actual bulkIn values for each contrast + // * outBulkOut: list of actual bulkOut values for each contrast + // * outResolution: list of actual resolution for each contrast + // for i = 1:nc + // thisBack = contrastBackgrounds(i); + *outBackgroundParam = backgroundParams[static_cast + (contrastBackgrounds) - 1]; + + // thisShift = contrastQzshifts(i); + *outQzshift = qzshifts[static_cast(contrastQzshifts) - 1]; + + // thisScale = contrastScalefactors(i); + *outScalefactor = scalefactors[static_cast(contrastScalefactors) - + 1]; + + // thisBulkIn = contrastBulkIns(i); + *outBulkIn = bulkIn[static_cast(contrastBulkIns) - 1]; + + // thisBulkOut = contrastBulkOuts(i); + *outBulkOut = bulkOut[static_cast(contrastBulkOuts) - 1]; + + // thisResol = contrastResolutions(i); + if (contrastResolutions != -1.0) { + *outResolutionParam = resolutionParams[static_cast + (contrastResolutions) - 1]; + } else { + *outResolutionParam = -1.0; + + // Negative value means we have a data resolution.. + } + + // end + } +} + +// End of code generation (backSort.cpp) diff --git a/cpp/RAT/backSort.h b/cpp/RAT/backSort.h new file mode 100644 index 00000000..3d03ba60 --- /dev/null +++ b/cpp/RAT/backSort.h @@ -0,0 +1,36 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// backSort.h +// +// Code generation for function 'backSort' +// +#ifndef BACKSORT_H +#define BACKSORT_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void backSort(real_T contrastBackgrounds, real_T contrastQzshifts, real_T + contrastScalefactors, real_T contrastBulkIns, real_T + contrastBulkOuts, real_T contrastResolutions, const ::coder:: + array &backgroundParams, const ::coder::array &qzshifts, const ::coder::array &scalefactors, + const ::coder::array &bulkIn, const ::coder::array< + real_T, 2U> &bulkOut, const ::coder::array + &resolutionParams, real_T *outBackgroundParam, real_T + *outQzshift, real_T *outScalefactor, real_T *outBulkIn, real_T + *outBulkOut, real_T *outResolutionParam); +} + +#endif + +// End of code generation (backSort.h) diff --git a/cpp/RAT/blockedSummation.cpp b/cpp/RAT/blockedSummation.cpp new file mode 100644 index 00000000..d161e65c --- /dev/null +++ b/cpp/RAT/blockedSummation.cpp @@ -0,0 +1,485 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// blockedSummation.cpp +// +// Code generation for function 'blockedSummation' +// + +// Include files +#include "blockedSummation.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Declarations +namespace RAT +{ + namespace coder + { + static real_T b_nestedIter(const ::coder::array &x, int32_T vlen); + static void nestedIter(const ::coder::array &x, int32_T vlen, :: + coder::array &y); + } +} + +// Function Definitions +namespace RAT +{ + namespace coder + { + static real_T b_nestedIter(const ::coder::array &x, int32_T vlen) + { + real_T y; + int32_T firstBlockLength; + int32_T lastBlockLength; + int32_T nblocks; + if (vlen <= 1024) { + firstBlockLength = vlen; + lastBlockLength = 0; + nblocks = 1; + } else { + firstBlockLength = 1024; + nblocks = vlen / 1024; + lastBlockLength = vlen - (nblocks << 10); + if (lastBlockLength > 0) { + nblocks++; + } else { + lastBlockLength = 1024; + } + } + + y = x[0]; + for (int32_T k{2}; k <= firstBlockLength; k++) { + if (vlen >= 2) { + y += x[k - 1]; + } + } + + for (int32_T ib{2}; ib <= nblocks; ib++) { + real_T bsum; + int32_T hi; + firstBlockLength = (ib - 1) << 10; + bsum = x[firstBlockLength]; + if (ib == nblocks) { + hi = lastBlockLength; + } else { + hi = 1024; + } + + for (int32_T k{2}; k <= hi; k++) { + if (vlen >= 2) { + bsum += x[(firstBlockLength + k) - 1]; + } + } + + y += bsum; + } + + return y; + } + + static void nestedIter(const ::coder::array &x, int32_T vlen, :: + coder::array &y) + { + ::coder::array bsum; + int32_T bsubs_idx_1; + int32_T firstBlockLength; + int32_T i; + int32_T lastBlockLength; + int32_T nblocks; + y.set_size(x.size(0)); + bsum.set_size(x.size(0)); + if (vlen <= 1024) { + firstBlockLength = vlen; + lastBlockLength = 0; + nblocks = 1; + } else { + firstBlockLength = 1024; + nblocks = vlen / 1024; + lastBlockLength = vlen - (nblocks << 10); + if (lastBlockLength > 0) { + nblocks++; + } else { + lastBlockLength = 1024; + } + } + + i = x.size(0); + for (int32_T k{0}; k < i; k++) { + y[k] = x[k]; + } + + for (int32_T k{2}; k <= firstBlockLength; k++) { + i = x.size(0); + for (int32_T b_k{0}; b_k < i; b_k++) { + if (vlen >= 2) { + y[b_k] = y[b_k] + x[b_k + x.size(0) * (k - 1)]; + } + } + } + + for (int32_T ib{2}; ib <= nblocks; ib++) { + int32_T hi; + firstBlockLength = (ib - 1) << 10; + i = x.size(0); + if (x.size(0) - 1 >= 0) { + bsubs_idx_1 = firstBlockLength + 1; + } + + for (int32_T k{0}; k < i; k++) { + bsum[k] = x[k + x.size(0) * (bsubs_idx_1 - 1)]; + } + + if (ib == nblocks) { + hi = lastBlockLength; + } else { + hi = 1024; + } + + for (int32_T k{2}; k <= hi; k++) { + int32_T varargin_1; + varargin_1 = firstBlockLength + k; + i = x.size(0); + for (int32_T b_k{0}; b_k < i; b_k++) { + if (vlen >= 2) { + bsum[b_k] = bsum[b_k] + x[b_k + x.size(0) * (varargin_1 - 1)]; + } + } + } + + i = y.size(0); + for (int32_T k{0}; k < i; k++) { + y[k] = y[k] + bsum[k]; + } + } + } + + real_T blockedSummation(const ::coder::array &x, int32_T vlen) + { + real_T y; + if ((x.size(1) == 0) || (vlen == 0)) { + y = 0.0; + } else { + y = b_nestedIter(x, vlen); + } + + return y; + } + + void blockedSummation(const ::coder::array &x, int32_T vlen, :: + coder::array &y) + { + if ((x.size(0) == 0) || (x.size(1) == 0) || (vlen == 0)) { + int32_T loop_ub; + y.set_size(1, x.size(1)); + loop_ub = x.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + y[i] = 0.0; + } + } else { + nestedIter(x, vlen, y); + } + } + + void blockedSummation(const ::coder::array &x, int32_T vlen, :: + coder::array &y) + { + if ((x.size(0) == 0) || (x.size(1) == 0) || (vlen == 0)) { + int32_T loop_ub; + y.set_size(x.size(0)); + loop_ub = x.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + y[i] = 0.0; + } + } else { + nestedIter(x, vlen, y); + } + } + + creal_T nestedIter(const ::coder::array &x, int32_T vlen) + { + creal_T y; + int32_T firstBlockLength; + int32_T lastBlockLength; + int32_T nblocks; + if (vlen <= 1024) { + firstBlockLength = vlen; + lastBlockLength = 0; + nblocks = 1; + } else { + firstBlockLength = 1024; + nblocks = vlen / 1024; + lastBlockLength = vlen - (nblocks << 10); + if (lastBlockLength > 0) { + nblocks++; + } else { + lastBlockLength = 1024; + } + } + + y = x[0]; + for (int32_T k{2}; k <= firstBlockLength; k++) { + if (vlen >= 2) { + y.re += x[k - 1].re; + y.im += x[k - 1].im; + } + } + + for (int32_T ib{2}; ib <= nblocks; ib++) { + real_T xk_im; + real_T xk_re; + int32_T hi; + firstBlockLength = (ib - 1) << 10; + xk_re = x[firstBlockLength].re; + xk_im = x[firstBlockLength].im; + if (ib == nblocks) { + hi = lastBlockLength; + } else { + hi = 1024; + } + + for (int32_T k{2}; k <= hi; k++) { + if (vlen >= 2) { + int32_T xk_re_tmp; + xk_re_tmp = (firstBlockLength + k) - 1; + xk_re += x[xk_re_tmp].re; + xk_im += x[xk_re_tmp].im; + } + } + + y.re += xk_re; + y.im += xk_im; + } + + return y; + } + + real_T nestedIter(const ::coder::array &x, int32_T vlen) + { + real_T y; + int32_T firstBlockLength; + int32_T lastBlockLength; + int32_T nblocks; + if (vlen <= 1024) { + firstBlockLength = vlen; + lastBlockLength = 0; + nblocks = 1; + } else { + firstBlockLength = 1024; + nblocks = vlen / 1024; + lastBlockLength = vlen - (nblocks << 10); + if (lastBlockLength > 0) { + nblocks++; + } else { + lastBlockLength = 1024; + } + } + + y = x[0]; + for (int32_T k{2}; k <= firstBlockLength; k++) { + if (vlen >= 2) { + y += x[k - 1]; + } + } + + for (int32_T ib{2}; ib <= nblocks; ib++) { + real_T bsum; + int32_T hi; + firstBlockLength = (ib - 1) << 10; + bsum = x[firstBlockLength]; + if (ib == nblocks) { + hi = lastBlockLength; + } else { + hi = 1024; + } + + for (int32_T k{2}; k <= hi; k++) { + if (vlen >= 2) { + bsum += x[(firstBlockLength + k) - 1]; + } + } + + y += bsum; + } + + return y; + } + + void nestedIter(const ::coder::array &x, int32_T vlen, ::coder:: + array &y) + { + int32_T firstBlockLength; + int32_T i; + int32_T i1; + int32_T lastBlockLength; + int32_T nblocks; + y.set_size(1, x.size(1), x.size(2)); + i = x.size(2); + if (x.size(2) - 1 >= 0) { + i1 = x.size(1); + if (x.size(1) - 1 >= 0) { + if (vlen <= 1024) { + firstBlockLength = vlen; + lastBlockLength = 0; + nblocks = 1; + } else { + firstBlockLength = 1024; + nblocks = vlen / 1024; + lastBlockLength = vlen - (nblocks << 10); + if (lastBlockLength > 0) { + nblocks++; + } else { + lastBlockLength = 1024; + } + } + } + } + + for (int32_T k{0}; k < i; k++) { + for (int32_T b_k{0}; b_k < i1; b_k++) { + y[b_k + y.size(1) * k] = x[x.size(0) * b_k + x.size(0) * x.size(1) * k]; + for (int32_T c_k{2}; c_k <= firstBlockLength; c_k++) { + if (vlen >= 2) { + y[b_k + y.size(1) * k] = y[b_k + y.size(1) * k] + x[((c_k + x.size + (0) * b_k) + x.size(0) * x.size(1) * k) - 1]; + } + } + + for (int32_T ib{2}; ib <= nblocks; ib++) { + real_T bsum; + int32_T hi; + int32_T offset; + offset = (ib - 1) << 10; + bsum = x[(offset + x.size(0) * b_k) + x.size(0) * x.size(1) * k]; + if (ib == nblocks) { + hi = lastBlockLength; + } else { + hi = 1024; + } + + for (int32_T c_k{2}; c_k <= hi; c_k++) { + if (vlen >= 2) { + bsum += x[(((offset + c_k) + x.size(0) * b_k) + x.size(0) * + x.size(1) * k) - 1]; + } + } + + y[b_k + y.size(1) * k] = y[b_k + y.size(1) * k] + bsum; + } + } + } + } + + void nestedIter(const ::coder::array &x, int32_T vlen, ::coder:: + array &y) + { + int32_T firstBlockLength; + int32_T i; + int32_T lastBlockLength; + int32_T nblocks; + y.set_size(1, x.size(1)); + i = x.size(1); + if (x.size(1) - 1 >= 0) { + if (vlen <= 1024) { + firstBlockLength = vlen; + lastBlockLength = 0; + nblocks = 1; + } else { + firstBlockLength = 1024; + nblocks = vlen / 1024; + lastBlockLength = vlen - (nblocks << 10); + if (lastBlockLength > 0) { + nblocks++; + } else { + lastBlockLength = 1024; + } + } + } + + for (int32_T k{0}; k < i; k++) { + y[k] = x[x.size(0) * k]; + for (int32_T b_k{2}; b_k <= firstBlockLength; b_k++) { + if (vlen >= 2) { + y[k] = y[k] + x[(b_k + x.size(0) * k) - 1]; + } + } + + for (int32_T ib{2}; ib <= nblocks; ib++) { + real_T bsum; + int32_T hi; + int32_T offset; + offset = (ib - 1) << 10; + bsum = x[offset + x.size(0) * k]; + if (ib == nblocks) { + hi = lastBlockLength; + } else { + hi = 1024; + } + + for (int32_T b_k{2}; b_k <= hi; b_k++) { + if (vlen >= 2) { + bsum += x[((offset + b_k) + x.size(0) * k) - 1]; + } + } + + y[k] = y[k] + bsum; + } + } + } + + real_T nestedIter(const ::coder::array &x, int32_T vlen) + { + real_T y; + int32_T firstBlockLength; + int32_T lastBlockLength; + int32_T nblocks; + if (vlen <= 1024) { + firstBlockLength = vlen; + lastBlockLength = 0; + nblocks = 1; + } else { + firstBlockLength = 1024; + nblocks = vlen / 1024; + lastBlockLength = vlen - (nblocks << 10); + if (lastBlockLength > 0) { + nblocks++; + } else { + lastBlockLength = 1024; + } + } + + y = x[0]; + for (int32_T k{2}; k <= firstBlockLength; k++) { + if (vlen >= 2) { + y += x[k - 1]; + } + } + + for (int32_T ib{2}; ib <= nblocks; ib++) { + real_T bsum; + int32_T hi; + firstBlockLength = (ib - 1) << 10; + bsum = x[firstBlockLength]; + if (ib == nblocks) { + hi = lastBlockLength; + } else { + hi = 1024; + } + + for (int32_T k{2}; k <= hi; k++) { + if (vlen >= 2) { + bsum += x[(firstBlockLength + k) - 1]; + } + } + + y += bsum; + } + + return y; + } + } +} + +// End of code generation (blockedSummation.cpp) diff --git a/cpp/RAT/blockedSummation.h b/cpp/RAT/blockedSummation.h new file mode 100644 index 00000000..90942c08 --- /dev/null +++ b/cpp/RAT/blockedSummation.h @@ -0,0 +1,41 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// blockedSummation.h +// +// Code generation for function 'blockedSummation' +// +#ifndef BLOCKEDSUMMATION_H +#define BLOCKEDSUMMATION_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + real_T blockedSummation(const ::coder::array &x, int32_T vlen); + void blockedSummation(const ::coder::array &x, int32_T vlen, :: + coder::array &y); + void blockedSummation(const ::coder::array &x, int32_T vlen, :: + coder::array &y); + creal_T nestedIter(const ::coder::array &x, int32_T vlen); + real_T nestedIter(const ::coder::array &x, int32_T vlen); + void nestedIter(const ::coder::array &x, int32_T vlen, ::coder:: + array &y); + void nestedIter(const ::coder::array &x, int32_T vlen, ::coder:: + array &y); + real_T nestedIter(const ::coder::array &x, int32_T vlen); + } +} + +#endif + +// End of code generation (blockedSummation.h) diff --git a/cpp/RAT/boundaryHandling.cpp b/cpp/RAT/boundaryHandling.cpp new file mode 100644 index 00000000..00ee09fe --- /dev/null +++ b/cpp/RAT/boundaryHandling.cpp @@ -0,0 +1,282 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// boundaryHandling.cpp +// +// Code generation for function 'boundaryHandling' +// + +// Include files +#include "boundaryHandling.h" +#include "find.h" +#include "rand.h" +#include "repmat.h" +#include "rt_nonfinite.h" +#include "strcmp.h" +#include "coder_array.h" + +// Function Declarations +namespace RAT +{ + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3, const :: + coder::array &in4, const ::coder::array &in5); +} + +// Function Definitions +namespace RAT +{ + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3, const :: + coder::array &in4, const ::coder::array &in5) + { + int32_T i; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_1_0; + int32_T stride_2_0; + stride_0_0 = (in2.size(0) != 1); + stride_1_0 = (in4.size(0) != 1); + stride_2_0 = (in2.size(0) != 1); + if (in2.size(0) == 1) { + i = in4.size(0); + } else { + i = in2.size(0); + } + + if (i == 1) { + loop_ub = in2.size(0); + } else if (in2.size(0) == 1) { + loop_ub = in4.size(0); + } else { + loop_ub = in2.size(0); + } + + for (i = 0; i < loop_ub; i++) { + int32_T i1; + i1 = in2[i * stride_2_0] - 1; + in1[in2[i] - 1] = in3[in2[i * stride_0_0] - 1] + in4[i * stride_1_0] * + (in5[i1] - in3[i1]); + } + } + + void boundaryHandling(::coder::array &x, const ::coder::array< + real_T, 2U> &Par_info_min, const ::coder::array &Par_info_max, const char_T + Par_info_boundhandling_data[], const int32_T + Par_info_boundhandling_size[2]) + { + ::coder::array max_d; + ::coder::array min_d; + ::coder::array b_max_d; + ::coder::array ii_low; + ::coder::array ii_up; + ::coder::array b_x; + real_T b_ii_low[2]; + int32_T b_loop_ub; + int32_T i; + int32_T loop_ub; + + // Function to check whether parameter values remain within prior bounds + // First determine the size of new + // Now replicate min and max + coder::repmat(Par_info_min, static_cast(x.size(0)), min_d); + coder::repmat(Par_info_max, static_cast(x.size(0)), max_d); + + // Now find which elements of x are smaller than their respective bound + if ((x.size(0) == min_d.size(0)) && (x.size(1) == min_d.size(1))) { + b_x.set_size(x.size(0), x.size(1)); + loop_ub = x.size(1); + for (i = 0; i < loop_ub; i++) { + b_loop_ub = x.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + b_x[i1 + b_x.size(0) * i] = (x[i1 + x.size(0) * i] < min_d[i1 + + min_d.size(0) * i]); + } + } + + coder::c_eml_find(b_x, ii_up); + } else { + c_binary_expand_op(ii_up, x, min_d); + } + + ii_low.set_size(ii_up.size(0)); + loop_ub = ii_up.size(0); + for (i = 0; i < loop_ub; i++) { + ii_low[i] = ii_up[i]; + } + + // Now find which elements of x are larger than their respective bound + if ((x.size(0) == max_d.size(0)) && (x.size(1) == max_d.size(1))) { + b_x.set_size(x.size(0), x.size(1)); + loop_ub = x.size(1); + for (i = 0; i < loop_ub; i++) { + b_loop_ub = x.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + b_x[i1 + b_x.size(0) * i] = (x[i1 + x.size(0) * i] > max_d[i1 + + max_d.size(0) * i]); + } + } + + coder::c_eml_find(b_x, ii_up); + } else { + binary_expand_op(ii_up, x, max_d); + } + + // Reflection + if (coder::internal::y_strcmp(Par_info_boundhandling_data, + Par_info_boundhandling_size)) { + // reflect in min + b_max_d.set_size(ii_low.size(0)); + loop_ub = ii_low.size(0); + for (i = 0; i < loop_ub; i++) { + b_max_d[i] = 2.0 * min_d[ii_low[i] - 1] - x[ii_low[i] - 1]; + } + + loop_ub = b_max_d.size(0); + for (i = 0; i < loop_ub; i++) { + x[ii_low[i] - 1] = b_max_d[i]; + } + + // reflect in max + b_max_d.set_size(ii_up.size(0)); + loop_ub = ii_up.size(0); + for (i = 0; i < loop_ub; i++) { + b_max_d[i] = 2.0 * max_d[ii_up[i] - 1] - x[ii_up[i] - 1]; + } + + loop_ub = b_max_d.size(0); + for (i = 0; i < loop_ub; i++) { + x[ii_up[i] - 1] = b_max_d[i]; + } + } + + // Bound + if (coder::internal::ab_strcmp(Par_info_boundhandling_data, + Par_info_boundhandling_size)) { + // set lower values to min + loop_ub = ii_low.size(0); + for (i = 0; i < loop_ub; i++) { + x[ii_low[i] - 1] = min_d[ii_low[i] - 1]; + } + + // set upper values to max + loop_ub = ii_up.size(0); + for (i = 0; i < loop_ub; i++) { + x[ii_up[i] - 1] = max_d[ii_up[i] - 1]; + } + } + + // Folding + if (coder::internal::bb_strcmp(Par_info_boundhandling_data, + Par_info_boundhandling_size)) { + // Fold parameter space lower values + b_max_d.set_size(ii_low.size(0)); + loop_ub = ii_low.size(0); + for (i = 0; i < loop_ub; i++) { + b_max_d[i] = max_d[ii_low[i] - 1] - (min_d[ii_low[i] - 1] - x[ii_low[i] + - 1]); + } + + loop_ub = b_max_d.size(0); + for (i = 0; i < loop_ub; i++) { + x[ii_low[i] - 1] = b_max_d[i]; + } + + // Fold parameter space upper values + b_max_d.set_size(ii_up.size(0)); + loop_ub = ii_up.size(0); + for (i = 0; i < loop_ub; i++) { + b_max_d[i] = min_d[ii_up[i] - 1] + (x[ii_up[i] - 1] - max_d[ii_up[i] - 1]); + } + + loop_ub = b_max_d.size(0); + for (i = 0; i < loop_ub; i++) { + x[ii_up[i] - 1] = b_max_d[i]; + } + } + + // Now double check in case elements are still out of bound -- this is + // theoretically possible if values are very small or large + // Now double check if all elements are within bounds + if ((x.size(0) == min_d.size(0)) && (x.size(1) == min_d.size(1))) { + b_x.set_size(x.size(0), x.size(1)); + loop_ub = x.size(1); + for (i = 0; i < loop_ub; i++) { + b_loop_ub = x.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + b_x[i1 + b_x.size(0) * i] = (x[i1 + x.size(0) * i] < min_d[i1 + + min_d.size(0) * i]); + } + } + + coder::c_eml_find(b_x, ii_up); + } else { + c_binary_expand_op(ii_up, x, min_d); + } + + ii_low.set_size(ii_up.size(0)); + loop_ub = ii_up.size(0); + for (i = 0; i < loop_ub; i++) { + ii_low[i] = ii_up[i]; + } + + b_ii_low[0] = ii_low.size(0); + b_ii_low[1] = 1.0; + coder::b_rand(b_ii_low, b_max_d); + if (b_max_d.size(0) == 1) { + i = ii_low.size(0); + } else { + i = b_max_d.size(0); + } + + if ((b_max_d.size(0) == ii_low.size(0)) && (ii_low.size(0) == i)) { + loop_ub = ii_low.size(0); + for (i = 0; i < loop_ub; i++) { + x[ii_low[i] - 1] = min_d[ii_low[i] - 1] + b_max_d[i] * (max_d[ii_low[i] + - 1] - min_d[ii_low[i] - 1]); + } + } else { + binary_expand_op(x, ii_low, min_d, b_max_d, max_d); + } + + if ((x.size(0) == max_d.size(0)) && (x.size(1) == max_d.size(1))) { + b_x.set_size(x.size(0), x.size(1)); + loop_ub = x.size(1); + for (i = 0; i < loop_ub; i++) { + b_loop_ub = x.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + b_x[i1 + b_x.size(0) * i] = (x[i1 + x.size(0) * i] > max_d[i1 + + max_d.size(0) * i]); + } + } + + coder::c_eml_find(b_x, ii_up); + } else { + binary_expand_op(ii_up, x, max_d); + } + + b_ii_low[0] = ii_up.size(0); + b_ii_low[1] = 1.0; + coder::b_rand(b_ii_low, b_max_d); + if (b_max_d.size(0) == 1) { + i = ii_up.size(0); + } else { + i = b_max_d.size(0); + } + + if ((b_max_d.size(0) == ii_up.size(0)) && (ii_up.size(0) == i)) { + loop_ub = ii_up.size(0); + for (i = 0; i < loop_ub; i++) { + x[ii_up[i] - 1] = min_d[ii_up[i] - 1] + b_max_d[i] * (max_d[ii_up[i] - 1] + - min_d[ii_up[i] - 1]); + } + } else { + binary_expand_op(x, ii_up, min_d, b_max_d, max_d); + } + } +} + +// End of code generation (boundaryHandling.cpp) diff --git a/cpp/RAT/boundaryHandling.h b/cpp/RAT/boundaryHandling.h new file mode 100644 index 00000000..91869c69 --- /dev/null +++ b/cpp/RAT/boundaryHandling.h @@ -0,0 +1,31 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// boundaryHandling.h +// +// Code generation for function 'boundaryHandling' +// +#ifndef BOUNDARYHANDLING_H +#define BOUNDARYHANDLING_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void boundaryHandling(::coder::array &x, const ::coder::array< + real_T, 2U> &Par_info_min, const ::coder::array &Par_info_max, const char_T + Par_info_boundhandling_data[], const int32_T + Par_info_boundhandling_size[2]); +} + +#endif + +// End of code generation (boundaryHandling.h) diff --git a/cpp/RAT/bsearch.cpp b/cpp/RAT/bsearch.cpp new file mode 100644 index 00000000..55e620a4 --- /dev/null +++ b/cpp/RAT/bsearch.cpp @@ -0,0 +1,89 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// bsearch.cpp +// +// Code generation for function 'bsearch' +// + +// Include files +#include "bsearch.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + int32_T b_bsearch(const real_T x_data[], real_T xi) + { + int32_T high_i; + int32_T low_ip1; + int32_T n; + n = 1; + low_ip1 = 2; + high_i = 4; + while (high_i > low_ip1) { + int32_T mid_i; + mid_i = (n >> 1) + (high_i >> 1); + if (((n & 1) == 1) && ((high_i & 1) == 1)) { + mid_i++; + } + + if (xi >= x_data[mid_i - 1]) { + n = mid_i; + low_ip1 = mid_i + 1; + } else { + high_i = mid_i; + } + } + + return n; + } + + int32_T b_bsearch(const ::coder::array &x, real_T xi) + { + int32_T high_i; + int32_T low_ip1; + int32_T n; + high_i = x.size(0); + n = 1; + low_ip1 = 2; + while (high_i > low_ip1) { + int32_T mid_i; + mid_i = (n >> 1) + (high_i >> 1); + if (((n & 1) == 1) && ((high_i & 1) == 1)) { + mid_i++; + } + + if (xi >= x[mid_i - 1]) { + n = mid_i; + low_ip1 = mid_i + 1; + } else { + high_i = mid_i; + } + } + + return n; + } + + int32_T c_bsearch(const real_T x[3], real_T xi) + { + int32_T n; + n = 1; + if (xi >= x[1]) { + n = 2; + } + + return n; + } + } + } +} + +// End of code generation (bsearch.cpp) diff --git a/cpp/RAT/bsearch.h b/cpp/RAT/bsearch.h new file mode 100644 index 00000000..37316d8e --- /dev/null +++ b/cpp/RAT/bsearch.h @@ -0,0 +1,35 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// bsearch.h +// +// Code generation for function 'bsearch' +// +#ifndef BSEARCH_H +#define BSEARCH_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + int32_T b_bsearch(const real_T x_data[], real_T xi); + int32_T b_bsearch(const ::coder::array &x, real_T xi); + int32_T c_bsearch(const real_T x[3], real_T xi); + } + } +} + +#endif + +// End of code generation (bsearch.h) diff --git a/cpp/RAT/bsxfun.cpp b/cpp/RAT/bsxfun.cpp new file mode 100644 index 00000000..f42b9d9c --- /dev/null +++ b/cpp/RAT/bsxfun.cpp @@ -0,0 +1,372 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// bsxfun.cpp +// +// Code generation for function 'bsxfun' +// + +// Include files +#include "bsxfun.h" +#include "rescale.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + void b_bsxfun(const ::coder::array &a, const ::coder::array< + real_T, 1U> &b, ::coder::array &c) + { + int32_T acoef; + int32_T csz_idx_0; + int32_T u0; + u0 = b.size(0); + acoef = a.size(0); + if (u0 <= acoef) { + acoef = u0; + } + + if (b.size(0) == 1) { + csz_idx_0 = a.size(0); + } else if (a.size(0) == 1) { + csz_idx_0 = b.size(0); + } else if (a.size(0) == b.size(0)) { + csz_idx_0 = a.size(0); + } else { + csz_idx_0 = acoef; + } + + u0 = b.size(0); + acoef = a.size(0); + if (u0 <= acoef) { + acoef = u0; + } + + if (b.size(0) == 1) { + acoef = a.size(0); + } else if (a.size(0) == 1) { + acoef = b.size(0); + } else if (a.size(0) == b.size(0)) { + acoef = a.size(0); + } + + c.set_size(acoef); + if (csz_idx_0 != 0) { + int32_T bcoef; + acoef = (a.size(0) != 1); + bcoef = (b.size(0) != 1); + u0 = csz_idx_0 - 1; + for (csz_idx_0 = 0; csz_idx_0 <= u0; csz_idx_0++) { + c[csz_idx_0] = rescale_anonFcn2(a[acoef * csz_idx_0], b[bcoef * + csz_idx_0]); + } + } + } + + void b_bsxfun(const ::coder::array &a, ::coder::array + &c) + { + c.set_size(a.size(0)); + if (a.size(0) != 0) { + int32_T acoef; + int32_T i; + acoef = (a.size(0) != 1); + i = a.size(0) - 1; + for (int32_T k{0}; k <= i; k++) { + real_T x; + x = a[acoef * k]; + if ((!std::isnan(x)) && (x < 0.0)) { + c[k] = 0.0; + } else { + c[k] = x; + } + } + } + } + + void bsxfun(const ::coder::array &a, const ::coder::array &b, ::coder::array &c) + { + int32_T acoef; + int32_T csz_idx_0; + int32_T u0; + u0 = b.size(0); + acoef = a.size(0); + if (u0 <= acoef) { + acoef = u0; + } + + if (b.size(0) == 1) { + csz_idx_0 = a.size(0); + } else if (a.size(0) == 1) { + csz_idx_0 = b.size(0); + } else if (a.size(0) == b.size(0)) { + csz_idx_0 = a.size(0); + } else { + csz_idx_0 = acoef; + } + + u0 = b.size(0); + acoef = a.size(0); + if (u0 <= acoef) { + acoef = u0; + } + + if (b.size(0) == 1) { + acoef = a.size(0); + } else if (a.size(0) == 1) { + acoef = b.size(0); + } else if (a.size(0) == b.size(0)) { + acoef = a.size(0); + } + + c.set_size(acoef); + if (csz_idx_0 != 0) { + int32_T bcoef; + acoef = (a.size(0) != 1); + bcoef = (b.size(0) != 1); + u0 = csz_idx_0 - 1; + for (csz_idx_0 = 0; csz_idx_0 <= u0; csz_idx_0++) { + c[csz_idx_0] = rescale_anonFcn1(a[acoef * csz_idx_0], b[bcoef * + csz_idx_0]); + } + } + } + + void bsxfun(const ::coder::array &a, ::coder::array + &c) + { + c.set_size(a.size(0)); + if (a.size(0) != 0) { + int32_T acoef; + int32_T i; + acoef = (a.size(0) != 1); + i = a.size(0) - 1; + for (int32_T k{0}; k <= i; k++) { + c[k] = a[acoef * k]; + } + } + } + + void c_bsxfun(const ::coder::array &a, const ::coder::array< + real_T, 1U> &b, ::coder::array &c) + { + int32_T acoef; + int32_T csz_idx_0; + int32_T u0; + u0 = b.size(0); + acoef = a.size(0); + if (u0 <= acoef) { + acoef = u0; + } + + if (b.size(0) == 1) { + csz_idx_0 = a.size(0); + } else if (a.size(0) == 1) { + csz_idx_0 = b.size(0); + } else if (a.size(0) == b.size(0)) { + csz_idx_0 = a.size(0); + } else { + csz_idx_0 = acoef; + } + + u0 = b.size(0); + acoef = a.size(0); + if (u0 <= acoef) { + acoef = u0; + } + + if (b.size(0) == 1) { + acoef = a.size(0); + } else if (a.size(0) == 1) { + acoef = b.size(0); + } else if (a.size(0) == b.size(0)) { + acoef = a.size(0); + } + + c.set_size(acoef); + if (csz_idx_0 != 0) { + int32_T bcoef; + acoef = (a.size(0) != 1); + bcoef = (b.size(0) != 1); + u0 = csz_idx_0 - 1; + for (csz_idx_0 = 0; csz_idx_0 <= u0; csz_idx_0++) { + c[csz_idx_0] = std::fmax(a[acoef * csz_idx_0], b[bcoef * csz_idx_0]); + } + } + } + + void c_bsxfun(const ::coder::array &a, ::coder::array + &c) + { + c.set_size(a.size(0)); + if (a.size(0) != 0) { + int32_T acoef; + int32_T i; + acoef = (a.size(0) != 1); + i = a.size(0) - 1; + for (int32_T k{0}; k <= i; k++) { + real_T x; + x = a[acoef * k]; + if ((!std::isnan(x)) && (x > 1.0)) { + c[k] = 1.0; + } else { + c[k] = x; + } + } + } + } + + void d_bsxfun(const ::coder::array &a, const ::coder::array< + real_T, 1U> &b, ::coder::array &c) + { + int32_T acoef; + int32_T csz_idx_0; + int32_T u0; + u0 = b.size(0); + acoef = a.size(0); + if (u0 <= acoef) { + acoef = u0; + } + + if (b.size(0) == 1) { + csz_idx_0 = a.size(0); + } else if (a.size(0) == 1) { + csz_idx_0 = b.size(0); + } else if (a.size(0) == b.size(0)) { + csz_idx_0 = a.size(0); + } else { + csz_idx_0 = acoef; + } + + u0 = b.size(0); + acoef = a.size(0); + if (u0 <= acoef) { + acoef = u0; + } + + if (b.size(0) == 1) { + acoef = a.size(0); + } else if (a.size(0) == 1) { + acoef = b.size(0); + } else if (a.size(0) == b.size(0)) { + acoef = a.size(0); + } + + c.set_size(acoef); + if (csz_idx_0 != 0) { + int32_T bcoef; + acoef = (a.size(0) != 1); + bcoef = (b.size(0) != 1); + u0 = csz_idx_0 - 1; + for (csz_idx_0 = 0; csz_idx_0 <= u0; csz_idx_0++) { + c[csz_idx_0] = a[acoef * csz_idx_0] - b[bcoef * csz_idx_0]; + } + } + } + + void e_bsxfun(const ::coder::array &a, const ::coder::array< + real_T, 1U> &b, ::coder::array &c) + { + int32_T acoef; + int32_T csz_idx_0; + int32_T u0; + u0 = b.size(0); + acoef = a.size(0); + if (u0 <= acoef) { + acoef = u0; + } + + if (b.size(0) == 1) { + csz_idx_0 = a.size(0); + } else if (a.size(0) == 1) { + csz_idx_0 = b.size(0); + } else if (a.size(0) == b.size(0)) { + csz_idx_0 = a.size(0); + } else { + csz_idx_0 = acoef; + } + + u0 = b.size(0); + acoef = a.size(0); + if (u0 <= acoef) { + acoef = u0; + } + + if (b.size(0) == 1) { + acoef = a.size(0); + } else if (a.size(0) == 1) { + acoef = b.size(0); + } else if (a.size(0) == b.size(0)) { + acoef = a.size(0); + } + + c.set_size(acoef); + if (csz_idx_0 != 0) { + int32_T bcoef; + acoef = (a.size(0) != 1); + bcoef = (b.size(0) != 1); + u0 = csz_idx_0 - 1; + for (csz_idx_0 = 0; csz_idx_0 <= u0; csz_idx_0++) { + c[csz_idx_0] = a[acoef * csz_idx_0] * b[bcoef * csz_idx_0]; + } + } + } + + void f_bsxfun(const ::coder::array &a, const ::coder::array< + real_T, 1U> &b, ::coder::array &c) + { + int32_T acoef; + int32_T csz_idx_0; + int32_T u0; + u0 = b.size(0); + acoef = a.size(0); + if (u0 <= acoef) { + acoef = u0; + } + + if (b.size(0) == 1) { + csz_idx_0 = a.size(0); + } else if (a.size(0) == 1) { + csz_idx_0 = b.size(0); + } else if (a.size(0) == b.size(0)) { + csz_idx_0 = a.size(0); + } else { + csz_idx_0 = acoef; + } + + u0 = b.size(0); + acoef = a.size(0); + if (u0 <= acoef) { + acoef = u0; + } + + if (b.size(0) == 1) { + acoef = a.size(0); + } else if (a.size(0) == 1) { + acoef = b.size(0); + } else if (a.size(0) == b.size(0)) { + acoef = a.size(0); + } + + c.set_size(acoef); + if (csz_idx_0 != 0) { + int32_T bcoef; + acoef = (a.size(0) != 1); + bcoef = (b.size(0) != 1); + u0 = csz_idx_0 - 1; + for (csz_idx_0 = 0; csz_idx_0 <= u0; csz_idx_0++) { + c[csz_idx_0] = a[acoef * csz_idx_0] + b[bcoef * csz_idx_0]; + } + } + } + } +} + +// End of code generation (bsxfun.cpp) diff --git a/cpp/RAT/bsxfun.h b/cpp/RAT/bsxfun.h new file mode 100644 index 00000000..5c9b7852 --- /dev/null +++ b/cpp/RAT/bsxfun.h @@ -0,0 +1,47 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// bsxfun.h +// +// Code generation for function 'bsxfun' +// +#ifndef BSXFUN_H +#define BSXFUN_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void b_bsxfun(const ::coder::array &a, const ::coder::array< + real_T, 1U> &b, ::coder::array &c); + void b_bsxfun(const ::coder::array &a, ::coder::array + &c); + void bsxfun(const ::coder::array &a, const ::coder::array &b, ::coder::array &c); + void bsxfun(const ::coder::array &a, ::coder::array + &c); + void c_bsxfun(const ::coder::array &a, const ::coder::array< + real_T, 1U> &b, ::coder::array &c); + void c_bsxfun(const ::coder::array &a, ::coder::array + &c); + void d_bsxfun(const ::coder::array &a, const ::coder::array< + real_T, 1U> &b, ::coder::array &c); + void e_bsxfun(const ::coder::array &a, const ::coder::array< + real_T, 1U> &b, ::coder::array &c); + void f_bsxfun(const ::coder::array &a, const ::coder::array< + real_T, 1U> &b, ::coder::array &c); + } +} + +#endif + +// End of code generation (bsxfun.h) diff --git a/cpp/RAT/calcDensity.cpp b/cpp/RAT/calcDensity.cpp new file mode 100644 index 00000000..86985526 --- /dev/null +++ b/cpp/RAT/calcDensity.cpp @@ -0,0 +1,165 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// calcDensity.cpp +// +// Code generation for function 'calcDensity' +// + +// Include files +#include "calcDensity.h" +#include "RATMain_types.h" +#include "rt_nonfinite.h" +#include "scaledGaussPrior.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void calcDensity(const ::coder::array &x, const ::coder::array< + real_T, 2U> &fx, const struct13_T *DREAMPar, const ::coder:: + array &ratInputs_problemStruct_fitLimits, const :: + coder::array &ratInputs_priors, ::coder::array< + real_T, 1U> &log_L, ::coder::array &log_PR) + { + ::coder::array PR; + ::coder::array b_x; + int32_T i; + int32_T loop_ub; + int32_T loop_ub_tmp; + + // Now calculate the likelihood (not used) and log-likelihood (used) + // --------------------------------------- + // For RAT, all the calculations are of the mvnpdf type, so remove the + // other options. + // ------------------------------------ AVH + // % If number of measurements larger than 0 --> simulation + // if Meas_info.N > 0 + // + // % Initialize "res" (residual matrix) + // res = NaN(Meas_info.N,DREAMPar.N); + // + // % Loop over each model realization + // for ii = 1 : DREAMPar.N + // + // % We now calculate the error residual + // res(:,ii) = (Meas_info.Y(:) - fx(1:Meas_info.N,ii)); + // + // end + // + // else + // + // % Do nothing, fx is a density or log-density returned by the PDF handle + // + // end + // ----------------------- Calculate log-prior ---------------------------- + // No ABC --> regular priors (pdfs) + // if ~DREAMPar.ABC + // + // % Calculate the log-prior + // if isfield(Par_info,'prior_marginal') + // + // % Compute prior densities for each parameter in each sequence + // for qq = 1 : DREAMPar.d + // for zz = 1 : DREAMPar.N + // % Compute prior density of proposal + // PR(zz,qq) = max ( eval(char(strrep(Par_info.prior_marginal(qq),'rnd(','pdf(x(zz,qq),'))) , 1e-299 ); + // end + // end + // + // % Take the log of the densities and their sum + // log_PR = sum ( log ( PR ) , 2 ); + // + // elseif isfield(Par_info,'mvnpdf') + // RAT specific prior funtion (mvnpdf) + loop_ub_tmp = static_cast(DREAMPar->N); + PR.set_size(1, loop_ub_tmp); + for (i = 0; i < loop_ub_tmp; i++) { + PR[i] = 0.0; + } + + if (loop_ub_tmp - 1 >= 0) { + loop_ub = x.size(1); + } + + // Take log of any non-zero values.. + log_PR.set_size(loop_ub_tmp); + for (int32_T b_i{0}; b_i < loop_ub_tmp; b_i++) { + // Loop over all the chains.. + b_x.set_size(1, x.size(1)); + for (i = 0; i < loop_ub; i++) { + b_x[i] = x[b_i + x.size(0) * i]; + } + + PR[b_i] = scaledGaussPrior(b_x, ratInputs_problemStruct_fitLimits, + ratInputs_priors); + + // mvnpdf automatically goes over all pars + log_PR[b_i] = 0.0; + } + + i = PR.size(1); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T d; + d = PR[b_i]; + if (d != 0.0) { + log_PR[b_i] = d; + + // log(PR(i)); % Does it even need to be log? + } else { + // Otherwise keep the zero values + log_PR[b_i] = 0.0; + } + } + + // log_PR = sum(log_PR(:)); % Enforce column vector + // else + // No use of prior --> set log-prior to zero (no effect in Metropolis) + // log_PR = zeros ( DREAMPar.N , 1 ); + // + // end + // + // + // else + // + // Diagnostic Bayes --> if summary metric is defined as prior + // if isfield(DREAMPar,'prior_handle') + // + // Evaluate distance between observed and simulated summary metrics + // for ii = 1 : DREAMPar.N + // + // Calculate summary metrics for "fx" + // S_sim = DREAMPar.prior_handle ( fx(:,ii) ); + // + // Now calculate log-density (not a true log-density! - but does not matter) + // log_PR(ii,1) = max ( abs ( Meas_info.S(:) - S_sim(:) ) ); + // + // end + // + // Regular ABC with summary metrics as likelihood function + // else + // + // log_PR = zeros ( DREAMPar.N , 1 ); + // + // end + // + // end + // --------------------- End Calculate log-prior --------------------------- + // -------------------- Calculate log-likelihood --------------------------- + // Loop over each model realization and calculate log-likelihood of each fx + log_L.set_size(loop_ub_tmp); + for (i = 0; i < loop_ub_tmp; i++) { + log_L[i] = 0.0; + } + + for (int32_T ii{0}; ii < loop_ub_tmp; ii++) { + log_L[ii] = fx[ii]; + } + + // ------------------ End Calculate log-likelihood ------------------------- + } +} + +// End of code generation (calcDensity.cpp) diff --git a/cpp/RAT/calcDensity.h b/cpp/RAT/calcDensity.h new file mode 100644 index 00000000..ccfe4a62 --- /dev/null +++ b/cpp/RAT/calcDensity.h @@ -0,0 +1,37 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// calcDensity.h +// +// Code generation for function 'calcDensity' +// +#ifndef CALCDENSITY_H +#define CALCDENSITY_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct struct13_T; +} + +// Function Declarations +namespace RAT +{ + void calcDensity(const ::coder::array &x, const ::coder::array< + real_T, 2U> &fx, const struct13_T *DREAMPar, const ::coder:: + array &ratInputs_problemStruct_fitLimits, const :: + coder::array &ratInputs_priors, ::coder::array< + real_T, 1U> &log_L, ::coder::array &log_PR); +} + +#endif + +// End of code generation (calcDensity.h) diff --git a/cpp/RAT/calcEllipsoid.cpp b/cpp/RAT/calcEllipsoid.cpp new file mode 100644 index 00000000..5db84c27 --- /dev/null +++ b/cpp/RAT/calcEllipsoid.cpp @@ -0,0 +1,220 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// calcEllipsoid.cpp +// +// Code generation for function 'calcEllipsoid' +// + +// Include files +#include "calcEllipsoid.h" +#include "RATMain_data.h" +#include "RATMain_rtwutil.h" +#include "cov.h" +#include "det.h" +#include "eml_mtimes_helper.h" +#include "gamma.h" +#include "ifWhileCond.h" +#include "matrix_to_integer_power.h" +#include "mean.h" +#include "mrdivide_helper.h" +#include "mtimes.h" +#include "rcond.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include +#include + +// Function Definitions +namespace RAT +{ + void calcEllipsoid(const ::coder::array &u, real_T VS, ::coder:: + array &B, ::coder::array &mu, + real_T VE_data[], int32_T VE_size[2], real_T *flag) + { + ::coder::array C; + ::coder::array b_u; + ::coder::array r; + ::coder::array y; + ::coder::array c_y_data; + ::coder::array d_y_data; + real_T b; + real_T y_data; + int32_T y_size[2]; + int32_T b_flag; + boolean_T b_y_data; + + // + // calculate properties of ellipsoid given a set of points u + // + // Inputs: + // u: Nxndims array where N is the number point and ndims is the + // number of dimensions + // VS: minimum volume that the bounding ellipsoid should have + // + // Outputs: + // B: bounding matrix for ellipsoid including scale factor + // for mininimum volume + // mu: centroid + // VE: volume of ellipsoid + // flag: = 1 if number of points too small or bounding matrix + // has bad condition number; otherwise = 0 + // + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // default values + B.set_size(0, 0); + mu.set_size(0, 0); + VE_size[0] = 0; + VE_size[1] = 0; + b_flag = 0; + + // extract number of points and number of dimensions + // check that total number of points is large enough + if (static_cast(u.size(0)) < static_cast(u.size(1)) + 1U) + { + if (DEBUG != 0.0) { + printf("number of samples too small to calculate bounding matrix for ellipsoid\n"); + fflush(stdout); + } + + b_flag = 1; + } else { + real_T x; + + // constant factor for volume of ellipsoid + b = static_cast(u.size(1)) / 2.0 + 1.0; + coder::b_gamma(&b); + + // calculate covariance matrix and centroid + coder::cov(u, C); + coder::mean(u, mu); + + // check condition number of C (eps = 2.2204e-16) + x = coder::rcond(C); + if ((x < 2.2204460492503131E-16) || std::isnan(x)) { + if (DEBUG != 0.0) { + printf("bad condition number!\n"); + fflush(stdout); + } + + b_flag = 1; + } else { + real_T fB; + real_T fV_data; + int32_T b_loop_ub; + int32_T i; + int32_T loop_ub; + + // find scale factor for bounding ellipsoid E + fB = 0.0; + + // coder.varsize('fB'); + i = u.size(0); + loop_ub = u.size(1); + b_loop_ub = u.size(1); + for (int32_T b_i{0}; b_i < i; b_i++) { + int32_T c_loop_ub; + if (u.size(1) == mu.size(1)) { + b_u.set_size(1, u.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_u[b_u.size(0) * i1] = u[b_i + u.size(0) * i1] - mu[mu.size(0) * + i1]; + } + + coder::internal::mrdiv(b_u, C, r); + } else { + binary_expand_op(r, u, b_i, mu, C); + } + + if (u.size(1) == mu.size(1)) { + b_u.set_size(1, u.size(1)); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + b_u[b_u.size(0) * i1] = u[b_i + u.size(0) * i1] - mu[mu.size(0) * + i1]; + } + + coder::internal::blas::mtimes(r, b_u, (real_T *)&y_data, y_size); + } else { + binary_expand_op((real_T *)&y_data, y_size, r, u, b_i, mu); + } + + c_loop_ub = y_size[1]; + for (int32_T i1{0}; i1 < c_loop_ub; i1++) { + int32_T d_loop_ub; + d_loop_ub = y_size[0]; + for (int32_T i2{0}; i2 < d_loop_ub; i2++) { + b_y_data = (y_data > fB); + } + } + + c_y_data.set(&b_y_data, y_size[0], y_size[1]); + if (coder::internal::ifWhileCond(c_y_data)) { + fB = y_data; + } + } + + // calculate volume of bounding ellipsoid E + y.set_size(C.size(0), C.size(1)); + loop_ub = C.size(1); + for (i = 0; i < loop_ub; i++) { + b_loop_ub = C.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + y[i1 + y.size(0) * i] = fB * C[i1 + C.size(0) * i]; + } + } + + VE_size[0] = 1; + VE_size[1] = 1; + x = rt_powd_snf(3.1415926535897931, static_cast(u.size(1)) / 2.0) + / b * std::sqrt(coder::det(y)); + VE_data[0] = x; + + // expand volume of bounding ellipsoid to VS if necessary + fV_data = 1.0; + b_y_data = (x < VS); + d_y_data.set(&b_y_data, 1, 1); + if (coder::internal::ifWhileCond(d_y_data)) { + b = 2.0 / static_cast(u.size(1)); + if (std::floor(b) == b) { + x = VS / x; + coder::matrix_to_integer_power((const real_T *)&x, b, (real_T *) + &fV_data, y_size); + } + + VE_size[0] = 1; + VE_size[1] = 1; + VE_data[0] = VS; + } + + // scale C to get bounding matrix B + // Again emphasise the scalar for the inner mutiplication + // matlab error in compiled code..... + // + // Error using eml_mtimes_helper>dynamic_size_checks + // Inner dimensions must agree. Generated code for a general matrix multiplication at this call site. If this should have been a scalar times a variable-size matrix, the + // scalar input must be fixed-size. + // + // Error in eml_mtimes_helper (line 69) + // dynamic_size_checks(a, b, innerDimA, innerDimB); + // + // Error in calcEllipsoid (line 73) + // B = fV * fB * C; + x = fV_data * fB; + B.set_size(C.size(0), C.size(1)); + loop_ub = C.size(1); + for (i = 0; i < loop_ub; i++) { + b_loop_ub = C.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + B[i1 + B.size(0) * i] = x * C[i1 + C.size(0) * i]; + } + } + } + } + + *flag = b_flag; + } +} + +// End of code generation (calcEllipsoid.cpp) diff --git a/cpp/RAT/calcEllipsoid.h b/cpp/RAT/calcEllipsoid.h new file mode 100644 index 00000000..4a95dce5 --- /dev/null +++ b/cpp/RAT/calcEllipsoid.h @@ -0,0 +1,29 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// calcEllipsoid.h +// +// Code generation for function 'calcEllipsoid' +// +#ifndef CALCELLIPSOID_H +#define CALCELLIPSOID_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void calcEllipsoid(const ::coder::array &u, real_T VS, ::coder:: + array &B, ::coder::array &mu, + real_T VE_data[], int32_T VE_size[2], real_T *flag); +} + +#endif + +// End of code generation (calcEllipsoid.h) diff --git a/cpp/RAT/calcProposal.cpp b/cpp/RAT/calcProposal.cpp new file mode 100644 index 00000000..025b107c --- /dev/null +++ b/cpp/RAT/calcProposal.cpp @@ -0,0 +1,580 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// calcProposal.cpp +// +// Code generation for function 'calcProposal' +// + +// Include files +#include "calcProposal.h" +#include "RATMain_types.h" +#include "blockedSummation.h" +#include "boundaryHandling.h" +#include "combineVectorElements.h" +#include "find.h" +#include "rand.h" +#include "randn.h" +#include "randperm.h" +#include "randsample.h" +#include "rt_nonfinite.h" +#include "sort.h" +#include "coder_array.h" + +// Function Declarations +namespace RAT +{ + static void binary_expand_op(::coder::array &in1, int32_T in2, + const ::coder::array &in3, const ::coder::array &in4, + real_T in5, const ::coder::array &in6, const ::coder::array< + real_T, 2U> &in7); + static void binary_expand_op(::coder::array &in1, int32_T in2, + const ::coder::array &in4, int32_T in5, const ::coder::array< + real_T, 2U> &in6, const ::coder::array &in7, int32_T in8); + static void plus(::coder::array &in1, const ::coder::array &in2, const ::coder::array &in3); +} + +// Function Definitions +namespace RAT +{ + static void binary_expand_op(::coder::array &in1, int32_T in2, + const ::coder::array &in3, const ::coder::array &in4, + real_T in5, const ::coder::array &in6, const ::coder::array< + real_T, 2U> &in7) + { + int32_T loop_ub; + int32_T stride_0_1; + int32_T stride_1_1; + int32_T stride_2_1; + stride_0_1 = (in3.size(0) != 1); + stride_1_1 = (in6.size(1) != 1); + stride_2_1 = (in3.size(0) != 1); + if (in3.size(0) == 1) { + if (in6.size(1) == 1) { + loop_ub = in3.size(0); + } else { + loop_ub = in6.size(1); + } + } else { + loop_ub = in3.size(0); + } + + for (int32_T i{0}; i < loop_ub; i++) { + in1[in2 + in1.size(0) * (static_cast(in3[i]) - 1)] = (in4[in2 + + in4.size(0) * (static_cast(in3[i * stride_0_1]) - 1)] + 1.0) * + in5 * in6[i * stride_1_1] + in7[in2 + in7.size(0) * (static_cast + (in3[i * stride_2_1]) - 1)]; + } + } + + static void binary_expand_op(::coder::array &in1, int32_T in2, + const ::coder::array &in4, int32_T in5, const ::coder::array< + real_T, 2U> &in6, const ::coder::array &in7, int32_T in8) + { + int32_T loop_ub; + int32_T stride_0_1; + int32_T stride_1_1; + int32_T stride_2_1; + stride_0_1 = (in5 + 1 != 1); + stride_1_1 = (in6.size(1) != 1); + stride_2_1 = (in8 + 1 != 1); + if (in8 + 1 == 1) { + if (in6.size(1) == 1) { + loop_ub = in5 + 1; + } else { + loop_ub = in6.size(1); + } + } else { + loop_ub = in8 + 1; + } + + for (int32_T i{0}; i < loop_ub; i++) { + in1[in2 + in1.size(0) * i] = (in4[in2 + in4.size(0) * (i * stride_0_1)] + + 1.0) * in6[i * stride_1_1] + in7[in2 + in7.size(0) * (i * stride_2_1)]; + } + } + + static void plus(::coder::array &in1, const ::coder::array &in2, const ::coder::array &in3) + { + int32_T aux_0_1; + int32_T aux_1_1; + int32_T i; + int32_T i1; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_0_1; + int32_T stride_1_0; + int32_T stride_1_1; + if (in3.size(0) == 1) { + i = in2.size(0); + } else { + i = in3.size(0); + } + + if (in3.size(1) == 1) { + i1 = in2.size(1); + } else { + i1 = in3.size(1); + } + + in1.set_size(i, i1); + stride_0_0 = (in2.size(0) != 1); + stride_0_1 = (in2.size(1) != 1); + stride_1_0 = (in3.size(0) != 1); + stride_1_1 = (in3.size(1) != 1); + aux_0_1 = 0; + aux_1_1 = 0; + if (in3.size(1) == 1) { + loop_ub = in2.size(1); + } else { + loop_ub = in3.size(1); + } + + for (i = 0; i < loop_ub; i++) { + int32_T b_loop_ub; + i1 = in3.size(0); + if (i1 == 1) { + b_loop_ub = in2.size(0); + } else { + b_loop_ub = i1; + } + + for (i1 = 0; i1 < b_loop_ub; i1++) { + in1[i1 + in1.size(0) * i] = in2[i1 * stride_0_0 + in2.size(0) * aux_0_1] + + in3[i1 * stride_1_0 + in3.size(0) * aux_1_1]; + } + + aux_1_1 += stride_1_1; + aux_0_1 += stride_0_1; + } + } + + void calcProposal(const ::coder::array &X, real_T CR_data[], const + struct13_T *DREAMPar, const ::coder::array + &Table_gamma, const ::coder::array &Par_info_min, + const ::coder::array &Par_info_max, const char_T + Par_info_boundhandling_data[], const int32_T + Par_info_boundhandling_size[2], ::coder::array + &x_new) + { + ::coder::array A; + ::coder::array a; + ::coder::array b; + ::coder::array b_gamma; + ::coder::array dx; + ::coder::array eps; + ::coder::array r; + ::coder::array r1; + ::coder::array r4; + ::coder::array r5; + ::coder::array r6; + ::coder::array rnd_cr; + ::coder::array rnd_jump; + ::coder::array DE_pairs; + ::coder::array r3; + ::coder::array draw; + ::coder::array r2; + ::coder::array b_rnd_cr; + int32_T b_loop_ub; + int32_T b_loop_ub_tmp; + int32_T i; + int32_T i1; + int32_T loop_ub; + int32_T loop_ub_tmp; + + // Calculate candidate points using discrete proposal distribution + // % % % Calculate the ergodicity perturbation + // % % eps = DREAMPar.zeta * randn(DREAMPar.N,DREAMPar.d); + // % % + // % % % Determine which sequences to evolve with what DE strategy + // % % DE_pairs = randsample( [1:DREAMPar.delta ] , DREAMPar.N , true , [ 1/DREAMPar.delta*ones(1,DREAMPar.delta) ])'; + // % % + // % % % Generate series of permutations of chains + // % % [dummy,tt] = sort(rand(DREAMPar.N-1,DREAMPar.N)); + // % % + // % % % Generate uniform random numbers for each chain to determine which dimension to update + // % % D = rand(DREAMPar.N,DREAMPar.d); + // % % + // % % % Ergodicity for each individual chain + // % % noise_x = DREAMPar.lambda * (2 * rand(DREAMPar.N,DREAMPar.d) - 1); + // % % + // % % % Initialize the delta update to zero + // % % delta_x = zeros(DREAMPar.N,DREAMPar.d); + // % % + // % % % Each chain evolves using information from other chains to create offspring + // % % for qq = 1:DREAMPar.N, + // % % + // % % % Define ii and remove current member as an option + // % % ii = ones(DREAMPar.N,1); ii(qq) = 0; idx = find(ii > 0); + // % % + // % % % randomly select two members of ii that have value == 1 + // % % rr = idx(tt(1:2*DE_pairs(qq,1),qq)); + // % % + // % % % --- WHICH DIMENSIONS TO UPDATE? DO SOMETHING WITH CROSSOVER ---- + // % % [i] = find(D(qq,1:DREAMPar.d) > (1-CR(qq,1))); + // % % + // % % % Update at least one dimension + // % % if isempty(i), i = randperm(DREAMPar.d); i = i(1); end; + // % % % ---------------------------------------------------------------- + // % % + // % % % Determine the associated JumpRate and compute the jump + // % % if (rand < (1 - DREAMPar.pJumpRate_one)), + // % % + // % % % % Now determine gamma, the jump factor + // % % % if ~DREAMPar.ABC + // % % % + // % % % Select the JumpRate (dependent of NrDim and number of pairs) + // % % NrDim = size(i,2); JumpRate = Table_gamma(NrDim,DE_pairs(qq,1)); + // % % + // % % % else + // % % % + // % % % % Turner (2012) paper -- CU[0.5,1] but needs scaling if + // % % % % more than 1 pair is used! + // % % % JumpRate = (0.5 + rand/2) * sqrt(1/DREAMPar.delta); + // % % + // % % % end; + // % % + // % % % Produce the difference of the pairs used for population evolution + // % % delta = sum(X(rr(1:DE_pairs(qq,1)),1:DREAMPar.d) - X(rr(DE_pairs(qq,1)+1:2*DE_pairs(qq,1)),1:DREAMPar.d),1); + // % % + // % % % Then fill update the dimension + // % % delta_x(qq,i) = (1 + noise_x(qq,i)) * JumpRate.*delta(1,i); + // % % + // % % else + // % % + // % % % Set the JumpRate to 1 and overwrite CR and DE_pairs + // % % JumpRate = 1; CR(qq,1) = -1; + // % % + // % % % Compute delta from one pair + // % % delta = X(rr(1),1:DREAMPar.d) - X(rr(2),1:DREAMPar.d); + // % % + // % % % Now jumprate to facilitate jumping from one mode to the other in all dimensions + // % % delta_x(qq,1:DREAMPar.d) = JumpRate * delta; + // % % + // % % end; + // % % + // % % % Check this line to avoid that jump = 0 and x_new is similar to X + // % % if (sum(delta_x(qq,1:DREAMPar.d).^2,2) == 0), + // % % + // % % % Compute the Cholesky Decomposition of X + // % % R = (2.38/sqrt(DREAMPar.d)) * chol(cov(X(1:end,1:DREAMPar.d)) + 1e-5*eye(DREAMPar.d)); + // % % + // % % % Generate jump using multinormal distribution + // % % delta_x(qq,1:DREAMPar.d) = randn(1,DREAMPar.d) * R; + // % % disp('hello'); + // % % end; + // % % + // % % end; + // % % + // % % % Generate candidate points by perturbing the current X values with jump and eps + // % % x_new = X + delta_x + eps; + // % % + // % % % If specified do boundary handling ( "Bound","Reflect","Fold") + // % % if isfield(Par_info,'boundhandling'), + // % % [x_new] = BoundaryHandling(x_new,Par_info,Par_info.boundhandling); + // % % end; + // % % + // ################################################## + // Calculate the ergodicity perturbation + coder::randn(DREAMPar->N, DREAMPar->d, b); + eps.set_size(b.size(0), b.size(1)); + loop_ub = b.size(1); + for (i = 0; i < loop_ub; i++) { + b_loop_ub = b.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + eps[i1 + eps.size(0) * i] = 1.0E-12 * b[i1 + b.size(0) * i]; + } + } + + real_T tmp_data[3]; + + // Determine how many chain pairs to use for each individual chain + r.set_size(1, 3); + r[0] = 1.0; + tmp_data[0] = 0.33333333333333331; + r[1] = 2.0; + tmp_data[1] = 0.33333333333333331; + r[2] = 3.0; + tmp_data[2] = 0.33333333333333331; + coder::randsample((const real_T *)r.data(), DREAMPar->N, tmp_data, r1); + DE_pairs.set_size(r1.size(1)); + loop_ub = r1.size(1); + for (i = 0; i < loop_ub; i++) { + DE_pairs[i] = r1[i]; + } + + // Generate uniform random numbers for each chain to determine which dimension to update + coder::b_rand(DREAMPar->N, DREAMPar->d, rnd_cr); + + // Ergodicity for each individual chain + coder::b_rand(DREAMPar->N, DREAMPar->d, b); + rnd_jump.set_size(b.size(0), b.size(1)); + loop_ub = b.size(1); + for (i = 0; i < loop_ub; i++) { + b_loop_ub = b.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + rnd_jump[i1 + rnd_jump.size(0) * i] = DREAMPar->lambda * (2.0 * b[i1 + + b.size(0) * i] - 1.0); + } + } + + // rnd_jump = DREAMPar.lambda * (2 * rand(DREAMPar.N,1) - 1); + // Randomly permute numbers [1,...,N-1] N times + coder::b_rand(DREAMPar->N - 1.0, DREAMPar->N, b); + coder::internal::b_sort(b, draw); + + // Set jump vectors equal to zero + loop_ub_tmp = static_cast(DREAMPar->N); + b_loop_ub_tmp = static_cast(DREAMPar->d); + dx.set_size(loop_ub_tmp, b_loop_ub_tmp); + for (i = 0; i < b_loop_ub_tmp; i++) { + for (i1 = 0; i1 < loop_ub_tmp; i1++) { + dx[i1 + dx.size(0) * i] = 0.0; + } + } + + real_T b_dv[2]; + + // Determine when jumprate is 1 + b_dv[0] = 1.0 - DREAMPar->pUnitGamma; + b_dv[1] = DREAMPar->pUnitGamma; + coder::randsample(DREAMPar->N, b_dv, b_gamma); + + // Create N proposals + for (int32_T b_i{0}; b_i < loop_ub_tmp; b_i++) { + real_T r2_data[6]; + real_T r1_data[3]; + real_T CR; + int32_T D; + int32_T i2; + + // Derive vector r1 + b_loop_ub_tmp = static_cast(DE_pairs[b_i]); + for (i = 0; i < b_loop_ub_tmp; i++) { + r1_data[i] = DREAMPar->R[b_i + DREAMPar->R.size(0) * (draw[i + draw.size + (0) * b_i] - 1)]; + } + + // Derive vector r2 + CR = 2.0 * DE_pairs[b_i]; + if (DE_pairs[b_i] + 1.0 > CR) { + i = 0; + i1 = 0; + } else { + i = static_cast(DE_pairs[b_i] + 1.0) - 1; + i1 = static_cast(CR); + } + + loop_ub = i1 - i; + for (i2 = 0; i2 < loop_ub; i2++) { + r2_data[i2] = DREAMPar->R[b_i + DREAMPar->R.size(0) * (draw[(i + i2) + + draw.size(0) * b_i] - 1)]; + } + + // Derive subset A with dimensions to sample + if (DREAMPar->d < 1.0) { + b_loop_ub = 0; + } else { + b_loop_ub = static_cast(DREAMPar->d); + } + + CR = CR_data[b_i]; + b_rnd_cr.set_size(1, b_loop_ub); + for (i2 = 0; i2 < b_loop_ub; i2++) { + b_rnd_cr[i2] = (rnd_cr[b_i + rnd_cr.size(0) * i2] < CR); + } + + coder::d_eml_find(b_rnd_cr, r2); + A.set_size(1, r2.size(1)); + b_loop_ub = r2.size(1); + for (i2 = 0; i2 < b_loop_ub; i2++) { + A[i2] = r2[i2]; + } + + // How many dimensions are sampled? + D = A.size(1); + + // Make sure that at least one dimension is selected! + if (A.size(1) == 0) { + coder::randperm(DREAMPar->d, a); + A.set_size(1, 1); + A[0] = a[0]; + D = 1; + } + + // Which gamma to use? + if (b_gamma[b_i] == 1.0) { + int32_T c_loop_ub; + int32_T dx_tmp; + + // Calculate direct jump + if (DREAMPar->d < 1.0) { + b_loop_ub = 0; + c_loop_ub = 0; + dx_tmp = 0; + } else { + b_loop_ub = static_cast(DREAMPar->d); + c_loop_ub = static_cast(DREAMPar->d); + dx_tmp = static_cast(DREAMPar->d); + } + + b.set_size(b_loop_ub_tmp, c_loop_ub); + for (i2 = 0; i2 < c_loop_ub; i2++) { + for (int32_T i3{0}; i3 < b_loop_ub_tmp; i3++) { + b[i3 + b.size(0) * i2] = X[(static_cast(r1_data[i3]) + + X.size(0) * i2) - 1]; + } + } + + r5.set_size(loop_ub, dx_tmp); + for (i2 = 0; i2 < dx_tmp; i2++) { + for (int32_T i3{0}; i3 < loop_ub; i3++) { + r5[i3 + r5.size(0) * i2] = X[(static_cast(r2_data[i3]) + + X.size(0) * i2) - 1]; + } + } + + if (DREAMPar->d < 1.0) { + i2 = 0; + } else { + i2 = static_cast(DREAMPar->d); + } + + if ((b.size(0) == r5.size(0)) && (b.size(1) == r5.size(1))) { + loop_ub = b.size(1); + for (int32_T i3{0}; i3 < loop_ub; i3++) { + c_loop_ub = b.size(0); + for (dx_tmp = 0; dx_tmp < c_loop_ub; dx_tmp++) { + b[dx_tmp + b.size(0) * i3] = b[dx_tmp + b.size(0) * i3] - + r5[dx_tmp + r5.size(0) * i3]; + } + } + + if (static_cast(DE_pairs[b_i]) == 1) { + i = i1 - i; + } else { + i = static_cast(DE_pairs[b_i]); + } + + coder::blockedSummation(b, i, r1); + } else { + binary_expand_op(r1, b, r5, DE_pairs, b_i, i1, i); + } + + if (b_loop_ub == 1) { + i = r1.size(1); + } else { + i = b_loop_ub; + } + + if ((b_loop_ub == r1.size(1)) && (i == i2)) { + for (i = 0; i < b_loop_ub; i++) { + dx[b_i + dx.size(0) * i] = (rnd_jump[b_i + rnd_jump.size(0) * i] + + 1.0) * r1[i] + eps[b_i + eps.size(0) * i]; + } + } else { + binary_expand_op(dx, b_i, rnd_jump, b_loop_ub - 1, r1, eps, i2 - 1); + } + + // Set CR to -1 so that this jump does not count for calculation of pCR + CR_data[b_i] = -1.0; + } else { + real_T gamma_D; + + // Unpack jump rate + gamma_D = Table_gamma[(D + Table_gamma.size(0) * (b_loop_ub_tmp - 1)) - + 1]; + + // Calculate jump + r3.set_size(A.size(1)); + b_loop_ub = A.size(1); + for (i2 = 0; i2 < b_loop_ub; i2++) { + r3[i2] = A[i2]; + } + + r4.set_size(b_loop_ub_tmp, r3.size(0)); + b_loop_ub = r3.size(0); + for (i2 = 0; i2 < b_loop_ub; i2++) { + for (int32_T i3{0}; i3 < b_loop_ub_tmp; i3++) { + r4[i3 + r4.size(0) * i2] = X[(static_cast(r1_data[i3]) + + X.size(0) * (static_cast(r3[i2]) - 1)) - 1]; + } + } + + r6.set_size(loop_ub, r3.size(0)); + b_loop_ub = r3.size(0); + for (i2 = 0; i2 < b_loop_ub; i2++) { + for (int32_T i3{0}; i3 < loop_ub; i3++) { + r6[i3 + r6.size(0) * i2] = X[(static_cast(r2_data[i3]) + + X.size(0) * (static_cast(r3[i2]) - 1)) - 1]; + } + } + + if (r4.size(0) == r6.size(0)) { + r5.set_size(r4.size(0), r4.size(1)); + loop_ub = r4.size(1); + b_loop_ub = r4.size(0); + for (i2 = 0; i2 < loop_ub; i2++) { + for (int32_T i3{0}; i3 < b_loop_ub; i3++) { + r5[i3 + r5.size(0) * i2] = r4[i3 + r4.size(0) * i2] - r6[i3 + + r6.size(0) * i2]; + } + } + + if (static_cast(DE_pairs[b_i]) == 1) { + i = i1 - i; + } else { + i = static_cast(DE_pairs[b_i]); + } + + coder::blockedSummation(r5, i, r1); + } else { + c_binary_expand_op(r1, r4, r6, DE_pairs, b_i, i1, i); + } + + if (r3.size(0) == 1) { + i = r1.size(1); + } else { + i = r3.size(0); + } + + if ((r3.size(0) == r1.size(1)) && (i == r3.size(0))) { + loop_ub = r3.size(0); + for (i = 0; i < loop_ub; i++) { + int32_T dx_tmp; + dx_tmp = static_cast(r3[i]) - 1; + dx[b_i + dx.size(0) * dx_tmp] = (rnd_jump[b_i + rnd_jump.size(0) * + dx_tmp] + 1.0) * gamma_D * r1[i] + eps[b_i + eps.size(0) * dx_tmp]; + } + } else { + binary_expand_op(dx, b_i, r3, rnd_jump, gamma_D, r1, eps); + } + } + } + + // Generate candidate points by perturbing the current X values with jump and eps + // If specified do boundary handling ( "Bound","Reflect","Fold") + if ((X.size(0) == dx.size(0)) && (X.size(1) == dx.size(1))) { + x_new.set_size(X.size(0), X.size(1)); + loop_ub = X.size(1); + for (i = 0; i < loop_ub; i++) { + b_loop_ub = X.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + x_new[i1 + x_new.size(0) * i] = X[i1 + X.size(0) * i] + dx[i1 + + dx.size(0) * i]; + } + } + } else { + plus(x_new, X, dx); + } + + boundaryHandling(x_new, Par_info_min, Par_info_max, + Par_info_boundhandling_data, Par_info_boundhandling_size); + } +} + +// End of code generation (calcProposal.cpp) diff --git a/cpp/RAT/calcProposal.h b/cpp/RAT/calcProposal.h new file mode 100644 index 00000000..4b4d3bff --- /dev/null +++ b/cpp/RAT/calcProposal.h @@ -0,0 +1,39 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// calcProposal.h +// +// Code generation for function 'calcProposal' +// +#ifndef CALCPROPOSAL_H +#define CALCPROPOSAL_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct struct13_T; +} + +// Function Declarations +namespace RAT +{ + void calcProposal(const ::coder::array &X, real_T CR_data[], const + struct13_T *DREAMPar, const ::coder::array + &Table_gamma, const ::coder::array &Par_info_min, + const ::coder::array &Par_info_max, const char_T + Par_info_boundhandling_data[], const int32_T + Par_info_boundhandling_size[2], ::coder::array + &x_new); +} + +#endif + +// End of code generation (calcProposal.h) diff --git a/cpp/RAT/calculate.cpp b/cpp/RAT/calculate.cpp new file mode 100644 index 00000000..2b1adb37 --- /dev/null +++ b/cpp/RAT/calculate.cpp @@ -0,0 +1,171 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// calculate.cpp +// +// Code generation for function 'calculate' +// + +// Include files +#include "calculate.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "parallelContrasts.h" +#include "parallelPoints.h" +#include "rt_nonfinite.h" +#include "single.h" +#include "strcmp.h" +#include "sum.h" +#include "coder_array.h" +#include "coder_bounded_array.h" + +// Function Definitions +namespace RAT +{ + namespace nonPolarisedTF + { + namespace standardLayers + { + void calculate(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, d_struct_T + *contrastParams, ::coder::array + &reflectivity, ::coder::array &simulation, + ::coder::array &shiftedData, ::coder:: + array &layerSlds, ::coder::array< + cell_wrap_8, 1U> &sldProfiles, ::coder::array &allLayers) + { + int32_T loop_ub_tmp; + + // Standard layers reflectivity calculation for nonPolarisedTF + // This function decides on parallelisation options before calling the + // relevant version ofthe main standard layers calculation. Parallelisation + // is either over the outer loop ('contrasts'), or the inner loop + // ('points'). The easiest way to do this is to have multiple versions of + // the same core calculation, rather than trying to make the parallel + // for loops conditional (although that would be much neater) There are: + // points - parallelise over points in the reflectivity calculation + // contrasts - parallelise over contrasts (outer for loop) + // Pre-allocation - It's necessary to + // pre-define the types for all the arrays + // for compilation, so do this in this block. + loop_ub_tmp = static_cast(problemStruct->numberOfContrasts); + contrastParams->ssubs.set_size(loop_ub_tmp); + contrastParams->backgroundParams.set_size(loop_ub_tmp); + contrastParams->qzshifts.set_size(loop_ub_tmp); + contrastParams->scalefactors.set_size(loop_ub_tmp); + contrastParams->bulkIn.set_size(loop_ub_tmp); + contrastParams->bulkOut.set_size(loop_ub_tmp); + contrastParams->calculations.allChis.set_size(loop_ub_tmp); + contrastParams->resolutionParams.set_size(loop_ub_tmp); + contrastParams->allSubRough.set_size(loop_ub_tmp); + reflectivity.set_size(loop_ub_tmp); + simulation.set_size(loop_ub_tmp); + shiftedData.set_size(loop_ub_tmp); + layerSlds.set_size(loop_ub_tmp); + sldProfiles.set_size(loop_ub_tmp); + allLayers.set_size(loop_ub_tmp); + for (int32_T i{0}; i < loop_ub_tmp; i++) { + contrastParams->ssubs[i] = 0.0; + contrastParams->backgroundParams[i] = 0.0; + contrastParams->qzshifts[i] = 0.0; + contrastParams->scalefactors[i] = 0.0; + contrastParams->bulkIn[i] = 0.0; + contrastParams->bulkOut[i] = 0.0; + contrastParams->calculations.allChis[i] = 0.0; + contrastParams->resolutionParams[i] = 0.0; + contrastParams->allSubRough[i] = 0.0; + reflectivity[i].f1.set_size(2, 2); + reflectivity[i].f1[0] = 1.0; + reflectivity[i].f1[1] = 1.0; + reflectivity[i].f1[reflectivity[i].f1.size(0)] = 1.0; + reflectivity[i].f1[reflectivity[i].f1.size(0) + 1] = 1.0; + simulation[i].f1.set_size(2, 2); + simulation[i].f1[0] = 1.0; + simulation[i].f1[1] = 1.0; + simulation[i].f1[simulation[i].f1.size(0)] = 1.0; + simulation[i].f1[simulation[i].f1.size(0) + 1] = 1.0; + shiftedData[i].f1.set_size(2, 3); + layerSlds[i].f1.set_size(2, 3); + sldProfiles[i].f1.set_size(2, 2); + sldProfiles[i].f1[0] = 1.0; + sldProfiles[i].f1[1] = 1.0; + sldProfiles[i].f1[sldProfiles[i].f1.size(0)] = 1.0; + sldProfiles[i].f1[sldProfiles[i].f1.size(0) + 1] = 1.0; + allLayers[i].f1.set_size(2, 3); + for (int32_T b_i{0}; b_i < 3; b_i++) { + shiftedData[i].f1[shiftedData[i].f1.size(0) * b_i] = 1.0; + shiftedData[i].f1[shiftedData[i].f1.size(0) * b_i + 1] = 1.0; + layerSlds[i].f1[layerSlds[i].f1.size(0) * b_i] = 1.0; + layerSlds[i].f1[layerSlds[i].f1.size(0) * b_i + 1] = 1.0; + allLayers[i].f1[allLayers[i].f1.size(0) * b_i] = 1.0; + allLayers[i].f1[allLayers[i].f1.size(0) * b_i + 1] = 1.0; + } + } + + // ------- End type definitions ------------- + if (coder::internal::n_strcmp(controls->parallel.data, + controls->parallel.size)) { + loop_ub_tmp = 0; + } else if (coder::internal::o_strcmp(controls->parallel.data, + controls->parallel.size)) { + loop_ub_tmp = 1; + } else if (coder::internal::p_strcmp(controls->parallel.data, + controls->parallel.size)) { + loop_ub_tmp = 2; + } else { + loop_ub_tmp = -1; + } + + switch (loop_ub_tmp) { + case 0: + b_single(problemStruct, problemCells, controls, contrastParams->ssubs, + contrastParams->backgroundParams, contrastParams->qzshifts, + contrastParams->scalefactors, contrastParams->bulkIn, + contrastParams->bulkOut, contrastParams->resolutionParams, + contrastParams->calculations.allChis, reflectivity, + simulation, shiftedData, layerSlds, sldProfiles, allLayers, + contrastParams->allSubRough); + break; + + case 1: + parallelPoints(problemStruct, problemCells, controls, + contrastParams->ssubs, contrastParams->backgroundParams, + contrastParams->qzshifts, contrastParams->scalefactors, + contrastParams->bulkIn, contrastParams->bulkOut, + contrastParams->resolutionParams, + contrastParams->calculations.allChis, reflectivity, + simulation, shiftedData, layerSlds, sldProfiles, + allLayers, contrastParams->allSubRough); + break; + + case 2: + c_parallelContrasts(problemStruct, problemCells, controls, + contrastParams->ssubs, + contrastParams->backgroundParams, + contrastParams->qzshifts, + contrastParams->scalefactors, + contrastParams->bulkIn, contrastParams->bulkOut, + contrastParams->resolutionParams, + contrastParams->calculations.allChis, reflectivity, + simulation, shiftedData, layerSlds, sldProfiles, + allLayers, contrastParams->allSubRough); + break; + } + + // Package everything into one array for tidy output + contrastParams->calculations.sumChi = coder::sum + (contrastParams->calculations.allChis); + contrastParams->resample.set_size(1, problemStruct->resample.size(1)); + loop_ub_tmp = problemStruct->resample.size(1); + for (int32_T b_i{0}; b_i < loop_ub_tmp; b_i++) { + contrastParams->resample[b_i] = problemStruct->resample[b_i]; + } + } + } + } +} + +// End of code generation (calculate.cpp) diff --git a/cpp/RAT/calculate.h b/cpp/RAT/calculate.h new file mode 100644 index 00000000..32ce782d --- /dev/null +++ b/cpp/RAT/calculate.h @@ -0,0 +1,42 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// calculate.h +// +// Code generation for function 'calculate' +// +#ifndef CALCULATE_H +#define CALCULATE_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace nonPolarisedTF + { + namespace standardLayers + { + void calculate(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, d_struct_T + *contrastParams, ::coder::array + &reflectivity, ::coder::array &simulation, + ::coder::array &shiftedData, ::coder:: + array &layerSlds, ::coder::array< + cell_wrap_8, 1U> &sldProfiles, ::coder::array &allLayers); + } + } +} + +#endif + +// End of code generation (calculate.h) diff --git a/cpp/RAT/calculate1.cpp b/cpp/RAT/calculate1.cpp new file mode 100644 index 00000000..2a020fb0 --- /dev/null +++ b/cpp/RAT/calculate1.cpp @@ -0,0 +1,169 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// calculate1.cpp +// +// Code generation for function 'calculate1' +// + +// Include files +#include "calculate1.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "parallelContrasts1.h" +#include "parallelPoints1.h" +#include "rt_nonfinite.h" +#include "single1.h" +#include "strcmp.h" +#include "sum.h" +#include "coder_array.h" +#include "coder_bounded_array.h" + +// Function Definitions +namespace RAT +{ + namespace nonPolarisedTF + { + namespace customLayers + { + void calculate(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, d_struct_T + *contrastParams, ::coder::array + &reflectivity, ::coder::array &simulation, + ::coder::array &shiftedData, ::coder:: + array &layerSlds, ::coder::array< + cell_wrap_8, 1U> &sldProfiles, ::coder::array &allLayers) + { + int32_T loop_ub_tmp; + + // Custom layers reflectivity calculation for nonPolarisedTF + // This function decides on parallelisation options before calling the + // relevant version of the main custom layers calculation. It is more + // efficient to have multiple versions of the core calculation, each dealing + // with a different scheme for parallelisation. These are: + // single - single threaded reflectivity calculation + // points - parallelise over points in the reflectivity calculation + // contrasts - parallelise over contrasts. + // Pre-allocation - It's necessary to + // pre-allocate the memory for all the arrays + // for compilation, so do this in this block. + loop_ub_tmp = static_cast(problemStruct->numberOfContrasts); + contrastParams->ssubs.set_size(loop_ub_tmp); + contrastParams->backgroundParams.set_size(loop_ub_tmp); + contrastParams->qzshifts.set_size(loop_ub_tmp); + contrastParams->scalefactors.set_size(loop_ub_tmp); + contrastParams->bulkIn.set_size(loop_ub_tmp); + contrastParams->bulkOut.set_size(loop_ub_tmp); + contrastParams->calculations.allChis.set_size(loop_ub_tmp); + contrastParams->resolutionParams.set_size(loop_ub_tmp); + contrastParams->allSubRough.set_size(loop_ub_tmp); + reflectivity.set_size(loop_ub_tmp); + simulation.set_size(loop_ub_tmp); + shiftedData.set_size(loop_ub_tmp); + layerSlds.set_size(loop_ub_tmp); + sldProfiles.set_size(loop_ub_tmp); + allLayers.set_size(loop_ub_tmp); + for (int32_T i{0}; i < loop_ub_tmp; i++) { + contrastParams->ssubs[i] = 0.0; + contrastParams->backgroundParams[i] = 0.0; + contrastParams->qzshifts[i] = 0.0; + contrastParams->scalefactors[i] = 0.0; + contrastParams->bulkIn[i] = 0.0; + contrastParams->bulkOut[i] = 0.0; + contrastParams->calculations.allChis[i] = 0.0; + contrastParams->resolutionParams[i] = 0.0; + contrastParams->allSubRough[i] = 0.0; + reflectivity[i].f1.set_size(2, 2); + reflectivity[i].f1[0] = 1.0; + reflectivity[i].f1[1] = 1.0; + reflectivity[i].f1[reflectivity[i].f1.size(0)] = 1.0; + reflectivity[i].f1[reflectivity[i].f1.size(0) + 1] = 1.0; + simulation[i].f1.set_size(2, 2); + simulation[i].f1[0] = 1.0; + simulation[i].f1[1] = 1.0; + simulation[i].f1[simulation[i].f1.size(0)] = 1.0; + simulation[i].f1[simulation[i].f1.size(0) + 1] = 1.0; + shiftedData[i].f1.set_size(2, 3); + layerSlds[i].f1.set_size(2, 3); + sldProfiles[i].f1.set_size(2, 2); + sldProfiles[i].f1[0] = 1.0; + sldProfiles[i].f1[1] = 1.0; + sldProfiles[i].f1[sldProfiles[i].f1.size(0)] = 1.0; + sldProfiles[i].f1[sldProfiles[i].f1.size(0) + 1] = 1.0; + allLayers[i].f1.set_size(2, 3); + for (int32_T b_i{0}; b_i < 3; b_i++) { + shiftedData[i].f1[shiftedData[i].f1.size(0) * b_i] = 1.0; + shiftedData[i].f1[shiftedData[i].f1.size(0) * b_i + 1] = 1.0; + layerSlds[i].f1[layerSlds[i].f1.size(0) * b_i] = 1.0; + layerSlds[i].f1[layerSlds[i].f1.size(0) * b_i + 1] = 1.0; + allLayers[i].f1[allLayers[i].f1.size(0) * b_i] = 1.0; + allLayers[i].f1[allLayers[i].f1.size(0) * b_i + 1] = 1.0; + } + } + + // End pre-allocation + if (coder::internal::n_strcmp(controls->parallel.data, + controls->parallel.size)) { + loop_ub_tmp = 0; + } else if (coder::internal::o_strcmp(controls->parallel.data, + controls->parallel.size)) { + loop_ub_tmp = 1; + } else if (coder::internal::p_strcmp(controls->parallel.data, + controls->parallel.size)) { + loop_ub_tmp = 2; + } else { + loop_ub_tmp = -1; + } + + switch (loop_ub_tmp) { + case 0: + b_single(problemStruct, problemCells, controls, contrastParams->ssubs, + contrastParams->backgroundParams, contrastParams->qzshifts, + contrastParams->scalefactors, contrastParams->bulkIn, + contrastParams->bulkOut, contrastParams->resolutionParams, + contrastParams->calculations.allChis, reflectivity, + simulation, shiftedData, layerSlds, sldProfiles, allLayers, + contrastParams->allSubRough); + break; + + case 1: + parallelPoints(problemStruct, problemCells, controls, + contrastParams->ssubs, contrastParams->backgroundParams, + contrastParams->qzshifts, contrastParams->scalefactors, + contrastParams->bulkIn, contrastParams->bulkOut, + contrastParams->resolutionParams, + contrastParams->calculations.allChis, reflectivity, + simulation, shiftedData, layerSlds, sldProfiles, + allLayers, contrastParams->allSubRough); + break; + + case 2: + c_parallelContrasts(problemStruct, problemCells, controls, + contrastParams->ssubs, + contrastParams->backgroundParams, + contrastParams->qzshifts, + contrastParams->scalefactors, + contrastParams->bulkIn, contrastParams->bulkOut, + contrastParams->resolutionParams, + contrastParams->calculations.allChis, reflectivity, + simulation, shiftedData, layerSlds, sldProfiles, + allLayers, contrastParams->allSubRough); + break; + } + + contrastParams->calculations.sumChi = coder::sum + (contrastParams->calculations.allChis); + contrastParams->resample.set_size(1, problemStruct->resample.size(1)); + loop_ub_tmp = problemStruct->resample.size(1); + for (int32_T b_i{0}; b_i < loop_ub_tmp; b_i++) { + contrastParams->resample[b_i] = problemStruct->resample[b_i]; + } + } + } + } +} + +// End of code generation (calculate1.cpp) diff --git a/cpp/RAT/calculate1.h b/cpp/RAT/calculate1.h new file mode 100644 index 00000000..ffd0507c --- /dev/null +++ b/cpp/RAT/calculate1.h @@ -0,0 +1,42 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// calculate1.h +// +// Code generation for function 'calculate1' +// +#ifndef CALCULATE1_H +#define CALCULATE1_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace nonPolarisedTF + { + namespace customLayers + { + void calculate(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, d_struct_T + *contrastParams, ::coder::array + &reflectivity, ::coder::array &simulation, + ::coder::array &shiftedData, ::coder:: + array &layerSlds, ::coder::array< + cell_wrap_8, 1U> &sldProfiles, ::coder::array &allLayers); + } + } +} + +#endif + +// End of code generation (calculate1.h) diff --git a/cpp/RAT/calculate2.cpp b/cpp/RAT/calculate2.cpp new file mode 100644 index 00000000..d22d049c --- /dev/null +++ b/cpp/RAT/calculate2.cpp @@ -0,0 +1,169 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// calculate2.cpp +// +// Code generation for function 'calculate2' +// + +// Include files +#include "calculate2.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "parallelContrasts2.h" +#include "parallelPoints2.h" +#include "rt_nonfinite.h" +#include "single2.h" +#include "strcmp.h" +#include "sum.h" +#include "coder_array.h" +#include "coder_bounded_array.h" + +// Function Definitions +namespace RAT +{ + namespace nonPolarisedTF + { + namespace customXY + { + void calculate(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, d_struct_T + *contrastParams, ::coder::array + &reflectivity, ::coder::array &simulation, + ::coder::array &shiftedData, ::coder:: + array &layerSlds, ::coder::array< + cell_wrap_8, 1U> &sldProfiles, ::coder::array &allLayers) + { + int32_T loop_ub_tmp; + + // Custom XP profile reflectivity calculation for nonPolarisedTF + // This function decides on parallelisation options before calling the + // relevant version of the main custom XY calculation. It is more + // efficient to have multiple versions of the core calculation, each dealing + // with a different scheme for parallelisation. These are: + // single - single threaded reflectivity calculation + // points - parallelise over points in the reflectivity calculation + // contrasts - parallelise over contrasts. + // Pre-allocation - It's necessary to + // pre-allocate the memory for all the arrays + // for compilation, so do this in this block. + loop_ub_tmp = static_cast(problemStruct->numberOfContrasts); + contrastParams->ssubs.set_size(loop_ub_tmp); + contrastParams->backgroundParams.set_size(loop_ub_tmp); + contrastParams->qzshifts.set_size(loop_ub_tmp); + contrastParams->scalefactors.set_size(loop_ub_tmp); + contrastParams->bulkIn.set_size(loop_ub_tmp); + contrastParams->bulkOut.set_size(loop_ub_tmp); + contrastParams->calculations.allChis.set_size(loop_ub_tmp); + contrastParams->resolutionParams.set_size(loop_ub_tmp); + contrastParams->allSubRough.set_size(loop_ub_tmp); + reflectivity.set_size(loop_ub_tmp); + simulation.set_size(loop_ub_tmp); + shiftedData.set_size(loop_ub_tmp); + layerSlds.set_size(loop_ub_tmp); + sldProfiles.set_size(loop_ub_tmp); + allLayers.set_size(loop_ub_tmp); + for (int32_T i{0}; i < loop_ub_tmp; i++) { + contrastParams->ssubs[i] = 0.0; + contrastParams->backgroundParams[i] = 0.0; + contrastParams->qzshifts[i] = 0.0; + contrastParams->scalefactors[i] = 0.0; + contrastParams->bulkIn[i] = 0.0; + contrastParams->bulkOut[i] = 0.0; + contrastParams->calculations.allChis[i] = 0.0; + contrastParams->resolutionParams[i] = 0.0; + contrastParams->allSubRough[i] = 0.0; + reflectivity[i].f1.set_size(2, 2); + reflectivity[i].f1[0] = 1.0; + reflectivity[i].f1[1] = 1.0; + reflectivity[i].f1[reflectivity[i].f1.size(0)] = 1.0; + reflectivity[i].f1[reflectivity[i].f1.size(0) + 1] = 1.0; + simulation[i].f1.set_size(2, 2); + simulation[i].f1[0] = 1.0; + simulation[i].f1[1] = 1.0; + simulation[i].f1[simulation[i].f1.size(0)] = 1.0; + simulation[i].f1[simulation[i].f1.size(0) + 1] = 1.0; + shiftedData[i].f1.set_size(2, 3); + layerSlds[i].f1.set_size(2, 3); + for (int32_T b_i{0}; b_i < 3; b_i++) { + shiftedData[i].f1[shiftedData[i].f1.size(0) * b_i] = 1.0; + shiftedData[i].f1[shiftedData[i].f1.size(0) * b_i + 1] = 1.0; + layerSlds[i].f1[layerSlds[i].f1.size(0) * b_i] = 1.0; + layerSlds[i].f1[layerSlds[i].f1.size(0) * b_i + 1] = 1.0; + } + + sldProfiles[i].f1.set_size(2, 2); + sldProfiles[i].f1[0] = 1.0; + sldProfiles[i].f1[1] = 1.0; + sldProfiles[i].f1[sldProfiles[i].f1.size(0)] = 1.0; + sldProfiles[i].f1[sldProfiles[i].f1.size(0) + 1] = 1.0; + allLayers[i].f1.set_size(2, 1); + allLayers[i].f1[0] = 1.0; + allLayers[i].f1[1] = 1.0; + } + + if (coder::internal::n_strcmp(controls->parallel.data, + controls->parallel.size)) { + loop_ub_tmp = 0; + } else if (coder::internal::o_strcmp(controls->parallel.data, + controls->parallel.size)) { + loop_ub_tmp = 1; + } else if (coder::internal::p_strcmp(controls->parallel.data, + controls->parallel.size)) { + loop_ub_tmp = 2; + } else { + loop_ub_tmp = -1; + } + + switch (loop_ub_tmp) { + case 0: + b_single(problemStruct, problemCells, controls, contrastParams->ssubs, + contrastParams->backgroundParams, contrastParams->qzshifts, + contrastParams->scalefactors, contrastParams->bulkIn, + contrastParams->bulkOut, contrastParams->resolutionParams, + contrastParams->calculations.allChis, reflectivity, + simulation, shiftedData, layerSlds, sldProfiles, allLayers, + contrastParams->allSubRough); + break; + + case 1: + parallelPoints(problemStruct, problemCells, controls, + contrastParams->ssubs, contrastParams->backgroundParams, + contrastParams->qzshifts, contrastParams->scalefactors, + contrastParams->bulkIn, contrastParams->bulkOut, + contrastParams->resolutionParams, + contrastParams->calculations.allChis, reflectivity, + simulation, shiftedData, layerSlds, sldProfiles, + allLayers, contrastParams->allSubRough); + break; + + case 2: + c_parallelContrasts(problemStruct, problemCells, controls, + contrastParams->ssubs, + contrastParams->backgroundParams, + contrastParams->qzshifts, + contrastParams->scalefactors, + contrastParams->bulkIn, contrastParams->bulkOut, + contrastParams->resolutionParams, + contrastParams->calculations.allChis, reflectivity, + simulation, shiftedData, layerSlds, sldProfiles, + allLayers, contrastParams->allSubRough); + break; + } + + contrastParams->calculations.sumChi = coder::sum + (contrastParams->calculations.allChis); + contrastParams->resample.set_size(1, contrastParams->allSubRough.size(0)); + loop_ub_tmp = contrastParams->allSubRough.size(0); + for (int32_T b_i{0}; b_i < loop_ub_tmp; b_i++) { + contrastParams->resample[b_i] = 1.0; + } + } + } + } +} + +// End of code generation (calculate2.cpp) diff --git a/cpp/RAT/calculate2.h b/cpp/RAT/calculate2.h new file mode 100644 index 00000000..023721e9 --- /dev/null +++ b/cpp/RAT/calculate2.h @@ -0,0 +1,42 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// calculate2.h +// +// Code generation for function 'calculate2' +// +#ifndef CALCULATE2_H +#define CALCULATE2_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace nonPolarisedTF + { + namespace customXY + { + void calculate(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, d_struct_T + *contrastParams, ::coder::array + &reflectivity, ::coder::array &simulation, + ::coder::array &shiftedData, ::coder:: + array &layerSlds, ::coder::array< + cell_wrap_8, 1U> &sldProfiles, ::coder::array &allLayers); + } + } +} + +#endif + +// End of code generation (calculate2.h) diff --git a/cpp/RAT/calculate3.cpp b/cpp/RAT/calculate3.cpp new file mode 100644 index 00000000..5d4ec9d1 --- /dev/null +++ b/cpp/RAT/calculate3.cpp @@ -0,0 +1,256 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// calculate3.cpp +// +// Code generation for function 'calculate3' +// + +// Include files +#include "calculate3.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "parallelContrasts3.h" +#include "parallelPoints3.h" +#include "rt_nonfinite.h" +#include "single3.h" +#include "strcmp.h" +#include "sum.h" +#include "coder_array.h" +#include "coder_bounded_array.h" + +// Function Definitions +namespace RAT +{ + namespace domainsTF + { + namespace standardLayers + { + void calculate(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, d_struct_T + *contrastParams, ::coder::array + &reflectivity, ::coder::array &simulation, + ::coder::array &shiftedData, ::coder:: + array &layerSlds, ::coder::array< + cell_wrap_8, 2U> &sldProfiles, ::coder::array &allLayers) + { + ::coder::array b_allLayers; + ::coder::array b_layerSlds; + ::coder::array b_sldProfiles; + int32_T loop_ub_tmp; + + // Standard layers reflectivity calculation for nonPolarisedTF + // This function decides on parallelisation options before calling the + // relevant version of the main standard layers calculation. Parallelisation + // is either over the outer loop ('contrasts'), or the inner loop + // ('points'). The easiest way to do this is to have multiple versions of + // the same core calculation, rather than trying to make the parallel + // for loops conditional (although that would be much neater) There are: + // points - parallelise over points in the reflectivity calculation + // contrasts - parallelise over contrasts (outer for loop) + // Pre-allocation - It's necessary to + // pre-define the types for all the arrays + // for compilation, so do this in this block. + loop_ub_tmp = static_cast(problemStruct->numberOfContrasts); + contrastParams->ssubs.set_size(loop_ub_tmp); + contrastParams->backgroundParams.set_size(loop_ub_tmp); + contrastParams->qzshifts.set_size(loop_ub_tmp); + contrastParams->scalefactors.set_size(loop_ub_tmp); + contrastParams->bulkIn.set_size(loop_ub_tmp); + contrastParams->bulkOut.set_size(loop_ub_tmp); + contrastParams->calculations.allChis.set_size(loop_ub_tmp); + contrastParams->resolutionParams.set_size(loop_ub_tmp); + contrastParams->allSubRough.set_size(loop_ub_tmp); + reflectivity.set_size(loop_ub_tmp); + simulation.set_size(loop_ub_tmp); + shiftedData.set_size(loop_ub_tmp); + layerSlds.set_size(loop_ub_tmp, 1); + sldProfiles.set_size(loop_ub_tmp, 1); + allLayers.set_size(loop_ub_tmp, 1); + for (int32_T i{0}; i < loop_ub_tmp; i++) { + contrastParams->ssubs[i] = 0.0; + contrastParams->backgroundParams[i] = 0.0; + contrastParams->qzshifts[i] = 0.0; + contrastParams->scalefactors[i] = 0.0; + contrastParams->bulkIn[i] = 0.0; + contrastParams->bulkOut[i] = 0.0; + contrastParams->calculations.allChis[i] = 0.0; + contrastParams->resolutionParams[i] = 0.0; + contrastParams->allSubRough[i] = 0.0; + reflectivity[i].f1.set_size(2, 2); + reflectivity[i].f1[0] = 1.0; + reflectivity[i].f1[1] = 1.0; + reflectivity[i].f1[reflectivity[i].f1.size(0)] = 1.0; + reflectivity[i].f1[reflectivity[i].f1.size(0) + 1] = 1.0; + simulation[i].f1.set_size(2, 2); + simulation[i].f1[0] = 1.0; + simulation[i].f1[1] = 1.0; + simulation[i].f1[simulation[i].f1.size(0)] = 1.0; + simulation[i].f1[simulation[i].f1.size(0) + 1] = 1.0; + shiftedData[i].f1.set_size(2, 3); + layerSlds[i].f1.set_size(2, 3); + sldProfiles[i].f1.set_size(2, 2); + sldProfiles[i].f1[0] = 1.0; + sldProfiles[i].f1[1] = 1.0; + sldProfiles[i].f1[sldProfiles[i].f1.size(0)] = 1.0; + sldProfiles[i].f1[sldProfiles[i].f1.size(0) + 1] = 1.0; + allLayers[i].f1.set_size(2, 3); + for (int32_T b_i{0}; b_i < 3; b_i++) { + shiftedData[i].f1[shiftedData[i].f1.size(0) * b_i] = 1.0; + shiftedData[i].f1[shiftedData[i].f1.size(0) * b_i + 1] = 1.0; + layerSlds[i].f1[layerSlds[i].f1.size(0) * b_i] = 1.0; + layerSlds[i].f1[layerSlds[i].f1.size(0) * b_i + 1] = 1.0; + allLayers[i].f1[allLayers[i].f1.size(0) * b_i] = 1.0; + allLayers[i].f1[allLayers[i].f1.size(0) * b_i + 1] = 1.0; + } + } + + // ------- End type definitions ------------- + if (coder::internal::n_strcmp(controls->parallel.data, + controls->parallel.size)) { + loop_ub_tmp = 0; + } else if (coder::internal::o_strcmp(controls->parallel.data, + controls->parallel.size)) { + loop_ub_tmp = 1; + } else if (coder::internal::p_strcmp(controls->parallel.data, + controls->parallel.size)) { + loop_ub_tmp = 2; + } else { + loop_ub_tmp = -1; + } + + switch (loop_ub_tmp) { + case 0: + { + int32_T b_loop_ub; + int32_T loop_ub; + b_single(problemStruct, problemCells, controls, + contrastParams->ssubs, contrastParams->backgroundParams, + contrastParams->qzshifts, contrastParams->scalefactors, + contrastParams->bulkIn, contrastParams->bulkOut, + contrastParams->resolutionParams, + contrastParams->calculations.allChis, reflectivity, + simulation, shiftedData, b_layerSlds, b_sldProfiles, + b_allLayers, contrastParams->allSubRough); + layerSlds.set_size(b_layerSlds.size(0), 2); + sldProfiles.set_size(b_sldProfiles.size(0), 2); + allLayers.set_size(b_allLayers.size(0), 2); + loop_ub_tmp = b_layerSlds.size(0); + loop_ub = b_sldProfiles.size(0); + b_loop_ub = b_allLayers.size(0); + for (int32_T b_i{0}; b_i < 2; b_i++) { + for (int32_T i1{0}; i1 < loop_ub_tmp; i1++) { + layerSlds[i1 + layerSlds.size(0) * b_i] = b_layerSlds[i1 + + b_layerSlds.size(0) * b_i]; + } + + for (int32_T i1{0}; i1 < loop_ub; i1++) { + sldProfiles[i1 + sldProfiles.size(0) * b_i] = b_sldProfiles[i1 + + b_sldProfiles.size(0) * b_i]; + } + + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + allLayers[i1 + allLayers.size(0) * b_i] = b_allLayers[i1 + + b_allLayers.size(0) * b_i]; + } + } + } + break; + + case 1: + { + int32_T b_loop_ub; + int32_T loop_ub; + parallelPoints(problemStruct, problemCells, controls, + contrastParams->ssubs, + contrastParams->backgroundParams, + contrastParams->qzshifts, + contrastParams->scalefactors, contrastParams->bulkIn, + contrastParams->bulkOut, + contrastParams->resolutionParams, + contrastParams->calculations.allChis, reflectivity, + simulation, shiftedData, b_layerSlds, b_sldProfiles, + b_allLayers, contrastParams->allSubRough); + layerSlds.set_size(b_layerSlds.size(0), 2); + sldProfiles.set_size(b_sldProfiles.size(0), 2); + allLayers.set_size(b_allLayers.size(0), 2); + loop_ub_tmp = b_layerSlds.size(0); + loop_ub = b_sldProfiles.size(0); + b_loop_ub = b_allLayers.size(0); + for (int32_T b_i{0}; b_i < 2; b_i++) { + for (int32_T i1{0}; i1 < loop_ub_tmp; i1++) { + layerSlds[i1 + layerSlds.size(0) * b_i] = b_layerSlds[i1 + + b_layerSlds.size(0) * b_i]; + } + + for (int32_T i1{0}; i1 < loop_ub; i1++) { + sldProfiles[i1 + sldProfiles.size(0) * b_i] = b_sldProfiles[i1 + + b_sldProfiles.size(0) * b_i]; + } + + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + allLayers[i1 + allLayers.size(0) * b_i] = b_allLayers[i1 + + b_allLayers.size(0) * b_i]; + } + } + } + break; + + case 2: + { + int32_T b_loop_ub; + int32_T loop_ub; + c_parallelContrasts(problemStruct, problemCells, controls, + contrastParams->ssubs, + contrastParams->backgroundParams, + contrastParams->qzshifts, + contrastParams->scalefactors, + contrastParams->bulkIn, contrastParams->bulkOut, + contrastParams->resolutionParams, + contrastParams->calculations.allChis, + reflectivity, simulation, shiftedData, + b_layerSlds, b_sldProfiles, b_allLayers, + contrastParams->allSubRough); + layerSlds.set_size(b_layerSlds.size(0), 2); + sldProfiles.set_size(b_sldProfiles.size(0), 2); + allLayers.set_size(b_allLayers.size(0), 2); + loop_ub_tmp = b_layerSlds.size(0); + loop_ub = b_sldProfiles.size(0); + b_loop_ub = b_allLayers.size(0); + for (int32_T b_i{0}; b_i < 2; b_i++) { + for (int32_T i1{0}; i1 < loop_ub_tmp; i1++) { + layerSlds[i1 + layerSlds.size(0) * b_i] = b_layerSlds[i1 + + b_layerSlds.size(0) * b_i]; + } + + for (int32_T i1{0}; i1 < loop_ub; i1++) { + sldProfiles[i1 + sldProfiles.size(0) * b_i] = b_sldProfiles[i1 + + b_sldProfiles.size(0) * b_i]; + } + + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + allLayers[i1 + allLayers.size(0) * b_i] = b_allLayers[i1 + + b_allLayers.size(0) * b_i]; + } + } + } + break; + } + + // Package everything into one array for tidy output + contrastParams->calculations.sumChi = coder::sum + (contrastParams->calculations.allChis); + contrastParams->resample.set_size(1, problemStruct->resample.size(1)); + loop_ub_tmp = problemStruct->resample.size(1); + for (int32_T b_i{0}; b_i < loop_ub_tmp; b_i++) { + contrastParams->resample[b_i] = problemStruct->resample[b_i]; + } + } + } + } +} + +// End of code generation (calculate3.cpp) diff --git a/cpp/RAT/calculate3.h b/cpp/RAT/calculate3.h new file mode 100644 index 00000000..3efdf953 --- /dev/null +++ b/cpp/RAT/calculate3.h @@ -0,0 +1,42 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// calculate3.h +// +// Code generation for function 'calculate3' +// +#ifndef CALCULATE3_H +#define CALCULATE3_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace domainsTF + { + namespace standardLayers + { + void calculate(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, d_struct_T + *contrastParams, ::coder::array + &reflectivity, ::coder::array &simulation, + ::coder::array &shiftedData, ::coder:: + array &layerSlds, ::coder::array< + cell_wrap_8, 2U> &sldProfiles, ::coder::array &allLayers); + } + } +} + +#endif + +// End of code generation (calculate3.h) diff --git a/cpp/RAT/calculate4.cpp b/cpp/RAT/calculate4.cpp new file mode 100644 index 00000000..3197e637 --- /dev/null +++ b/cpp/RAT/calculate4.cpp @@ -0,0 +1,214 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// calculate4.cpp +// +// Code generation for function 'calculate4' +// + +// Include files +#include "calculate4.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "parallelContrasts4.h" +#include "parallelPoints4.h" +#include "rt_nonfinite.h" +#include "single4.h" +#include "strcmp.h" +#include "sum.h" +#include "coder_array.h" +#include "coder_bounded_array.h" + +// Function Definitions +namespace RAT +{ + namespace domainsTF + { + namespace customLayers + { + void calculate(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, d_struct_T + *contrastParams, ::coder::array + &reflectivity, ::coder::array &simulation, + ::coder::array &shiftedData, ::coder:: + array &layerSlds, ::coder::array< + cell_wrap_8, 2U> &domainSldProfiles, ::coder::array< + cell_wrap_8, 2U> &allLayers) + { + ::coder::array b_allLayers; + int32_T loop_ub_tmp; + + // Custom layers reflectivity calculation for domainsTF + // This function decides on parallelisation options before calling the + // relevant version of the main custom layers calculation. It is more + // efficient to have multiple versions of the core calculation, each dealing + // with a different scheme for parallelisation. These are: + // single - single threaded reflectivity calculation + // points - parallelise over points in the reflectivity calculation + // contrasts - parallelise over contrasts. + // Pre-allocation - It's necessary to + // pre-allocate the memory for all the arrays + // for compilation, so do this in this block. + loop_ub_tmp = static_cast(problemStruct->numberOfContrasts); + contrastParams->ssubs.set_size(loop_ub_tmp); + contrastParams->backgroundParams.set_size(loop_ub_tmp); + contrastParams->qzshifts.set_size(loop_ub_tmp); + contrastParams->scalefactors.set_size(loop_ub_tmp); + contrastParams->bulkIn.set_size(loop_ub_tmp); + contrastParams->bulkOut.set_size(loop_ub_tmp); + contrastParams->calculations.allChis.set_size(loop_ub_tmp); + contrastParams->resolutionParams.set_size(loop_ub_tmp); + contrastParams->allSubRough.set_size(loop_ub_tmp); + reflectivity.set_size(loop_ub_tmp); + simulation.set_size(loop_ub_tmp); + shiftedData.set_size(loop_ub_tmp); + layerSlds.set_size(loop_ub_tmp, 2); + domainSldProfiles.set_size(loop_ub_tmp, 2); + allLayers.set_size(loop_ub_tmp, 2); + for (int32_T i{0}; i < loop_ub_tmp; i++) { + contrastParams->ssubs[i] = 0.0; + contrastParams->backgroundParams[i] = 0.0; + contrastParams->qzshifts[i] = 0.0; + contrastParams->scalefactors[i] = 0.0; + contrastParams->bulkIn[i] = 0.0; + contrastParams->bulkOut[i] = 0.0; + contrastParams->calculations.allChis[i] = 0.0; + contrastParams->resolutionParams[i] = 0.0; + contrastParams->allSubRough[i] = 0.0; + reflectivity[i].f1.set_size(2, 2); + reflectivity[i].f1[0] = 1.0; + reflectivity[i].f1[1] = 1.0; + reflectivity[i].f1[reflectivity[i].f1.size(0)] = 1.0; + reflectivity[i].f1[reflectivity[i].f1.size(0) + 1] = 1.0; + simulation[i].f1.set_size(2, 2); + simulation[i].f1[0] = 1.0; + simulation[i].f1[1] = 1.0; + simulation[i].f1[simulation[i].f1.size(0)] = 1.0; + simulation[i].f1[simulation[i].f1.size(0) + 1] = 1.0; + shiftedData[i].f1.set_size(2, 3); + layerSlds[i].f1.set_size(2, 3); + layerSlds[i + layerSlds.size(0)].f1.set_size(2, 3); + domainSldProfiles[i].f1.set_size(2, 2); + domainSldProfiles[i + domainSldProfiles.size(0)].f1.set_size(2, 2); + domainSldProfiles[i].f1[0] = 1.0; + domainSldProfiles[i + domainSldProfiles.size(0)].f1[0] = 1.0; + domainSldProfiles[i].f1[1] = 1.0; + domainSldProfiles[i + domainSldProfiles.size(0)].f1[1] = 1.0; + domainSldProfiles[i].f1[domainSldProfiles[i].f1.size(0)] = 1.0; + domainSldProfiles[i + domainSldProfiles.size(0)] + .f1[domainSldProfiles[i + domainSldProfiles.size(0)].f1.size(0)] = + 1.0; + domainSldProfiles[i].f1[domainSldProfiles[i].f1.size(0) + 1] = 1.0; + domainSldProfiles[i + domainSldProfiles.size(0)] + .f1[domainSldProfiles[i + domainSldProfiles.size(0)].f1.size(0) + 1] + = 1.0; + allLayers[i].f1.set_size(2, 3); + allLayers[i + allLayers.size(0)].f1.set_size(2, 3); + for (int32_T b_i{0}; b_i < 3; b_i++) { + shiftedData[i].f1[shiftedData[i].f1.size(0) * b_i] = 1.0; + shiftedData[i].f1[shiftedData[i].f1.size(0) * b_i + 1] = 1.0; + layerSlds[i].f1[layerSlds[i].f1.size(0) * b_i] = 1.0; + layerSlds[i + layerSlds.size(0)].f1[layerSlds[i + layerSlds.size(0)] + .f1.size(0) * b_i] = 1.0; + layerSlds[i].f1[layerSlds[i].f1.size(0) * b_i + 1] = 1.0; + layerSlds[i + layerSlds.size(0)].f1[layerSlds[i + layerSlds.size(0)] + .f1.size(0) * b_i + 1] = 1.0; + allLayers[i].f1[allLayers[i].f1.size(0) * b_i] = 1.0; + allLayers[i + allLayers.size(0)].f1[allLayers[i + allLayers.size(0)] + .f1.size(0) * b_i] = 1.0; + allLayers[i].f1[allLayers[i].f1.size(0) * b_i + 1] = 1.0; + allLayers[i + allLayers.size(0)].f1[allLayers[i + allLayers.size(0)] + .f1.size(0) * b_i + 1] = 1.0; + } + } + + // End pre-allocation + if (coder::internal::n_strcmp(controls->parallel.data, + controls->parallel.size)) { + loop_ub_tmp = 0; + } else if (coder::internal::o_strcmp(controls->parallel.data, + controls->parallel.size)) { + loop_ub_tmp = 1; + } else if (coder::internal::p_strcmp(controls->parallel.data, + controls->parallel.size)) { + loop_ub_tmp = 2; + } else { + loop_ub_tmp = -1; + } + + switch (loop_ub_tmp) { + case 0: + b_single(problemStruct, problemCells, controls, contrastParams->ssubs, + contrastParams->backgroundParams, contrastParams->qzshifts, + contrastParams->scalefactors, contrastParams->bulkIn, + contrastParams->bulkOut, contrastParams->resolutionParams, + contrastParams->calculations.allChis, reflectivity, + simulation, shiftedData, layerSlds, domainSldProfiles, + b_allLayers, contrastParams->allSubRough); + allLayers.set_size(b_allLayers.size(0), 2); + loop_ub_tmp = b_allLayers.size(0); + for (int32_T b_i{0}; b_i < 2; b_i++) { + for (int32_T i1{0}; i1 < loop_ub_tmp; i1++) { + allLayers[i1 + allLayers.size(0) * b_i] = b_allLayers[i1 + + b_allLayers.size(0) * b_i]; + } + } + break; + + case 1: + parallelPoints(problemStruct, problemCells, controls, + contrastParams->ssubs, contrastParams->backgroundParams, + contrastParams->qzshifts, contrastParams->scalefactors, + contrastParams->bulkIn, contrastParams->bulkOut, + contrastParams->resolutionParams, + contrastParams->calculations.allChis, reflectivity, + simulation, shiftedData, layerSlds, domainSldProfiles, + b_allLayers, contrastParams->allSubRough); + allLayers.set_size(b_allLayers.size(0), 2); + loop_ub_tmp = b_allLayers.size(0); + for (int32_T b_i{0}; b_i < 2; b_i++) { + for (int32_T i1{0}; i1 < loop_ub_tmp; i1++) { + allLayers[i1 + allLayers.size(0) * b_i] = b_allLayers[i1 + + b_allLayers.size(0) * b_i]; + } + } + break; + + case 2: + c_parallelContrasts(problemStruct, problemCells, controls, + contrastParams->ssubs, + contrastParams->backgroundParams, + contrastParams->qzshifts, + contrastParams->scalefactors, + contrastParams->bulkIn, contrastParams->bulkOut, + contrastParams->resolutionParams, + contrastParams->calculations.allChis, reflectivity, + simulation, shiftedData, layerSlds, + domainSldProfiles, b_allLayers, + contrastParams->allSubRough); + allLayers.set_size(b_allLayers.size(0), 2); + loop_ub_tmp = b_allLayers.size(0); + for (int32_T b_i{0}; b_i < 2; b_i++) { + for (int32_T i1{0}; i1 < loop_ub_tmp; i1++) { + allLayers[i1 + allLayers.size(0) * b_i] = b_allLayers[i1 + + b_allLayers.size(0) * b_i]; + } + } + break; + } + + contrastParams->calculations.sumChi = coder::sum + (contrastParams->calculations.allChis); + contrastParams->resample.set_size(1, problemStruct->resample.size(1)); + loop_ub_tmp = problemStruct->resample.size(1); + for (int32_T b_i{0}; b_i < loop_ub_tmp; b_i++) { + contrastParams->resample[b_i] = problemStruct->resample[b_i]; + } + } + } + } +} + +// End of code generation (calculate4.cpp) diff --git a/cpp/RAT/calculate4.h b/cpp/RAT/calculate4.h new file mode 100644 index 00000000..98a05479 --- /dev/null +++ b/cpp/RAT/calculate4.h @@ -0,0 +1,42 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// calculate4.h +// +// Code generation for function 'calculate4' +// +#ifndef CALCULATE4_H +#define CALCULATE4_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace domainsTF + { + namespace customLayers + { + void calculate(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, d_struct_T + *contrastParams, ::coder::array + &reflectivity, ::coder::array &simulation, + ::coder::array &shiftedData, ::coder:: + array &layerSlds, ::coder::array< + cell_wrap_8, 2U> &domainSldProfiles, ::coder::array< + cell_wrap_8, 2U> &allLayers); + } + } +} + +#endif + +// End of code generation (calculate4.h) diff --git a/cpp/RAT/calculate5.cpp b/cpp/RAT/calculate5.cpp new file mode 100644 index 00000000..79a7ecd3 --- /dev/null +++ b/cpp/RAT/calculate5.cpp @@ -0,0 +1,214 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// calculate5.cpp +// +// Code generation for function 'calculate5' +// + +// Include files +#include "calculate5.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "parallelContrasts5.h" +#include "parallelPoints5.h" +#include "rt_nonfinite.h" +#include "single5.h" +#include "strcmp.h" +#include "sum.h" +#include "coder_array.h" +#include "coder_bounded_array.h" + +// Function Definitions +namespace RAT +{ + namespace domainsTF + { + namespace customXY + { + void calculate(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, d_struct_T + *contrastParams, ::coder::array + &reflectivity, ::coder::array &simulation, + ::coder::array &shiftedData, ::coder:: + array &layerSlds, ::coder::array< + cell_wrap_8, 2U> &domainSldProfiles, ::coder::array< + cell_wrap_8, 2U> &allLayers) + { + ::coder::array b_allLayers; + int32_T loop_ub_tmp; + + // Custom layers reflectivity calculation for domainsTF + // This function decides on parallelisation options before calling the + // relevant version of the main custom layers calculation. It is more + // efficient to have multiple versions of the core calculation, each dealing + // with a different scheme for parallelisation. These are: + // single - single threaded reflectivity calculation + // points - parallelise over points in the reflectivity calculation + // contrasts - parallelise over contrasts. + // Pre-allocation - It's necessary to + // pre-allocate the memory for all the arrays + // for compilation, so do this in this block. + loop_ub_tmp = static_cast(problemStruct->numberOfContrasts); + contrastParams->ssubs.set_size(loop_ub_tmp); + contrastParams->backgroundParams.set_size(loop_ub_tmp); + contrastParams->qzshifts.set_size(loop_ub_tmp); + contrastParams->scalefactors.set_size(loop_ub_tmp); + contrastParams->bulkIn.set_size(loop_ub_tmp); + contrastParams->bulkOut.set_size(loop_ub_tmp); + contrastParams->calculations.allChis.set_size(loop_ub_tmp); + contrastParams->resolutionParams.set_size(loop_ub_tmp); + contrastParams->allSubRough.set_size(loop_ub_tmp); + reflectivity.set_size(loop_ub_tmp); + simulation.set_size(loop_ub_tmp); + shiftedData.set_size(loop_ub_tmp); + layerSlds.set_size(loop_ub_tmp, 2); + domainSldProfiles.set_size(loop_ub_tmp, 2); + allLayers.set_size(loop_ub_tmp, 2); + for (int32_T i{0}; i < loop_ub_tmp; i++) { + contrastParams->ssubs[i] = 0.0; + contrastParams->backgroundParams[i] = 0.0; + contrastParams->qzshifts[i] = 0.0; + contrastParams->scalefactors[i] = 0.0; + contrastParams->bulkIn[i] = 0.0; + contrastParams->bulkOut[i] = 0.0; + contrastParams->calculations.allChis[i] = 0.0; + contrastParams->resolutionParams[i] = 0.0; + contrastParams->allSubRough[i] = 0.0; + reflectivity[i].f1.set_size(2, 2); + reflectivity[i].f1[0] = 1.0; + reflectivity[i].f1[1] = 1.0; + reflectivity[i].f1[reflectivity[i].f1.size(0)] = 1.0; + reflectivity[i].f1[reflectivity[i].f1.size(0) + 1] = 1.0; + simulation[i].f1.set_size(2, 2); + simulation[i].f1[0] = 1.0; + simulation[i].f1[1] = 1.0; + simulation[i].f1[simulation[i].f1.size(0)] = 1.0; + simulation[i].f1[simulation[i].f1.size(0) + 1] = 1.0; + shiftedData[i].f1.set_size(2, 3); + layerSlds[i].f1.set_size(2, 3); + layerSlds[i + layerSlds.size(0)].f1.set_size(2, 3); + domainSldProfiles[i].f1.set_size(2, 2); + domainSldProfiles[i + domainSldProfiles.size(0)].f1.set_size(2, 2); + domainSldProfiles[i].f1[0] = 1.0; + domainSldProfiles[i + domainSldProfiles.size(0)].f1[0] = 1.0; + domainSldProfiles[i].f1[1] = 1.0; + domainSldProfiles[i + domainSldProfiles.size(0)].f1[1] = 1.0; + domainSldProfiles[i].f1[domainSldProfiles[i].f1.size(0)] = 1.0; + domainSldProfiles[i + domainSldProfiles.size(0)] + .f1[domainSldProfiles[i + domainSldProfiles.size(0)].f1.size(0)] = + 1.0; + domainSldProfiles[i].f1[domainSldProfiles[i].f1.size(0) + 1] = 1.0; + domainSldProfiles[i + domainSldProfiles.size(0)] + .f1[domainSldProfiles[i + domainSldProfiles.size(0)].f1.size(0) + 1] + = 1.0; + allLayers[i].f1.set_size(2, 3); + allLayers[i + allLayers.size(0)].f1.set_size(2, 3); + for (int32_T b_i{0}; b_i < 3; b_i++) { + shiftedData[i].f1[shiftedData[i].f1.size(0) * b_i] = 1.0; + shiftedData[i].f1[shiftedData[i].f1.size(0) * b_i + 1] = 1.0; + layerSlds[i].f1[layerSlds[i].f1.size(0) * b_i] = 1.0; + layerSlds[i + layerSlds.size(0)].f1[layerSlds[i + layerSlds.size(0)] + .f1.size(0) * b_i] = 1.0; + layerSlds[i].f1[layerSlds[i].f1.size(0) * b_i + 1] = 1.0; + layerSlds[i + layerSlds.size(0)].f1[layerSlds[i + layerSlds.size(0)] + .f1.size(0) * b_i + 1] = 1.0; + allLayers[i].f1[allLayers[i].f1.size(0) * b_i] = 1.0; + allLayers[i + allLayers.size(0)].f1[allLayers[i + allLayers.size(0)] + .f1.size(0) * b_i] = 1.0; + allLayers[i].f1[allLayers[i].f1.size(0) * b_i + 1] = 1.0; + allLayers[i + allLayers.size(0)].f1[allLayers[i + allLayers.size(0)] + .f1.size(0) * b_i + 1] = 1.0; + } + } + + // End pre-allocation + if (coder::internal::n_strcmp(controls->parallel.data, + controls->parallel.size)) { + loop_ub_tmp = 0; + } else if (coder::internal::o_strcmp(controls->parallel.data, + controls->parallel.size)) { + loop_ub_tmp = 1; + } else if (coder::internal::p_strcmp(controls->parallel.data, + controls->parallel.size)) { + loop_ub_tmp = 2; + } else { + loop_ub_tmp = -1; + } + + switch (loop_ub_tmp) { + case 0: + b_single(problemStruct, problemCells, controls, contrastParams->ssubs, + contrastParams->backgroundParams, contrastParams->qzshifts, + contrastParams->scalefactors, contrastParams->bulkIn, + contrastParams->bulkOut, contrastParams->resolutionParams, + contrastParams->calculations.allChis, reflectivity, + simulation, shiftedData, layerSlds, domainSldProfiles, + b_allLayers, contrastParams->allSubRough); + allLayers.set_size(b_allLayers.size(0), 2); + loop_ub_tmp = b_allLayers.size(0); + for (int32_T b_i{0}; b_i < 2; b_i++) { + for (int32_T i1{0}; i1 < loop_ub_tmp; i1++) { + allLayers[i1 + allLayers.size(0) * b_i] = b_allLayers[i1 + + b_allLayers.size(0) * b_i]; + } + } + break; + + case 1: + parallelPoints(problemStruct, problemCells, controls, + contrastParams->ssubs, contrastParams->backgroundParams, + contrastParams->qzshifts, contrastParams->scalefactors, + contrastParams->bulkIn, contrastParams->bulkOut, + contrastParams->resolutionParams, + contrastParams->calculations.allChis, reflectivity, + simulation, shiftedData, layerSlds, domainSldProfiles, + b_allLayers, contrastParams->allSubRough); + allLayers.set_size(b_allLayers.size(0), 2); + loop_ub_tmp = b_allLayers.size(0); + for (int32_T b_i{0}; b_i < 2; b_i++) { + for (int32_T i1{0}; i1 < loop_ub_tmp; i1++) { + allLayers[i1 + allLayers.size(0) * b_i] = b_allLayers[i1 + + b_allLayers.size(0) * b_i]; + } + } + break; + + case 2: + c_parallelContrasts(problemStruct, problemCells, controls, + contrastParams->ssubs, + contrastParams->backgroundParams, + contrastParams->qzshifts, + contrastParams->scalefactors, + contrastParams->bulkIn, contrastParams->bulkOut, + contrastParams->resolutionParams, + contrastParams->calculations.allChis, reflectivity, + simulation, shiftedData, layerSlds, + domainSldProfiles, b_allLayers, + contrastParams->allSubRough); + allLayers.set_size(b_allLayers.size(0), 2); + loop_ub_tmp = b_allLayers.size(0); + for (int32_T b_i{0}; b_i < 2; b_i++) { + for (int32_T i1{0}; i1 < loop_ub_tmp; i1++) { + allLayers[i1 + allLayers.size(0) * b_i] = b_allLayers[i1 + + b_allLayers.size(0) * b_i]; + } + } + break; + } + + contrastParams->calculations.sumChi = coder::sum + (contrastParams->calculations.allChis); + contrastParams->resample.set_size(1, problemStruct->resample.size(1)); + loop_ub_tmp = problemStruct->resample.size(1); + for (int32_T b_i{0}; b_i < loop_ub_tmp; b_i++) { + contrastParams->resample[b_i] = problemStruct->resample[b_i]; + } + } + } + } +} + +// End of code generation (calculate5.cpp) diff --git a/cpp/RAT/calculate5.h b/cpp/RAT/calculate5.h new file mode 100644 index 00000000..7c2fe788 --- /dev/null +++ b/cpp/RAT/calculate5.h @@ -0,0 +1,42 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// calculate5.h +// +// Code generation for function 'calculate5' +// +#ifndef CALCULATE5_H +#define CALCULATE5_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace domainsTF + { + namespace customXY + { + void calculate(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, d_struct_T + *contrastParams, ::coder::array + &reflectivity, ::coder::array &simulation, + ::coder::array &shiftedData, ::coder:: + array &layerSlds, ::coder::array< + cell_wrap_8, 2U> &domainSldProfiles, ::coder::array< + cell_wrap_8, 2U> &allLayers); + } + } +} + +#endif + +// End of code generation (calculate5.h) diff --git a/cpp/RAT/callCppFunction.cpp b/cpp/RAT/callCppFunction.cpp new file mode 100644 index 00000000..b7f165d3 --- /dev/null +++ b/cpp/RAT/callCppFunction.cpp @@ -0,0 +1,222 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// callCppFunction.cpp +// +// Code generation for function 'callCppFunction' +// + +// Include files +#include "callCppFunction.h" +#include "rt_nonfinite.h" +#include "classHandle.hpp" +#include "coder_array.h" +#include +#include +#include + +// Function Definitions +namespace RAT +{ + void b_callCppFunction(const char_T pointer_data[], const int32_T + pointer_size[2], ::coder::array ¶ms, real_T bulkIn, ::coder:: + array &bulkOut, real_T contrast, ::coder::array + &output, real_T *subRough) + { + CallbackInterface * callback; + ClassHandle * callbackHandle; + std::vector bulkInArray; + std::vector bulkOutArray; + std::vector outArray; + std::vector paramsArray; + ::coder::array tempOutput; + real_T outputSize[2]; + real_T d; + int32_T loop_ub; + int32_T loop_ub_tmp; + char_T b_pointer_data[10000]; + loop_ub = pointer_size[1]; + if (loop_ub - 1 >= 0) { + std::copy(&pointer_data[0], &pointer_data[loop_ub], &b_pointer_data[0]); + } + + callbackHandle = convertString2HandlePtr(&b_pointer_data + [0]); + callback = std::mem_fn(&ClassHandle::ptr)(callbackHandle); + paramsArray = convertPtr2Vector(¶ms[0], static_cast(params.size + (1))); + bulkInArray = convertPtr2Vector(&bulkIn, 1.0); + bulkOutArray = convertPtr2Vector(&bulkOut[0], static_cast + (bulkOut.size(1))); + outArray = { }; + + // domain should either before 0 or 1. A value less than zero indicates no domains + std::mem_fn&, std::vector&, std::vector< + double>&, int, int, std::vector&, double*, double*)> + (&CallbackInterface::invoke)(callback, paramsArray, bulkInArray, + bulkOutArray, contrast, 0.0, outArray, &outputSize[0], subRough); + d = std::round(outputSize[0] * outputSize[1]); + if (d < 2.147483648E+9) { + if (d >= -2.147483648E+9) { + loop_ub = static_cast(d); + } else { + loop_ub = MIN_int32_T; + } + } else if (d >= 2.147483648E+9) { + loop_ub = MAX_int32_T; + } else { + loop_ub = 0; + } + + tempOutput.set_size(1, loop_ub); + for (int32_T i{0}; i < loop_ub; i++) { + tempOutput[i] = 0.0; + } + + convertVector2Ptr(outArray, &tempOutput[0]); + loop_ub_tmp = static_cast(outputSize[1]); + loop_ub = static_cast(outputSize[0]); + output.set_size(loop_ub, loop_ub_tmp); + for (int32_T i{0}; i < loop_ub_tmp; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + output[i1 + output.size(0) * i] = tempOutput[i + loop_ub_tmp * i1]; + } + } + } + + void c_callCppFunction(const char_T pointer_data[], const int32_T + pointer_size[2], ::coder::array ¶ms, real_T bulkIn, ::coder:: + array &bulkOut, real_T contrast, ::coder::array + &output, real_T *subRough) + { + CallbackInterface * callback; + ClassHandle * callbackHandle; + std::vector bulkInArray; + std::vector bulkOutArray; + std::vector outArray; + std::vector paramsArray; + ::coder::array tempOutput; + real_T outputSize[2]; + real_T d; + int32_T loop_ub; + int32_T loop_ub_tmp; + char_T b_pointer_data[10000]; + loop_ub = pointer_size[1]; + if (loop_ub - 1 >= 0) { + std::copy(&pointer_data[0], &pointer_data[loop_ub], &b_pointer_data[0]); + } + + callbackHandle = convertString2HandlePtr(&b_pointer_data + [0]); + callback = std::mem_fn(&ClassHandle::ptr)(callbackHandle); + paramsArray = convertPtr2Vector(¶ms[0], static_cast(params.size + (1))); + bulkInArray = convertPtr2Vector(&bulkIn, 1.0); + bulkOutArray = convertPtr2Vector(&bulkOut[0], static_cast + (bulkOut.size(1))); + outArray = { }; + + // domain should either before 0 or 1. A value less than zero indicates no domains + std::mem_fn&, std::vector&, std::vector< + double>&, int, int, std::vector&, double*, double*)> + (&CallbackInterface::invoke)(callback, paramsArray, bulkInArray, + bulkOutArray, contrast, 1.0, outArray, &outputSize[0], subRough); + d = std::round(outputSize[0] * outputSize[1]); + if (d < 2.147483648E+9) { + if (d >= -2.147483648E+9) { + loop_ub = static_cast(d); + } else { + loop_ub = MIN_int32_T; + } + } else if (d >= 2.147483648E+9) { + loop_ub = MAX_int32_T; + } else { + loop_ub = 0; + } + + tempOutput.set_size(1, loop_ub); + for (int32_T i{0}; i < loop_ub; i++) { + tempOutput[i] = 0.0; + } + + convertVector2Ptr(outArray, &tempOutput[0]); + loop_ub_tmp = static_cast(outputSize[1]); + loop_ub = static_cast(outputSize[0]); + output.set_size(loop_ub, loop_ub_tmp); + for (int32_T i{0}; i < loop_ub_tmp; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + output[i1 + output.size(0) * i] = tempOutput[i + loop_ub_tmp * i1]; + } + } + } + + void callCppFunction(const char_T pointer_data[], const int32_T pointer_size[2], + ::coder::array ¶ms, real_T bulkIn, :: + coder::array &bulkOut, real_T contrast, :: + coder::array &output, real_T *subRough) + { + CallbackInterface * callback; + ClassHandle * callbackHandle; + std::vector bulkInArray; + std::vector bulkOutArray; + std::vector outArray; + std::vector paramsArray; + ::coder::array tempOutput; + real_T outputSize[2]; + real_T d; + int32_T loop_ub; + int32_T loop_ub_tmp; + char_T b_pointer_data[10000]; + loop_ub = pointer_size[1]; + if (loop_ub - 1 >= 0) { + std::copy(&pointer_data[0], &pointer_data[loop_ub], &b_pointer_data[0]); + } + + callbackHandle = convertString2HandlePtr(&b_pointer_data + [0]); + callback = std::mem_fn(&ClassHandle::ptr)(callbackHandle); + paramsArray = convertPtr2Vector(¶ms[0], static_cast(params.size + (1))); + bulkInArray = convertPtr2Vector(&bulkIn, 1.0); + bulkOutArray = convertPtr2Vector(&bulkOut[0], static_cast + (bulkOut.size(1))); + outArray = { }; + + // domain should either before 0 or 1. A value less than zero indicates no domains + std::mem_fn&, std::vector&, std::vector< + double>&, int, std::vector&, double*, double*)> + (&CallbackInterface::invoke)(callback, paramsArray, bulkInArray, + bulkOutArray, contrast, outArray, &outputSize[0], subRough); + d = std::round(outputSize[0] * outputSize[1]); + if (d < 2.147483648E+9) { + if (d >= -2.147483648E+9) { + loop_ub = static_cast(d); + } else { + loop_ub = MIN_int32_T; + } + } else if (d >= 2.147483648E+9) { + loop_ub = MAX_int32_T; + } else { + loop_ub = 0; + } + + tempOutput.set_size(1, loop_ub); + for (int32_T i{0}; i < loop_ub; i++) { + tempOutput[i] = 0.0; + } + + convertVector2Ptr(outArray, &tempOutput[0]); + loop_ub_tmp = static_cast(outputSize[1]); + loop_ub = static_cast(outputSize[0]); + output.set_size(loop_ub, loop_ub_tmp); + for (int32_T i{0}; i < loop_ub_tmp; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + output[i1 + output.size(0) * i] = tempOutput[i + loop_ub_tmp * i1]; + } + } + } +} + +// End of code generation (callCppFunction.cpp) diff --git a/cpp/RAT/callCppFunction.h b/cpp/RAT/callCppFunction.h new file mode 100644 index 00000000..7ce9ecbe --- /dev/null +++ b/cpp/RAT/callCppFunction.h @@ -0,0 +1,38 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// callCppFunction.h +// +// Code generation for function 'callCppFunction' +// +#ifndef CALLCPPFUNCTION_H +#define CALLCPPFUNCTION_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void b_callCppFunction(const char_T pointer_data[], const int32_T + pointer_size[2], ::coder::array ¶ms, real_T bulkIn, ::coder:: + array &bulkOut, real_T contrast, ::coder::array + &output, real_T *subRough); + void c_callCppFunction(const char_T pointer_data[], const int32_T + pointer_size[2], ::coder::array ¶ms, real_T bulkIn, ::coder:: + array &bulkOut, real_T contrast, ::coder::array + &output, real_T *subRough); + void callCppFunction(const char_T pointer_data[], const int32_T pointer_size[2], + ::coder::array ¶ms, real_T bulkIn, :: + coder::array &bulkOut, real_T contrast, :: + coder::array &output, real_T *subRough); +} + +#endif + +// End of code generation (callCppFunction.h) diff --git a/cpp/RAT/callReflectivity.cpp b/cpp/RAT/callReflectivity.cpp new file mode 100644 index 00000000..de5eaa5b --- /dev/null +++ b/cpp/RAT/callReflectivity.cpp @@ -0,0 +1,541 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// callReflectivity.cpp +// +// Code generation for function 'callReflectivity' +// + +// Include files +#include "callReflectivity.h" +#include "abelesParallelPoints.h" +#include "abelesSingle.h" +#include "colon.h" +#include "dataResolutionPolly.h" +#include "resolutionPolly.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + void b_callReflectivity(real_T bulkIns, real_T bulkOuts, const real_T + simLimits[2], const real_T repeatLayers[2], const ::coder::array + &thisData, ::coder::array &layers, real_T ssubs, real_T + resolution, boolean_T useImaginary, ::coder::array &reflectivity, + ::coder::array &simulation) + { + ::coder::array slds; + ::coder::array firstSection; + ::coder::array lastSection; + ::coder::array r; + ::coder::array roughs; + ::coder::array simRef; + ::coder::array simResolData; + ::coder::array simXdata; + ::coder::array thicks; + real_T b; + real_T nLayersTot; + real_T nRepeats; + real_T step; + int32_T i; + int32_T i1; + int32_T loop_ub; + int32_T loop_ub_tmp; + uint32_T layerCount; + uint32_T splits_idx_1; + if (repeatLayers[0] != 0.0) { + nRepeats = repeatLayers[1]; + } else { + nRepeats = 1.0; + } + + // Build the input arrays for thick, sld and rough..... + if (layers.size(0) == 0) { + // No layers defined. Make a zeros dummy zero layer + layers.set_size(1, 3); + layers[0] = 0.0; + layers[layers.size(0)] = bulkIns; + layers[layers.size(0) * 2] = 0.0; + } + + // Number of layers (including repeats) + nLayersTot = static_cast(layers.size(0)) * nRepeats + 2.0; + + // Make arrays for thick, sld, rough + loop_ub_tmp = static_cast(nLayersTot); + thicks.set_size(loop_ub_tmp); + roughs.set_size(loop_ub_tmp); + for (i = 0; i < loop_ub_tmp; i++) { + thicks[i] = 0.0; + roughs[i] = 0.0; + } + + if (useImaginary) { + slds.set_size(loop_ub_tmp); + for (i = 0; i < loop_ub_tmp; i++) { + slds[i].re = 0.0; + slds[i].im = 0.0; + } + } else { + slds.set_size(loop_ub_tmp); + for (i = 0; i < loop_ub_tmp; i++) { + slds[i].re = 0.0; + slds[i].im = 0.0; + } + } + + // Populate the d,rho,sig arrays... + layerCount = 2U; + i = static_cast(nRepeats); + for (int32_T m{0}; m < i; m++) { + i1 = layers.size(0); + for (int32_T n{0}; n < i1; n++) { + if (!useImaginary) { + loop_ub_tmp = static_cast(layerCount + static_cast + (n)) - 1; + thicks[loop_ub_tmp] = layers[n]; + slds[loop_ub_tmp].re = layers[n + layers.size(0)]; + slds[loop_ub_tmp].im = 0.0; + roughs[loop_ub_tmp] = layers[n + layers.size(0) * 2]; + } else { + loop_ub_tmp = static_cast(layerCount + static_cast + (n)) - 1; + thicks[loop_ub_tmp] = layers[n]; + slds[loop_ub_tmp].re = layers[n + layers.size(0)]; + slds[loop_ub_tmp].im = layers[n + layers.size(0) * 2]; + roughs[loop_ub_tmp] = layers[n + layers.size(0) * 3]; + } + } + + layerCount += static_cast(layers.size(0)); + } + + // Add the air and substrate parameters + slds[0].re = bulkIns; + slds[0].im = 0.0; + slds[slds.size(0) - 1].re = bulkOuts; + slds[slds.size(0) - 1].im = 0.0; + roughs[roughs.size(0) - 1] = ssubs; + if (simLimits[0] < thisData[0]) { + step = thisData[1] - thisData[0]; + b = thisData[0] - step; + if (std::isnan(step) || std::isnan(b)) { + firstSection.set_size(1, 1); + firstSection[0] = rtNaN; + } else if ((step == 0.0) || ((simLimits[0] < b) && (step < 0.0)) || ((b < + simLimits[0]) && (step > 0.0))) { + firstSection.set_size(1, 0); + } else if ((std::isinf(simLimits[0]) || std::isinf(b)) && (std::isinf(step) + || (simLimits[0] == b))) { + firstSection.set_size(1, 1); + firstSection[0] = rtNaN; + } else if (std::isinf(step)) { + firstSection.set_size(1, 1); + firstSection[0] = simLimits[0]; + } else if ((std::floor(simLimits[0]) == simLimits[0]) && (std::floor(step) + == step)) { + loop_ub = static_cast((b - simLimits[0]) / step); + firstSection.set_size(1, loop_ub + 1); + for (i = 0; i <= loop_ub; i++) { + firstSection[i] = simLimits[0] + step * static_cast(i); + } + } else { + coder::eml_float_colon(simLimits[0], step, b, firstSection); + } + } else { + firstSection.set_size(1, 0); + } + + if (simLimits[1] > thisData[thisData.size(0) - 1]) { + step = thisData[thisData.size(0) - 1] - thisData[thisData.size(0) - 2]; + b = thisData[thisData.size(0) - 1] + step; + if (std::isnan(b) || std::isnan(step)) { + lastSection.set_size(1, 1); + lastSection[0] = rtNaN; + } else if ((step == 0.0) || ((b < simLimits[1]) && (step < 0.0)) || + ((simLimits[1] < b) && (step > 0.0))) { + lastSection.set_size(1, 0); + } else if ((std::isinf(b) || std::isinf(simLimits[1])) && (std::isinf(step) + || (b == simLimits[1]))) { + lastSection.set_size(1, 1); + lastSection[0] = rtNaN; + } else if (std::isinf(step)) { + lastSection.set_size(1, 1); + lastSection[0] = b; + } else if ((std::floor(b) == b) && (std::floor(step) == step)) { + loop_ub = static_cast((simLimits[1] - b) / step); + lastSection.set_size(1, loop_ub + 1); + for (i = 0; i <= loop_ub; i++) { + lastSection[i] = b + step * static_cast(i); + } + } else { + coder::eml_float_colon(b, step, simLimits[1], lastSection); + } + } else { + lastSection.set_size(1, 0); + } + + loop_ub_tmp = firstSection.size(1); + simXdata.set_size((thisData.size(0) + firstSection.size(1)) + + lastSection.size(1)); + loop_ub = firstSection.size(1); + for (i = 0; i < loop_ub; i++) { + simXdata[i] = firstSection[i]; + } + + loop_ub = thisData.size(0); + for (i = 0; i < loop_ub; i++) { + simXdata[i + loop_ub_tmp] = thisData[i]; + } + + loop_ub = lastSection.size(1); + for (i = 0; i < loop_ub; i++) { + simXdata[(i + loop_ub_tmp) + thisData.size(0)] = lastSection[i]; + } + + splits_idx_1 = static_cast(firstSection.size(1)) + + static_cast(thisData.size(0)); + simulation.set_size(simXdata.size(0), 2); + loop_ub = simXdata.size(0); + for (i = 0; i < 2; i++) { + for (i1 = 0; i1 < loop_ub; i1++) { + simulation[i1 + simulation.size(0) * i] = 0.0; + } + } + + loop_ub = simXdata.size(0); + for (i = 0; i < loop_ub; i++) { + simulation[i] = simXdata[i]; + } + + // If we are using data resolutions, then we also need to adjust the length + // of the reolution column. We do thit by just extending with the rosolution + // values at the ends of the curve. + simResolData.set_size(1); + simResolData[0] = 0.0; + if (resolution == -1.0) { + loop_ub_tmp = firstSection.size(1); + simResolData.set_size((thisData.size(0) + firstSection.size(1)) + + lastSection.size(1)); + loop_ub = firstSection.size(1); + for (i = 0; i < loop_ub; i++) { + simResolData[i] = thisData[thisData.size(0) * 3]; + } + + loop_ub = thisData.size(0); + for (i = 0; i < loop_ub; i++) { + simResolData[i + loop_ub_tmp] = thisData[i + thisData.size(0) * 3]; + } + + loop_ub = lastSection.size(1); + for (i = 0; i < loop_ub; i++) { + simResolData[(i + loop_ub_tmp) + thisData.size(0)] = thisData + [(thisData.size(0) + thisData.size(0) * 3) - 1]; + } + } + + // Parallelise over points + // Calculate reflectivity.... + abelesParallelPoints(simXdata, nLayersTot, thicks, slds, roughs, simRef); + + // Apply resolution + // Note: paraPoints gives an error during valifation, so use + // single cored resolution as a workaround for now. + if (resolution == -1.0) { + // simRef = dataResolutionPollyParallelPoints(simXdata,simRef,simResolData,length(simXdata)); + dataResolutionPolly(simXdata, simRef, simResolData, static_cast + (simXdata.size(0)), r); + loop_ub = r.size(0); + for (i = 0; i < loop_ub; i++) { + simulation[i + simulation.size(0)] = r[i]; + } + } else { + // simRef = resolutionPollyParallelPoints(simXdata,simRef,res,length(simXdata)); + resolutionPolly(simXdata, simRef, resolution, static_cast + (simXdata.size(0)), r); + loop_ub = r.size(0); + for (i = 0; i < loop_ub; i++) { + simulation[i + simulation.size(0)] = r[i]; + } + } + + if (static_cast(firstSection.size(1)) + 1U > splits_idx_1) { + i = 0; + i1 = 0; + } else { + i = firstSection.size(1); + i1 = static_cast(splits_idx_1); + } + + loop_ub = i1 - i; + reflectivity.set_size(loop_ub, 2); + for (i1 = 0; i1 < 2; i1++) { + for (loop_ub_tmp = 0; loop_ub_tmp < loop_ub; loop_ub_tmp++) { + reflectivity[loop_ub_tmp + reflectivity.size(0) * i1] = simulation[(i + + loop_ub_tmp) + simulation.size(0) * i1]; + } + } + } + + void callReflectivity(real_T bulkIns, real_T bulkOuts, const real_T simLimits + [2], const real_T repeatLayers[2], const ::coder::array< + real_T, 2U> &thisData, ::coder::array + &layers, real_T ssubs, real_T resolution, boolean_T + useImaginary, ::coder::array &reflectivity, :: + coder::array &simulation) + { + ::coder::array slds; + ::coder::array firstSection; + ::coder::array lastSection; + ::coder::array r; + ::coder::array roughs; + ::coder::array simRef; + ::coder::array simResolData; + ::coder::array simXdata; + ::coder::array thicks; + real_T b; + real_T nLayersTot; + real_T nRepeats; + real_T step; + int32_T i; + int32_T i1; + int32_T loop_ub; + int32_T loop_ub_tmp; + uint32_T layerCount; + uint32_T splits_idx_1; + if (repeatLayers[0] != 0.0) { + nRepeats = repeatLayers[1]; + } else { + nRepeats = 1.0; + } + + // Build the input arrays for thick, sld and rough..... + if (layers.size(0) == 0) { + // No layers defined. Make a zeros dummy zero layer + layers.set_size(1, 3); + layers[0] = 0.0; + layers[layers.size(0)] = bulkIns; + layers[layers.size(0) * 2] = 0.0; + } + + // Number of layers (including repeats) + nLayersTot = static_cast(layers.size(0)) * nRepeats + 2.0; + + // Make arrays for thick, sld, rough + loop_ub_tmp = static_cast(nLayersTot); + thicks.set_size(loop_ub_tmp); + roughs.set_size(loop_ub_tmp); + for (i = 0; i < loop_ub_tmp; i++) { + thicks[i] = 0.0; + roughs[i] = 0.0; + } + + if (useImaginary) { + slds.set_size(loop_ub_tmp); + for (i = 0; i < loop_ub_tmp; i++) { + slds[i].re = 0.0; + slds[i].im = 0.0; + } + } else { + slds.set_size(loop_ub_tmp); + for (i = 0; i < loop_ub_tmp; i++) { + slds[i].re = 0.0; + slds[i].im = 0.0; + } + } + + // Populate the d,rho,sig arrays... + layerCount = 2U; + i = static_cast(nRepeats); + for (int32_T m{0}; m < i; m++) { + i1 = layers.size(0); + for (int32_T n{0}; n < i1; n++) { + if (!useImaginary) { + loop_ub_tmp = static_cast(layerCount + static_cast + (n)) - 1; + thicks[loop_ub_tmp] = layers[n]; + slds[loop_ub_tmp].re = layers[n + layers.size(0)]; + slds[loop_ub_tmp].im = 0.0; + roughs[loop_ub_tmp] = layers[n + layers.size(0) * 2]; + } else { + loop_ub_tmp = static_cast(layerCount + static_cast + (n)) - 1; + thicks[loop_ub_tmp] = layers[n]; + slds[loop_ub_tmp].re = layers[n + layers.size(0)]; + slds[loop_ub_tmp].im = layers[n + layers.size(0) * 2]; + roughs[loop_ub_tmp] = layers[n + layers.size(0) * 3]; + } + } + + layerCount += static_cast(layers.size(0)); + } + + // Add the air and substrate parameters + slds[0].re = bulkIns; + slds[0].im = 0.0; + slds[slds.size(0) - 1].re = bulkOuts; + slds[slds.size(0) - 1].im = 0.0; + roughs[roughs.size(0) - 1] = ssubs; + if (simLimits[0] < thisData[0]) { + step = thisData[1] - thisData[0]; + b = thisData[0] - step; + if (std::isnan(step) || std::isnan(b)) { + firstSection.set_size(1, 1); + firstSection[0] = rtNaN; + } else if ((step == 0.0) || ((simLimits[0] < b) && (step < 0.0)) || ((b < + simLimits[0]) && (step > 0.0))) { + firstSection.set_size(1, 0); + } else if ((std::isinf(simLimits[0]) || std::isinf(b)) && (std::isinf(step) + || (simLimits[0] == b))) { + firstSection.set_size(1, 1); + firstSection[0] = rtNaN; + } else if (std::isinf(step)) { + firstSection.set_size(1, 1); + firstSection[0] = simLimits[0]; + } else if ((std::floor(simLimits[0]) == simLimits[0]) && (std::floor(step) + == step)) { + loop_ub = static_cast((b - simLimits[0]) / step); + firstSection.set_size(1, loop_ub + 1); + for (i = 0; i <= loop_ub; i++) { + firstSection[i] = simLimits[0] + step * static_cast(i); + } + } else { + coder::eml_float_colon(simLimits[0], step, b, firstSection); + } + } else { + firstSection.set_size(1, 0); + } + + if (simLimits[1] > thisData[thisData.size(0) - 1]) { + step = thisData[thisData.size(0) - 1] - thisData[thisData.size(0) - 2]; + b = thisData[thisData.size(0) - 1] + step; + if (std::isnan(b) || std::isnan(step)) { + lastSection.set_size(1, 1); + lastSection[0] = rtNaN; + } else if ((step == 0.0) || ((b < simLimits[1]) && (step < 0.0)) || + ((simLimits[1] < b) && (step > 0.0))) { + lastSection.set_size(1, 0); + } else if ((std::isinf(b) || std::isinf(simLimits[1])) && (std::isinf(step) + || (b == simLimits[1]))) { + lastSection.set_size(1, 1); + lastSection[0] = rtNaN; + } else if (std::isinf(step)) { + lastSection.set_size(1, 1); + lastSection[0] = b; + } else if ((std::floor(b) == b) && (std::floor(step) == step)) { + loop_ub = static_cast((simLimits[1] - b) / step); + lastSection.set_size(1, loop_ub + 1); + for (i = 0; i <= loop_ub; i++) { + lastSection[i] = b + step * static_cast(i); + } + } else { + coder::eml_float_colon(b, step, simLimits[1], lastSection); + } + } else { + lastSection.set_size(1, 0); + } + + loop_ub_tmp = firstSection.size(1); + simXdata.set_size((thisData.size(0) + firstSection.size(1)) + + lastSection.size(1)); + loop_ub = firstSection.size(1); + for (i = 0; i < loop_ub; i++) { + simXdata[i] = firstSection[i]; + } + + loop_ub = thisData.size(0); + for (i = 0; i < loop_ub; i++) { + simXdata[i + loop_ub_tmp] = thisData[i]; + } + + loop_ub = lastSection.size(1); + for (i = 0; i < loop_ub; i++) { + simXdata[(i + loop_ub_tmp) + thisData.size(0)] = lastSection[i]; + } + + splits_idx_1 = static_cast(firstSection.size(1)) + + static_cast(thisData.size(0)); + simulation.set_size(simXdata.size(0), 2); + loop_ub = simXdata.size(0); + for (i = 0; i < 2; i++) { + for (i1 = 0; i1 < loop_ub; i1++) { + simulation[i1 + simulation.size(0) * i] = 0.0; + } + } + + loop_ub = simXdata.size(0); + for (i = 0; i < loop_ub; i++) { + simulation[i] = simXdata[i]; + } + + // If we are using data resolutions, then we also need to adjust the length + // of the reolution column. We do thit by just extending with the rosolution + // values at the ends of the curve. + simResolData.set_size(1); + simResolData[0] = 0.0; + if (resolution == -1.0) { + loop_ub_tmp = firstSection.size(1); + simResolData.set_size((thisData.size(0) + firstSection.size(1)) + + lastSection.size(1)); + loop_ub = firstSection.size(1); + for (i = 0; i < loop_ub; i++) { + simResolData[i] = thisData[thisData.size(0) * 3]; + } + + loop_ub = thisData.size(0); + for (i = 0; i < loop_ub; i++) { + simResolData[i + loop_ub_tmp] = thisData[i + thisData.size(0) * 3]; + } + + loop_ub = lastSection.size(1); + for (i = 0; i < loop_ub; i++) { + simResolData[(i + loop_ub_tmp) + thisData.size(0)] = thisData + [(thisData.size(0) + thisData.size(0) * 3) - 1]; + } + } + + // Single cored over points + // Calculate reflectivity..... + abelesSingle(simXdata, nLayersTot, thicks, slds, roughs, simRef); + + // Apply resolution correction... + if (resolution == -1.0) { + dataResolutionPolly(simXdata, simRef, simResolData, static_cast + (simXdata.size(0)), r); + loop_ub = r.size(0); + for (i = 0; i < loop_ub; i++) { + simulation[i + simulation.size(0)] = r[i]; + } + } else { + resolutionPolly(simXdata, simRef, resolution, static_cast + (simXdata.size(0)), r); + loop_ub = r.size(0); + for (i = 0; i < loop_ub; i++) { + simulation[i + simulation.size(0)] = r[i]; + } + } + + if (static_cast(firstSection.size(1)) + 1U > splits_idx_1) { + i = 0; + i1 = 0; + } else { + i = firstSection.size(1); + i1 = static_cast(splits_idx_1); + } + + loop_ub = i1 - i; + reflectivity.set_size(loop_ub, 2); + for (i1 = 0; i1 < 2; i1++) { + for (loop_ub_tmp = 0; loop_ub_tmp < loop_ub; loop_ub_tmp++) { + reflectivity[loop_ub_tmp + reflectivity.size(0) * i1] = simulation[(i + + loop_ub_tmp) + simulation.size(0) * i1]; + } + } + } +} + +// End of code generation (callReflectivity.cpp) diff --git a/cpp/RAT/callReflectivity.h b/cpp/RAT/callReflectivity.h new file mode 100644 index 00000000..550331ae --- /dev/null +++ b/cpp/RAT/callReflectivity.h @@ -0,0 +1,37 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// callReflectivity.h +// +// Code generation for function 'callReflectivity' +// +#ifndef CALLREFLECTIVITY_H +#define CALLREFLECTIVITY_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void b_callReflectivity(real_T bulkIns, real_T bulkOuts, const real_T + simLimits[2], const real_T repeatLayers[2], const ::coder::array + &thisData, ::coder::array &layers, real_T ssubs, real_T + resolution, boolean_T useImaginary, ::coder::array &reflectivity, + ::coder::array &simulation); + void callReflectivity(real_T bulkIns, real_T bulkOuts, const real_T simLimits + [2], const real_T repeatLayers[2], const ::coder::array< + real_T, 2U> &thisData, ::coder::array + &layers, real_T ssubs, real_T resolution, boolean_T + useImaginary, ::coder::array &reflectivity, :: + coder::array &simulation); +} + +#endif + +// End of code generation (callReflectivity.h) diff --git a/cpp/RAT/cat.cpp b/cpp/RAT/cat.cpp new file mode 100644 index 00000000..1c12a541 --- /dev/null +++ b/cpp/RAT/cat.cpp @@ -0,0 +1,61 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// cat.cpp +// +// Code generation for function 'cat' +// + +// Include files +#include "cat.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in2, real_T in3, const ::coder::array< + real_T, 2U> &in4) + { + ::coder::array b_in3; + int32_T i; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_1_0; + if (in4.size(0) == 1) { + i = in2.size(0); + } else { + i = in4.size(0); + } + + b_in3.set_size(i); + stride_0_0 = (in2.size(0) != 1); + stride_1_0 = (in4.size(0) != 1); + if (in4.size(0) == 1) { + loop_ub = in2.size(0); + } else { + loop_ub = in4.size(0); + } + + for (i = 0; i < loop_ub; i++) { + b_in3[i] = in3 * in2[i * stride_0_0 + in2.size(0)] + (1.0 - in3) * in4[i * + stride_1_0 + in4.size(0)]; + } + + in1.set_size(in2.size(0), 2); + loop_ub = in2.size(0); + for (i = 0; i < loop_ub; i++) { + in1[i] = in2[i]; + } + + loop_ub = b_in3.size(0); + for (i = 0; i < loop_ub; i++) { + in1[i + in1.size(0)] = b_in3[i]; + } + } +} + +// End of code generation (cat.cpp) diff --git a/cpp/RAT/cat.h b/cpp/RAT/cat.h new file mode 100644 index 00000000..eab1a742 --- /dev/null +++ b/cpp/RAT/cat.h @@ -0,0 +1,29 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// cat.h +// +// Code generation for function 'cat' +// +#ifndef CAT_H +#define CAT_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in2, real_T in3, const ::coder::array< + real_T, 2U> &in4); +} + +#endif + +// End of code generation (cat.h) diff --git a/cpp/RAT/chiSquared.cpp b/cpp/RAT/chiSquared.cpp new file mode 100644 index 00000000..e63d8da5 --- /dev/null +++ b/cpp/RAT/chiSquared.cpp @@ -0,0 +1,85 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// chiSquared.cpp +// +// Code generation for function 'chiSquared' +// + +// Include files +#include "chiSquared.h" +#include "find.h" +#include "minOrMax.h" +#include "rt_nonfinite.h" +#include "sum.h" +#include "unsafeSxfun.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + real_T chiSquared(const ::coder::array &thisData, const ::coder:: + array &thisFit, real_T P) + { + ::coder::array terms; + ::coder::array n; + ::coder::array b_terms; + real_T b_thisData[2]; + real_T N; + int32_T i; + int32_T loop_ub; + + // Chi-squared function is used to evaluate the goodness of fit. + // It is a measure of the difference between the observed and expected. + // allChis = zeros(1,numberOfContrasts); + // thisData = allData{i}; + // thisFit = allFits{i}; + b_thisData[0] = thisData.size(0); + b_thisData[1] = 1.0; + N = coder::internal::maximum(b_thisData); + if (N <= P) { + N = P + 1.0; + } + + if (thisData.size(0) == 1) { + i = thisFit.size(0); + } else { + i = thisData.size(0); + } + + if ((thisData.size(0) == thisFit.size(0)) && (i == thisData.size(0))) { + terms.set_size(thisData.size(0)); + loop_ub = thisData.size(0); + for (i = 0; i < loop_ub; i++) { + real_T varargin_1; + varargin_1 = (thisData[i + thisData.size(0)] - thisFit[i + thisFit.size + (0)]) / thisData[i + thisData.size(0) * 2]; + terms[i] = varargin_1 * varargin_1; + } + } else { + binary_expand_op(terms, thisData, thisFit); + } + + b_terms.set_size(terms.size(0)); + loop_ub = terms.size(0); + for (i = 0; i < loop_ub; i++) { + b_terms[i] = (terms[i] == rtInf); + } + + coder::eml_find(b_terms, n); + if (n.size(0) != 0) { + loop_ub = n.size(0); + for (i = 0; i < loop_ub; i++) { + terms[n[i] - 1] = 0.0; + } + } + + return 1.0 / (N - P) * coder::sum(terms); + + // allChis(i) = chi2; + } +} + +// End of code generation (chiSquared.cpp) diff --git a/cpp/RAT/chiSquared.h b/cpp/RAT/chiSquared.h new file mode 100644 index 00000000..eb9822ea --- /dev/null +++ b/cpp/RAT/chiSquared.h @@ -0,0 +1,28 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// chiSquared.h +// +// Code generation for function 'chiSquared' +// +#ifndef CHISQUARED_H +#define CHISQUARED_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + real_T chiSquared(const ::coder::array &thisData, const ::coder:: + array &thisFit, real_T P); +} + +#endif + +// End of code generation (chiSquared.h) diff --git a/cpp/RAT/classHandle.hpp b/cpp/RAT/classHandle.hpp new file mode 100644 index 00000000..ca08e2e7 --- /dev/null +++ b/cpp/RAT/classHandle.hpp @@ -0,0 +1,69 @@ +/* +Adapted from https://github.com/ojwoodford/mex_class_wrapper + +* The class handle is used to hold a pointer with a method to validate the ptr is valid +* The callback interface is provides the interface for domain and non-domain custom function +*/ +#ifndef __CLASS_HANDLE_HPP__ +#define __CLASS_HANDLE_HPP__ + +#include +#include +#include +#include +#include +#include + +#define CLASS_HANDLE_SIGNATURE 0xFF00F0A5 +template class ClassHandle +{ +public: + ClassHandle(base *ptr) : signature_m(CLASS_HANDLE_SIGNATURE), name_m(typeid(base).name()), ptr_m(ptr) {} + ~ClassHandle() { signature_m = 0; delete ptr_m; } + bool isValid() { return ((signature_m == CLASS_HANDLE_SIGNATURE) && !strcmp(name_m.c_str(), typeid(base).name())); } + base* ptr() { return ptr_m; } + +private: + uint32_t signature_m; + const std::string name_m; + base* const ptr_m; +}; + + +class CallbackInterface +{ +public: + virtual void invoke(std::vector& params, std::vector& bulk_in, std::vector& bulk_out, + int contrast, std::vector& tempOutput, double *outputSize, double *roughness)=0; + virtual void invoke(std::vector& params, std::vector& bulk_in, std::vector& bulk_out, + int contrast, int domainNumber, std::vector& tempOutput, double *outputSize, double *roughness)=0; +}; + +inline std::vector convertPtr2Vector(double* ptr, int size) +{ + std::vector array(ptr, ptr + size); + return array; +} + +inline std::size_t convertVector2Ptr(std::vector& array, double* ptr) +{ + std::memcpy(ptr, array.data(), array.size()*sizeof(double)); + return array.size(); +} + +template inline std::string convertPtr2String(base *ptr) +{ + auto handle = reinterpret_cast(new ClassHandle(ptr)); + return std::to_string(handle); +} + +template inline ClassHandle *convertString2HandlePtr(const char* in) +{ + uint64_t value = stoull(std::string(in)); + ClassHandle *ptr = reinterpret_cast *>(value); + if (!ptr->isValid()) + throw std::invalid_argument("callback handle is not valid"); + return ptr; +} + +#endif // __CLASS_HANDLE_HPP__ diff --git a/cpp/RAT/coder_array.h b/cpp/RAT/coder_array.h new file mode 100644 index 00000000..c6f39d7e --- /dev/null +++ b/cpp/RAT/coder_array.h @@ -0,0 +1,796 @@ +/* Copyright 2019-2021 The MathWorks, Inc. */ +/* Copied from + * fullfile(matlabroot,'extern','include','coder','coder_array','coder_array_rtw_cpp11.h') */ + +#ifndef _mw_coder_array_cpp11_h +#define _mw_coder_array_cpp11_h + +// Usage: +// +// coder::array: T base type of data, N number of dimensions +// +// coder::array() +// : default constructor +// coder::array(coder::array const &) +// : copy constructor (always make a deep copy of other array) +// coder::array(T const *data, SizeType const *sz) +// : Set data with sizes of this array. +// : (Data is not copied, data is not deleted) +// coder::array::operator = (coder coder::array &) +// : Assign into this array; +// : delete its previous contents (if owning the data.) +// set(T const *data, SizeType sz1, SizeType sz2, ...) +// : Set data with dimensions. +// : (Data is not copied, data is not deleted) +// set_size(SizeType sz1, SizeType sz2, ...) +// : Set sizes of array. Reallocate memory of data if needed. +// bool is_owner() : Return true if the data is owned by the class. +// void set_owner(b) : Set if the data is owned by the class. +// SizeType capacity() : How many entries are reserved by memory allocation. +// reshape( SizeType sz1, SizeType sz2, ...) +// : Reshape array to a different ND shape. Do not copy the data. +// : The number of elements must not be changed (numel()==sz1*sz2*...) +// : Return the array with possibly new number of dimensions. +// clear() : Reset array to be empty. +// SizeType numel() : Return the number of elements. +// operator [] (SizeType index) : Extract element at linear index (0 based.) +// size(SizeType dimension) : Size of array of the provided dimension. +// SizeType * size() : Return the pointer to all the sizes of this array. +// SizeType index(SizeType i1, SizeType i2, ...) +// : Compute the linear index from ND index (i1,i2,...) +// at(SizeType i1, SizeType i2, ...) : The element at index (i1,i2,...) + +#include +#include +#include +#include +#include + +#ifndef INT32_T +#include "rtwtypes.h" +#endif + +namespace coder { + +#ifndef CODER_ARRAY_NEW_DELETE +#define CODER_ARRAY_NEW_DELETE +#define CODER_NEW(T, N) new T[N] +#define CODER_DELETE(P) delete[](P) +#endif + +#ifndef CODER_ARRAY_SIZE_TYPE_DEFINED +using SizeType = int; +#endif + +namespace std = ::std; + +namespace detail { + +#ifndef CODER_ARRAY_DATA_PTR_DEFINED +template +class data_ptr { + public: + using value_type = T; + using size_type = SZ; + + data_ptr() + : data_(nullptr) + , size_(0) + , capacity_(0) + , owner_(false) { + } + data_ptr(T* _data, SZ _sz) + : data_(_data) + , size_(_sz) + , capacity_(_sz) + , owner_(false) { + } + + data_ptr(data_ptr const& _other) + : data_(_other.owner_ ? nullptr : _other.data_) + , size_(_other.owner_ ? 0 : _other.size_) + , capacity_(_other.owner_ ? 0 : _other.capacity_) + , owner_(_other.owner_) { + if (owner_) { + resize(_other.size_); + (void)std::copy(_other.data_, _other.data_ + size_, data_); + } + } + + ~data_ptr() { + if (owner_) { + CODER_DELETE(data_); + } + } + SZ capacity() const { + return capacity_; + } + void reserve(SZ _n) { + if (_n > capacity_) { + T* const new_data{CODER_NEW(T, _n)}; + (void)std::copy(data_, data_ + size_, new_data); + if (owner_) { + CODER_DELETE(data_); + } + data_ = new_data; + capacity_ = _n; + owner_ = true; + } + } + void resize(SZ _n) { + reserve(_n); + size_ = _n; + } + + private: + // Prohibit use of assignment operator to prevent subtle bugs + void operator=(data_ptr const& _other); + + public: + void set(T* _data, SZ _sz) { + if (owner_) { + CODER_DELETE(data_); + } + data_ = _data; + size_ = _sz; + owner_ = false; + capacity_ = size_; + } + + void copy(T const* const _data, SZ _size) { + if (data_ == _data) { + size_ = _size; + return; + } + if (owner_) { + CODER_DELETE(data_); + } + data_ = CODER_NEW(T, _size); + owner_ = true; + size_ = _size; + capacity_ = size_; + (void)std::copy(_data, _data + _size, data_); + } + + void copy(data_ptr const& _other) { + copy(_other.data_, _other.size_); + } + + operator T*() { + return &data_[0]; + } + + operator T const *() const { + return &data_[0]; + } + + T& operator[](SZ _index) { + return data_[_index]; + } + T const& operator[](SZ _index) const { + return data_[_index]; + } + + T* operator->() { + return data_; + } + + T const* operator->() const { + return data_; + } + + bool is_null() const { + return data_ == nullptr; + } + + void clear() { + if (owner_) { + CODER_DELETE(data_); + } + data_ = nullptr; + size_ = 0; + capacity_ = 0; + owner_ = false; + } + + bool is_owner() const { + return owner_; + } + + void set_owner(bool _b) { + owner_ = _b; + } + + private: + T* data_; + SZ size_; + SZ capacity_; + bool owner_; +}; +#endif + +} // namespace detail + +// Implementing the random access iterator class so coder::array can be +// used in STL iterators. +template +class array_iterator : public std::iterator { + public: + array_iterator() + : arr_(nullptr) + , i_(0) { + } + array_iterator(array_iterator const& other) + : arr_(other.arr_) + , i_(other.i_) { + } + ~array_iterator() { + } + typename T::value_type& operator*() const { + return (*arr_)[i_]; + } + typename T::value_type* operator->() const { + return &(*arr_)[i_]; + } + typename T::value_type& operator[](typename T::size_type _di) const { + return (*arr_)[i_ + _di]; + } + array_iterator& operator++() { + ++i_; + return *this; + } + array_iterator& operator--() { + --i_; + return *this; + } + array_iterator operator++(int) { + array_iterator cp{*this}; + ++i_; + return cp; + } + array_iterator operator--(int) { + array_iterator cp{*this}; + --i_; + return cp; + } + array_iterator& operator=(array_iterator const& _other) { + this->i_ = _other.i_; + return *this; + } + bool operator==(array_iterator const& _other) const { + return i_ == _other.i_; + } + bool operator!=(array_iterator const& _other) const { + return i_ != _other.i_; + } + bool operator<(array_iterator const& _other) const { + return i_ < _other.i_; + } + bool operator>(array_iterator const& _other) const { + return i_ > _other.i_; + } + bool operator<=(array_iterator const& _other) const { + return i_ <= _other.i_; + } + bool operator>=(array_iterator const& _other) const { + return i_ >= _other.i_; + } + array_iterator operator+(typename T::size_type _add) const { + array_iterator cp{*this}; + cp.i_ += _add; + return cp; + } + array_iterator& operator+=(typename T::size_type _add) { + this->i_ += _add; + return *this; + } + array_iterator operator-(typename T::size_type _subtract) const { + array_iterator cp{*this}; + cp.i_ -= _subtract; + return cp; + } + array_iterator& operator-=(typename T::size_type _subtract) { + this->i_ -= _subtract; + return *this; + } + typename T::size_type operator-(array_iterator const& _other) const { + return static_cast(this->i_ - _other.i_); + } + + array_iterator(T* _arr, typename T::size_type _i) + : arr_(_arr) + , i_(_i) { + } + + private: + T* arr_; + typename T::size_type i_; +}; + +// Const version of the array iterator. +template +class const_array_iterator : public std::iterator { + public: + const_array_iterator() + : arr_(nullptr) + , i_(0) { + } + const_array_iterator(const_array_iterator const& other) + : arr_(other.arr_) + , i_(other.i_) { + } + ~const_array_iterator() { + } + typename T::value_type const& operator*() const { + return (*arr_)[i_]; + } + typename T::value_type const* operator->() const { + return &(*arr_)[i_]; + } + typename T::value_type const& operator[](typename T::size_type _di) const { + return (*arr_)[i_ + _di]; + } + const_array_iterator& operator++() { + ++i_; + return *this; + } + const_array_iterator& operator--() { + --i_; + return *this; + } + const_array_iterator operator++(int) { + const_array_iterator copy{*this}; + ++i_; + return copy; + } + const_array_iterator operator--(int) { + const_array_iterator copy{*this}; + --i_; + return copy; + } + const_array_iterator& operator=(const_array_iterator const& _other) { + this->i_ = _other.i_; + return *this; + } + bool operator==(const_array_iterator const& _other) const { + return i_ == _other.i_; + } + bool operator!=(const_array_iterator const& _other) const { + return i_ != _other.i_; + } + bool operator<(const_array_iterator const& _other) const { + return i_ < _other.i_; + } + bool operator>(const_array_iterator const& _other) const { + return i_ > _other.i_; + } + bool operator<=(const_array_iterator const& _other) const { + return i_ <= _other.i_; + } + bool operator>=(const_array_iterator const& _other) const { + return i_ >= _other.i_; + } + const_array_iterator operator+(typename T::size_type _add) const { + const_array_iterator cp{*this}; + cp.i_ += _add; + return cp; + } + const_array_iterator& operator+=(typename T::size_type _add) { + this->i_ += _add; + return *this; + } + const_array_iterator operator-(typename T::size_type _subtract) const { + const_array_iterator cp{*this}; + cp.i_ -= _subtract; + return cp; + } + + const_array_iterator& operator-=(typename T::size_type _subtract) { + this->i_ -= _subtract; + return *this; + } + + typename T::size_type operator-(const_array_iterator const& _other) const { + return static_cast(this->i_ - _other.i_); + } + + const_array_iterator(T const* _arr, typename T::size_type _i) + : arr_(_arr) + , i_(_i) { + } + + private: + T const* arr_; + typename T::size_type i_; + typename T::size_type n_; +}; + +namespace detail { + +// detail::numel: Compile-time product of the given size vector of length N. +template +class numel { + public: + template + static SZ compute(SZ _size[]) { + return _size[N - 1] * numel::compute(_size); + } +}; +template <> +class numel<0> { + public: + template + static SZ compute(SZ[]) { + return 1; + } +}; + +// Compute the product for a set of numeric arguments: product(10, 20, 30, ...) => +// 10*20*30*... +template +struct product_i { + static SZ compute(First _f, Rest... _rest) { + return _f * product_i::compute(_rest...); + } +}; +template +struct product_i { + static SZ compute(Last _l) { + return _l; + } +}; + +template +SZ product(Args... args) { + return product_i::compute(args...); +} + +// Compute flat index from (column-major) ND size vector and a list of indices. +template +class index_nd { + public: + template + static SZ compute(SZ const _size[], SZ const _indices[]) { + SZ const weight{numel::compute(_size)}; + return weight * _indices[I - 1] + index_nd::compute(_size, _indices); + } +}; + +template <> +class index_nd<0> { + public: + template + static SZ compute(SZ[], SZ[]) { + return 0; + } +}; + +template +struct match_dimensions {}; + +template <> +struct match_dimensions { + static void check() { + } +}; + +} // namespace detail + +// Base class for code::array. SZ is the type used for sizes (currently int32_t.) +// Overloading up to 10 dimensions (not using variadic templates to +// stay compatible with C++98.) +template +class array_base { + public: + using value_type = T; + using size_type = SZ; + + array_base() { + (void)::memset(size_, 0, sizeof(SZ) * N); + } + + array_base(T* _data, SZ const* _sz) + : data_(_data, coder::detail::numel::compute(_sz)) { + (void)std::copy(_sz, _sz + N, size_); + } + + array_base(array_base const&) = default; + + array_base& operator=(array_base const& _other) { + data_.copy(_other.data_); + (void)std::copy(_other.size_, _other.size_ + N, size_); + return *this; + } + + template + void set(T* _data, Dims... dims) { + coder::detail::match_dimensions::check(); + data_.set(_data, coder::detail::product(dims...)); + set_size_i<0>(dims...); + } + + bool is_owner() const { + return data_.is_owner(); + } + + void set_owner(bool b) { + data_.set_owner(b); + } + + SZ capacity() const { + return data_.capacity(); + } + + private: + template + void set_size_i(First f, Rest... rest) { + size_[_i] = f; + set_size_i<_i + 1, Rest...>(rest...); + } + template + void set_size_i(Last l) { + size_[_i] = l; + } + + public: + void reserve(SZ _n) { + ensureCapacity(_n); + } + + template + void set_size(Dims... dims) { + coder::detail::match_dimensions::check(); + set_size_i<0>(dims...); + ensureCapacity(numel()); + } + + template + array_base reshape_n(SZ const (&_ns)[N1]) const { + array_base reshaped{const_cast(&data_[0]), _ns}; + return reshaped; + } + + template + array_base(sizeof...(Dims))> reshape(Dims... dims) const { + SZ const ns[]{static_cast(dims)...}; + return reshape_n(ns); + } + + T& operator[](SZ _index) { + return data_[_index]; + } + + T const& operator[](SZ _index) const { + return data_[_index]; + } + + void clear() { + data_.clear(); + } + + T* data() { + return data_; + } + + T const* data() const { + return data_; + } + + SZ* size() { + return &size_[0]; + } + + SZ const* size() const { + return &size_[0]; + } + + SZ size(SZ _index) const { + return size_[_index]; + } + + SZ numel() const { + return coder::detail::numel::compute(size_); + } + + template + SZ index(Dims... _dims) const { + coder::detail::match_dimensions::check(); + SZ const indices[]{static_cast(_dims)...}; + return coder::detail::index_nd(sizeof...(_dims))>::compute(size_, indices); + } + + template + T& at(Dims... _i) { + coder::detail::match_dimensions::check(); + return data_[index(_i...)]; + } + + template + T const& at(Dims... _i) const { + coder::detail::match_dimensions::check(); + return data_[index(_i...)]; + } + + array_iterator > begin() { + return array_iterator >(this, 0); + } + array_iterator > end() { + return array_iterator >(this, this->numel()); + } + const_array_iterator > begin() const { + return const_array_iterator >(this, 0); + } + const_array_iterator > end() const { + return const_array_iterator >(this, this->numel()); + } + + protected: + coder::detail::data_ptr data_; + SZ size_[N]; + + private: + void ensureCapacity(SZ _newNumel) { + if (_newNumel > data_.capacity()) { + SZ i{data_.capacity()}; + if (i < 16) { + i = 16; + } + + while (i < _newNumel) { + if (i > 1073741823) { + i = MAX_int32_T; + } else { + i *= 2; + } + } + data_.reserve(i); + } + data_.resize(_newNumel); + } +}; + +// The standard coder::array class with base type and number of dimensions. +template +class array : public array_base { + private: + using Base = array_base; + + public: + array() + : Base() { + } + array(array const& _other) + : Base(_other) { + } + array(Base const& _other) + : Base(_other) { + } + array(T* _data, SizeType const* _sz) + : Base(_data, _sz) { + } +}; + +// Specialize on char_T (row vector) for better support on strings. +template <> +class array : public array_base { + private: + using Base = array_base; + + public: + array() + : array_base() { + } + array(array const& _other) + : Base(_other) { + } + array(Base const& _other) + : Base(_other) { + } + + array(std::string const& _str) { + operator=(_str); + } + + array(char_T const* const _str) { + operator=(_str); + } + + array(std::vector const& _vec) { + SizeType const n{static_cast(_vec.size())}; + set_size(1, n); + data_.copy(&_vec[0], n); + } + + array& operator=(std::string const& _str) { + SizeType const n{static_cast(_str.size())}; + set_size(1, n); + data_.copy(_str.c_str(), n); + return *this; + } + + array& operator=(char_T const* const _str) { + SizeType const n{static_cast(strlen(_str))}; + set_size(1, n); + data_.copy(_str, n); + return *this; + } + + operator std::string() const { + return std::string(static_cast(&(*this)[0]), static_cast(size(1))); + } +}; + +// Specialize on 2 dimensions for better support interactions with +// std::vector and row vectors. +template +class array : public array_base { + private: + using Base = array_base; + + public: + array() + : Base() { + } + array(array const& _other) + : Base(_other) { + } + array(Base const& _other) + : Base(_other) { + } + array(std::vector const& _vec) { + operator=(_vec); + } + + array& operator=(std::vector const& _vec) { + SizeType n{static_cast(_vec.size())}; + Base::set_size(1, n); + Base::data_.copy(&_vec[0], n); + return *this; + } + + operator std::vector() const { + T const* p{&Base::data_[0]}; + return std::vector(p, p + Base::numel()); + } +}; + +// Specialize on 1 dimension for better support with std::vector and +// column vectors. +template +class array : public array_base { + private: + using Base = array_base; + + public: + array() + : Base() { + } + array(array const& _other) + : Base(_other) { + } + array(Base const& _other) + : Base(_other) { + } + array(std::vector const& _vec) { + operator=(_vec); + } + + array& operator=(std::vector const& _vec) { + SizeType n{static_cast(_vec.size())}; + Base::set_size(n); + Base::data_.copy(&_vec[0], n); + return *this; + } + + operator std::vector() const { + T const* p{&Base::data_[0]}; + return std::vector(p, p + Base::numel()); + } +}; +} // namespace coder + +#endif diff --git a/cpp/RAT/coder_bounded_array.h b/cpp/RAT/coder_bounded_array.h new file mode 100644 index 00000000..b08c1fdd --- /dev/null +++ b/cpp/RAT/coder_bounded_array.h @@ -0,0 +1,37 @@ +/* Copyright 2020 The Mathworks, Inc. */ +/* Copied from fullfile(matlabroot,'extern','include','coder','coder_array','coder_bounded_array.h') + */ + +#ifndef _mw_coder_bounded_array_h +#define _mw_coder_bounded_array_h + +#ifdef MATLAB_MEX_FILE +#include "tmwtypes.h" +#else +#include "rtwtypes.h" +#endif + +namespace coder { + +#ifndef CODER_ARRAY_SIZE_TYPE_DEFINED +#if __cplusplus >= 201103L +using SizeType = int; +#else +typedef int SizeType; +#endif +#endif + +// Bounded array +template +struct bounded_array { + T data[UpperBoundSize]; + SizeType size[NumDims]; +}; + +template +struct empty_bounded_array { + SizeType size[NumDims]; +}; +} // namespace coder + +#endif diff --git a/cpp/RAT/coder_posix_time.c b/cpp/RAT/coder_posix_time.c new file mode 100644 index 00000000..1d83c1ce --- /dev/null +++ b/cpp/RAT/coder_posix_time.c @@ -0,0 +1,162 @@ +/* MATLAB Coder time APIs */ +/* Copyright 2020-2022 The MathWorks, Inc. */ + +/* Sort out the defines early before any headers are included + * to avoid includes with inconsistent defines + */ +#if (!defined(CODER_WINAPI)) && (defined(_WIN32)) +#define CODER_WINAPI +#endif + +/* Ensure we get the right _POSIX_C_SOURCE and isolate our define to just this C file */ +#if !defined(CODER_WINAPI) +#undef _POSIX_C_SOURCE +#if defined(__QNX__) +/* QNX wants a newer POSIX version to make CLOCK_MONOTONIC available */ +#define _POSIX_C_SOURCE 200112L +#else +#define _POSIX_C_SOURCE 199309L +#endif /* defined(__QNX__) */ +#endif /* !defined(CODER_WINAPI) */ + +#ifdef CODER_WINAPI +#define NOMINMAX +#include +#endif /* CODER_WINAPI */ + +#include "coder_posix_time.h" +#include +#include +#include + +/* Prototypes */ +#ifndef CODER_WINAPI +/** + * @brief Convert coderTimeSpec to POSIX timespec + * + */ +static void coderToPOSIXTimespec(coderTimespec const * const aCoderTimespec, + struct timespec* const aTimespec); + +/** + * @brief Convert POSIX timespec to coderTimeSpec + * + */ +static void posixToCoderTimespec(const struct timespec* const aTimespec, + coderTimespec* const aCoderTimespec); + +static void coderToPOSIXTimespec(coderTimespec const * const aCoderTimespec, + struct timespec* const aTimespec) { + aTimespec->tv_sec = (time_t)(aCoderTimespec->tv_sec); + aTimespec->tv_nsec = (long)(aCoderTimespec->tv_nsec); +} + +static void posixToCoderTimespec(const struct timespec* const aTimespec, + coderTimespec* const aCoderTimespec) { + aCoderTimespec->tv_sec = (double)(aTimespec->tv_sec); + aCoderTimespec->tv_nsec = (double)(aTimespec->tv_nsec); +} +#endif /* CODER_WINAPI */ + +int coderInitTimeFunctions(double* const aFrequency) { +#ifdef CODER_WINAPI + LARGE_INTEGER freqL; + int status; + status = QueryPerformanceFrequency(&freqL); + *aFrequency = (double)freqL.QuadPart; + /* Invert status since in Windows, 0 means failure */ + return status == 0; +#else + *aFrequency = 0.0; + return 0; +#endif +} + +int coderTimeClockGettimeMonotonic(coderTimespec* const aCoderTimespec, double aFrequency) { +#ifdef CODER_WINAPI + static const double BILLION = 1e9; + LARGE_INTEGER timeL; + double timeDouble, timeRemainder, seconds, nanoseconds; + BOOL status = QueryPerformanceCounter(&timeL); + timeDouble = (double)timeL.QuadPart; + timeRemainder = fmod(timeDouble, aFrequency); + seconds = (timeDouble - timeRemainder) / aFrequency; + nanoseconds = (timeRemainder * BILLION) / aFrequency; + aCoderTimespec->tv_sec = seconds; + aCoderTimespec->tv_nsec = nanoseconds; + + /* Invert status since in Windows, 0 means failure */ + return status == 0; +#else + struct timespec tspec; + int status; + (void) aFrequency; + status = clock_gettime(CLOCK_MONOTONIC, &tspec); + posixToCoderTimespec(&tspec, aCoderTimespec); + return status; +#endif /* defined(_WIN32) || defined(WIN32) */ +} + +int coderTimeSleep(coderTimespec const * const aCoderTimespec) { +#ifdef CODER_WINAPI + /* WIndows */ + static const double MILLI = 1e3; + static const double BILLION = 1e9; + double delayMilli, delay; + DWORD delayUint32; + delayMilli = floor(aCoderTimespec->tv_nsec / (BILLION / MILLI)); + delay = MILLI * aCoderTimespec->tv_sec + delayMilli; + delayUint32 = (DWORD)ceil(delay); + Sleep(delayUint32); + return 0; +#else + /* POSIX */ + struct timespec ts; + coderToPOSIXTimespec(aCoderTimespec, &ts); + return nanosleep(&ts, NULL); +#endif +} + +int coderLocalTime(coderTm* const aTm) { +#ifdef CODER_WINAPI + /* WIndows */ + SYSTEMTIME sysTime; + TIME_ZONE_INFORMATION tzInfo; + DWORD dstInfo; + GetLocalTime(&sysTime); + aTm->tm_nsec = ((long)sysTime.wMilliseconds) * 1000000; + aTm->tm_sec = sysTime.wSecond; + aTm->tm_min = sysTime.wMinute; + aTm->tm_hour = sysTime.wHour; + aTm->tm_mday = sysTime.wDay; + aTm->tm_mon = sysTime.wMonth; + aTm->tm_year = sysTime.wYear; + aTm->tm_wday = 0; + aTm->tm_yday = 0; + + dstInfo = GetTimeZoneInformation(&tzInfo); + aTm->tm_isdst = dstInfo == TIME_ZONE_ID_DAYLIGHT; + return 0; +#else + /* POSIX */ + struct timespec ts; + struct tm* tmVal; + int status; + const int YEAR_OFFSET = 1900; /* +1900 for human year */ + const int MONTH_OFFSET = 1; /* +1 for 1-based month */ + status = clock_gettime(CLOCK_REALTIME, &ts); + tmVal = localtime(&ts.tv_sec); + aTm->tm_nsec = ts.tv_nsec; + aTm->tm_sec = tmVal->tm_sec; + aTm->tm_min = tmVal->tm_min; + aTm->tm_hour = tmVal->tm_hour; + aTm->tm_mday = tmVal->tm_mday; + aTm->tm_mon = tmVal->tm_mon + MONTH_OFFSET; + aTm->tm_year = tmVal->tm_year + YEAR_OFFSET; + aTm->tm_wday = tmVal->tm_wday; + aTm->tm_yday = tmVal->tm_yday; + aTm->tm_isdst = tmVal->tm_isdst; + + return status; +#endif +} diff --git a/cpp/RAT/coder_posix_time.h b/cpp/RAT/coder_posix_time.h new file mode 100644 index 00000000..d5cbdc8f --- /dev/null +++ b/cpp/RAT/coder_posix_time.h @@ -0,0 +1,73 @@ +/* Copyright 2020-2021 The MathWorks, Inc. */ +/* Wrapper file for time.h that ensures the proper POSIX defines for MATLAB Coder */ +#ifndef CODER_POSIX_TIME_H +#define CODER_POSIX_TIME_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @brief Represents generic timestamps + * + */ +typedef struct coderTimespec_tag { + double tv_sec; + double tv_nsec; +} coderTimespec; + +/** + * @brief Represents a localized time + * + */ +typedef struct coderTm_tag { + long tm_nsec; /* nanoseconds */ + int tm_sec; /* seconds */ + int tm_min; /* minutes */ + int tm_hour; /* hours */ + int tm_mday; /* day of the month */ + int tm_mon; /* month */ + int tm_year; /* year */ + int tm_wday; /* day of the week */ + int tm_yday; /* day in the year */ + int tm_isdst; /* daylight saving time */ +} coderTm; + +/** + * @brief Initialize state for time functions + * + * @param aFrequency Returned clock frequency for Windows APIs + * @return int Status code. 0 for success. Non-zero for failure + */ +int coderInitTimeFunctions(double* const aFrequency); + +/** + * @brief Returns a timestamp from a monotonic clock + * + * @param aCoderTimespec The returned timestamp + * @param aFrequency Frequency obtained from coderInitTimeFunctions + * @return int Status code. 0 for success. Non-zero for failure + */ +int coderTimeClockGettimeMonotonic(coderTimespec* const aCoderTimespec, double aFrequency); + +/** + * @brief Sleep for a specified duration + * + * @param aCoderTimespec Amount of time to sleep for + * @return int Status code. 0 for success. Non-zero for failure + */ +int coderTimeSleep(coderTimespec const * const aCoderTimespec); + +/** + * @brief Query the local time + * + * @param aTm Returned local time + * @return int Status code. 0 for success. Non-zero for failure + */ +int coderLocalTime(coderTm* const aTm); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CODER_POSIX_TIME_H */ diff --git a/cpp/RAT/coder_setenv.c b/cpp/RAT/coder_setenv.c new file mode 100644 index 00000000..4a3c00e5 --- /dev/null +++ b/cpp/RAT/coder_setenv.c @@ -0,0 +1,22 @@ +/* Copyright 2020 The MathWorks, Inc. */ +#include "coder_setenv.h" + +#ifdef _MSC_VER +#include +#include +#include +#else +#define _POSIX_C_SOURCE 200112L +#include +#endif + +void portableSetEnv(const char* aName, const char* aValue) { +#ifdef _MSC_VER + char* pvBuffer = (char*)malloc(strlen(aName) + strlen(aValue) + 2); + sprintf(pvBuffer, "%s=%s", aName, aValue); + _putenv(pvBuffer); + free(pvBuffer); +#else + setenv(aName, aValue, 1); +#endif +} diff --git a/cpp/RAT/coder_setenv.h b/cpp/RAT/coder_setenv.h new file mode 100644 index 00000000..03598cdf --- /dev/null +++ b/cpp/RAT/coder_setenv.h @@ -0,0 +1,15 @@ +/* Copyright 2020 The MathWorks, Inc. */ +#ifndef CODER_SETENV_H +#define CODER_SETENV_H + +#ifdef __cplusplus +extern "C" { +#endif + +void portableSetEnv(const char* aName, const char* aValue); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cpp/RAT/colon.cpp b/cpp/RAT/colon.cpp new file mode 100644 index 00000000..63c9594b --- /dev/null +++ b/cpp/RAT/colon.cpp @@ -0,0 +1,120 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// colon.cpp +// +// Code generation for function 'colon' +// + +// Include files +#include "colon.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + static void float_colon_length(real_T a, real_T d, real_T b, int32_T *n, + real_T *anew, real_T *bnew, boolean_T *n_too_large); + } +} + +// Function Definitions +namespace RAT +{ + namespace coder + { + static void float_colon_length(real_T a, real_T d, real_T b, int32_T *n, + real_T *anew, real_T *bnew, boolean_T *n_too_large) + { + real_T cdiff; + real_T ndbl; + *anew = a; + ndbl = std::floor((b - a) / d + 0.5); + *bnew = a + ndbl * d; + if (d > 0.0) { + cdiff = *bnew - b; + } else { + cdiff = b - *bnew; + } + + if (std::abs(cdiff) < 4.4408920985006262E-16 * std::fmax(std::abs(a), std:: + abs(b))) { + ndbl++; + *bnew = b; + } else if (cdiff > 0.0) { + *bnew = a + (ndbl - 1.0) * d; + } else { + ndbl++; + } + + *n_too_large = (ndbl > 2.147483647E+9); + if (ndbl >= 0.0) { + *n = static_cast(ndbl); + } else { + *n = 0; + } + } + + void eml_float_colon(real_T a, real_T d, real_T b, ::coder::array + &y) + { + real_T a1; + real_T b1; + int32_T n; + boolean_T n_too_large; + float_colon_length(a, d, b, &n, &a1, &b1, &n_too_large); + y.set_size(1, n); + if (n > 0) { + y[0] = a1; + if (n > 1) { + real_T kd; + int32_T nm1d2; + y[n - 1] = b1; + nm1d2 = (n - 1) / 2; + for (int32_T k{0}; k <= nm1d2 - 2; k++) { + kd = (static_cast(k) + 1.0) * d; + y[k + 1] = a1 + kd; + y[(n - k) - 2] = b1 - kd; + } + + if (nm1d2 << 1 == n - 1) { + y[nm1d2] = (a1 + b1) / 2.0; + } else { + kd = static_cast(nm1d2) * d; + y[nm1d2] = a1 + kd; + y[nm1d2 + 1] = b1 - kd; + } + } + } + } + + void eml_integer_colon_dispatcher(int32_T b, ::coder::array &y) + { + int32_T n; + if (b < 1) { + n = 0; + } else { + n = b; + } + + y.set_size(1, n); + if (n > 0) { + int32_T yk; + y[0] = 1; + yk = 1; + for (int32_T k{2}; k <= n; k++) { + yk++; + y[k - 1] = yk; + } + } + } + } +} + +// End of code generation (colon.cpp) diff --git a/cpp/RAT/colon.h b/cpp/RAT/colon.h new file mode 100644 index 00000000..8cdede94 --- /dev/null +++ b/cpp/RAT/colon.h @@ -0,0 +1,32 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// colon.h +// +// Code generation for function 'colon' +// +#ifndef COLON_H +#define COLON_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void eml_float_colon(real_T a, real_T d, real_T b, ::coder::array + &y); + void eml_integer_colon_dispatcher(int32_T b, ::coder::array &y); + } +} + +#endif + +// End of code generation (colon.h) diff --git a/cpp/RAT/combineVectorElements.cpp b/cpp/RAT/combineVectorElements.cpp new file mode 100644 index 00000000..0f937db2 --- /dev/null +++ b/cpp/RAT/combineVectorElements.cpp @@ -0,0 +1,186 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// combineVectorElements.cpp +// +// Code generation for function 'combineVectorElements' +// + +// Include files +#include "combineVectorElements.h" +#include "blockedSummation.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in2, const ::coder::array &in3, + const ::coder::array &in4, int32_T in5, + int32_T in6, int32_T in7) + { + ::coder::array b_in2; + int32_T aux_0_1; + int32_T aux_1_1; + int32_T i; + int32_T i1; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_0_1; + int32_T stride_1_0; + int32_T stride_1_1; + if (in3.size(0) == 1) { + i = in2.size(0); + } else { + i = in3.size(0); + } + + if (in3.size(1) == 1) { + i1 = in2.size(1); + } else { + i1 = in3.size(1); + } + + b_in2.set_size(i, i1); + stride_0_0 = (in2.size(0) != 1); + stride_0_1 = (in2.size(1) != 1); + stride_1_0 = (in3.size(0) != 1); + stride_1_1 = (in3.size(1) != 1); + aux_0_1 = 0; + aux_1_1 = 0; + if (in3.size(1) == 1) { + loop_ub = in2.size(1); + } else { + loop_ub = in3.size(1); + } + + for (i = 0; i < loop_ub; i++) { + int32_T b_loop_ub; + i1 = in3.size(0); + if (i1 == 1) { + b_loop_ub = in2.size(0); + } else { + b_loop_ub = i1; + } + + for (i1 = 0; i1 < b_loop_ub; i1++) { + b_in2[i1 + b_in2.size(0) * i] = in2[i1 * stride_0_0 + in2.size(0) * + aux_0_1] - in3[i1 * stride_1_0 + in3.size(0) * aux_1_1]; + } + + aux_1_1 += stride_1_1; + aux_0_1 += stride_0_1; + } + + if (static_cast(in4[in5]) == 1) { + i = in6 - in7; + } else { + i = static_cast(in4[in5]); + } + + coder::blockedSummation(b_in2, i, in1); + } + + void c_binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in2, const ::coder::array &in3, const ::coder:: + array &in4, int32_T in5, int32_T in6, int32_T in7) + { + ::coder::array b_in2; + int32_T i; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_1_0; + if (in3.size(0) == 1) { + i = in2.size(0); + } else { + i = in3.size(0); + } + + b_in2.set_size(i, in2.size(1)); + stride_0_0 = (in2.size(0) != 1); + stride_1_0 = (in3.size(0) != 1); + loop_ub = in2.size(1); + for (i = 0; i < loop_ub; i++) { + int32_T b_loop_ub; + int32_T i1; + i1 = in3.size(0); + if (i1 == 1) { + b_loop_ub = in2.size(0); + } else { + b_loop_ub = i1; + } + + for (i1 = 0; i1 < b_loop_ub; i1++) { + b_in2[i1 + b_in2.size(0) * i] = in2[i1 * stride_0_0 + in2.size(0) * i] - + in3[i1 * stride_1_0 + in3.size(0) * i]; + } + } + + if (static_cast(in4[in5]) == 1) { + i = in6 - in7; + } else { + i = static_cast(in4[in5]); + } + + coder::blockedSummation(b_in2, i, in1); + } + + namespace coder + { + real_T b_combineVectorElements(const ::coder::array &x, int32_T + vlen) + { + real_T y; + if ((x.size(0) == 0) || (vlen == 0)) { + y = 0.0; + } else { + y = nestedIter(x, vlen); + } + + return y; + } + + int32_T c_combineVectorElements(const ::coder::array &x) + { + int32_T vlen; + int32_T y; + vlen = x.size(0); + if (x.size(0) == 0) { + y = 0; + } else { + y = x[0]; + for (int32_T k{2}; k <= vlen; k++) { + if (vlen >= 2) { + y += x[k - 1]; + } + } + } + + return y; + } + + int32_T combineVectorElements(const ::coder::array &x) + { + int32_T vlen; + int32_T y; + vlen = x.size(1); + if (x.size(1) == 0) { + y = 0; + } else { + y = x[0]; + for (int32_T k{2}; k <= vlen; k++) { + if (vlen >= 2) { + y += x[k - 1]; + } + } + } + + return y; + } + } +} + +// End of code generation (combineVectorElements.cpp) diff --git a/cpp/RAT/combineVectorElements.h b/cpp/RAT/combineVectorElements.h new file mode 100644 index 00000000..a811ef95 --- /dev/null +++ b/cpp/RAT/combineVectorElements.h @@ -0,0 +1,40 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// combineVectorElements.h +// +// Code generation for function 'combineVectorElements' +// +#ifndef COMBINEVECTORELEMENTS_H +#define COMBINEVECTORELEMENTS_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in2, const ::coder::array &in3, + const ::coder::array &in4, int32_T in5, + int32_T in6, int32_T in7); + void c_binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in2, const ::coder::array &in3, const ::coder:: + array &in4, int32_T in5, int32_T in6, int32_T in7); + namespace coder + { + real_T b_combineVectorElements(const ::coder::array &x, int32_T + vlen); + int32_T c_combineVectorElements(const ::coder::array &x); + int32_T combineVectorElements(const ::coder::array &x); + } +} + +#endif + +// End of code generation (combineVectorElements.h) diff --git a/cpp/RAT/complexTimes.cpp b/cpp/RAT/complexTimes.cpp new file mode 100644 index 00000000..3634df04 --- /dev/null +++ b/cpp/RAT/complexTimes.cpp @@ -0,0 +1,141 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// complexTimes.cpp +// +// Code generation for function 'complexTimes' +// + +// Include files +#include "complexTimes.h" +#include "rt_nonfinite.h" +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace scalar + { + static real_T b_rescale(real_T *re, real_T *im); + } + } + } +} + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace scalar + { + static real_T b_rescale(real_T *re, real_T *im) + { + real_T absim; + real_T scale; + scale = std::abs(*re); + absim = std::abs(*im); + if (scale > absim) { + if (*re < 0.0) { + *re = -1.0; + } else { + *re = 1.0; + } + + *im /= scale; + } else if (absim > scale) { + *re /= absim; + if (*im < 0.0) { + *im = -1.0; + } else { + *im = 1.0; + } + + scale = absim; + } else { + if (*re < 0.0) { + *re = -1.0; + } else { + *re = 1.0; + } + + if (*im < 0.0) { + *im = -1.0; + } else { + *im = 1.0; + } + } + + return scale; + } + + real_T complexTimes(real_T ar, real_T ai, real_T br, real_T bi) + { + real_T cr; + real_T sai; + real_T sar; + real_T sbi; + real_T sbr; + if ((ai == 0.0) && (bi == 0.0)) { + cr = 0.0; + } else { + real_T t3; + real_T t4; + t3 = ar * bi; + t4 = ai * br; + cr = t3 + t4; + if ((std::isinf(cr) || std::isnan(cr)) && (!std::isnan(ar)) && (!std:: + isnan(ai)) && (!std::isnan(br)) && (!std::isnan(bi))) { + real_T scaleA; + real_T scaleB; + boolean_T finiteScale; + sar = ar; + sai = ai; + scaleA = b_rescale(&sar, &sai); + sbr = br; + sbi = bi; + scaleB = b_rescale(&sbr, &sbi); + if ((!std::isinf(scaleA)) && (!std::isnan(scaleA)) && ((!std:: + isinf(scaleB)) && (!std::isnan(scaleB)))) { + finiteScale = true; + } else { + finiteScale = false; + } + + if (std::isnan(cr) || (std::isinf(cr) && finiteScale)) { + cr = sar * sbi + sai * sbr; + if (cr != 0.0) { + cr = cr * scaleA * scaleB; + } else if ((std::isinf(scaleA) && ((br == 0.0) || (bi == 0.0))) || + (std::isinf(scaleB) && ((ar == 0.0) || (ai == 0.0)))) + { + if (std::isnan(t3)) { + t3 = 0.0; + } + + if (std::isnan(t4)) { + t4 = 0.0; + } + + cr = t3 + t4; + } + } + } + } + + return cr; + } + } + } + } +} + +// End of code generation (complexTimes.cpp) diff --git a/cpp/RAT/complexTimes.h b/cpp/RAT/complexTimes.h new file mode 100644 index 00000000..978ad9f0 --- /dev/null +++ b/cpp/RAT/complexTimes.h @@ -0,0 +1,35 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// complexTimes.h +// +// Code generation for function 'complexTimes' +// +#ifndef COMPLEXTIMES_H +#define COMPLEXTIMES_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace scalar + { + real_T complexTimes(real_T ar, real_T ai, real_T br, real_T bi); + } + } + } +} + +#endif + +// End of code generation (complexTimes.h) diff --git a/cpp/RAT/coreLayersCalculation.cpp b/cpp/RAT/coreLayersCalculation.cpp new file mode 100644 index 00000000..b536645f --- /dev/null +++ b/cpp/RAT/coreLayersCalculation.cpp @@ -0,0 +1,692 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// coreLayersCalculation.cpp +// +// Code generation for function 'coreLayersCalculation' +// + +// Include files +#include "coreLayersCalculation.h" +#include "applyBackgroundCorrection.h" +#include "callReflectivity.h" +#include "chiSquared.h" +#include "groupLayersMod.h" +#include "groupLayersModImaginary.h" +#include "makeSLDProfiles.h" +#include "resampleLayers.h" +#include "resampleLayersReIm.h" +#include "rt_nonfinite.h" +#include "shiftData.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace nonPolarisedTF + { + void b_coreLayersCalculation(const ::coder::array + &contrastLayers, real_T rough, const char_T geometry_data[], const int32_T + geometry_size[2], real_T bulkIn, real_T bulkOut, real_T resample, + boolean_T calcSld, real_T scalefactor, real_T qzshift, real_T dataPresent, + const ::coder::array &data, const real_T dataLimits[2], const + real_T simLimits[2], const real_T repeatLayers[2], real_T background, + real_T resolution, real_T contrastBackgroundsType, real_T params, const + real_T resamPars[2], boolean_T useImaginary, ::coder::array + &sldProfile, ::coder::array &reflect, ::coder::array &simulation, ::coder::array &shiftedData, ::coder::array< + real_T, 2U> &theseLayers, ::coder::array &resamLayers, real_T * + chiSq, real_T *ssubs) + { + ::coder::array b_data; + ::coder::array b_theseLayers; + ::coder::array c_theseLayers; + ::coder::array layerSld; + ::coder::array sldProfileIm; + ::coder::array thisSldLays; + ::coder::array thisSldLaysIm; + ::coder::array d_theseLayers; + int32_T b_loop_ub; + int32_T i; + int32_T i1; + int32_T loop_ub; + + // This is the main reflectivity calculation for all Layers models in the + // non polarised target function. + // + // The function first arranges the + // roughness' in the correct order according + // to geometry. Then, if required it calculates the SLD profile and if + // requested resamples this into a number of zero-roughness layers + // (roughness resampling). It the applies any scalefactors and qz shifts + // the data requires. This is done before calculating the reflectivity to + // ensure that the reflectivity is calculated over the same range in qz as + // the shifted datapoints. The main reflectivity calculation is then + // called, including the resolution function. The calculation outputs two + // profiles - 'reflect' which is the same range as the points, and + // 'simulation' which can be a different range to allow extrapolation. + // The background correction is the applied, and finally chi-squared is + // calculated. + // + // Inputs: + // contrastLayers : + // rough : + // geometry : + // bulkIn : + // bulkOut : + // resample : + // calcSld : + // scalefactor : + // qzshift : + // dataPresent : + // data : + // dataLimits : + // simLimits : + // repeatLayers : + // background : + // resol : + // contrastBackgroundsType : + // params : + // parallelPoints : + // + // Outputs: + // + // ------------------------------------------------------------------------ + // + // (c) Arwel Hughes - 12/1/21 + // + // Last Modified: 12/1/21 by Arwel Hughes. + // + // ------------------------------------------------------------------------ + // Pre-definition for Coder + thisSldLaysIm.set_size(1, 2); + sldProfileIm.set_size(1, 2); + thisSldLaysIm[0] = 0.0; + sldProfileIm[0] = 0.0; + thisSldLaysIm[thisSldLaysIm.size(0)] = 0.0; + sldProfileIm[sldProfileIm.size(0)] = 0.0; + + // Bulid up the layers matrix for this contrast + if (!useImaginary) { + groupLayersMod(contrastLayers, rough, geometry_data, geometry_size, + bulkIn, bulkOut, layerSld, ssubs); + theseLayers.set_size(layerSld.size(0), 3); + loop_ub = layerSld.size(0); + for (i = 0; i < 3; i++) { + for (i1 = 0; i1 < loop_ub; i1++) { + theseLayers[i1 + theseLayers.size(0) * i] = layerSld[i1 + + layerSld.size(0) * i]; + } + } + } else { + groupLayersModImaginary(contrastLayers, rough, geometry_data, + geometry_size, bulkIn, bulkOut, layerSld, ssubs); + theseLayers.set_size(layerSld.size(0), 4); + loop_ub = layerSld.size(0); + for (i = 0; i < 4; i++) { + for (i1 = 0; i1 < loop_ub; i1++) { + theseLayers[i1 + theseLayers.size(0) * i] = layerSld[i1 + + layerSld.size(0) * i]; + } + } + } + + // Make the SLD profiles. + // If resampling is needed, then enforce the calcSLD flag, so as to catch + // the error af trying to resample a non-existent profile. + if ((resample == 1.0) && (!calcSld)) { + calcSld = true; + } + + // If calc SLD flag is set, then calculate the SLD profile + if (calcSld) { + // If we need them both, we process real and imaginary parts of the SLD + // seperately... + if (useImaginary) { + int32_T result; + int8_T input_sizes_idx_1; + int8_T sizes_idx_1; + boolean_T empty_non_axis_sizes; + if (theseLayers.size(1) < 4) { + i = 0; + i1 = 0; + } else { + i = 3; + i1 = 4; + } + + if (theseLayers.size(0) != 0) { + result = theseLayers.size(0); + } else { + result = 0; + } + + empty_non_axis_sizes = (result == 0); + if (empty_non_axis_sizes || (theseLayers.size(0) != 0)) { + input_sizes_idx_1 = 2; + } else { + input_sizes_idx_1 = 0; + } + + if (empty_non_axis_sizes || ((theseLayers.size(0) != 0) && (i1 - i != + 0))) { + sizes_idx_1 = static_cast(i1 - i); + } else { + sizes_idx_1 = 0; + } + + b_theseLayers.set_size(theseLayers.size(0), 2); + loop_ub = theseLayers.size(0); + for (int32_T i2{0}; i2 < 2; i2++) { + for (b_loop_ub = 0; b_loop_ub < loop_ub; b_loop_ub++) { + b_theseLayers[b_loop_ub + b_theseLayers.size(0) * i2] = + theseLayers[b_loop_ub + theseLayers.size(0) * i2]; + } + } + + loop_ub = i1 - i; + c_theseLayers.set_size(theseLayers.size(0), loop_ub); + for (i1 = 0; i1 < loop_ub; i1++) { + b_loop_ub = theseLayers.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + c_theseLayers[i2 + c_theseLayers.size(0) * i1] = theseLayers[i2 + + theseLayers.size(0) * (i + i1)]; + } + } + + thisSldLays.set_size(result, input_sizes_idx_1 + sizes_idx_1); + loop_ub = input_sizes_idx_1; + for (i = 0; i < loop_ub; i++) { + for (i1 = 0; i1 < result; i1++) { + thisSldLays[i1 + thisSldLays.size(0) * i] = b_theseLayers[i1 + + result * i]; + } + } + + loop_ub = sizes_idx_1; + for (i = 0; i < loop_ub; i++) { + for (i1 = 0; i1 < result; i1++) { + thisSldLays[i1 + thisSldLays.size(0) * (i + input_sizes_idx_1)] = + c_theseLayers[i1 + result * i]; + } + } + + if (theseLayers.size(0) != 0) { + result = theseLayers.size(0); + } else { + result = 0; + } + + empty_non_axis_sizes = (result == 0); + if (empty_non_axis_sizes || (theseLayers.size(0) != 0)) { + input_sizes_idx_1 = 1; + } else { + input_sizes_idx_1 = 0; + } + + if (empty_non_axis_sizes || (theseLayers.size(0) != 0)) { + sizes_idx_1 = static_cast(theseLayers.size(1) - 2); + } else { + sizes_idx_1 = 0; + } + + d_theseLayers.set_size(theseLayers.size(0)); + loop_ub = theseLayers.size(0); + for (i = 0; i < loop_ub; i++) { + d_theseLayers[i] = theseLayers[i]; + } + + c_theseLayers.set_size(theseLayers.size(0), theseLayers.size(1) - 2); + loop_ub = theseLayers.size(1); + b_loop_ub = theseLayers.size(0); + for (i = 0; i <= loop_ub - 3; i++) { + for (i1 = 0; i1 < b_loop_ub; i1++) { + c_theseLayers[i1 + c_theseLayers.size(0) * i] = theseLayers[i1 + + theseLayers.size(0) * (i + 2)]; + } + } + + thisSldLaysIm.set_size(result, input_sizes_idx_1 + sizes_idx_1); + loop_ub = input_sizes_idx_1; + for (i = 0; i < loop_ub; i++) { + for (i1 = 0; i1 < result; i1++) { + thisSldLaysIm[i1] = d_theseLayers[i1]; + } + } + + loop_ub = sizes_idx_1; + for (i = 0; i < loop_ub; i++) { + for (i1 = 0; i1 < result; i1++) { + thisSldLaysIm[i1 + thisSldLaysIm.size(0) * (i + input_sizes_idx_1)] + = c_theseLayers[i1 + result * i]; + } + } + } else { + thisSldLays.set_size(theseLayers.size(0), theseLayers.size(1)); + loop_ub = theseLayers.size(1); + b_loop_ub = theseLayers.size(0); + for (i = 0; i < loop_ub; i++) { + for (i1 = 0; i1 < b_loop_ub; i1++) { + thisSldLays[i1 + thisSldLays.size(0) * i] = theseLayers[i1 + + theseLayers.size(0) * i]; + } + } + } + + makeSLDProfiles(bulkIn, bulkOut, thisSldLays, *ssubs, repeatLayers, + b_theseLayers); + sldProfile.set_size(b_theseLayers.size(0), 2); + loop_ub = b_theseLayers.size(0); + for (i = 0; i < 2; i++) { + for (i1 = 0; i1 < loop_ub; i1++) { + sldProfile[i1 + sldProfile.size(0) * i] = b_theseLayers[i1 + + b_theseLayers.size(0) * i]; + } + } + + // If we have imaginary, we are also + // going to need an SLD profile for the imaginary part + if (useImaginary) { + // Note bulkIn and bulkOut = 0 since there is never any imaginary part for + // the bulk phases.. + makeSLDProfiles(thisSldLaysIm, *ssubs, repeatLayers, b_theseLayers); + sldProfileIm.set_size(b_theseLayers.size(0), 2); + loop_ub = b_theseLayers.size(0); + for (i = 0; i < 2; i++) { + for (i1 = 0; i1 < loop_ub; i1++) { + sldProfileIm[i1 + sldProfileIm.size(0) * i] = b_theseLayers[i1 + + b_theseLayers.size(0) * i]; + } + } + } + } else { + sldProfile.set_size(1, 2); + sldProfile[0] = 0.0; + sldProfile[sldProfile.size(0)] = 0.0; + } + + // If required, then resample the SLD + if (resample == 1.0) { + if (!useImaginary) { + resampleLayers(sldProfile, resamPars, layerSld); + } else { + resampleLayersReIm(sldProfile, sldProfileIm, resamPars, layerSld); + } + + resamLayers.set_size(layerSld.size(0), layerSld.size(1)); + loop_ub = layerSld.size(1); + b_loop_ub = layerSld.size(0); + for (i = 0; i < loop_ub; i++) { + for (i1 = 0; i1 < b_loop_ub; i1++) { + resamLayers[i1 + resamLayers.size(0) * i] = layerSld[i1 + + layerSld.size(0) * i]; + } + } + } else { + resamLayers.set_size(1, 3); + resamLayers[0] = 0.0; + resamLayers[resamLayers.size(0)] = 0.0; + resamLayers[resamLayers.size(0) * 2] = 0.0; + } + + // Apply scale factors and q shifts to the data + b_data.set_size(data.size(0), data.size(1)); + loop_ub = data.size(1) - 1; + for (i = 0; i <= loop_ub; i++) { + b_loop_ub = data.size(0) - 1; + for (i1 = 0; i1 <= b_loop_ub; i1++) { + b_data[i1 + b_data.size(0) * i] = data[i1 + data.size(0) * i]; + } + } + + shiftData(scalefactor, qzshift, dataPresent, b_data, dataLimits, simLimits, + shiftedData); + + // Calculate the reflectivity + b_callReflectivity(bulkIn, bulkOut, simLimits, repeatLayers, shiftedData, + layerSld, *ssubs, resolution, useImaginary, reflect, + simulation); + + // Apply background correction, either to the simulation or the data + applyBackgroundCorrection(reflect, simulation, shiftedData, background, + contrastBackgroundsType); + + // Calculate chi squared. + *chiSq = chiSquared(shiftedData, reflect, params); + } + + void coreLayersCalculation(const ::coder::array &contrastLayers, + real_T rough, const char_T geometry_data[], const int32_T geometry_size[2], + real_T bulkIn, real_T bulkOut, real_T resample, boolean_T calcSld, real_T + scalefactor, real_T qzshift, real_T dataPresent, const ::coder::array< + real_T, 2U> &data, const real_T dataLimits[2], const real_T simLimits[2], + const real_T repeatLayers[2], real_T background, real_T resolution, real_T + contrastBackgroundsType, real_T params, const real_T resamPars[2], + boolean_T useImaginary, ::coder::array &sldProfile, ::coder:: + array &reflect, ::coder::array &simulation, :: + coder::array &shiftedData, ::coder::array + &theseLayers, ::coder::array &resamLayers, real_T *chiSq, + real_T *ssubs) + { + ::coder::array b_data; + ::coder::array b_theseLayers; + ::coder::array c_theseLayers; + ::coder::array layerSld; + ::coder::array sldProfileIm; + ::coder::array thisSldLays; + ::coder::array thisSldLaysIm; + ::coder::array d_theseLayers; + int32_T b_loop_ub; + int32_T i; + int32_T i1; + int32_T loop_ub; + + // This is the main reflectivity calculation for all Layers models in the + // non polarised target function. + // + // The function first arranges the + // roughness' in the correct order according + // to geometry. Then, if required it calculates the SLD profile and if + // requested resamples this into a number of zero-roughness layers + // (roughness resampling). It the applies any scalefactors and qz shifts + // the data requires. This is done before calculating the reflectivity to + // ensure that the reflectivity is calculated over the same range in qz as + // the shifted datapoints. The main reflectivity calculation is then + // called, including the resolution function. The calculation outputs two + // profiles - 'reflect' which is the same range as the points, and + // 'simulation' which can be a different range to allow extrapolation. + // The background correction is the applied, and finally chi-squared is + // calculated. + // + // Inputs: + // contrastLayers : + // rough : + // geometry : + // bulkIn : + // bulkOut : + // resample : + // calcSld : + // scalefactor : + // qzshift : + // dataPresent : + // data : + // dataLimits : + // simLimits : + // repeatLayers : + // background : + // resol : + // contrastBackgroundsType : + // params : + // parallelPoints : + // + // Outputs: + // + // ------------------------------------------------------------------------ + // + // (c) Arwel Hughes - 12/1/21 + // + // Last Modified: 12/1/21 by Arwel Hughes. + // + // ------------------------------------------------------------------------ + // Pre-definition for Coder + thisSldLaysIm.set_size(1, 2); + sldProfileIm.set_size(1, 2); + thisSldLaysIm[0] = 0.0; + sldProfileIm[0] = 0.0; + thisSldLaysIm[thisSldLaysIm.size(0)] = 0.0; + sldProfileIm[sldProfileIm.size(0)] = 0.0; + + // Bulid up the layers matrix for this contrast + if (!useImaginary) { + groupLayersMod(contrastLayers, rough, geometry_data, geometry_size, + bulkIn, bulkOut, layerSld, ssubs); + theseLayers.set_size(layerSld.size(0), 3); + loop_ub = layerSld.size(0); + for (i = 0; i < 3; i++) { + for (i1 = 0; i1 < loop_ub; i1++) { + theseLayers[i1 + theseLayers.size(0) * i] = layerSld[i1 + + layerSld.size(0) * i]; + } + } + } else { + groupLayersModImaginary(contrastLayers, rough, geometry_data, + geometry_size, bulkIn, bulkOut, layerSld, ssubs); + theseLayers.set_size(layerSld.size(0), 4); + loop_ub = layerSld.size(0); + for (i = 0; i < 4; i++) { + for (i1 = 0; i1 < loop_ub; i1++) { + theseLayers[i1 + theseLayers.size(0) * i] = layerSld[i1 + + layerSld.size(0) * i]; + } + } + } + + // Make the SLD profiles. + // If resampling is needed, then enforce the calcSLD flag, so as to catch + // the error af trying to resample a non-existent profile. + if ((resample == 1.0) && (!calcSld)) { + calcSld = true; + } + + // If calc SLD flag is set, then calculate the SLD profile + if (calcSld) { + // If we need them both, we process real and imaginary parts of the SLD + // seperately... + if (useImaginary) { + int32_T result; + int8_T input_sizes_idx_1; + int8_T sizes_idx_1; + boolean_T empty_non_axis_sizes; + if (theseLayers.size(1) < 4) { + i = 0; + i1 = 0; + } else { + i = 3; + i1 = 4; + } + + if (theseLayers.size(0) != 0) { + result = theseLayers.size(0); + } else { + result = 0; + } + + empty_non_axis_sizes = (result == 0); + if (empty_non_axis_sizes || (theseLayers.size(0) != 0)) { + input_sizes_idx_1 = 2; + } else { + input_sizes_idx_1 = 0; + } + + if (empty_non_axis_sizes || ((theseLayers.size(0) != 0) && (i1 - i != + 0))) { + sizes_idx_1 = static_cast(i1 - i); + } else { + sizes_idx_1 = 0; + } + + b_theseLayers.set_size(theseLayers.size(0), 2); + loop_ub = theseLayers.size(0); + for (int32_T i2{0}; i2 < 2; i2++) { + for (b_loop_ub = 0; b_loop_ub < loop_ub; b_loop_ub++) { + b_theseLayers[b_loop_ub + b_theseLayers.size(0) * i2] = + theseLayers[b_loop_ub + theseLayers.size(0) * i2]; + } + } + + loop_ub = i1 - i; + c_theseLayers.set_size(theseLayers.size(0), loop_ub); + for (i1 = 0; i1 < loop_ub; i1++) { + b_loop_ub = theseLayers.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + c_theseLayers[i2 + c_theseLayers.size(0) * i1] = theseLayers[i2 + + theseLayers.size(0) * (i + i1)]; + } + } + + thisSldLays.set_size(result, input_sizes_idx_1 + sizes_idx_1); + loop_ub = input_sizes_idx_1; + for (i = 0; i < loop_ub; i++) { + for (i1 = 0; i1 < result; i1++) { + thisSldLays[i1 + thisSldLays.size(0) * i] = b_theseLayers[i1 + + result * i]; + } + } + + loop_ub = sizes_idx_1; + for (i = 0; i < loop_ub; i++) { + for (i1 = 0; i1 < result; i1++) { + thisSldLays[i1 + thisSldLays.size(0) * (i + input_sizes_idx_1)] = + c_theseLayers[i1 + result * i]; + } + } + + if (theseLayers.size(0) != 0) { + result = theseLayers.size(0); + } else { + result = 0; + } + + empty_non_axis_sizes = (result == 0); + if (empty_non_axis_sizes || (theseLayers.size(0) != 0)) { + input_sizes_idx_1 = 1; + } else { + input_sizes_idx_1 = 0; + } + + if (empty_non_axis_sizes || (theseLayers.size(0) != 0)) { + sizes_idx_1 = static_cast(theseLayers.size(1) - 2); + } else { + sizes_idx_1 = 0; + } + + d_theseLayers.set_size(theseLayers.size(0)); + loop_ub = theseLayers.size(0); + for (i = 0; i < loop_ub; i++) { + d_theseLayers[i] = theseLayers[i]; + } + + c_theseLayers.set_size(theseLayers.size(0), theseLayers.size(1) - 2); + loop_ub = theseLayers.size(1); + b_loop_ub = theseLayers.size(0); + for (i = 0; i <= loop_ub - 3; i++) { + for (i1 = 0; i1 < b_loop_ub; i1++) { + c_theseLayers[i1 + c_theseLayers.size(0) * i] = theseLayers[i1 + + theseLayers.size(0) * (i + 2)]; + } + } + + thisSldLaysIm.set_size(result, input_sizes_idx_1 + sizes_idx_1); + loop_ub = input_sizes_idx_1; + for (i = 0; i < loop_ub; i++) { + for (i1 = 0; i1 < result; i1++) { + thisSldLaysIm[i1] = d_theseLayers[i1]; + } + } + + loop_ub = sizes_idx_1; + for (i = 0; i < loop_ub; i++) { + for (i1 = 0; i1 < result; i1++) { + thisSldLaysIm[i1 + thisSldLaysIm.size(0) * (i + input_sizes_idx_1)] + = c_theseLayers[i1 + result * i]; + } + } + } else { + thisSldLays.set_size(theseLayers.size(0), theseLayers.size(1)); + loop_ub = theseLayers.size(1); + b_loop_ub = theseLayers.size(0); + for (i = 0; i < loop_ub; i++) { + for (i1 = 0; i1 < b_loop_ub; i1++) { + thisSldLays[i1 + thisSldLays.size(0) * i] = theseLayers[i1 + + theseLayers.size(0) * i]; + } + } + } + + makeSLDProfiles(bulkIn, bulkOut, thisSldLays, *ssubs, repeatLayers, + b_theseLayers); + sldProfile.set_size(b_theseLayers.size(0), 2); + loop_ub = b_theseLayers.size(0); + for (i = 0; i < 2; i++) { + for (i1 = 0; i1 < loop_ub; i1++) { + sldProfile[i1 + sldProfile.size(0) * i] = b_theseLayers[i1 + + b_theseLayers.size(0) * i]; + } + } + + // If we have imaginary, we are also + // going to need an SLD profile for the imaginary part + if (useImaginary) { + // Note bulkIn and bulkOut = 0 since there is never any imaginary part for + // the bulk phases.. + makeSLDProfiles(thisSldLaysIm, *ssubs, repeatLayers, b_theseLayers); + sldProfileIm.set_size(b_theseLayers.size(0), 2); + loop_ub = b_theseLayers.size(0); + for (i = 0; i < 2; i++) { + for (i1 = 0; i1 < loop_ub; i1++) { + sldProfileIm[i1 + sldProfileIm.size(0) * i] = b_theseLayers[i1 + + b_theseLayers.size(0) * i]; + } + } + } + } else { + sldProfile.set_size(1, 2); + sldProfile[0] = 0.0; + sldProfile[sldProfile.size(0)] = 0.0; + } + + // If required, then resample the SLD + if (resample == 1.0) { + if (!useImaginary) { + resampleLayers(sldProfile, resamPars, layerSld); + } else { + resampleLayersReIm(sldProfile, sldProfileIm, resamPars, layerSld); + } + + resamLayers.set_size(layerSld.size(0), layerSld.size(1)); + loop_ub = layerSld.size(1); + b_loop_ub = layerSld.size(0); + for (i = 0; i < loop_ub; i++) { + for (i1 = 0; i1 < b_loop_ub; i1++) { + resamLayers[i1 + resamLayers.size(0) * i] = layerSld[i1 + + layerSld.size(0) * i]; + } + } + } else { + resamLayers.set_size(1, 3); + resamLayers[0] = 0.0; + resamLayers[resamLayers.size(0)] = 0.0; + resamLayers[resamLayers.size(0) * 2] = 0.0; + } + + // Apply scale factors and q shifts to the data + b_data.set_size(data.size(0), data.size(1)); + loop_ub = data.size(1) - 1; + for (i = 0; i <= loop_ub; i++) { + b_loop_ub = data.size(0) - 1; + for (i1 = 0; i1 <= b_loop_ub; i1++) { + b_data[i1 + b_data.size(0) * i] = data[i1 + data.size(0) * i]; + } + } + + shiftData(scalefactor, qzshift, dataPresent, b_data, dataLimits, simLimits, + shiftedData); + + // Calculate the reflectivity + callReflectivity(bulkIn, bulkOut, simLimits, repeatLayers, shiftedData, + layerSld, *ssubs, resolution, useImaginary, reflect, + simulation); + + // Apply background correction, either to the simulation or the data + applyBackgroundCorrection(reflect, simulation, shiftedData, background, + contrastBackgroundsType); + + // Calculate chi squared. + *chiSq = chiSquared(shiftedData, reflect, params); + } + } +} + +// End of code generation (coreLayersCalculation.cpp) diff --git a/cpp/RAT/coreLayersCalculation.h b/cpp/RAT/coreLayersCalculation.h new file mode 100644 index 00000000..6bc8b3a1 --- /dev/null +++ b/cpp/RAT/coreLayersCalculation.h @@ -0,0 +1,53 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// coreLayersCalculation.h +// +// Code generation for function 'coreLayersCalculation' +// +#ifndef CORELAYERSCALCULATION_H +#define CORELAYERSCALCULATION_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace nonPolarisedTF + { + void b_coreLayersCalculation(const ::coder::array + &contrastLayers, real_T rough, const char_T geometry_data[], const int32_T + geometry_size[2], real_T bulkIn, real_T bulkOut, real_T resample, + boolean_T calcSld, real_T scalefactor, real_T qzshift, real_T dataPresent, + const ::coder::array &data, const real_T dataLimits[2], const + real_T simLimits[2], const real_T repeatLayers[2], real_T background, + real_T resolution, real_T contrastBackgroundsType, real_T params, const + real_T resamPars[2], boolean_T useImaginary, ::coder::array + &sldProfile, ::coder::array &reflect, ::coder::array &simulation, ::coder::array &shiftedData, ::coder::array< + real_T, 2U> &theseLayers, ::coder::array &resamLayers, real_T * + chiSq, real_T *ssubs); + void coreLayersCalculation(const ::coder::array &contrastLayers, + real_T rough, const char_T geometry_data[], const int32_T geometry_size[2], + real_T bulkIn, real_T bulkOut, real_T resample, boolean_T calcSld, real_T + scalefactor, real_T qzshift, real_T dataPresent, const ::coder::array< + real_T, 2U> &data, const real_T dataLimits[2], const real_T simLimits[2], + const real_T repeatLayers[2], real_T background, real_T resolution, real_T + contrastBackgroundsType, real_T params, const real_T resamPars[2], + boolean_T useImaginary, ::coder::array &sldProfile, ::coder:: + array &reflect, ::coder::array &simulation, :: + coder::array &shiftedData, ::coder::array + &theseLayers, ::coder::array &resamLayers, real_T *chiSq, + real_T *ssubs); + } +} + +#endif + +// End of code generation (coreLayersCalculation.h) diff --git a/cpp/RAT/cov.cpp b/cpp/RAT/cov.cpp new file mode 100644 index 00000000..754b8303 --- /dev/null +++ b/cpp/RAT/cov.cpp @@ -0,0 +1,149 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// cov.cpp +// +// Code generation for function 'cov' +// + +// Include files +#include "cov.h" +#include "isrow.h" +#include "rt_nonfinite.h" +#include "xgemm.h" +#include "coder_array.h" + +// Function Declarations +namespace RAT +{ + namespace coder + { + static void local_cov(::coder::array &x, ::coder::array &c); + static real_T local_cov(::coder::array &x); + } +} + +// Function Definitions +namespace RAT +{ + namespace coder + { + static void local_cov(::coder::array &x, ::coder::array &c) + { + int32_T b_i; + int32_T j; + int32_T m; + int32_T n; + m = x.size(0); + n = x.size(1); + c.set_size(x.size(1), x.size(1)); + j = x.size(1); + for (int32_T i{0}; i < j; i++) { + b_i = x.size(1); + for (int32_T i1{0}; i1 < b_i; i1++) { + c[i1 + c.size(0) * i] = 0.0; + } + } + + if ((x.size(0) == 0) || (x.size(1) == 0)) { + c.set_size(x.size(1), x.size(1)); + j = x.size(1); + for (int32_T i{0}; i < j; i++) { + b_i = x.size(1); + for (int32_T i1{0}; i1 < b_i; i1++) { + c[i1 + c.size(0) * i] = rtNaN; + } + } + } else if (x.size(0) >= 2) { + for (j = 0; j < n; j++) { + real_T muj; + muj = 0.0; + for (b_i = 0; b_i < m; b_i++) { + muj += x[b_i + x.size(0) * j]; + } + + muj /= static_cast(m); + for (b_i = 0; b_i < m; b_i++) { + x[b_i + x.size(0) * j] = x[b_i + x.size(0) * j] - muj; + } + } + + c.set_size(x.size(1), x.size(1)); + j = x.size(1); + b_i = x.size(1); + for (int32_T i{0}; i < j; i++) { + for (int32_T i1{0}; i1 < b_i; i1++) { + c[i1 + c.size(0) * i] = 0.0; + } + } + + internal::blas::xgemm(x.size(1), x.size(1), x.size(0), 1.0 / ( + static_cast(x.size(0)) - 1.0), x, x.size(0), x, x.size(0), c, + x.size(1)); + } + } + + static real_T local_cov(::coder::array &x) + { + real_T c; + int32_T m; + m = x.size(0) - 1; + c = 0.0; + if (x.size(0) == 0) { + c = rtNaN; + } else if (x.size(0) >= 2) { + real_T muj; + muj = 0.0; + for (int32_T i{0}; i <= m; i++) { + muj += x[i]; + } + + muj /= static_cast(x.size(0)); + for (int32_T i{0}; i <= m; i++) { + x[i] = x[i] - muj; + } + + c = internal::blas::xgemm(x.size(0), 1.0 / (static_cast(x.size(0)) + - 1.0), x, x); + } + + return c; + } + + void cov(const ::coder::array &x, ::coder::array &xy) + { + ::coder::array b_x; + ::coder::array c_x; + if (isrow(x)) { + int32_T loop_ub; + c_x.set_size(x.size(1)); + loop_ub = x.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + c_x[i] = x[x.size(0) * i]; + } + + xy.set_size(1, 1); + xy[0] = local_cov(c_x); + } else { + int32_T loop_ub; + b_x.set_size(x.size(0), x.size(1)); + loop_ub = x.size(1) - 1; + for (int32_T i{0}; i <= loop_ub; i++) { + int32_T b_loop_ub; + b_loop_ub = x.size(0) - 1; + for (int32_T i1{0}; i1 <= b_loop_ub; i1++) { + b_x[i1 + b_x.size(0) * i] = x[i1 + x.size(0) * i]; + } + } + + local_cov(b_x, xy); + } + } + } +} + +// End of code generation (cov.cpp) diff --git a/cpp/RAT/cov.h b/cpp/RAT/cov.h new file mode 100644 index 00000000..59091130 --- /dev/null +++ b/cpp/RAT/cov.h @@ -0,0 +1,30 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// cov.h +// +// Code generation for function 'cov' +// +#ifndef COV_H +#define COV_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void cov(const ::coder::array &x, ::coder::array &xy); + } +} + +#endif + +// End of code generation (cov.h) diff --git a/cpp/RAT/dataResolutionPolly.cpp b/cpp/RAT/dataResolutionPolly.cpp new file mode 100644 index 00000000..b0f98a4f --- /dev/null +++ b/cpp/RAT/dataResolutionPolly.cpp @@ -0,0 +1,71 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// dataResolutionPolly.cpp +// +// Code generation for function 'dataResolutionPolly' +// + +// Include files +#include "dataResolutionPolly.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + void dataResolutionPolly(const ::coder::array &xdata, const :: + coder::array &ydata, const ::coder::array &resData, + real_T points, ::coder::array &out) + { + int32_T i; + int32_T loop_ub_tmp; + + // Apply resolution correction + loop_ub_tmp = static_cast(points); + out.set_size(loop_ub_tmp); + for (i = 0; i < loop_ub_tmp; i++) { + out[i] = 0.0; + } + + for (int32_T j{0}; j < loop_ub_tmp; j++) { + real_T a; + real_T sumg; + int32_T ilow; + sumg = 0.0; + out[j] = 0.0; + if (static_cast(j) + 1U > 10U) { + ilow = -10; + } else { + ilow = static_cast(-(static_cast(j) + 1.0)) + 1; + } + + if (static_cast(j) + 1.0 < points - 10.0) { + a = 10.0; + } else { + a = points - (static_cast(j) + 1.0); + } + + i = static_cast(a + (1.0 - static_cast(ilow))); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T g; + int32_T a_tmp; + a_tmp = static_cast((static_cast(j) + 1.0) + + static_cast(ilow + b_i)) - 1; + a = (xdata[a_tmp] - xdata[j]) / (resData[j] * xdata[j]); + g = std::exp(-(a * a)); + sumg += g; + out[j] = out[j] + ydata[a_tmp] * g; + } + + if (sumg != 0.0) { + out[j] = out[j] / sumg; + } + } + } +} + +// End of code generation (dataResolutionPolly.cpp) diff --git a/cpp/RAT/dataResolutionPolly.h b/cpp/RAT/dataResolutionPolly.h new file mode 100644 index 00000000..44aa5787 --- /dev/null +++ b/cpp/RAT/dataResolutionPolly.h @@ -0,0 +1,29 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// dataResolutionPolly.h +// +// Code generation for function 'dataResolutionPolly' +// +#ifndef DATARESOLUTIONPOLLY_H +#define DATARESOLUTIONPOLLY_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void dataResolutionPolly(const ::coder::array &xdata, const :: + coder::array &ydata, const ::coder::array &resData, + real_T points, ::coder::array &out); +} + +#endif + +// End of code generation (dataResolutionPolly.h) diff --git a/cpp/RAT/deopt.cpp b/cpp/RAT/deopt.cpp new file mode 100644 index 00000000..b6ad7115 --- /dev/null +++ b/cpp/RAT/deopt.cpp @@ -0,0 +1,830 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// deopt.cpp +// +// Code generation for function 'deopt' +// + +// Include files +#include "deopt.h" +#include "RATMain_internal_types.h" +#include "RATMain_rtwutil.h" +#include "RATMain_types.h" +#include "leftWin.h" +#include "mergesort.h" +#include "rand.h" +#include "randperm.h" +#include "repmat.h" +#include "rt_nonfinite.h" +#include "runDE.h" +#include "strcmp.h" +#include "validate_print_arguments.h" +#include "coder_array.h" +#include + +// Function Declarations +namespace RAT +{ + static void binary_expand_op(::coder::array &in1, int32_T in2, + const j_struct_T *in3, const ::coder::array &in4); + static void h_binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3, const :: + coder::array &in4, const ::coder::array &in5, const :: + coder::array &in6, const int32_T in7[2], real_T in8); +} + +// Function Definitions +namespace RAT +{ + static void binary_expand_op(::coder::array &in1, int32_T in2, + const j_struct_T *in3, const ::coder::array &in4) + { + int32_T i; + int32_T loop_ub; + int32_T stride_0_1; + int32_T stride_1_1; + int32_T stride_2_1; + int32_T stride_3_1; + stride_0_1 = (in3->FVr_minbound.size(1) != 1); + stride_1_1 = (in4.size(1) != 1); + stride_2_1 = (in3->FVr_maxbound.size(1) != 1); + stride_3_1 = (in3->FVr_minbound.size(1) != 1); + if (in3->FVr_minbound.size(1) == 1) { + i = in3->FVr_maxbound.size(1); + } else { + i = in3->FVr_minbound.size(1); + } + + if (i == 1) { + i = in4.size(1); + } else if (in3->FVr_minbound.size(1) == 1) { + i = in3->FVr_maxbound.size(1); + } else { + i = in3->FVr_minbound.size(1); + } + + if (i == 1) { + loop_ub = in3->FVr_minbound.size(1); + } else { + if (in3->FVr_minbound.size(1) == 1) { + i = in3->FVr_maxbound.size(1); + } else { + i = in3->FVr_minbound.size(1); + } + + if (i == 1) { + loop_ub = in4.size(1); + } else if (in3->FVr_minbound.size(1) == 1) { + loop_ub = in3->FVr_maxbound.size(1); + } else { + loop_ub = in3->FVr_minbound.size(1); + } + } + + for (i = 0; i < loop_ub; i++) { + in1[in2 + in1.size(0) * i] = in3->FVr_minbound[i * stride_0_1] + in4[i * + stride_1_1] * (in3->FVr_maxbound[i * stride_2_1] - in3->FVr_minbound[i * + stride_3_1]); + } + } + + static void h_binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3, const :: + coder::array &in4, const ::coder::array &in5, const :: + coder::array &in6, const int32_T in7[2], real_T in8) + { + int32_T aux_0_1; + int32_T aux_1_1; + int32_T aux_2_1; + int32_T aux_3_1; + int32_T aux_4_1; + int32_T aux_5_1; + int32_T b_in5; + int32_T b_in7; + int32_T i; + int32_T i1; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_0_1; + int32_T stride_1_0; + int32_T stride_1_1; + int32_T stride_2_0; + int32_T stride_2_1; + int32_T stride_3_0; + int32_T stride_3_1; + int32_T stride_4_0; + int32_T stride_4_1; + int32_T stride_5_0; + int32_T stride_5_1; + b_in5 = in5.size(1); + b_in7 = in7[1]; + if (b_in7 == 1) { + i = b_in5; + } else { + i = b_in7; + } + + if (in3.size(0) == 1) { + if (i == 1) { + i = in4.size(0); + } else if (b_in7 == 1) { + i = b_in5; + } else { + i = b_in7; + } + } else { + i = in3.size(0); + } + + if (b_in7 == 1) { + i1 = b_in5; + } else { + i1 = b_in7; + } + + if (i == 1) { + if (in3.size(0) == 1) { + i = in2.size(0); + } else { + i = in3.size(0); + } + } else if (in3.size(0) == 1) { + if (i1 == 1) { + i = in4.size(0); + } else if (b_in7 == 1) { + i = b_in5; + } else { + i = b_in7; + } + } else { + i = in3.size(0); + } + + if (in3.size(1) == 1) { + if (in2.size(1) == 1) { + i1 = in4.size(1); + } else { + i1 = in2.size(1); + } + } else { + i1 = in3.size(1); + } + + if (i1 == 1) { + if (in3.size(1) == 1) { + i1 = in2.size(1); + } else { + i1 = in3.size(1); + } + } else if (in3.size(1) == 1) { + if (in2.size(1) == 1) { + i1 = in4.size(1); + } else { + i1 = in2.size(1); + } + } else { + i1 = in3.size(1); + } + + in1.set_size(i, i1); + stride_0_0 = (in2.size(0) != 1); + stride_0_1 = (in2.size(1) != 1); + stride_1_0 = (in3.size(0) != 1); + stride_1_1 = (in3.size(1) != 1); + stride_2_0 = (in4.size(0) != 1); + stride_2_1 = (in4.size(1) != 1); + stride_3_0 = (b_in5 != 1); + stride_3_1 = (in2.size(1) != 1); + stride_4_0 = (b_in7 != 1); + stride_4_1 = (in2.size(1) != 1); + stride_5_0 = (in3.size(0) != 1); + stride_5_1 = (in3.size(1) != 1); + aux_0_1 = 0; + aux_1_1 = 0; + aux_2_1 = 0; + aux_3_1 = 0; + aux_4_1 = 0; + aux_5_1 = 0; + if (in3.size(1) == 1) { + if (in2.size(1) == 1) { + i = in4.size(1); + } else { + i = in2.size(1); + } + } else { + i = in3.size(1); + } + + if (i == 1) { + if (in3.size(1) == 1) { + loop_ub = in2.size(1); + } else { + loop_ub = in3.size(1); + } + } else if (in3.size(1) == 1) { + if (in2.size(1) == 1) { + loop_ub = in4.size(1); + } else { + loop_ub = in2.size(1); + } + } else { + loop_ub = in3.size(1); + } + + for (i = 0; i < loop_ub; i++) { + int32_T b_loop_ub; + int32_T i2; + i1 = in3.size(0); + b_loop_ub = in4.size(0); + if (b_in7 == 1) { + i2 = b_in5; + } else { + i2 = b_in7; + } + + if (i1 == 1) { + if (i2 == 1) { + i2 = b_loop_ub; + } else if (b_in7 == 1) { + i2 = b_in5; + } else { + i2 = b_in7; + } + } else { + i2 = i1; + } + + if (i2 == 1) { + if (i1 == 1) { + b_loop_ub = in2.size(0); + } else { + b_loop_ub = i1; + } + } else if (i1 == 1) { + if (b_in7 == 1) { + i1 = b_in5; + } else { + i1 = b_in7; + } + + if (i1 != 1) { + if (b_in7 == 1) { + b_loop_ub = b_in5; + } else { + b_loop_ub = b_in7; + } + } + } else { + b_loop_ub = i1; + } + + for (i1 = 0; i1 < b_loop_ub; i1++) { + in1[i1 + in1.size(0) * i] = in2[i1 * stride_0_0 + in2.size(0) * aux_0_1] + * static_cast(static_cast(in3[i1 * stride_1_0 + + in3.size(0) * aux_1_1]) < 0.5) + (in4[i1 * stride_2_0 + in4.size(0) * + aux_2_1] + (in2[(static_cast(in5[i1 * stride_3_0]) + in2.size + (0) * aux_3_1) - 1] - in2[(static_cast + (in6[i1 * stride_4_0]) + in2.size(0) * aux_4_1) - 1]) * in8) * + static_cast(in3[i1 * stride_5_0 + in3.size(0) * aux_5_1]); + } + + aux_5_1 += stride_5_1; + aux_4_1 += stride_4_1; + aux_3_1 += stride_3_1; + aux_2_1 += stride_2_1; + aux_1_1 += stride_1_1; + aux_0_1 += stride_0_1; + } + } + + void deopt(const c_struct_T *problem, const ::coder::array + &problemCells_f1, const ::coder::array + &problemCells_f2, const ::coder::array + &problemCells_f3, const ::coder::array + &problemCells_f4, const ::coder::array + &problemCells_f5, const ::coder::array + &problemCells_f6, const ::coder::array + &problemCells_f14, const ::coder::array + &problemCells_f19, const char_T controls_parallel_data[], const + int32_T controls_parallel_size[2], const real_T controls_resamPars + [2], boolean_T controls_calcSldDuringFit, const char_T + controls_display_data[], const int32_T controls_display_size[2], + const struct3_T *controls_checks, const j_struct_T *S_struct, :: + coder::array &FVr_bestmem) + { + ::coder::array S_val; + ::coder::array FM_pm3; + ::coder::array FM_pop; + ::coder::array FM_ui; + ::coder::array FVr_a1; + ::coder::array FVr_a2; + ::coder::array FVr_a3; + ::coder::array b_FM_pop; + ::coder::array r; + ::coder::array r1; + ::coder::array FM_mui; + c_struct_T b_problem; + real_T F_CR; + real_T I_D; + real_T I_NP; + real_T I_iter; + real_T I_itermax; + real_T S_bestval_FVr_oa; + real_T b; + real_T fWeight; + int32_T b_loop_ub_tmp; + int32_T i; + int32_T i1; + int32_T i2; + int32_T loop_ub; + int32_T loop_ub_tmp; + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // Function: [FVr_bestmem,S_bestval,I_nfeval] = deopt(fname,S_struct) + // + // Author: Rainer Storn, Ken Price, Arnold Neumaier, Jim Van Zandt + // Description: Minimization of a user-supplied function with respect to x(1:I_D), + // using the differential evolution (DE) algorithm. + // DE works best if [FVr_minbound,FVr_maxbound] covers the region where the + // global minimum is expected. DE is also somewhat sensitive to + // the choice of the stepsize fWeight. A good initial guess is to + // choose fWeight from interval [0.5, 1], e.g. 0.8. F_CR, the crossover + // probability constant from interval [0, 1] helps to maintain + // the diversity of the population but should be close to 1 for most. + // practical cases. Only separable problems do better with CR close to 0. + // If the parameters are correlated, high values of F_CR work better. + // The reverse is true for no correlation. + // + // The number of population members I_NP is also not very critical. A + // good initial guess is 10*I_D. Depending on the difficulty of the + // problem I_NP can be lower than 10*I_D or must be higher than 10*I_D + // to achieve convergence. + // + // deopt is a vectorized variant of DE which, however, has a + // property which differs from the original version of DE: + // The random selection of vectors is performed by shuffling the + // population array. Hence a certain vector can't be chosen twice + // in the same term of the perturbation expression. + // Due to the vectorized expressions deopt executes fairly fast + // in MATLAB's interpreter environment. + // + // Parameters: fname (I) String naming a function f(x,y) to minimize. + // S_struct (I) Problem data vector (must remain fixed during the + // minimization). For details see Rundeopt.m. + // ---------members of S_struct---------------------------------------------------- + // F_VTR (I) "Value To Reach". deopt will stop its minimization + // if either the maximum number of iterations "I_itermax" + // is reached or the best parameter vector "FVr_bestmem" + // has found a value f(FVr_bestmem,y) <= F_VTR. + // FVr_minbound (I) Vector of lower bounds FVr_minbound(1) ... FVr_minbound(I_D) + // of initial population. + // *** note: these are not bound constraints!! *** + // FVr_maxbound (I) Vector of upper bounds FVr_maxbound(1) ... FVr_maxbound(I_D) + // of initial population. + // I_D (I) Number of parameters of the objective function. + // I_NP (I) Number of population members. + // I_itermax (I) Maximum number of iterations (generations). + // fWeight (I) DE-stepsize fWeight from interval [0, 2]. + // F_CR (I) Crossover probability constant from interval [0, 1]. + // I_strategy (I) 1 --> DE/rand/1 + // 2 --> DE/local-to-best/1 + // 3 --> DE/best/1 with jitter + // 4 --> DE/rand/1 with per-vector-dither + // 5 --> DE/rand/1 with per-generation-dither + // 6 --> DE/rand/1 either-or-algorithm + // I_refresh (I) Intermediate output will be produced after "I_refresh" + // iterations. No intermediate output will be produced + // if I_refresh is < 1. + // + // Return value: FVr_bestmem (O) Best parameter vector. + // S_bestval.I_nc (O) Number of constraints + // S_bestval.FVr_ca (O) Constraint values. 0 means the constraints + // are met. Values > 0 measure the distance + // to a particular constraint. + // S_bestval.I_no (O) Number of objectives. + // S_bestval.FVr_oa (O) Objective function values. + // I_nfeval (O) Number of function evaluations. + // + // Note: + // This program is free software; you can redistribute it and/or modify + // it under the terms of the GNU General Public License as published by + // the Free Software Foundation; either version 1, or (at your option) + // any later version. + // + // This program is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. A copy of the GNU + // General Public License can be obtained from the + // Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // -----This is just for notational convenience and to keep the code uncluttered.-------- + I_NP = S_struct->I_NP; + fWeight = S_struct->fWeight; + F_CR = S_struct->F_CR; + I_D = S_struct->I_D; + I_itermax = S_struct->I_itermax; + + // -----Check input variables--------------------------------------------- + if (S_struct->I_NP < 5.0) { + I_NP = 5.0; + printf(" I_NP increased to minimal value 5\n"); + fflush(stdout); + } + + if ((S_struct->F_CR < 0.0) || (S_struct->F_CR > 1.0)) { + F_CR = 0.5; + printf("F_CR should be from interval [0,1]; set to default value 0.5\n"); + fflush(stdout); + } + + if (S_struct->I_itermax <= 0.0) { + I_itermax = 200.0; + printf("I_itermax should be > 0; set to default value 200\n"); + fflush(stdout); + } + + // -----Initialize population and some arrays------------------------------- + i = static_cast(I_NP); + loop_ub_tmp = static_cast(S_struct->I_D); + FM_pop.set_size(i, loop_ub_tmp); + + // initialize FM_pop to gain speed + // ----FM_pop is a matrix of size I_NPx(I_D+1). It will be initialized------ + // ----with random values between the min and max values of the------------- + // ----parameters----------------------------------------------------------- + loop_ub = S_struct->FVr_minbound.size(1); + for (int32_T k{0}; k < i; k++) { + coder::b_rand(I_D, r); + if (S_struct->FVr_maxbound.size(1) == 1) { + i1 = S_struct->FVr_minbound.size(1); + } else { + i1 = S_struct->FVr_maxbound.size(1); + } + + if (r.size(1) == 1) { + if (S_struct->FVr_maxbound.size(1) == 1) { + i2 = S_struct->FVr_minbound.size(1); + } else { + i2 = S_struct->FVr_maxbound.size(1); + } + } else { + i2 = r.size(1); + } + + if ((S_struct->FVr_maxbound.size(1) == S_struct->FVr_minbound.size(1)) && + (r.size(1) == i1) && (S_struct->FVr_minbound.size(1) == i2)) { + for (i1 = 0; i1 < loop_ub; i1++) { + b = S_struct->FVr_minbound[i1]; + FM_pop[k + FM_pop.size(0) * i1] = b + r[i1] * (S_struct-> + FVr_maxbound[i1] - b); + } + } else { + binary_expand_op(FM_pop, k, S_struct, r); + } + } + + // number of function evaluations + // ------Evaluate the best member after initialization---------------------- + coder::repmat(I_NP, S_val); + + // start with first population member + b_FM_pop.set_size(1, FM_pop.size(1)); + loop_ub = FM_pop.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + b_FM_pop[i1] = FM_pop[FM_pop.size(0) * i1]; + } + + b_problem = *problem; + S_val[0] = intrafun(b_FM_pop, &b_problem, controls_parallel_data, + controls_parallel_size, controls_resamPars, + controls_calcSldDuringFit, controls_checks, + problemCells_f1, problemCells_f2, problemCells_f3, + problemCells_f4, problemCells_f5, problemCells_f6, + problemCells_f14, problemCells_f19); + S_bestval_FVr_oa = S_val[0].FVr_oa; + + // best objective function value so far + b_loop_ub_tmp = static_cast(I_NP - 1.0); + loop_ub = FM_pop.size(1); + for (int32_T k{0}; k < b_loop_ub_tmp; k++) { + l_struct_T expl_temp; + + // check the remaining members + b_FM_pop.set_size(1, FM_pop.size(1)); + for (i1 = 0; i1 < loop_ub; i1++) { + b_FM_pop[i1] = FM_pop[(k + FM_pop.size(0) * i1) + 1]; + } + + b_problem = *problem; + expl_temp = intrafun(b_FM_pop, &b_problem, controls_parallel_data, + controls_parallel_size, controls_resamPars, + controls_calcSldDuringFit, controls_checks, + problemCells_f1, problemCells_f2, problemCells_f3, + problemCells_f4, problemCells_f5, problemCells_f6, + problemCells_f14, problemCells_f19); + S_val[k + 1] = expl_temp; + if (leftWin(expl_temp.I_no, expl_temp.FVr_oa, S_bestval_FVr_oa) == 1.0) { + // save its location + S_bestval_FVr_oa = expl_temp.FVr_oa; + } + } + + // best member of current iteration + // best member ever + // ------DE-Minimization--------------------------------------------- + // ------FM_popold is the population which has to compete. It is-------- + // ------static through one iteration. FM_pop is the newly-------------- + // ------emerging population.---------------------------------------- + // initialize population matrix 1 + // initialize population matrix 2 + // initialize population matrix 3 + // initialize population matrix 4 + // initialize population matrix 5 + // initialize FVr_bestmember matrix + // intermediate population of perturbed vectors + // mask for intermediate population + // mask for old population + // rotating index array (size I_NP) + // rotating index array (size I_D) + // another rotating index array + // rotating index array for exponential crossover + // index array + FVr_bestmem.set_size(1, loop_ub_tmp); + for (i1 = 0; i1 < loop_ub_tmp; i1++) { + FVr_bestmem[i1] = 0.0; + } + + // + // FM_pop = zeros(I_NP,2); + I_iter = 1.0; + while ((I_iter < I_itermax) && (S_bestval_FVr_oa > S_struct->F_VTR)) { + real_T p[4]; + int32_T iv[4]; + int32_T FVr_rt_size[2]; + int32_T b_FVr_a1; + + // save the old population + // S_struct.FM_pop = FM_pop; + coder::b_rand(p); + iv[0] = 0; + iv[1] = 0; + iv[2] = 0; + iv[3] = 0; + coder::internal::b_mergesort(iv, p); + p[0] = iv[0]; + p[1] = iv[1]; + + // index pointer array + coder::randperm(I_NP, r); + FVr_a1.set_size(1, r.size(1)); + loop_ub = r.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + FVr_a1[FVr_a1.size(0) * i1] = r[i1]; + } + + // shuffle locations of vectors + r.set_size(1, static_cast(I_NP - 1.0) + 1); + for (i1 = 0; i1 <= b_loop_ub_tmp; i1++) { + r[i1] = rt_remd_snf(static_cast(i1) + p[0], I_NP); + } + + FVr_rt_size[0] = 1; + FVr_rt_size[1] = r.size(1); + + // rotate indices by ind(1) positions + r.set_size(1, static_cast(I_NP - 1.0) + 1); + for (i1 = 0; i1 <= b_loop_ub_tmp; i1++) { + r[i1] = rt_remd_snf(static_cast(i1) + p[0], I_NP); + } + + FVr_a2.set_size(1, r.size(1)); + loop_ub = r.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + FVr_a2[FVr_a2.size(0) * i1] = FVr_a1[static_cast(r[i1] + 1.0) - + 1]; + } + + // rotate vector locations + r.set_size(1, static_cast(I_NP - 1.0) + 1); + for (i1 = 0; i1 <= b_loop_ub_tmp; i1++) { + r[i1] = rt_remd_snf(static_cast(i1) + p[1], I_NP); + } + + FVr_a3.set_size(1, r.size(1)); + loop_ub = r.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + FVr_a3[FVr_a3.size(0) * i1] = FVr_a2[static_cast(r[i1] + 1.0) - + 1]; + } + + // shuffled population 1 + // shuffled population 2 + r.set_size(1, static_cast(I_NP - 1.0) + 1); + for (i1 = 0; i1 <= b_loop_ub_tmp; i1++) { + r[i1] = rt_remd_snf(static_cast(i1) + p[1], I_NP); + } + + b_FVr_a1 = r.size(1); + FM_pm3.set_size(r.size(1), FM_pop.size(1)); + loop_ub = FM_pop.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + for (i2 = 0; i2 < b_FVr_a1; i2++) { + FM_pm3[i2 + FM_pm3.size(0) * i1] = FM_pop[(static_cast + (FVr_a3[i2]) + FM_pop.size(0) * i1) - 1]; + } + } + + // shuffled population 3 + // shuffled population 4 + // shuffled population 5 + coder::b_rand(I_NP, I_D, r1); + FM_mui.set_size(r1.size(0), r1.size(1)); + loop_ub = r1.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + b_FVr_a1 = r1.size(0); + for (i2 = 0; i2 < b_FVr_a1; i2++) { + FM_mui[i2 + FM_mui.size(0) * i1] = (r1[i2 + r1.size(0) * i1] < F_CR); + } + } + + // all random numbers < F_CR are 1, 0 otherwise + // ----Insert this if you want exponential crossover.---------------- + // FM_mui = sort(FM_mui'); % transpose, collect 1's in each column + // for k = 1:I_NP + // n = floor(rand*I_D); + // if (n > 0) + // FVr_rtd = rem(FVr_rotd+n,I_D); + // FM_mui(:,k) = FM_mui(FVr_rtd+1,k); %rotate column k by n + // end + // end + // FM_mui = FM_mui'; % transpose back + // ----End: exponential crossover------------------------------------ + // inverse mask to FM_mui + // DE/rand/1 with per-vector-dither + b = (1.0 - fWeight) * coder::b_rand() + fWeight; + + // differential variation + if (FM_pm3.size(0) == 1) { + i1 = FVr_a1.size(1); + } else { + i1 = FM_pm3.size(0); + } + + if (FM_pm3.size(1) == 1) { + i2 = FM_pop.size(1); + } else { + i2 = FM_pm3.size(1); + } + + if (FM_pop.size(1) == 1) { + b_FVr_a1 = FM_mui.size(1); + } else { + b_FVr_a1 = FM_pop.size(1); + } + + if (FM_pm3.size(1) == 1) { + loop_ub = FM_pop.size(1); + } else { + loop_ub = FM_pm3.size(1); + } + + if (loop_ub == 1) { + loop_ub = FM_mui.size(1); + } else if (FM_pm3.size(1) == 1) { + loop_ub = FM_pop.size(1); + } else { + loop_ub = FM_pm3.size(1); + } + + if ((FM_pop.size(1) == FM_mui.size(1)) && (FVr_a1.size(1) == FVr_rt_size[1]) + && (FM_pm3.size(0) == FVr_a1.size(1)) && (FM_pm3.size(1) == + FM_pop.size(1)) && (i1 == FM_mui.size(0)) && (i2 == FM_mui.size(1)) && + (FM_pop.size(0) == FM_mui.size(0)) && (b_FVr_a1 == loop_ub)) { + FM_ui.set_size(FM_pop.size(0), FM_pop.size(1)); + loop_ub = FM_pop.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + b_FVr_a1 = FM_pop.size(0); + for (i2 = 0; i2 < b_FVr_a1; i2++) { + boolean_T b_b; + b_b = FM_mui[i2 + FM_mui.size(0) * i1]; + FM_ui[i2 + FM_ui.size(0) * i1] = FM_pop[i2 + FM_pop.size(0) * i1] * + static_cast(static_cast(b_b) < 0.5) + (FM_pm3[i2 + + FM_pm3.size(0) * i1] + (FM_pop[(static_cast(FVr_a1[i2]) + + FM_pop.size(0) * i1) - 1] - FM_pop[(static_cast(FVr_a2[i2]) + + FM_pop.size(0) * i1) - 1]) * b) * static_cast(b_b); + } + } + } else { + h_binary_expand_op(FM_ui, FM_pop, FM_mui, FM_pm3, FVr_a1, FVr_a2, + FVr_rt_size, b); + } + + // crossover + // -----Optional parent+child selection----------------------------------------- + // -----Select which vectors are allowed to enter the new population------------ + for (int32_T k{0}; k < i; k++) { + l_struct_T S_tempval; + + // =====Only use this if boundary constraints are needed================== + for (int32_T j{0}; j < loop_ub_tmp; j++) { + real_T d; + + // ----boundary constraints via bounce back------- + b = FM_ui[k + FM_ui.size(0) * j]; + d = S_struct->FVr_maxbound[j]; + if (b > d) { + b = d + coder::b_rand() * (FM_pm3[k + FM_pm3.size(0) * j] - d); + FM_ui[k + FM_ui.size(0) * j] = b; + } + + d = S_struct->FVr_minbound[j]; + if (b < d) { + b = d + coder::b_rand() * (FM_pm3[k + FM_pm3.size(0) * j] - d); + FM_ui[k + FM_ui.size(0) * j] = b; + } + } + + // =====End boundary constraints========================================== + loop_ub = FM_ui.size(1); + b_FM_pop.set_size(1, FM_ui.size(1)); + for (i1 = 0; i1 < loop_ub; i1++) { + b_FM_pop[i1] = FM_ui[k + FM_ui.size(0) * i1]; + } + + b_problem = *problem; + S_tempval = intrafun(b_FM_pop, &b_problem, controls_parallel_data, + controls_parallel_size, controls_resamPars, + controls_calcSldDuringFit, controls_checks, + problemCells_f1, problemCells_f2, problemCells_f3, + problemCells_f4, problemCells_f5, problemCells_f6, + problemCells_f14, problemCells_f19); + + // check cost of competitor + if (leftWin(S_tempval.I_no, S_tempval.FVr_oa, S_val[k].FVr_oa) == 1.0) { + loop_ub = FM_ui.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + FM_pop[k + FM_pop.size(0) * i1] = FM_ui[k + FM_ui.size(0) * i1]; + } + + // replace old vector with new one (for new iteration) + S_val[k] = S_tempval; + + // save value in "cost array" + // ----we update S_bestval only in case of success to save time----------- + if (leftWin(S_tempval.I_no, S_tempval.FVr_oa, S_bestval_FVr_oa) == 1.0) + { + S_bestval_FVr_oa = S_tempval.FVr_oa; + + // new best value + loop_ub = FM_ui.size(1); + FVr_bestmem.set_size(1, FM_ui.size(1)); + for (i1 = 0; i1 < loop_ub; i1++) { + FVr_bestmem[i1] = FM_ui[k + FM_ui.size(0) * i1]; + } + + // new best parameter vector ever + } + } + } + + // for k = 1:NP + // freeze the best member of this iteration for the coming + // iteration. This is needed for some of the strategies. + // ----Output section---------------------------------------------------------- + if (((rt_remd_snf(I_iter, 1.0) == 0.0) || (I_iter == 1.0)) && coder:: + internal::w_strcmp(controls_display_data, controls_display_size)) { + real_T validatedHoleFilling[5]; + coder::internal::validate_print_arguments(I_iter, S_bestval_FVr_oa, + fWeight, F_CR, I_NP, validatedHoleFilling); + printf("Iteration: %g, Best: %f, fWeight: %f, F_CR: %f, I_NP: %g\n\n", + validatedHoleFilling[0], validatedHoleFilling[1], + validatedHoleFilling[2], validatedHoleFilling[3], + validatedHoleFilling[4]); + fflush(stdout); + + // disp(S_bestval); + // var(FM_pop) + // format long e; + // for n=1:I_D + // fprintf('best(%d) = %g\n',n,FVr_bestmem(n)); + // end + // if (I_plotting == 1) + // PlotIt(FVr_bestmem,problem); + // end + } + + I_iter++; + } + + // ---end while ((I_iter < I_itermax) ... + // problemStruct.fitParams = x; + // problemStruct = unpackParams(problemStruct,controls); + // [problem,res] = reflectivityCalculation(problemStruct,problemCells,controls); + } +} + +// End of code generation (deopt.cpp) diff --git a/cpp/RAT/deopt.h b/cpp/RAT/deopt.h new file mode 100644 index 00000000..cd162a1a --- /dev/null +++ b/cpp/RAT/deopt.h @@ -0,0 +1,48 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// deopt.h +// +// Code generation for function 'deopt' +// +#ifndef DEOPT_H +#define DEOPT_H + +// Include files +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct c_struct_T; + struct j_struct_T; +} + +// Function Declarations +namespace RAT +{ + void deopt(const c_struct_T *problem, const ::coder::array + &problemCells_f1, const ::coder::array + &problemCells_f2, const ::coder::array + &problemCells_f3, const ::coder::array + &problemCells_f4, const ::coder::array + &problemCells_f5, const ::coder::array + &problemCells_f6, const ::coder::array + &problemCells_f14, const ::coder::array + &problemCells_f19, const char_T controls_parallel_data[], const + int32_T controls_parallel_size[2], const real_T controls_resamPars + [2], boolean_T controls_calcSldDuringFit, const char_T + controls_display_data[], const int32_T controls_display_size[2], + const struct3_T *controls_checks, const j_struct_T *S_struct, :: + coder::array &FVr_bestmem); +} + +#endif + +// End of code generation (deopt.h) diff --git a/cpp/RAT/det.cpp b/cpp/RAT/det.cpp new file mode 100644 index 00000000..c110a55a --- /dev/null +++ b/cpp/RAT/det.cpp @@ -0,0 +1,68 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// det.cpp +// +// Code generation for function 'det' +// + +// Include files +#include "det.h" +#include "rt_nonfinite.h" +#include "xgetrf.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + real_T det(const ::coder::array &x) + { + ::coder::array b_x; + ::coder::array ipiv; + real_T y; + if ((x.size(0) == 0) || (x.size(1) == 0)) { + y = 1.0; + } else { + int32_T i; + int32_T k; + int32_T loop_ub; + boolean_T isodd; + b_x.set_size(x.size(0), x.size(1)); + k = x.size(1); + loop_ub = x.size(0); + for (i = 0; i < k; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_x[i1 + b_x.size(0) * i] = x[i1 + x.size(0) * i]; + } + } + + internal::lapack::xgetrf(x.size(0), x.size(1), b_x, x.size(0), ipiv); + y = b_x[0]; + i = b_x.size(0); + for (k = 0; k <= i - 2; k++) { + y *= b_x[(k + b_x.size(0) * (k + 1)) + 1]; + } + + isodd = false; + i = ipiv.size(1); + for (k = 0; k <= i - 2; k++) { + if (ipiv[k] > k + 1) { + isodd = !isodd; + } + } + + if (isodd) { + y = -y; + } + } + + return y; + } + } +} + +// End of code generation (det.cpp) diff --git a/cpp/RAT/det.h b/cpp/RAT/det.h new file mode 100644 index 00000000..07affd96 --- /dev/null +++ b/cpp/RAT/det.h @@ -0,0 +1,30 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// det.h +// +// Code generation for function 'det' +// +#ifndef DET_H +#define DET_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + real_T det(const ::coder::array &x); + } +} + +#endif + +// End of code generation (det.h) diff --git a/cpp/RAT/diag.cpp b/cpp/RAT/diag.cpp new file mode 100644 index 00000000..c35a5995 --- /dev/null +++ b/cpp/RAT/diag.cpp @@ -0,0 +1,132 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// diag.cpp +// +// Code generation for function 'diag' +// + +// Include files +#include "diag.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Declarations +namespace RAT +{ + namespace coder + { + static void calclen(const ::coder::array &A, int32_T *dlen, + int32_T *i, int32_T *j); + static void calclen(const ::coder::array &A, int32_T *dlen, + int32_T *i, int32_T *j); + } +} + +// Function Definitions +namespace RAT +{ + namespace coder + { + static void calclen(const ::coder::array &A, int32_T *dlen, + int32_T *i, int32_T *j) + { + if (A.size(1) > 0) { + int32_T u0; + u0 = A.size(0); + *dlen = A.size(1); + if (u0 <= *dlen) { + *dlen = u0; + } + + *i = 1; + *j = 1; + } else { + *dlen = 0; + *i = 1; + *j = 1; + } + } + + static void calclen(const ::coder::array &A, int32_T *dlen, + int32_T *i, int32_T *j) + { + if (A.size(1) > 0) { + int32_T u0; + u0 = A.size(0); + *dlen = A.size(1); + if (u0 <= *dlen) { + *dlen = u0; + } + + *i = 1; + *j = 1; + } else { + *dlen = 0; + *i = 1; + *j = 1; + } + } + + void diag(const ::coder::array &v, ::coder::array + &d) + { + int32_T dlen; + int32_T j; + int32_T k; + if ((v.size(0) == 1) && (v.size(1) == 1)) { + d.set_size(1); + d[0] = v[0]; + } else { + calclen(v, &dlen, &k, &j); + d.set_size(dlen); + dlen--; + for (k = 0; k <= dlen; k++) { + d[k] = v[k + v.size(0) * k]; + } + } + } + + void diag(const ::coder::array &v, ::coder::array &d) + { + int32_T j; + int32_T nv; + nv = v.size(0); + d.set_size(v.size(0), v.size(0)); + j = v.size(0); + for (int32_T i{0}; i < j; i++) { + int32_T loop_ub; + loop_ub = v.size(0); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + d[i1 + d.size(0) * i] = 0.0; + } + } + + for (j = 0; j < nv; j++) { + d[j + d.size(0) * j] = v[j]; + } + } + + void diag(const ::coder::array &v, ::coder::array &d) + { + int32_T dlen; + int32_T j; + int32_T k; + if ((v.size(0) == 1) && (v.size(1) == 1)) { + d.set_size(1); + d[0] = v[0]; + } else { + calclen(v, &dlen, &k, &j); + d.set_size(dlen); + dlen--; + for (k = 0; k <= dlen; k++) { + d[k] = v[k + v.size(0) * k]; + } + } + } + } +} + +// End of code generation (diag.cpp) diff --git a/cpp/RAT/diag.h b/cpp/RAT/diag.h new file mode 100644 index 00000000..ed397b01 --- /dev/null +++ b/cpp/RAT/diag.h @@ -0,0 +1,33 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// diag.h +// +// Code generation for function 'diag' +// +#ifndef DIAG_H +#define DIAG_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void diag(const ::coder::array &v, ::coder::array + &d); + void diag(const ::coder::array &v, ::coder::array &d); + void diag(const ::coder::array &v, ::coder::array &d); + } +} + +#endif + +// End of code generation (diag.h) diff --git a/cpp/RAT/div.cpp b/cpp/RAT/div.cpp new file mode 100644 index 00000000..6656f217 --- /dev/null +++ b/cpp/RAT/div.cpp @@ -0,0 +1,69 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// div.cpp +// +// Code generation for function 'div' +// + +// Include files +#include "div.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void binary_expand_op(::coder::array &in1, int32_T in2, const :: + coder::array &in3, const ::coder::array< + real_T, 2U> &in4, const ::coder::array &in5) + { + int32_T loop_ub; + int32_T stride_0_1; + int32_T stride_1_1; + stride_0_1 = (in3.size(0) != 1); + stride_1_1 = (in5.size(0) != 1); + if (in5.size(0) == 1) { + loop_ub = in3.size(0); + } else { + loop_ub = in5.size(0); + } + + for (int32_T i{0}; i < loop_ub; i++) { + in1[in2 + in1.size(0) * (static_cast(in3[i]) - 1)] = in4[in2 + + in4.size(0) * (static_cast(in3[i * stride_0_1]) - 1)] / in5[i * + stride_1_1]; + } + } + + void rdivide(::coder::array &in1, const ::coder::array + &in2, const ::coder::array &in3) + { + int32_T i; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_1_0; + if (in3.size(0) == 1) { + i = in2.size(0); + } else { + i = in3.size(0); + } + + in1.set_size(i); + stride_0_0 = (in2.size(0) != 1); + stride_1_0 = (in3.size(0) != 1); + if (in3.size(0) == 1) { + loop_ub = in2.size(0); + } else { + loop_ub = in3.size(0); + } + + for (i = 0; i < loop_ub; i++) { + in1[i] = in2[i * stride_0_0] / in3[i * stride_1_0]; + } + } +} + +// End of code generation (div.cpp) diff --git a/cpp/RAT/div.h b/cpp/RAT/div.h new file mode 100644 index 00000000..5b3aac16 --- /dev/null +++ b/cpp/RAT/div.h @@ -0,0 +1,31 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// div.h +// +// Code generation for function 'div' +// +#ifndef DIV_H +#define DIV_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void binary_expand_op(::coder::array &in1, int32_T in2, const :: + coder::array &in3, const ::coder::array< + real_T, 2U> &in4, const ::coder::array &in5); + void rdivide(::coder::array &in1, const ::coder::array + &in2, const ::coder::array &in3); +} + +#endif + +// End of code generation (div.h) diff --git a/cpp/RAT/drawCR.cpp b/cpp/RAT/drawCR.cpp new file mode 100644 index 00000000..3c853d24 --- /dev/null +++ b/cpp/RAT/drawCR.cpp @@ -0,0 +1,124 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// drawCR.cpp +// +// Code generation for function 'drawCR' +// + +// Include files +#include "drawCR.h" +#include "RATMain_types.h" +#include "multrnd.h" +#include "randperm.h" +#include "randsample.h" +#include "reshapeSizeChecks.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void drawCR(const struct13_T *DREAMPar, const real_T pCR_data[], const int32_T + pCR_size[2], ::coder::array &CR) + { + ::coder::array b_r; + ::coder::array r; + ::coder::array cCR; + ::coder::array r1; + real_T L_data[3]; + + // Generates CR values based on current crossover probabilities + if (DREAMPar->adaptPCR) { + real_T L2_data[4]; + int32_T L_size[2]; + int32_T DREAMPar_idx_0_tmp; + int32_T i; + int32_T i1; + int32_T loop_ub; + + // If crossover probabilities are updated + // How many candidate points for each crossover value? + multrnd(DREAMPar->N * DREAMPar->steps, pCR_data, pCR_size, L_data, L_size); + L_data[1] += L_data[0]; + L_data[2] += L_data[1]; + L2_data[0] = 0.0; + L2_data[1] = L_data[0]; + L2_data[2] = L_data[1]; + L2_data[3] = L_data[2]; + + // Then select which candidate points are selected with what CR + coder::randperm(DREAMPar->N * DREAMPar->steps, b_r); + + // Then generate CR values for each chain + cCR.set_size(1000000); + for (i = 0; i < 1000000; i++) { + cCR[i] = 0.0; + } + + for (int32_T zz{0}; zz < 3; zz++) { + real_T d; + real_T d1; + + // Define start and end + // Take the appropriate elements of r + d = L2_data[zz + 1]; + d1 = L2_data[zz]; + if (d1 + 1.0 > d) { + i = 0; + i1 = 0; + } else { + i = static_cast(d1 + 1.0) - 1; + i1 = static_cast(d); + } + + // Assign these indices DREAMPar.CR(zz) + loop_ub = i1 - i; + r1.set_size(loop_ub); + for (i1 = 0; i1 < loop_ub; i1++) { + r1[i1] = static_cast(b_r[i + i1]); + } + + loop_ub = r1.size(0); + for (i = 0; i < loop_ub; i++) { + cCR[r1[i] - 1] = (static_cast(zz) + 1.0) / 3.0; + } + } + + // Now reshape CR + // CR = reshape(cCR,DREAMPar.N,DREAMPar.steps); + loop_ub = coder::internal::computeDimsData(DREAMPar->N); + DREAMPar_idx_0_tmp = static_cast(DREAMPar->N); + CR.set_size(static_cast(DREAMPar->N), loop_ub); + for (i = 0; i < loop_ub; i++) { + int32_T DREAMPar_tmp_tmp; + DREAMPar_tmp_tmp = static_cast(DREAMPar->N); + for (i1 = 0; i1 < DREAMPar_tmp_tmp; i1++) { + CR[i1 + CR.size(0) * i] = cCR[i1 + DREAMPar_idx_0_tmp * i]; + } + } + } else { + real_T tmp_data[3]; + int32_T DREAMPar_idx_0_tmp; + int32_T DREAMPar_tmp_tmp; + + // If crossover probabilities are not updated + tmp_data[0] = 0.33333333333333331; + tmp_data[1] = 0.66666666666666663; + tmp_data[2] = 1.0; + coder::randsample(tmp_data, DREAMPar->steps * DREAMPar->N, pCR_data, r); + DREAMPar_idx_0_tmp = static_cast(DREAMPar->N); + DREAMPar_tmp_tmp = static_cast(DREAMPar->steps); + CR.set_size(DREAMPar_idx_0_tmp, DREAMPar_tmp_tmp); + for (int32_T i{0}; i < DREAMPar_tmp_tmp; i++) { + for (int32_T i1{0}; i1 < DREAMPar_idx_0_tmp; i1++) { + CR[i1 + CR.size(0) * i] = r[i1 + DREAMPar_idx_0_tmp * i]; + } + } + } + } +} + +// End of code generation (drawCR.cpp) diff --git a/cpp/RAT/drawCR.h b/cpp/RAT/drawCR.h new file mode 100644 index 00000000..35690faa --- /dev/null +++ b/cpp/RAT/drawCR.h @@ -0,0 +1,34 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// drawCR.h +// +// Code generation for function 'drawCR' +// +#ifndef DRAWCR_H +#define DRAWCR_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct struct13_T; +} + +// Function Declarations +namespace RAT +{ + void drawCR(const struct13_T *DREAMPar, const real_T pCR_data[], const int32_T + pCR_size[2], ::coder::array &CR); +} + +#endif + +// End of code generation (drawCR.h) diff --git a/cpp/RAT/drawEllipsoidPoints.cpp b/cpp/RAT/drawEllipsoidPoints.cpp new file mode 100644 index 00000000..dec165cb --- /dev/null +++ b/cpp/RAT/drawEllipsoidPoints.cpp @@ -0,0 +1,146 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// drawEllipsoidPoints.cpp +// +// Code generation for function 'drawEllipsoidPoints' +// + +// Include files +#include "drawEllipsoidPoints.h" +#include "RATMain_rtwutil.h" +#include "blockedSummation.h" +#include "diag.h" +#include "eig.h" +#include "eml_mtimes_helper.h" +#include "mtimes.h" +#include "rand.h" +#include "randn.h" +#include "rt_nonfinite.h" +#include "sqrt.h" +#include "coder_array.h" +#include + +// Function Declarations +namespace RAT +{ + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3); +} + +// Function Definitions +namespace RAT +{ + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3) + { + int32_T loop_ub; + int32_T stride_0_1; + int32_T stride_1_1; + stride_0_1 = (in2.size(1) != 1); + stride_1_1 = (in3.size(1) != 1); + if (in3.size(1) == 1) { + loop_ub = in2.size(1); + } else { + loop_ub = in3.size(1); + } + + for (int32_T i{0}; i < loop_ub; i++) { + in1[i] = in2[i * stride_0_1].re + in3[i * stride_1_1]; + } + } + + void drawEllipsoidPoints(const ::coder::array &B, const ::coder:: + array &mu, ::coder::array &pnts) + { + ::coder::array E; + ::coder::array V; + ::coder::array b_pnts; + ::coder::array r1; + ::coder::array r; + ::coder::array pt; + ::coder::array x; + real_T a; + int32_T i; + int32_T k; + + // function pnts = drawEllipsoidPoints(B, mu, N ) + // + // This function draws points uniformly from an ndims-dimensional ellipsoid + // with edges and orientation defined by the the bounding matrix B and + // centroid mu. The output is a Nxndims dimensional array pnts. + // + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // get number of dimensions from the bounding matrix B + // calculate eigenvalues and vectors of the bounding matrix + coder::eig(B, V, E); + + // check size of mu and transpose if necessary + // generate radii of hyperspheres + a = coder::b_rand(); + + // generate points + coder::randn(static_cast(B.size(0)), pt); + + // get scalings for each point onto the surface of a unit hypersphere + x.set_size(1, pt.size(1)); + k = pt.size(1); + for (i = 0; i < k; i++) { + real_T varargin_1; + varargin_1 = pt[i]; + x[i] = rt_powd_snf(varargin_1, 2.0); + } + + // calculate scaling for each point to be within the unit hypersphere + // with radii rs + a = rt_powd_snf(a, 1.0 / static_cast(B.size(0))) / std::sqrt(coder:: + blockedSummation(x, x.size(1))); + pnts.set_size(1, B.size(0)); + k = B.size(0); + for (i = 0; i < k; i++) { + pnts[i] = 0.0; + } + + // scale points to the ellipsoid using the eigenvalues and rotate with + // the eigenvectors and add centroid + // scale points to a uniform distribution within unit hypersphere + k = pt.size(1); + for (i = 0; i < k; i++) { + pnts[i] = a * pt[i]; + } + + // scale and rotate to ellipsoid + // ('real' needed for compile....) + coder::diag(E, r); + i = r.size(0); + for (k = 0; k < i; k++) { + coder::internal::scalar::d_sqrt(&r[k]); + } + + if (r.size(0) == pnts.size(1)) { + b_pnts.set_size(1, pnts.size(1)); + k = pnts.size(1); + for (i = 0; i < k; i++) { + b_pnts[i].re = pnts[i] * r[i].re; + b_pnts[i].im = pnts[i] * -r[i].im; + } + + coder::internal::blas::mtimes(b_pnts, V, r1); + } else { + binary_expand_op(r1, pnts, r, V); + } + + if (r1.size(1) == mu.size(1)) { + k = r1.size(1); + for (i = 0; i < k; i++) { + pnts[i] = r1[i].re + mu[i]; + } + } else { + binary_expand_op(pnts, r1, mu); + } + } +} + +// End of code generation (drawEllipsoidPoints.cpp) diff --git a/cpp/RAT/drawEllipsoidPoints.h b/cpp/RAT/drawEllipsoidPoints.h new file mode 100644 index 00000000..892edcd7 --- /dev/null +++ b/cpp/RAT/drawEllipsoidPoints.h @@ -0,0 +1,28 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// drawEllipsoidPoints.h +// +// Code generation for function 'drawEllipsoidPoints' +// +#ifndef DRAWELLIPSOIDPOINTS_H +#define DRAWELLIPSOIDPOINTS_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void drawEllipsoidPoints(const ::coder::array &B, const ::coder:: + array &mu, ::coder::array &pnts); +} + +#endif + +// End of code generation (drawEllipsoidPoints.h) diff --git a/cpp/RAT/drawMCMC.cpp b/cpp/RAT/drawMCMC.cpp new file mode 100644 index 00000000..2d09e649 --- /dev/null +++ b/cpp/RAT/drawMCMC.cpp @@ -0,0 +1,331 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// drawMCMC.cpp +// +// Code generation for function 'drawMCMC' +// + +// Include files +#include "drawMCMC.h" +#include "RATMain_data.h" +#include "RATMain_internal_types.h" +#include "RATMain_rtwutil.h" +#include "RATMain_types.h" +#include "logPlus.h" +#include "mtimes.h" +#include "nsIntraFun.h" +#include "rand.h" +#include "randn.h" +#include "rescaleParameters.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3, real_T in4, + real_T in5); + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3, real_T in4); +} + +// Function Definitions +namespace RAT +{ + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3, real_T in4, + real_T in5) + { + int32_T i; + int32_T loop_ub; + int32_T stride_0_1; + int32_T stride_1_1; + if (in3.size(1) == 1) { + i = in2.size(1); + } else { + i = in3.size(1); + } + + in1.set_size(1, i); + stride_0_1 = (in2.size(1) != 1); + stride_1_1 = (in3.size(1) != 1); + if (in3.size(1) == 1) { + loop_ub = in2.size(1); + } else { + loop_ub = in3.size(1); + } + + for (i = 0; i < loop_ub; i++) { + int32_T i1; + i1 = i * stride_1_1; + in1[i] = in2[i * stride_0_1] + (in3[(static_cast(in4) + in3.size + (0) * i1) - 1] - in3[(static_cast(in5) + in3.size(0) * i1) - 1]); + } + } + + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3, real_T in4) + { + int32_T i; + int32_T loop_ub; + int32_T stride_0_1; + int32_T stride_1_1; + if (in3.size(0) == 1) { + i = in2.size(1); + } else { + i = in3.size(0); + } + + in1.set_size(1, i); + stride_0_1 = (in2.size(1) != 1); + stride_1_1 = (in3.size(0) != 1); + if (in3.size(0) == 1) { + loop_ub = in2.size(1); + } else { + loop_ub = in3.size(0); + } + + for (i = 0; i < loop_ub; i++) { + in1[i] = in2[i * stride_0_1] + in3[i * stride_1_1] * in4; + } + } + + void drawMCMC(const ::coder::array &livepoints, const ::coder:: + array &cholmat, real_T logLmin, const ::coder::array< + real_T, 2U> &prior, const c_struct_T *data_f1, const struct2_T + *data_f2, const cell_11 *data_f4, real_T Nmcmc, ::coder::array< + real_T, 2U> &sample, real_T *logL) + { + ::coder::array sampletmp; + ::coder::array gasdevs; + ::coder::array r; + real_T Ntimes; + real_T acc; + int32_T Nlive; + int32_T Npars; + int32_T i; + int32_T loop_ub; + + // This function will draw a multi-dimensional sample from the prior volume + // for use in the nested sampling algorithm. The new point will have a + // likelihood greater than the value logLmin. The new point will be found by + // evolving a random multi-dimensional sample from within the sample array, + // livepoints, using an MCMC with Nmcmc iterations. The MCMC will use a + // Students-t (with N=2 degrees of freedom) proposal distribution based on + // the Cholesky decomposed covariance matrix of the array, cholmat. 10% of + // the samples will actually be drawn using differential evolution by taking + // two random points from the current live points. extraparvals is a vector + // of additional parameters needed by the model. + // + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + *logL = logLmin; + + // useful constant + Nlive = livepoints.size(0); + Npars = livepoints.size(1) - 1; + + // degrees of freedom of Students't distribution + // initialize counters + Ntimes = 1.0; + loop_ub = livepoints.size(1); + i = static_cast(Nmcmc); + real_T sampidx; + int32_T exitg1; + do { + real_T currentPrior; + real_T priortype; + real_T pv_tmp; + int32_T j; + exitg1 = 0; + acc = 0.0; + + // get random point from live point array + sampidx = coder::b_rand() * static_cast(Nlive); + sampidx = std::ceil(sampidx); + sample.set_size(1, livepoints.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + sample[i1] = livepoints[(static_cast(sampidx) + livepoints.size + (0) * i1) - 1]; + } + + // get the sample prior + currentPrior = rtMinusInf; + for (j = 0; j <= Npars; j++) { + priortype = prior[j]; + + // p3 = prior{j,3}; + // p4 = prior{j,4}; + if (priortype == 1.0) { + currentPrior = logPlus(currentPrior, -std::log(prior[j + prior.size(0) + * 4] - prior[j + prior.size(0) * 3])); + } else if (priortype == 2.0) { + real_T p4; + p4 = prior[j + prior.size(0) * 2]; + pv_tmp = sample[j] - prior[j + prior.size(0)]; + currentPrior = logPlus(currentPrior, (-0.91893853320467267 - std::log + (p4)) - pv_tmp * pv_tmp / (2.0 * (p4 * p4))); + } else if (priortype == 3.0) { + pv_tmp = std::log10(prior[j + prior.size(0)]); + currentPrior = logPlus(currentPrior, -std::log(rt_powd_snf(10.0, + sample[j] * (std::log10(prior[j + prior.size(0) * 2]) - pv_tmp) + + pv_tmp))); + } + } + + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T newPrior; + int32_T b_loop_ub; + boolean_T exitg2; + if (coder::b_rand() < 0.9) { + real_T a[2]; + + // use Students-t proposal + // draw points from mulitvariate Gaussian distribution + coder::randn(static_cast(Npars + 1), gasdevs); + + // calculate chi-square distributed value + coder::randn(a); + + // add value onto old sample + pv_tmp = std::sqrt(2.0 / (rt_powd_snf(a[0], 2.0) + rt_powd_snf(a[1], + 2.0))); + coder::internal::blas::mtimes(cholmat, gasdevs, r); + b_loop_ub = sample.size(1); + if (r.size(0) == sample.size(1)) { + sampletmp.set_size(1, sample.size(1)); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + sampletmp[i1] = sample[i1] + r[i1] * pv_tmp; + } + } else { + binary_expand_op(sampletmp, sample, r, pv_tmp); + } + } else { + real_T idx1; + real_T idx2; + + // use differential evolution + // draw two random (different points) A and B and add (B-A) to + // the current sample + idx1 = coder::b_rand() * static_cast(Nlive); + idx1 = std::ceil(idx1); + idx2 = idx1; + while (idx2 == idx1) { + idx2 = coder::b_rand() * static_cast(Nlive); + idx2 = std::ceil(idx2); + } + + b_loop_ub = sample.size(1); + if (sample.size(1) == livepoints.size(1)) { + sampletmp.set_size(1, sample.size(1)); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + sampletmp[i1] = sample[i1] + (livepoints[(static_cast + (idx2) + livepoints.size(0) * i1) - 1] - livepoints[( + static_cast(idx1) + livepoints.size(0) * i1) - 1]); + } + } else { + binary_expand_op(sampletmp, sample, livepoints, idx2, idx1); + } + } + + // check sample is within the (scaled) prior + newPrior = rtMinusInf; + j = 0; + exitg2 = false; + while ((!exitg2) && (j <= Npars)) { + priortype = prior[j]; + + // p3 = prior{j,3}; + // p4 = prior{j,4}; + if (priortype == 1.0) { + // uniform + if ((sampletmp[j] < 0.0) || (sampletmp[j] > 1.0)) { + // wrap parameter from one side to the other + while (sampletmp[j] > 1.0) { + sampletmp[j] = sampletmp[j] - 1.0; + } + + while (sampletmp[j] < 0.0) { + sampletmp[j] = sampletmp[j] + 1.0; + } + } + + newPrior = logPlus(newPrior, -std::log(prior[j + prior.size(0) * 4] + - prior[j + prior.size(0) * 3])); + j++; + } else if (priortype == 2.0) { + // gaussian + newPrior = logPlus(newPrior, -0.91893853320467267 - sampletmp[j] * + sampletmp[j] / 2.0); + j++; + } else if (priortype == 3.0) { + // 'jeffreys' + // behaviour = char(prior(j,5)); + if ((sampletmp[j] < 0.0) || (sampletmp[j] > 1.0)) { + newPrior = rtMinusInf; + exitg2 = true; + } else { + pv_tmp = std::log10(prior[j + prior.size(0)]); + newPrior = logPlus(newPrior, -std::log(rt_powd_snf(10.0, + sampletmp[j] * (std::log10(prior[j + prior.size(0) * 2]) - + pv_tmp) + pv_tmp))); + j++; + } + } else { + j++; + } + } + + pv_tmp = coder::b_rand(); + if (!(std::log(pv_tmp) > newPrior - currentPrior)) { + real_T logLnew; + + // rescale sample back to its proper range for likelihood + // get the likelihood of the new sample + // likestart = tic; + // logLnew = likelihood(data, model, parnames, ... + // loopCell(sc)); + rescaleParameters(prior, sampletmp, r); + logLnew = nsIntraFun(data_f1, data_f2, data_f4, r); + + // likedur = toc(likestart); + // fprintf(1, 'liketime = %.6f\n', likedur); + // if logLnew is greater than logLmin accept point + if (logLnew > logLmin) { + acc++; + currentPrior = newPrior; + sample.set_size(1, sampletmp.size(1)); + b_loop_ub = sampletmp.size(1); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + sample[i1] = sampletmp[i1]; + } + + *logL = logLnew; + } + } else { + // reject point + } + } + + // only break if at least one point was accepted otherwise try again + if (acc > 0.0) { + exitg1 = 1; + } else { + Ntimes++; + } + } while (exitg1 == 0); + + // print out acceptance ratio + if (verbose != 0.0) { + printf("Acceptance ratio: %1.4f, \n\n", acc / (Ntimes * Nmcmc)); + fflush(stdout); + } + } +} + +// End of code generation (drawMCMC.cpp) diff --git a/cpp/RAT/drawMCMC.h b/cpp/RAT/drawMCMC.h new file mode 100644 index 00000000..5a73f152 --- /dev/null +++ b/cpp/RAT/drawMCMC.h @@ -0,0 +1,39 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// drawMCMC.h +// +// Code generation for function 'drawMCMC' +// +#ifndef DRAWMCMC_H +#define DRAWMCMC_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct c_struct_T; + struct struct2_T; + struct cell_11; +} + +// Function Declarations +namespace RAT +{ + void drawMCMC(const ::coder::array &livepoints, const ::coder:: + array &cholmat, real_T logLmin, const ::coder::array< + real_T, 2U> &prior, const c_struct_T *data_f1, const struct2_T + *data_f2, const cell_11 *data_f4, real_T Nmcmc, ::coder::array< + real_T, 2U> &sample, real_T *logL); +} + +#endif + +// End of code generation (drawMCMC.h) diff --git a/cpp/RAT/drawMultiNest.cpp b/cpp/RAT/drawMultiNest.cpp new file mode 100644 index 00000000..d6f8e757 --- /dev/null +++ b/cpp/RAT/drawMultiNest.cpp @@ -0,0 +1,152 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// drawMultiNest.cpp +// +// Code generation for function 'drawMultiNest' +// + +// Include files +#include "drawMultiNest.h" +#include "RATMain_data.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "drawEllipsoidPoints.h" +#include "inEllipsoids.h" +#include "nsIntraFun.h" +#include "rand.h" +#include "rescaleParameters.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + void drawMultiNest(const ::coder::array &fracvol, const ::coder:: + array &Bs, const ::coder::array + &mus, real_T logLmin, const ::coder::array + &prior, const c_struct_T *data_f1, const struct2_T *data_f2, + const cell_11 *data_f4, ::coder::array &sample, + real_T *logL) + { + ::coder::array B; + ::coder::array mu; + ::coder::array pnt; + ::coder::array r; + int32_T b_loop_ub; + int32_T loop_ub; + int32_T ndims; + + // This function draws a multi-dimensional sample from the prior volume + // for use in the nested sampling algorithm. The new point will have a + // likelihood greater than the value logLmin. The new point will be found by + // drawing a random multi-dimensional sample from within the set of optimal + // ellipsoids constructed using the MultiNest algorithm. The bounding + // ellipsoids are defined by their bounding matrices Bs and centroids mus. + // extraparvals is a vector of additional parameters needed by the model. + // + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // extra number of ellipsoids, number of dimensions + ndims = mus.size(1); + pnt.set_size(1, 2); + pnt[0] = 1.0; + pnt[1] = 1.0; + sample.set_size(1, 0); + loop_ub = Bs.size(1); + b_loop_ub = mus.size(1); + real_T inN; + real_T rval; + int32_T k; + int32_T k0; + boolean_T exitg1; + do { + int32_T c_loop_ub; + int32_T i; + int32_T i1; + + // find the ellipsoid from which to draw a new point + rval = coder::b_rand(); + k0 = 0; + k = 0; + exitg1 = false; + while ((!exitg1) && (k <= mus.size(0) - 1)) { + k0 = k; + if (rval < fracvol[k]) { + k++; + } else { + exitg1 = true; + } + } + + // extract bounding matrix and centroid for that ellipsoid + i = k0 * ndims; + i1 = (k0 + 1) * ndims; + if (i + 1 > i1) { + i = 0; + i1 = 0; + } + + c_loop_ub = i1 - i; + B.set_size(c_loop_ub, Bs.size(1)); + for (i1 = 0; i1 < loop_ub; i1++) { + for (int32_T i2{0}; i2 < c_loop_ub; i2++) { + B[i2 + B.size(0) * i1] = Bs[(i + i2) + Bs.size(0) * i1]; + } + } + + mu.set_size(1, mus.size(1)); + for (i = 0; i < b_loop_ub; i++) { + mu[i] = mus[k0 + mus.size(0) * i]; + } + + // draw points from that ellipsoid until logL >= logLmin + *logL = rtMinusInf; + while (*logL < logLmin) { + int32_T in_range; + in_range = 1; + + // default value + // draw one point from the ellipsoid + drawEllipsoidPoints(B, mu, pnt); + + // make sure that the point lies in unit hypercube + for (int32_T ii{0}; ii < ndims; ii++) { + real_T d; + d = pnt[ii]; + if ((d < 0.0) || (d > 1.0)) { + in_range = 0; + if (DEBUG != 0.0) { + printf("new point not in range!!!!\n"); + fflush(stdout); + } + } + } + + if (in_range != 0) { + // assign as candidate replacement live point + sample.set_size(1, pnt.size(1)); + c_loop_ub = pnt.size(1); + for (i = 0; i < c_loop_ub; i++) { + sample[sample.size(0) * i] = pnt[i]; + } + + // rescale point back to full range + // get new likelihood + // logL = likelihood(data, model, parnames, loopCell(rescaledpnt)); + rescaleParameters(prior, pnt, r); + *logL = nsIntraFun(data_f1, data_f2, data_f4, r); + } + } + + // check how many ellipsoids this point lies in + inN = inEllipsoids(pnt, Bs, mus); + + // only accept sample with 1/inN probability + } while (!(coder::b_rand() < 1.0 / inN)); + } +} + +// End of code generation (drawMultiNest.cpp) diff --git a/cpp/RAT/drawMultiNest.h b/cpp/RAT/drawMultiNest.h new file mode 100644 index 00000000..b350db67 --- /dev/null +++ b/cpp/RAT/drawMultiNest.h @@ -0,0 +1,40 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// drawMultiNest.h +// +// Code generation for function 'drawMultiNest' +// +#ifndef DRAWMULTINEST_H +#define DRAWMULTINEST_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct c_struct_T; + struct struct2_T; + struct cell_11; +} + +// Function Declarations +namespace RAT +{ + void drawMultiNest(const ::coder::array &fracvol, const ::coder:: + array &Bs, const ::coder::array + &mus, real_T logLmin, const ::coder::array + &prior, const c_struct_T *data_f1, const struct2_T *data_f2, + const cell_11 *data_f4, ::coder::array &sample, + real_T *logL); +} + +#endif + +// End of code generation (drawMultiNest.h) diff --git a/cpp/RAT/dylib.hpp b/cpp/RAT/dylib.hpp new file mode 100644 index 00000000..00dd978a --- /dev/null +++ b/cpp/RAT/dylib.hpp @@ -0,0 +1,320 @@ +/** + * \file dylib.hpp + * \brief Cross-platform Dynamic Library Loader + * \author Martin Olivier + * \version 1.8.1 + * + * MIT License + * Copyright (c) 2022 Martin Olivier + */ + +#pragma once + +#include +#include +#include +#include +#if defined(_WIN32) || defined(_WIN64) +#define WIN32_LEAN_AND_MEAN +#define DYLIB_API extern "C" __declspec(dllexport) +#include +#undef WIN32_LEAN_AND_MEAN +#else +#define DYLIB_API extern "C" +#include +#endif + +/** + * The dylib class can hold a dynamic library instance and interact with it + * by getting its symbols like functions or global variables + */ +class dylib +{ +private: +#if defined(_WIN32) || defined(_WIN64) + HINSTANCE m_handle{nullptr}; + static HINSTANCE open_lib(const char *path) noexcept + { + return LoadLibraryA(path); + } + FARPROC get_symbol(const char *name) const noexcept + { + return GetProcAddress(m_handle, name); + } + void close_lib() noexcept + { + FreeLibrary(m_handle); + } + static char *get_error_message() noexcept + { + constexpr size_t buf_size = 512; + auto error_code = GetLastError(); + if (!error_code) + return nullptr; + static char msg[buf_size]; + auto lang = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US); + const DWORD len = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, error_code, lang, msg, buf_size, nullptr); + if (len > 0) + return msg; + return nullptr; + } +#else + void *m_handle{nullptr}; + static void *open_lib(const char *path) noexcept + { + return dlopen(path, RTLD_NOW | RTLD_LOCAL); + } + void *get_symbol(const char *name) const noexcept + { + return dlsym(m_handle, name); + } + void close_lib() noexcept + { + dlclose(m_handle); + } + static char *get_error_message() noexcept + { + return dlerror(); + } +#endif + static std::string get_handle_error(const std::string &name) + { + std::string msg = "dylib: error while loading dynamic library \"" + name + "\""; + auto err = get_error_message(); + if (!err) + return msg; + return msg + '\n' + err; + } + static std::string get_symbol_error(const std::string &name) + { + std::string msg = "dylib: error while loading symbol \"" + name + "\""; + auto err = get_error_message(); + if (!err) + return msg; + return msg + '\n' + err; + } + static std::string get_missing_handle_error(const std::string &symbol_name) + { + return "dylib: could not get symbol \"" + symbol_name + "\", no dynamic library currently loaded"; + } + +public: + +#if defined(_WIN32) || defined(_WIN64) + static constexpr auto extension = ".dll"; +#elif defined(__APPLE__) + static constexpr auto extension = ".dylib"; +#else + static constexpr auto extension = ".so"; +#endif + + /** + * This exception is thrown when the dylib class encountered an error + * + * @return the error message by calling what() member function + */ + class exception : public std::exception + { + protected: + const std::string m_error; + public: + explicit exception(std::string &&message) : m_error(std::move(message)) {} + const char *what() const noexcept override {return m_error.c_str();} + }; + + /** + * This exception is thrown when the library failed to load + * or encountered symbol resolution issues + * + * @param message the error message + */ + class handle_error : public exception + { + public: + explicit handle_error(std::string &&message) : exception(std::move(message)) {} + }; + + /** + * This exception is thrown when the library failed to load a symbol. + * This usually happens when you forgot to put before a library function or variable + * + * @param message the error message + */ + class symbol_error : public exception + { + public: + explicit symbol_error(std::string &&message) : exception(std::move(message)) {} + }; + + dylib(const dylib&) = delete; + dylib& operator=(const dylib&) = delete; + + dylib(dylib &&other) noexcept : m_handle(other.m_handle) + { + other.m_handle = nullptr; + } + + dylib& operator=(dylib &&other) noexcept + { + if (this != &other) { + close(); + m_handle = other.m_handle; + other.m_handle = nullptr; + } + return *this; + } + + dylib() noexcept = default; + + /** + * Creates a dynamic library instance + * + * @param path path to the dynamic library to load + * @param ext use dylib::extension to specify the os extension (optional parameter) + */ + explicit dylib(const char *path) + { + open(path); + } + + explicit dylib(const std::string &path) + { + open(path.c_str()); + } + + dylib(std::string path, const char *ext) + { + open(std::move(path), ext); + } + + ~dylib() + { + close(); + } + + /** + * Load a dynamic library into the object. + * If a dynamic library was already opened, it will be unload and replaced + * + * @param path the path of the dynamic library to load + * @param ext use dylib::extension to detect the current os extension (optional parameter) + */ + void open(const char *path) + { + close(); + if (!path) + throw handle_error(get_handle_error("(nullptr)")); + m_handle = open_lib(path); + if (!m_handle) + throw handle_error(get_handle_error(path)); + } + + void open(const std::string &path) + { + open(path.c_str()); + } + + void open(std::string path, const char *ext) + { + if (!ext) + throw handle_error("dylib: failed to load \"" + path + "\", bad extension: (nullptr)"); + open(path + ext); + } + + /** + * Get a function from the dynamic library currently loaded in the object + * + * @param T the template argument must be the function prototype. + * it must be the same pattern as the template of std::function + * @param name the symbol name of the function to get from the dynamic library + * + * @return std::function that contains the function + */ + template + std::function get_function(const char *name) const + { + if (!name) + throw symbol_error(get_symbol_error("(nullptr)")); + if (!m_handle) + throw handle_error(get_missing_handle_error(name)); + auto sym = get_symbol(name); + if (!sym) + throw symbol_error(get_symbol_error(name)); + return reinterpret_cast(sym); + } + + template + std::function get_function(const std::string &name) const + { + return get_function(name.c_str()); + } + + /** + * Get a global variable from the dynamic library currently loaded in the object + * + * @param T type of the global variable + * @param name the name of the global variable to get from the dynamic library + * + * @return global variable of type + */ + template + T &get_variable(const char *name) const + { + if (!name) + throw symbol_error(get_symbol_error("(nullptr)")); + if (!m_handle) + throw handle_error(get_missing_handle_error(name)); + auto sym = get_symbol(name); + if (!sym) + throw symbol_error(get_symbol_error(name)); + return *reinterpret_cast(sym); + } + + template + T &get_variable(const std::string &name) const + { + return get_variable(name.c_str()); + } + + /** + * Check if a symbol exists in the currently loaded dynamic library. + * This method will return false if no dynamic library is currently loaded or if the symbol equals nullptr + * + * @param symbol the symbol name to look for + * + * @return true if the symbol exists in the dynamic library, false otherwise + */ + bool has_symbol(const char *symbol) const noexcept + { + if (!symbol) + return false; + if (!m_handle) + return false; + return get_symbol(symbol) != nullptr; + } + + bool has_symbol(const std::string &symbol) const noexcept + { + return has_symbol(symbol.c_str()); + } + + /** + * @return true if a dynamic library is currently loaded in the object, false otherwise + */ + operator bool() const noexcept + { + return m_handle != nullptr; + } + + /** + * Close the dynamic library currently loaded in the object. + * This function will be automatically called by the class destructor + */ + void close() noexcept + { + if (m_handle) { + close_lib(); + m_handle = nullptr; + } + } +}; \ No newline at end of file diff --git a/cpp/RAT/eig.cpp b/cpp/RAT/eig.cpp new file mode 100644 index 00000000..d17c1093 --- /dev/null +++ b/cpp/RAT/eig.cpp @@ -0,0 +1,101 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// eig.cpp +// +// Code generation for function 'eig' +// + +// Include files +#include "eig.h" +#include "anyNonFinite.h" +#include "eigHermitianStandard.h" +#include "eigSkewHermitianStandard.h" +#include "ishermitian.h" +#include "makeD.h" +#include "rt_nonfinite.h" +#include "schur.h" +#include "xzgeev.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + void eig(const ::coder::array &A, ::coder::array &V, + ::coder::array &D) + { + ::coder::array alpha1; + ::coder::array beta1; + ::coder::array b_D; + ::coder::array b_V; + int32_T info; + int32_T n; + n = A.size(0); + V.set_size(A.size(0), A.size(0)); + D.set_size(A.size(0), A.size(0)); + if ((A.size(0) != 0) && (A.size(1) != 0)) { + if (internal::anyNonFinite(A)) { + int32_T loop_ub; + info = A.size(0); + loop_ub = A.size(0); + V.set_size(A.size(0), A.size(0)); + for (int32_T i{0}; i < loop_ub; i++) { + for (int32_T i1{0}; i1 < info; i1++) { + V[i1 + V.size(0) * i].re = rtNaN; + V[i1 + V.size(0) * i].im = 0.0; + } + } + + info = A.size(0); + loop_ub = A.size(0); + D.set_size(A.size(0), A.size(0)); + for (int32_T i{0}; i < loop_ub; i++) { + for (int32_T i1{0}; i1 < info; i1++) { + D[i1 + D.size(0) * i].re = 0.0; + D[i1 + D.size(0) * i].im = 0.0; + } + } + + for (info = 0; info < n; info++) { + D[info + D.size(0) * info].re = rtNaN; + D[info + D.size(0) * info].im = 0.0; + } + } else if (ishermitian(A)) { + int32_T loop_ub; + schur(A, b_V, b_D); + V.set_size(b_V.size(0), b_V.size(1)); + info = b_V.size(1); + for (int32_T i{0}; i < info; i++) { + loop_ub = b_V.size(0); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + V[i1 + V.size(0) * i].re = b_V[i1 + b_V.size(0) * i]; + V[i1 + V.size(0) * i].im = 0.0; + } + } + + diagDiagUpperHessNoImag(b_D); + D.set_size(b_D.size(0), b_D.size(1)); + info = b_D.size(1); + for (int32_T i{0}; i < info; i++) { + loop_ub = b_D.size(0); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + D[i1 + D.size(0) * i].re = b_D[i1 + b_D.size(0) * i]; + D[i1 + D.size(0) * i].im = 0.0; + } + } + } else if (b_ishermitian(A)) { + eigSkewHermitianStandard(A, V, D); + } else { + internal::reflapack::xzgeev(A, &info, alpha1, beta1, V); + makeD(alpha1, beta1, D); + } + } + } + } +} + +// End of code generation (eig.cpp) diff --git a/cpp/RAT/eig.h b/cpp/RAT/eig.h new file mode 100644 index 00000000..9d4d7232 --- /dev/null +++ b/cpp/RAT/eig.h @@ -0,0 +1,31 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// eig.h +// +// Code generation for function 'eig' +// +#ifndef EIG_H +#define EIG_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void eig(const ::coder::array &A, ::coder::array &V, + ::coder::array &D); + } +} + +#endif + +// End of code generation (eig.h) diff --git a/cpp/RAT/eigHermitianStandard.cpp b/cpp/RAT/eigHermitianStandard.cpp new file mode 100644 index 00000000..41009cb3 --- /dev/null +++ b/cpp/RAT/eigHermitianStandard.cpp @@ -0,0 +1,35 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// eigHermitianStandard.cpp +// +// Code generation for function 'eigHermitianStandard' +// + +// Include files +#include "eigHermitianStandard.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + void diagDiagUpperHessNoImag(::coder::array &D) + { + int32_T n; + n = D.size(0); + for (int32_T j{2}; j <= n; j++) { + D[(j + D.size(0) * (j - 2)) - 1] = 0.0; + for (int32_T i{0}; i <= j - 2; i++) { + D[i + D.size(0) * (j - 1)] = 0.0; + } + } + } + } +} + +// End of code generation (eigHermitianStandard.cpp) diff --git a/cpp/RAT/eigHermitianStandard.h b/cpp/RAT/eigHermitianStandard.h new file mode 100644 index 00000000..aad79a49 --- /dev/null +++ b/cpp/RAT/eigHermitianStandard.h @@ -0,0 +1,30 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// eigHermitianStandard.h +// +// Code generation for function 'eigHermitianStandard' +// +#ifndef EIGHERMITIANSTANDARD_H +#define EIGHERMITIANSTANDARD_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void diagDiagUpperHessNoImag(::coder::array &D); + } +} + +#endif + +// End of code generation (eigHermitianStandard.h) diff --git a/cpp/RAT/eigRealSkewSymmetricStandard.cpp b/cpp/RAT/eigRealSkewSymmetricStandard.cpp new file mode 100644 index 00000000..d2d26dfb --- /dev/null +++ b/cpp/RAT/eigRealSkewSymmetricStandard.cpp @@ -0,0 +1,122 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// eigRealSkewSymmetricStandard.cpp +// +// Code generation for function 'eigRealSkewSymmetricStandard' +// + +// Include files +#include "eigRealSkewSymmetricStandard.h" +#include "RATMain_data.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + void extractEigenValues(const ::coder::array &T, ::coder::array< + creal_T, 2U> &D) + { + int32_T i; + int32_T n; + n = T.size(0); + D.set_size(T.size(0), T.size(0)); + i = T.size(0); + for (int32_T b_i{0}; b_i < i; b_i++) { + int32_T loop_ub; + loop_ub = T.size(0); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + D[i1 + D.size(0) * b_i].re = 0.0; + D[i1 + D.size(0) * b_i].im = 0.0; + } + } + + i = 1; + int32_T exitg1; + do { + exitg1 = 0; + if (i <= n) { + if (i != n) { + real_T lambda; + lambda = T[i + T.size(0) * (i - 1)]; + if (lambda != 0.0) { + lambda = std::abs(lambda); + D[(i + D.size(0) * (i - 1)) - 1].re = 0.0; + D[(i + D.size(0) * (i - 1)) - 1].im = lambda; + D[i + D.size(0) * i].re = 0.0; + D[i + D.size(0) * i].im = -lambda; + i += 2; + } else { + i++; + } + } else { + i++; + } + } else { + exitg1 = 1; + } + } while (exitg1 == 0); + } + + void extractEigenVectors(const ::coder::array &U, const ::coder:: + array &T, ::coder::array &V) + { + int32_T j; + int32_T n; + int32_T sgn; + V.set_size(U.size(0), U.size(1)); + j = U.size(1); + for (sgn = 0; sgn < j; sgn++) { + n = U.size(0); + for (int32_T i{0}; i < n; i++) { + V[i + V.size(0) * sgn].re = U[i + U.size(0) * sgn]; + V[i + V.size(0) * sgn].im = 0.0; + } + } + + j = 1; + n = T.size(0); + while (j <= n) { + if ((j != n) && (T[j + T.size(0) * (j - 1)] != 0.0)) { + if (T[j + T.size(0) * (j - 1)] < 0.0) { + sgn = 1; + } else { + sgn = -1; + } + + for (int32_T i{0}; i < n; i++) { + real_T ai; + real_T ar; + ar = V[i + V.size(0) * (j - 1)].re; + ai = static_cast(sgn) * V[i + V.size(0) * j].re; + if (ai == 0.0) { + V[i + V.size(0) * (j - 1)].re = ar / 1.4142135623730951; + V[i + V.size(0) * (j - 1)].im = 0.0; + } else if (ar == 0.0) { + V[i + V.size(0) * (j - 1)].re = 0.0; + V[i + V.size(0) * (j - 1)].im = ai / 1.4142135623730951; + } else { + V[i + V.size(0) * (j - 1)].re = ar / 1.4142135623730951; + V[i + V.size(0) * (j - 1)].im = ai / 1.4142135623730951; + } + + V[i + V.size(0) * j].re = V[i + V.size(0) * (j - 1)].re; + V[i + V.size(0) * j].im = -V[i + V.size(0) * (j - 1)].im; + } + + j += 2; + } else { + j++; + } + } + } + } +} + +// End of code generation (eigRealSkewSymmetricStandard.cpp) diff --git a/cpp/RAT/eigRealSkewSymmetricStandard.h b/cpp/RAT/eigRealSkewSymmetricStandard.h new file mode 100644 index 00000000..8545709e --- /dev/null +++ b/cpp/RAT/eigRealSkewSymmetricStandard.h @@ -0,0 +1,33 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// eigRealSkewSymmetricStandard.h +// +// Code generation for function 'eigRealSkewSymmetricStandard' +// +#ifndef EIGREALSKEWSYMMETRICSTANDARD_H +#define EIGREALSKEWSYMMETRICSTANDARD_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void extractEigenValues(const ::coder::array &T, ::coder::array< + creal_T, 2U> &D); + void extractEigenVectors(const ::coder::array &U, const ::coder:: + array &T, ::coder::array &V); + } +} + +#endif + +// End of code generation (eigRealSkewSymmetricStandard.h) diff --git a/cpp/RAT/eigSkewHermitianStandard.cpp b/cpp/RAT/eigSkewHermitianStandard.cpp new file mode 100644 index 00000000..b1a04554 --- /dev/null +++ b/cpp/RAT/eigSkewHermitianStandard.cpp @@ -0,0 +1,35 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// eigSkewHermitianStandard.cpp +// +// Code generation for function 'eigSkewHermitianStandard' +// + +// Include files +#include "eigSkewHermitianStandard.h" +#include "eigRealSkewSymmetricStandard.h" +#include "rt_nonfinite.h" +#include "schur.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + void eigSkewHermitianStandard(const ::coder::array &A, ::coder:: + array &V, ::coder::array &D) + { + ::coder::array T; + ::coder::array U; + schur(A, U, T); + extractEigenValues(T, D); + extractEigenVectors(U, T, V); + } + } +} + +// End of code generation (eigSkewHermitianStandard.cpp) diff --git a/cpp/RAT/eigSkewHermitianStandard.h b/cpp/RAT/eigSkewHermitianStandard.h new file mode 100644 index 00000000..9efe73fa --- /dev/null +++ b/cpp/RAT/eigSkewHermitianStandard.h @@ -0,0 +1,31 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// eigSkewHermitianStandard.h +// +// Code generation for function 'eigSkewHermitianStandard' +// +#ifndef EIGSKEWHERMITIANSTANDARD_H +#define EIGSKEWHERMITIANSTANDARD_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void eigSkewHermitianStandard(const ::coder::array &A, ::coder:: + array &V, ::coder::array &D); + } +} + +#endif + +// End of code generation (eigSkewHermitianStandard.h) diff --git a/cpp/RAT/eml_erfcore.cpp b/cpp/RAT/eml_erfcore.cpp new file mode 100644 index 00000000..f2ca84d3 --- /dev/null +++ b/cpp/RAT/eml_erfcore.cpp @@ -0,0 +1,128 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// eml_erfcore.cpp +// +// Code generation for function 'eml_erfcore' +// + +// Include files +#include "eml_erfcore.h" +#include "RATMain_rtwutil.h" +#include "log2.h" +#include "rt_nonfinite.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + real_T scalar_erf(real_T x) + { + real_T P; + real_T absx; + real_T s; + real_T y; + + // ========================== COPYRIGHT NOTICE ============================ + // The algorithms for calculating ERF(X) and ERFC(X) are derived + // from FDLIBM, which has the following notice: + // + // Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + // + // Developed at SunSoft, a Sun Microsystems, Inc. business. + // Permission to use, copy, modify, and distribute this + // software is freely granted, provided that this notice + // is preserved. + // ============================= END ================================ + absx = std::abs(x); + if (std::isnan(x)) { + y = rtNaN; + } else if (std::isinf(x)) { + if (x < 0.0) { + y = -1.0; + } else { + y = 1.0; + } + } else if (absx < 0.84375) { + if (absx < 3.7252902984619141E-9) { + if (absx < 2.8480945388892178E-306) { + y = 0.125 * (8.0 * x + 1.0270333367641007 * x); + } else { + y = x + 0.12837916709551259 * x; + } + } else { + s = x * x; + y = x + x * ((s * (s * (s * (s * -2.3763016656650163E-5 - + 0.0057702702964894416) - 0.02848174957559851) - 0.3250421072470015) + + 0.12837916709551256) / (s * (s * (s * (s * (s * + -3.9602282787753681E-6 + 0.00013249473800432164) + + 0.0050813062818757656) + 0.0650222499887673) + 0.39791722395915535) + + 1.0)); + } + } else if (absx < 1.25) { + P = (absx - 1.0) * ((absx - 1.0) * ((absx - 1.0) * ((absx - 1.0) * + ((absx - 1.0) * ((absx - 1.0) * -0.0021663755948687908 + + 0.035478304325618236) - 0.11089469428239668) + + 0.31834661990116175) - 0.37220787603570132) + 0.41485611868374833) - + 0.0023621185607526594; + s = (absx - 1.0) * ((absx - 1.0) * ((absx - 1.0) * ((absx - 1.0) * + ((absx - 1.0) * ((absx - 1.0) * 0.011984499846799107 + + 0.013637083912029051) + 0.12617121980876164) + + 0.071828654414196266) + 0.540397917702171) + 0.10642088040084423) + + 1.0; + if (x >= 0.0) { + y = P / s + 0.84506291151046753; + } else { + y = -0.84506291151046753 - P / s; + } + } else if (absx > 6.0) { + if (x < 0.0) { + y = -1.0; + } else { + y = 1.0; + } + } else { + real_T R; + real_T S; + s = 1.0 / (absx * absx); + if (absx < 2.8571434020996094) { + R = s * (s * (s * (s * (s * (s * (s * -9.8143293441691455 - + 81.2874355063066) - 184.60509290671104) - 162.39666946257347) - + 62.375332450326006) - 10.558626225323291) - + 0.69385857270718176) - 0.0098649440348471482; + S = s * (s * (s * (s * (s * (s * (s * (s * -0.0604244152148581 + + 6.5702497703192817) + 108.63500554177944) + 429.00814002756783) + + 645.38727173326788) + 434.56587747522923) + + 137.65775414351904) + 19.651271667439257) + 1.0; + } else { + R = s * (s * (s * (s * (s * (s * -483.5191916086514 - + 1025.0951316110772) - 637.56644336838963) - 160.63638485582192) - + 17.757954917754752) - 0.799283237680523) - + 0.0098649429247001; + S = s * (s * (s * (s * (s * (s * (s * -22.440952446585818 + + 474.52854120695537) + 2553.0504064331644) + 3199.8582195085955) + + 1536.729586084437) + 325.79251299657392) + + 30.338060743482458) + 1.0; + } + + b_log2(absx, &s, &P); + s = std::floor(s * 2.097152E+6) / 2.097152E+6 * rt_powd_snf(2.0, P); + y = std::exp(-s * s - 0.5625) * std::exp((s - absx) * (s + absx) + R / S) + / absx; + if (x < 0.0) { + y--; + } else { + y = 1.0 - y; + } + } + + return y; + } + } +} + +// End of code generation (eml_erfcore.cpp) diff --git a/cpp/RAT/eml_erfcore.h b/cpp/RAT/eml_erfcore.h new file mode 100644 index 00000000..f76642bb --- /dev/null +++ b/cpp/RAT/eml_erfcore.h @@ -0,0 +1,29 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// eml_erfcore.h +// +// Code generation for function 'eml_erfcore' +// +#ifndef EML_ERFCORE_H +#define EML_ERFCORE_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + real_T scalar_erf(real_T x); + } +} + +#endif + +// End of code generation (eml_erfcore.h) diff --git a/cpp/RAT/eml_mtimes_helper.cpp b/cpp/RAT/eml_mtimes_helper.cpp new file mode 100644 index 00000000..fdb86586 --- /dev/null +++ b/cpp/RAT/eml_mtimes_helper.cpp @@ -0,0 +1,205 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// eml_mtimes_helper.cpp +// +// Code generation for function 'eml_mtimes_helper' +// + +// Include files +#include "eml_mtimes_helper.h" +#include "mtimes.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void binary_expand_op(real_T in1_data[], int32_T in1_size[2], const ::coder:: + array &in2, const ::coder::array + &in3, int32_T in4, const ::coder::array &in5) + { + ::coder::array b_in3; + int32_T i; + int32_T loop_ub; + int32_T stride_0_1; + int32_T stride_1_1; + if (in5.size(1) == 1) { + i = in3.size(1); + } else { + i = in5.size(1); + } + + b_in3.set_size(1, i); + stride_0_1 = (in3.size(1) != 1); + stride_1_1 = (in5.size(1) != 1); + if (in5.size(1) == 1) { + loop_ub = in3.size(1); + } else { + loop_ub = in5.size(1); + } + + for (i = 0; i < loop_ub; i++) { + b_in3[b_in3.size(0) * i] = in3[in4 + in3.size(0) * (i * stride_0_1)] - + in5[in5.size(0) * (i * stride_1_1)]; + } + + coder::internal::blas::mtimes(in2, b_in3, in1_data, in1_size); + } + + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in2, const ::coder::array &in3, + const ::coder::array &in4) + { + ::coder::array b_in2; + int32_T i; + int32_T loop_ub; + int32_T stride_0_1; + int32_T stride_1_1; + if (in3.size(0) == 1) { + i = in2.size(1); + } else { + i = in3.size(0); + } + + b_in2.set_size(1, i); + stride_0_1 = (in2.size(1) != 1); + stride_1_1 = (in3.size(0) != 1); + if (in3.size(0) == 1) { + loop_ub = in2.size(1); + } else { + loop_ub = in3.size(0); + } + + for (i = 0; i < loop_ub; i++) { + int32_T in3_re_tmp; + in3_re_tmp = i * stride_1_1; + b_in2[i].re = in2[i * stride_0_1] * in3[in3_re_tmp].re; + b_in2[i].im = in2[i * stride_0_1] * -in3[in3_re_tmp].im; + } + + coder::internal::blas::mtimes(b_in2, in4, in1); + } + + void binary_expand_op(::coder::array &in1, real_T in2, const :: + coder::array &in3, const ::coder::array< + real_T, 2U> &in4) + { + int32_T i; + int32_T loop_ub; + int32_T stride_0_1; + int32_T stride_1_1; + if (in4.size(1) == 1) { + i = in3.size(1); + } else { + i = in4.size(1); + } + + in1.set_size(1, i); + stride_0_1 = (in3.size(1) != 1); + stride_1_1 = (in4.size(1) != 1); + if (in4.size(1) == 1) { + loop_ub = in3.size(1); + } else { + loop_ub = in4.size(1); + } + + for (i = 0; i < loop_ub; i++) { + in1[i] = in2 * (in3[i * stride_0_1] - in4[i * stride_1_1]); + } + } + + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in2, const ::coder::array &in3) + { + int32_T i; + int32_T loop_ub; + int32_T stride_0_1; + int32_T stride_1_1; + if (in3.size(1) == 1) { + i = in2.size(1); + } else { + i = in3.size(1); + } + + in1.set_size(1, i); + stride_0_1 = (in2.size(1) != 1); + stride_1_1 = (in3.size(1) != 1); + if (in3.size(1) == 1) { + loop_ub = in2.size(1); + } else { + loop_ub = in3.size(1); + } + + for (i = 0; i < loop_ub; i++) { + in1[i] = 0.0 * (in2[i * stride_0_1] - in3[i * stride_1_1]); + } + } + + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in3, const ::coder::array &in4, + const ::coder::array &in5) + { + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_1_0; + stride_0_0 = (in4.size(0) != 1); + stride_1_0 = (in5.size(0) != 1); + if (in5.size(0) == 1) { + loop_ub = in4.size(0); + } else { + loop_ub = in5.size(0); + } + + for (int32_T i{0}; i < loop_ub; i++) { + in1[i] = 0.5 * (in3[in4[i * stride_0_0] - 1] + in3[in5[i * stride_1_0] - 1]); + } + } + + void c_binary_expand_op(real_T in1_data[], int32_T in1_size[2], const ::coder:: + array &in2, const ::coder::array &in3, int32_T in4, + const ::coder::array &in5) + { + ::coder::array b_in3; + int32_T aux_0_1; + int32_T aux_1_1; + int32_T i; + int32_T loop_ub; + int32_T stride_0_1; + int32_T stride_1_1; + if (in5.size(1) == 1) { + i = in3.size(1); + } else { + i = in5.size(1); + } + + b_in3.set_size(in5.size(0), i); + stride_0_1 = (in3.size(1) != 1); + stride_1_1 = (in5.size(1) != 1); + aux_0_1 = 0; + aux_1_1 = 0; + if (in5.size(1) == 1) { + loop_ub = in3.size(1); + } else { + loop_ub = in5.size(1); + } + + for (i = 0; i < loop_ub; i++) { + int32_T b_loop_ub; + b_loop_ub = in5.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + b_in3[b_in3.size(0) * i] = in3[in4 + in3.size(0) * aux_0_1] - + in5[in5.size(0) * aux_1_1]; + } + + aux_1_1 += stride_1_1; + aux_0_1 += stride_0_1; + } + + coder::internal::blas::mtimes(in2, b_in3, in1_data, in1_size); + } +} + +// End of code generation (eml_mtimes_helper.cpp) diff --git a/cpp/RAT/eml_mtimes_helper.h b/cpp/RAT/eml_mtimes_helper.h new file mode 100644 index 00000000..bfd57829 --- /dev/null +++ b/cpp/RAT/eml_mtimes_helper.h @@ -0,0 +1,43 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// eml_mtimes_helper.h +// +// Code generation for function 'eml_mtimes_helper' +// +#ifndef EML_MTIMES_HELPER_H +#define EML_MTIMES_HELPER_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void binary_expand_op(real_T in1_data[], int32_T in1_size[2], const ::coder:: + array &in2, const ::coder::array + &in3, int32_T in4, const ::coder::array &in5); + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in2, const ::coder::array &in3, + const ::coder::array &in4); + void binary_expand_op(::coder::array &in1, real_T in2, const :: + coder::array &in3, const ::coder::array< + real_T, 2U> &in4); + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in2, const ::coder::array &in3); + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in3, const ::coder::array &in4, + const ::coder::array &in5); + void c_binary_expand_op(real_T in1_data[], int32_T in1_size[2], const ::coder:: + array &in2, const ::coder::array &in3, int32_T in4, + const ::coder::array &in5); +} + +#endif + +// End of code generation (eml_mtimes_helper.h) diff --git a/cpp/RAT/eml_rand_mt19937ar.cpp b/cpp/RAT/eml_rand_mt19937ar.cpp new file mode 100644 index 00000000..92830b29 --- /dev/null +++ b/cpp/RAT/eml_rand_mt19937ar.cpp @@ -0,0 +1,170 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// eml_rand_mt19937ar.cpp +// +// Code generation for function 'eml_rand_mt19937ar' +// + +// Include files +#include "eml_rand_mt19937ar.h" +#include "RATMain_data.h" +#include "rt_nonfinite.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + real_T b_eml_rand_mt19937ar(uint32_T b_state[625]) + { + real_T r; + int32_T exitg1; + int32_T i; + uint32_T u32[2]; + do { + exitg1 = 0; + genrand_uint32_vector(b_state, u32); + i = static_cast((u32[1] >> 24U) + 1U); + r = ((static_cast(u32[0] >> 3U) * 1.6777216E+7 + + static_cast(static_cast(u32[1]) & 16777215)) * + 2.2204460492503131E-16 - 1.0) * dv[i]; + if (std::abs(r) <= dv[i - 1]) { + exitg1 = 1; + } else if (i < 256) { + real_T u; + u = eml_rand_mt19937ar(b_state); + if (dv1[i] + u * (dv1[i - 1] - dv1[i]) < std::exp(-0.5 * r * r)) { + exitg1 = 1; + } + } else { + real_T u; + real_T x; + do { + u = eml_rand_mt19937ar(b_state); + x = std::log(u) * 0.273661237329758; + u = eml_rand_mt19937ar(b_state); + } while (!(-2.0 * std::log(u) > x * x)); + + if (r < 0.0) { + r = x - 3.65415288536101; + } else { + r = 3.65415288536101 - x; + } + + exitg1 = 1; + } + } while (exitg1 == 0); + + return r; + } + + real_T eml_rand_mt19937ar(uint32_T b_state[625]) + { + real_T r; + + // ========================= COPYRIGHT NOTICE ============================ + // This is a uniform (0,1) pseudorandom number generator based on: + // + // A C-program for MT19937, with initialization improved 2002/1/26. + // Coded by Takuji Nishimura and Makoto Matsumoto. + // + // Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + // All rights reserved. + // + // Redistribution and use in source and binary forms, with or without + // modification, are permitted provided that the following conditions + // are met: + // + // 1. Redistributions of source code must retain the above copyright + // notice, this list of conditions and the following disclaimer. + // + // 2. Redistributions in binary form must reproduce the above copyright + // notice, this list of conditions and the following disclaimer + // in the documentation and/or other materials provided with the + // distribution. + // + // 3. The names of its contributors may not be used to endorse or + // promote products derived from this software without specific + // prior written permission. + // + // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + // + // ============================= END ================================= + uint32_T u[2]; + do { + genrand_uint32_vector(b_state, u); + u[0] >>= 5U; + u[1] >>= 6U; + r = 1.1102230246251565E-16 * (static_cast(u[0]) * 6.7108864E+7 + + static_cast(u[1])); + } while (r == 0.0); + + return r; + } + + void genrand_uint32_vector(uint32_T mt[625], uint32_T u[2]) + { + for (int32_T j{0}; j < 2; j++) { + uint32_T mti; + uint32_T y; + mti = mt[624] + 1U; + if (mti >= 625U) { + for (int32_T kk{0}; kk < 227; kk++) { + y = (mt[kk] & 2147483648U) | (mt[kk + 1] & 2147483647U); + if ((y & 1U) == 0U) { + y >>= 1U; + } else { + y = y >> 1U ^ 2567483615U; + } + + mt[kk] = mt[kk + 397] ^ y; + } + + for (int32_T kk{0}; kk < 396; kk++) { + y = (mt[kk + 227] & 2147483648U) | (mt[kk + 228] & 2147483647U); + if ((y & 1U) == 0U) { + y >>= 1U; + } else { + y = y >> 1U ^ 2567483615U; + } + + mt[kk + 227] = mt[kk] ^ y; + } + + y = (mt[623] & 2147483648U) | (mt[0] & 2147483647U); + if ((y & 1U) == 0U) { + y >>= 1U; + } else { + y = y >> 1U ^ 2567483615U; + } + + mt[623] = mt[396] ^ y; + mti = 1U; + } + + y = mt[static_cast(mti) - 1]; + mt[624] = mti; + y ^= y >> 11U; + y ^= y << 7U & 2636928640U; + y ^= y << 15U & 4022730752U; + u[j] = y ^ y >> 18U; + } + } + } +} + +// End of code generation (eml_rand_mt19937ar.cpp) diff --git a/cpp/RAT/eml_rand_mt19937ar.h b/cpp/RAT/eml_rand_mt19937ar.h new file mode 100644 index 00000000..293ffc95 --- /dev/null +++ b/cpp/RAT/eml_rand_mt19937ar.h @@ -0,0 +1,31 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// eml_rand_mt19937ar.h +// +// Code generation for function 'eml_rand_mt19937ar' +// +#ifndef EML_RAND_MT19937AR_H +#define EML_RAND_MT19937AR_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + real_T b_eml_rand_mt19937ar(uint32_T b_state[625]); + real_T eml_rand_mt19937ar(uint32_T b_state[625]); + void genrand_uint32_vector(uint32_T mt[625], uint32_T u[2]); + } +} + +#endif + +// End of code generation (eml_rand_mt19937ar.h) diff --git a/cpp/RAT/eml_rand_mt19937ar_stateful.cpp b/cpp/RAT/eml_rand_mt19937ar_stateful.cpp new file mode 100644 index 00000000..a7687a91 --- /dev/null +++ b/cpp/RAT/eml_rand_mt19937ar_stateful.cpp @@ -0,0 +1,35 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// eml_rand_mt19937ar_stateful.cpp +// +// Code generation for function 'eml_rand_mt19937ar_stateful' +// + +// Include files +#include "eml_rand_mt19937ar_stateful.h" +#include "RATMain_data.h" +#include "rt_nonfinite.h" +#include + +// Function Definitions +namespace RAT +{ + void eml_rand_mt19937ar_stateful_init() + { + uint32_T r; + std::memset(&state[0], 0, 625U * sizeof(uint32_T)); + r = 5489U; + state[0] = 5489U; + for (int32_T mti{0}; mti < 623; mti++) { + r = ((r ^ r >> 30U) * 1812433253U + static_cast(mti)) + 1U; + state[mti + 1] = r; + } + + state[624] = 624U; + } +} + +// End of code generation (eml_rand_mt19937ar_stateful.cpp) diff --git a/cpp/RAT/eml_rand_mt19937ar_stateful.h b/cpp/RAT/eml_rand_mt19937ar_stateful.h new file mode 100644 index 00000000..e059c204 --- /dev/null +++ b/cpp/RAT/eml_rand_mt19937ar_stateful.h @@ -0,0 +1,26 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// eml_rand_mt19937ar_stateful.h +// +// Code generation for function 'eml_rand_mt19937ar_stateful' +// +#ifndef EML_RAND_MT19937AR_STATEFUL_H +#define EML_RAND_MT19937AR_STATEFUL_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void eml_rand_mt19937ar_stateful_init(); +} + +#endif + +// End of code generation (eml_rand_mt19937ar_stateful.h) diff --git a/cpp/RAT/eml_setop.cpp b/cpp/RAT/eml_setop.cpp new file mode 100644 index 00000000..c386a1e3 --- /dev/null +++ b/cpp/RAT/eml_setop.cpp @@ -0,0 +1,112 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// eml_setop.cpp +// +// Code generation for function 'eml_setop' +// + +// Include files +#include "eml_setop.h" +#include "relop.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Declarations +namespace RAT +{ + namespace coder + { + static real_T skip_to_last_equal_value(int32_T *k, const ::coder::array< + real_T, 2U> &x); + } +} + +// Function Definitions +namespace RAT +{ + namespace coder + { + static real_T skip_to_last_equal_value(int32_T *k, const ::coder::array< + real_T, 2U> &x) + { + real_T xk; + xk = x[*k - 1]; + while ((*k < x.size(1)) && (x[*k] == xk)) { + (*k)++; + } + + return xk; + } + + void do_vectors(const ::coder::array &a, real_T b, ::coder:: + array &c, ::coder::array &ia, + int32_T *ib_size) + { + real_T ak; + int32_T b_ialast; + int32_T iafirst; + int32_T ialast; + int32_T iblast; + int32_T na; + int32_T nc; + int32_T nia; + na = a.size(1); + c.set_size(1, a.size(1)); + ia.set_size(a.size(1)); + *ib_size = 0; + nc = 0; + nia = 0; + iafirst = 0; + ialast = 1; + iblast = 1; + while ((ialast <= na) && (iblast <= 1)) { + b_ialast = ialast; + ak = skip_to_last_equal_value(&b_ialast, a); + ialast = b_ialast; + if (ak == b) { + ialast = b_ialast + 1; + iafirst = b_ialast; + iblast = 2; + } else if (internal::c_relop(ak, b)) { + nc++; + nia++; + c[nc - 1] = ak; + ia[nia - 1] = iafirst + 1; + ialast = b_ialast + 1; + iafirst = b_ialast; + } else { + iblast = 2; + } + } + + while (ialast <= na) { + iblast = ialast; + ak = skip_to_last_equal_value(&iblast, a); + nc++; + nia++; + c[nc - 1] = ak; + ia[nia - 1] = iafirst + 1; + ialast = iblast + 1; + iafirst = iblast; + } + + if (a.size(1) > 0) { + if (nia < 1) { + nia = 0; + } + + ia.set_size(nia); + if (nc < 1) { + nc = 0; + } + + c.set_size(c.size(0), nc); + } + } + } +} + +// End of code generation (eml_setop.cpp) diff --git a/cpp/RAT/eml_setop.h b/cpp/RAT/eml_setop.h new file mode 100644 index 00000000..a14b8dd9 --- /dev/null +++ b/cpp/RAT/eml_setop.h @@ -0,0 +1,32 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// eml_setop.h +// +// Code generation for function 'eml_setop' +// +#ifndef EML_SETOP_H +#define EML_SETOP_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void do_vectors(const ::coder::array &a, real_T b, ::coder:: + array &c, ::coder::array &ia, + int32_T *ib_size); + } +} + +#endif + +// End of code generation (eml_setop.h) diff --git a/cpp/RAT/eps.cpp b/cpp/RAT/eps.cpp new file mode 100644 index 00000000..7aca6740 --- /dev/null +++ b/cpp/RAT/eps.cpp @@ -0,0 +1,41 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// eps.cpp +// +// Code generation for function 'eps' +// + +// Include files +#include "eps.h" +#include "rt_nonfinite.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + real_T eps(real_T x) + { + real_T absx; + real_T r; + int32_T exponent; + absx = std::abs(x); + if (std::isinf(absx) || std::isnan(absx)) { + r = rtNaN; + } else if (absx < 4.4501477170144028E-308) { + r = 4.94065645841247E-324; + } else { + std::frexp(absx, &exponent); + r = std::ldexp(1.0, exponent - 53); + } + + return r; + } + } +} + +// End of code generation (eps.cpp) diff --git a/cpp/RAT/eps.h b/cpp/RAT/eps.h new file mode 100644 index 00000000..eb9cda19 --- /dev/null +++ b/cpp/RAT/eps.h @@ -0,0 +1,29 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// eps.h +// +// Code generation for function 'eps' +// +#ifndef EPS_H +#define EPS_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + real_T eps(real_T x); + } +} + +#endif + +// End of code generation (eps.h) diff --git a/cpp/RAT/erf.cpp b/cpp/RAT/erf.cpp new file mode 100644 index 00000000..732ce526 --- /dev/null +++ b/cpp/RAT/erf.cpp @@ -0,0 +1,37 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// erf.cpp +// +// Code generation for function 'erf' +// + +// Include files +#include "erf.h" +#include "eml_erfcore.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + void b_erf(const ::coder::array &x, ::coder::array + &y) + { + y.set_size(1, x.size(1)); + if (x.size(1) != 0) { + int32_T i; + i = x.size(1); + for (int32_T k{0}; k < i; k++) { + y[k] = scalar_erf(x[k]); + } + } + } + } +} + +// End of code generation (erf.cpp) diff --git a/cpp/RAT/erf.h b/cpp/RAT/erf.h new file mode 100644 index 00000000..54f5df83 --- /dev/null +++ b/cpp/RAT/erf.h @@ -0,0 +1,31 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// erf.h +// +// Code generation for function 'erf' +// +#ifndef ERF_H +#define ERF_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void b_erf(const ::coder::array &x, ::coder::array + &y); + } +} + +#endif + +// End of code generation (erf.h) diff --git a/cpp/RAT/evaluateModel.cpp b/cpp/RAT/evaluateModel.cpp new file mode 100644 index 00000000..e3dd81a2 --- /dev/null +++ b/cpp/RAT/evaluateModel.cpp @@ -0,0 +1,69 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// evaluateModel.cpp +// +// Code generation for function 'evaluateModel' +// + +// Include files +#include "evaluateModel.h" +#include "DREAMWrapper.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void evaluateModel(const ::coder::array &x, const struct13_T + *DREAMPar, const c_struct_T *ratInputs_problemStruct, const + cell_11 *ratInputs_problemCells, const struct2_T + *ratInputs_controls, ::coder::array &fx) + { + ::coder::array b_x; + int32_T loop_ub_tmp; + + // This function computes the likelihood and log-likelihood of each d-vector + // of x values + // + // Code both for sequential and parallel evaluation of model ( = pdf ) + // + // Written by Jasper A. Vrugt + // Check whether to store the output of each model evaluation (function call) + // if DREAMPar.modout && ( Meas_info.N > 0 ) + // + // % Create initial fx of size model output by DREAMPar.N + // fx = NaN(Meas_info.N,DREAMPar.N); + // + // end + // Now evaluate the model + loop_ub_tmp = static_cast(DREAMPar->N); + fx.set_size(1, loop_ub_tmp); + for (int32_T i{0}; i < loop_ub_tmp; i++) { + fx[i] = 0.0; + } + + // Sequential evaluation + // Loop over each d-vector of parameter values of x using 1 worker + for (int32_T ii{0}; ii < loop_ub_tmp; ii++) { + int32_T loop_ub; + + // Execute the model and return the model simulation + // fx(:,ii) = f_handle(x(ii,:), ratInputs); + loop_ub = x.size(1); + b_x.set_size(1, x.size(1)); + for (int32_T i{0}; i < loop_ub; i++) { + b_x[i] = x[ii + x.size(0) * i]; + } + + fx[ii] = DREAMWrapper(b_x, ratInputs_problemStruct, ratInputs_problemCells, + ratInputs_controls); + } + } +} + +// End of code generation (evaluateModel.cpp) diff --git a/cpp/RAT/evaluateModel.h b/cpp/RAT/evaluateModel.h new file mode 100644 index 00000000..ca3e877e --- /dev/null +++ b/cpp/RAT/evaluateModel.h @@ -0,0 +1,39 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// evaluateModel.h +// +// Code generation for function 'evaluateModel' +// +#ifndef EVALUATEMODEL_H +#define EVALUATEMODEL_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct struct13_T; + struct c_struct_T; + struct cell_11; + struct struct2_T; +} + +// Function Declarations +namespace RAT +{ + void evaluateModel(const ::coder::array &x, const struct13_T + *DREAMPar, const c_struct_T *ratInputs_problemStruct, const + cell_11 *ratInputs_problemCells, const struct2_T + *ratInputs_controls, ::coder::array &fx); +} + +#endif + +// End of code generation (evaluateModel.h) diff --git a/cpp/RAT/eventHelper.hpp b/cpp/RAT/eventHelper.hpp new file mode 100644 index 00000000..9a9c2241 --- /dev/null +++ b/cpp/RAT/eventHelper.hpp @@ -0,0 +1,90 @@ +#ifndef WRAPPER_H +#define WRAPPER_H + +#include +#include +#include "dylib.hpp" // dylib.hpp is a header file that contains the dylib class that extracts a function from dll + +class eventHelper +{ + public: + std::unique_ptr library; + bool initialised = false; + + eventHelper(void){}; + ~eventHelper(void){}; + + eventHelper& operator=(eventHelper* other) noexcept + { + if (other) { + this->library = std::move(other->library); + this->initialised = other->initialised; + } + else { + this->library = NULL; + this->initialised = false; + } + return *this; + }; + + eventHelper& operator=(eventHelper &&other) noexcept + { + if (this != &other) { + this->library = std::move(other.library); + this->initialised = other.initialised; + } + return *this; + }; + + bool isInitialised(void){ return this->initialised;}; + + void init(const char* path) + { + try + { + char filename[18] = "eventManager"; + this->library = std::unique_ptr(new dylib(path, strcat(filename, dylib::extension))); + this->initialised = true; + } + catch (const dylib::handle_error &) + { + this->initialised = false; + } + }; + + void sendMessage(const char* msg) + { + auto sendMessage = library->get_function("sendMessage"); + + // pass the arguments to the function + return sendMessage(msg); + + }; + + bool hasPlotHandler(void) + { + auto hasPlotHandler = library->get_function("hasPlotHandler"); + + // pass the arguments to the function + return hasPlotHandler(); + }; + + void updatePlot(int nContrast, double* reflect, double* nReflect, double* shiftedData, double* nShiftedData, + double* sldProfiles, double* nSldProfiles, double* layers, double* nLayers, + double* sldProfiles2, double* nSldProfiles2, double* layers2, double* nLayers2, double* ssubs, + double* resample, double* dataPresent, const char* modelType) + { + auto updatePlot = library->get_function("updatePlot"); + + // pass the arguments to the function + return updatePlot(nContrast, reflect, nReflect, shiftedData, nShiftedData, sldProfiles, nSldProfiles, + layers, nLayers, sldProfiles2, nSldProfiles2, layers2, nLayers2, ssubs, resample, + dataPresent, modelType); + + }; +}; + +#endif diff --git a/cpp/RAT/events/eventManager.cpp b/cpp/RAT/events/eventManager.cpp new file mode 100644 index 00000000..90a9047d --- /dev/null +++ b/cpp/RAT/events/eventManager.cpp @@ -0,0 +1,60 @@ +#include "eventManager.h" + +LIB_EXPORT void sendMessage(const char* msg) +{ + notify(messageEvent(msg)); +} + +LIB_EXPORT void updatePlot(int nContrast, double* reflect, double* nReflect, double* shiftedData, double* nShiftedData, + double* sldProfiles, double* nSldProfiles, double* layers, double* nLayers, + double* sldProfiles2, double* nSldProfiles2, double* layers2, double* nLayers2, double* ssubs, + double* resample, double* dataPresent, const char* modelType) +{ + plotData data; + data.nContrast = nContrast; + data.reflect = reflect; + data.nReflect = nReflect; + data.shiftedData = shiftedData; + data.nShiftedData = nShiftedData; + data.sldProfiles = sldProfiles; + data.nSldProfiles = nSldProfiles; + data.layers = layers; + data.nLayers = nLayers; + data.sldProfiles2 = sldProfiles2; + data.nSldProfiles2 = nSldProfiles2; + data.layers2 = layers2; + data.nLayers2 = nLayers2; + data.ssubs = ssubs; + data.resample = resample; + data.dataPresent = dataPresent; + data.modelType = modelType; + notify(plotEvent(&data)); +} + +LIB_EXPORT void notify(const baseEvent& event) +{ + eventManager::get_instance()->notify(event); +} + +LIB_EXPORT void addListener(EventTypes type, const std::function fn) +{ + if (type == EventTypes::Message) + eventManager::get_instance()->addListener(EventTypes::Message, fn); + else if (type == EventTypes::Plot) + eventManager::get_instance()->addListener(EventTypes::Plot, fn); +} + +LIB_EXPORT void clearListeners() +{ + eventManager::get_instance()->clear(); +} + +LIB_EXPORT bool hasPlotHandler() +{ + auto names = eventManager::get_instance()->getEventNames(); + for(unsigned i=0; i < names.size(); i++) { + if (names[i] == EventTypes::Plot) + return true; + } + return false; +} diff --git a/cpp/RAT/events/eventManager.h b/cpp/RAT/events/eventManager.h new file mode 100644 index 00000000..29a31676 --- /dev/null +++ b/cpp/RAT/events/eventManager.h @@ -0,0 +1,35 @@ +#include "eventManagerImpl.hpp" + +#ifndef EVENT_MANAGER_H +#define EVENT_MANAGER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_WIN32) || defined(_WIN64) +#define LIB_EXPORT __declspec(dllexport) +#else +#define LIB_EXPORT +#endif + +LIB_EXPORT void updatePlot(int nContrast, double* reflect, double* nReflect, double* shiftedData, double* nShiftedData, + double* sldProfiles, double* nSldProfiles, double* layers, double* nLayers, + double* sldProfiles2, double* nSldProfiles2, double* layers2, double* nLayers2, double* ssubs, + double* resample, double* dataPresent, const char* modelType); + +LIB_EXPORT void sendMessage(const char* msg); + +LIB_EXPORT void notify(const baseEvent& event); + +LIB_EXPORT void addListener(EventTypes type, const std::function fn); + +LIB_EXPORT void clearListeners(); + +LIB_EXPORT bool hasPlotHandler(); + +#ifdef __cplusplus +} +#endif + +#endif // EVENT_MANAGER_H \ No newline at end of file diff --git a/cpp/RAT/events/eventManagerImpl.hpp b/cpp/RAT/events/eventManagerImpl.hpp new file mode 100644 index 00000000..8f10212d --- /dev/null +++ b/cpp/RAT/events/eventManagerImpl.hpp @@ -0,0 +1,102 @@ +#ifndef EVENT_MANAGER_IMPL_HPP +#define EVENT_MANAGER_IMPL_HPP + +#include +#include +#include + +/* + Implementation of a singleton event manager with support for multiple + event types. +*/ +enum class EventTypes { + Message, + Plot +}; + + +struct plotData { + int nContrast; + double* reflect; + double* nReflect; + double* shiftedData; + double* nShiftedData; + double* sldProfiles; + double* nSldProfiles; + double* layers; + double* nLayers; + double* sldProfiles2; + double* nSldProfiles2; + double* layers2; + double* nLayers2; + double* ssubs; + double* resample; + double* dataPresent; + const char* modelType; +}; + + +struct baseEvent { + EventTypes type; + baseEvent(EventTypes type) : type(type) {} + virtual ~baseEvent() {} +}; + +struct messageEvent : baseEvent { + const char* msg; + messageEvent(const char* msg) : baseEvent(EventTypes::Message), msg(msg) {} +}; + +struct plotEvent : baseEvent { + const plotData* data; + plotEvent(const plotData* data) : baseEvent(EventTypes::Plot), data(data) {} +}; + + +typedef void (*callback) (const baseEvent&); + + +class eventManager +{ +public: + + eventManager(eventManager const&) = delete; + eventManager& operator=(eventManager const&) = delete; + ~eventManager() {} + + const std::vector& getEventNames()const {return eventNames;} + + void addListener(EventTypes type, const std::function fn) { + std::lock_guard lock(m_mutex); + eventNames.push_back(type); + eventHandlers.push_back(fn); + } + + void notify(const baseEvent& event) { + for(unsigned i=0; i < eventNames.size(); i++) { + if (event.type == eventNames[i]) + eventHandlers[i] (event); + } + } + + void clear() { + eventNames.clear(); + eventHandlers.clear(); + } + + static eventManager* get_instance() + { + // Static local variable initialization is thread-safe + // and will be initialized only once. + static eventManager instance{}; + return &instance; + } + +private: + explicit eventManager() {} + std::vector eventNames; + std::vector> eventHandlers; + std::mutex m_mutex; +}; + +#endif // EVENT_MANAGER_IMPL_HPP \ No newline at end of file diff --git a/cpp/RAT/examples/main.cpp b/cpp/RAT/examples/main.cpp new file mode 100644 index 00000000..11165b6a --- /dev/null +++ b/cpp/RAT/examples/main.cpp @@ -0,0 +1,677 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// main.cpp +// +// Code generation for function 'main' +// + +/*************************************************************************/ +/* This automatically generated example C++ main file shows how to call */ +/* entry-point functions that MATLAB Coder generated. You must customize */ +/* this file for your application. Do not modify this file directly. */ +/* Instead, make a copy of this file, modify it, and integrate it into */ +/* your development environment. */ +/* */ +/* This file initializes entry-point function arguments to a default */ +/* size and value before calling the entry-point functions. It does */ +/* not store or use any values returned from the entry-point functions. */ +/* If necessary, it does pre-allocate memory for returned values. */ +/* You can use this file as a starting point for a main function that */ +/* you can deploy in your application. */ +/* */ +/* After you copy the file, and before you deploy it, you must make the */ +/* following changes: */ +/* * For variable-size function arguments, change the example sizes to */ +/* the sizes that your application requires. */ +/* * Change the example values of function arguments to the values that */ +/* your application requires. */ +/* * If the entry-point functions return values, store these values or */ +/* otherwise use them as required by your application. */ +/* */ +/*************************************************************************/ + +// Include files +#include "main.h" +#include "RATMain.h" +#include "RATMain_initialize.h" +#include "RATMain_terminate.h" +#include "RATMain_types.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include "coder_bounded_array.h" + +// Function Declarations +static void argInit_1x2_real_T(real_T result[2]); +static coder::array argInit_1xUnbounded_char_T(); +static coder::array argInit_1xd10000_cell_wrap_2(); +static coder::array argInit_1xd10000_cell_wrap_3(); +static coder::array argInit_1xd10000_cell_wrap_4(); +static coder::array argInit_1xd10000_cell_wrap_6(); +static void argInit_1xd10000_char_T(char_T result_data[], int32_T result_size[2]); +static coder::array argInit_1xd10000_real_T(); +static coder::array argInit_Unboundedx1_cell_0(); +static coder::array argInit_Unboundedx1_cell_wrap_1(); +static coder::array argInit_Unboundedx3_real_T(); +static boolean_T argInit_boolean_T(); +static void argInit_cell_0(RAT::cell_0 *result); +static void argInit_cell_7(RAT::cell_7 *result); +static RAT::cell_wrap_1 argInit_cell_wrap_1(); +static RAT::cell_wrap_2 argInit_cell_wrap_2(); +static RAT::cell_wrap_3 argInit_cell_wrap_3(); +static RAT::cell_wrap_4 argInit_cell_wrap_4(); +static void argInit_cell_wrap_5(RAT::cell_wrap_5 *result); +static void argInit_cell_wrap_6(RAT::cell_wrap_6 *result); +static char_T argInit_char_T(); +static coder::array argInit_d10000x1_cell_wrap_5(); +static coder::array argInit_d10000x2_real_T(); +static coder::array argInit_d10000xd10000_real_T(); +static coder::array argInit_d1xd10000_real_T(); +static void argInit_d1xd10_real_T(real_T result_data[], int32_T result_size[2]); +static real_T argInit_real_T(); +static void argInit_struct0_T(RAT::struct0_T *result); +static void argInit_struct1_T(RAT::struct1_T *result); +static void argInit_struct2_T(RAT::struct2_T *result); +static void argInit_struct3_T(RAT::struct3_T *result); +static void argInit_struct4_T(RAT::struct4_T *result); + +// Function Definitions +static void argInit_1x2_real_T(real_T result[2]) +{ + // Loop over the array to initialize each element. + for (int32_T idx1{0}; idx1 < 2; idx1++) { + // Set the value of the array element. + // Change this value to the value that the application requires. + result[idx1] = argInit_real_T(); + } +} + +static coder::array argInit_1xUnbounded_char_T() +{ + coder::array result; + + // Set the size of the array. + // Change this size to the value that the application requires. + result.set_size(1, 2); + + // Loop over the array to initialize each element. + for (int32_T idx0{0}; idx0 < 1; idx0++) { + for (int32_T idx1{0}; idx1 < result.size(1); idx1++) { + // Set the value of the array element. + // Change this value to the value that the application requires. + result[idx1] = argInit_char_T(); + } + } + + return result; +} + +static coder::array argInit_1xd10000_cell_wrap_2() +{ + coder::array result; + + // Set the size of the array. + // Change this size to the value that the application requires. + result.set_size(1, 2); + + // Loop over the array to initialize each element. + for (int32_T idx0{0}; idx0 < 1; idx0++) { + for (int32_T idx1{0}; idx1 < result.size(1); idx1++) { + // Set the value of the array element. + // Change this value to the value that the application requires. + result[idx1] = argInit_cell_wrap_2(); + } + } + + return result; +} + +static coder::array argInit_1xd10000_cell_wrap_3() +{ + coder::array result; + + // Set the size of the array. + // Change this size to the value that the application requires. + result.set_size(1, 2); + + // Loop over the array to initialize each element. + for (int32_T idx0{0}; idx0 < 1; idx0++) { + for (int32_T idx1{0}; idx1 < result.size(1); idx1++) { + // Set the value of the array element. + // Change this value to the value that the application requires. + result[idx1] = argInit_cell_wrap_3(); + } + } + + return result; +} + +static coder::array argInit_1xd10000_cell_wrap_4() +{ + coder::array result; + + // Set the size of the array. + // Change this size to the value that the application requires. + result.set_size(1, 2); + + // Loop over the array to initialize each element. + for (int32_T idx0{0}; idx0 < 1; idx0++) { + for (int32_T idx1{0}; idx1 < result.size(1); idx1++) { + // Set the value of the array element. + // Change this value to the value that the application requires. + result[idx1] = argInit_cell_wrap_4(); + } + } + + return result; +} + +static coder::array argInit_1xd10000_cell_wrap_6() +{ + coder::array result; + + // Set the size of the array. + // Change this size to the value that the application requires. + result.set_size(1, 2); + + // Loop over the array to initialize each element. + for (int32_T idx0{0}; idx0 < 1; idx0++) { + for (int32_T idx1{0}; idx1 < result.size(1); idx1++) { + // Set the value of the array element. + // Change this value to the value that the application requires. + argInit_cell_wrap_6(&result[idx1]); + } + } + + return result; +} + +static void argInit_1xd10000_char_T(char_T result_data[], int32_T result_size[2]) +{ + // Set the size of the array. + // Change this size to the value that the application requires. + result_size[0] = 1; + result_size[1] = 2; + + // Loop over the array to initialize each element. + for (int32_T idx1{0}; idx1 < 2; idx1++) { + // Set the value of the array element. + // Change this value to the value that the application requires. + result_data[idx1] = argInit_char_T(); + } +} + +static coder::array argInit_1xd10000_real_T() +{ + coder::array result; + + // Set the size of the array. + // Change this size to the value that the application requires. + result.set_size(1, 2); + + // Loop over the array to initialize each element. + for (int32_T idx0{0}; idx0 < 1; idx0++) { + for (int32_T idx1{0}; idx1 < result.size(1); idx1++) { + // Set the value of the array element. + // Change this value to the value that the application requires. + result[idx1] = argInit_real_T(); + } + } + + return result; +} + +static coder::array argInit_Unboundedx1_cell_0() +{ + coder::array result; + + // Set the size of the array. + // Change this size to the value that the application requires. + result.set_size(2); + + // Loop over the array to initialize each element. + for (int32_T idx0{0}; idx0 < result.size(0); idx0++) { + // Set the value of the array element. + // Change this value to the value that the application requires. + argInit_cell_0(&result[idx0]); + } + + return result; +} + +static coder::array argInit_Unboundedx1_cell_wrap_1() +{ + coder::array result; + + // Set the size of the array. + // Change this size to the value that the application requires. + result.set_size(2); + + // Loop over the array to initialize each element. + for (int32_T idx0{0}; idx0 < result.size(0); idx0++) { + // Set the value of the array element. + // Change this value to the value that the application requires. + result[idx0] = argInit_cell_wrap_1(); + } + + return result; +} + +static coder::array argInit_Unboundedx3_real_T() +{ + coder::array result; + + // Set the size of the array. + // Change this size to the value that the application requires. + result.set_size(2, 3); + + // Loop over the array to initialize each element. + for (int32_T idx0{0}; idx0 < result.size(0); idx0++) { + for (int32_T idx1{0}; idx1 < 3; idx1++) { + // Set the value of the array element. + // Change this value to the value that the application requires. + result[idx0 + result.size(0) * idx1] = argInit_real_T(); + } + } + + return result; +} + +static boolean_T argInit_boolean_T() +{ + return false; +} + +static void argInit_cell_0(RAT::cell_0 *result) +{ + coder::array b_result_tmp; + real_T result_tmp; + + // Set the value of each structure field. + // Change this value to the value that the application requires. + result_tmp = argInit_real_T(); + result->f4 = result_tmp; + b_result_tmp = argInit_1xUnbounded_char_T(); + result->f1 = b_result_tmp; + result->f2 = b_result_tmp; + result->f3 = result_tmp; +} + +static void argInit_cell_7(RAT::cell_7 *result) +{ + coder::array result_tmp; + coder::array b_result_tmp; + coder::array c_result_tmp; + coder::array d_result_tmp; + + // Set the value of each structure field. + // Change this value to the value that the application requires. + result_tmp = argInit_1xd10000_cell_wrap_2(); + result->f1 = result_tmp; + b_result_tmp = argInit_1xd10000_cell_wrap_3(); + result->f2 = b_result_tmp; + result->f3 = result_tmp; + result->f4 = result_tmp; + c_result_tmp = argInit_1xd10000_cell_wrap_4(); + result->f5 = c_result_tmp; + result->f6 = argInit_d10000x1_cell_wrap_5(); + d_result_tmp = argInit_1xd10000_cell_wrap_6(); + result->f7 = d_result_tmp; + result->f8 = d_result_tmp; + result->f9 = d_result_tmp; + result->f10 = d_result_tmp; + result->f11 = d_result_tmp; + result->f12 = d_result_tmp; + result->f13 = d_result_tmp; + result->f14 = d_result_tmp; + result->f15 = d_result_tmp; + result->f16 = d_result_tmp; + result->f17 = b_result_tmp; + result->f18 = result_tmp; + result->f19 = c_result_tmp; + result->f20 = d_result_tmp; +} + +static RAT::cell_wrap_1 argInit_cell_wrap_1() +{ + RAT::cell_wrap_1 result; + + // Set the value of each structure field. + // Change this value to the value that the application requires. + result.f1 = argInit_1xUnbounded_char_T(); + return result; +} + +static RAT::cell_wrap_2 argInit_cell_wrap_2() +{ + RAT::cell_wrap_2 result; + + // Set the value of each structure field. + // Change this value to the value that the application requires. + argInit_1x2_real_T(result.f1); + return result; +} + +static RAT::cell_wrap_3 argInit_cell_wrap_3() +{ + RAT::cell_wrap_3 result; + + // Set the value of each structure field. + // Change this value to the value that the application requires. + result.f1 = argInit_d10000xd10000_real_T(); + return result; +} + +static RAT::cell_wrap_4 argInit_cell_wrap_4() +{ + RAT::cell_wrap_4 result; + + // Set the value of each structure field. + // Change this value to the value that the application requires. + result.f1 = argInit_d1xd10000_real_T(); + return result; +} + +static void argInit_cell_wrap_5(RAT::cell_wrap_5 *result) +{ + // Set the value of each structure field. + // Change this value to the value that the application requires. + argInit_d1xd10_real_T(result->f1.data, result->f1.size); +} + +static void argInit_cell_wrap_6(RAT::cell_wrap_6 *result) +{ + // Set the value of each structure field. + // Change this value to the value that the application requires. + argInit_1xd10000_char_T(result->f1.data, result->f1.size); +} + +static char_T argInit_char_T() +{ + return '?'; +} + +static coder::array argInit_d10000x1_cell_wrap_5() +{ + coder::array result; + + // Set the size of the array. + // Change this size to the value that the application requires. + result.set_size(2); + + // Loop over the array to initialize each element. + for (int32_T idx0{0}; idx0 < result.size(0); idx0++) { + // Set the value of the array element. + // Change this value to the value that the application requires. + argInit_cell_wrap_5(&result[idx0]); + } + + return result; +} + +static coder::array argInit_d10000x2_real_T() +{ + coder::array result; + + // Set the size of the array. + // Change this size to the value that the application requires. + result.set_size(2, 2); + + // Loop over the array to initialize each element. + for (int32_T idx0{0}; idx0 < result.size(0); idx0++) { + for (int32_T idx1{0}; idx1 < 2; idx1++) { + // Set the value of the array element. + // Change this value to the value that the application requires. + result[idx0 + result.size(0) * idx1] = argInit_real_T(); + } + } + + return result; +} + +static coder::array argInit_d10000xd10000_real_T() +{ + coder::array result; + + // Set the size of the array. + // Change this size to the value that the application requires. + result.set_size(2, 2); + + // Loop over the array to initialize each element. + for (int32_T idx0{0}; idx0 < result.size(0); idx0++) { + for (int32_T idx1{0}; idx1 < result.size(1); idx1++) { + // Set the value of the array element. + // Change this value to the value that the application requires. + result[idx0 + result.size(0) * idx1] = argInit_real_T(); + } + } + + return result; +} + +static coder::array argInit_d1xd10000_real_T() +{ + coder::array result; + + // Set the size of the array. + // Change this size to the value that the application requires. + result.set_size(1, 2); + + // Loop over the array to initialize each element. + for (int32_T idx0{0}; idx0 < result.size(0); idx0++) { + for (int32_T idx1{0}; idx1 < result.size(1); idx1++) { + // Set the value of the array element. + // Change this value to the value that the application requires. + result[result.size(0) * idx1] = argInit_real_T(); + } + } + + return result; +} + +static void argInit_d1xd10_real_T(real_T result_data[], int32_T result_size[2]) +{ + // Set the size of the array. + // Change this size to the value that the application requires. + result_size[0] = 1; + result_size[1] = 2; + + // Loop over the array to initialize each element. + for (int32_T idx1{0}; idx1 < 2; idx1++) { + // Set the value of the array element. + // Change this value to the value that the application requires. + result_data[idx1] = argInit_real_T(); + } +} + +static real_T argInit_real_T() +{ + return 0.0; +} + +static void argInit_struct0_T(RAT::struct0_T *result) +{ + coder::array b_result_tmp; + real_T result_tmp; + + // Set the value of each structure field. + // Change this value to the value that the application requires. + result_tmp = argInit_real_T(); + result->numberOfLayers = result_tmp; + result->numberOfDomainContrasts = result_tmp; + b_result_tmp = argInit_1xd10000_real_T(); + result->contrastBackgrounds = b_result_tmp; + result->contrastBackgroundsType = b_result_tmp; + argInit_1xd10000_char_T(result->TF.data, result->TF.size); + result->resample = b_result_tmp; + result->dataPresent = b_result_tmp; + result->oilChiDataPresent = b_result_tmp; + result->numberOfContrasts = result_tmp; + argInit_1xd10000_char_T(result->geometry.data, result->geometry.size); + result->useImaginary = argInit_boolean_T(); + result->contrastQzshifts = b_result_tmp; + result->contrastScalefactors = b_result_tmp; + result->contrastBulkIns = b_result_tmp; + result->contrastBulkOuts = b_result_tmp; + result->contrastResolutions = b_result_tmp; + result->backgroundParams = b_result_tmp; + result->qzshifts = b_result_tmp; + result->scalefactors = b_result_tmp; + result->bulkIn = b_result_tmp; + result->bulkOut = b_result_tmp; + result->resolutionParams = b_result_tmp; + result->params = b_result_tmp; + argInit_1xd10000_char_T(result->modelType.data, result->modelType.size); + result->contrastCustomFiles = b_result_tmp; + result->contrastDomainRatios = b_result_tmp; + result->domainRatio = b_result_tmp; + b_result_tmp = argInit_d10000xd10000_real_T(); + result->fitParams = b_result_tmp; + result->otherParams = b_result_tmp; + result->fitLimits = b_result_tmp; + result->otherLimits = b_result_tmp; +} + +static void argInit_struct1_T(RAT::struct1_T *result) +{ + coder::array result_tmp; + + // Set the value of each structure field. + // Change this value to the value that the application requires. + result_tmp = argInit_d10000x2_real_T(); + result->param = result_tmp; + result->backgroundParam = result_tmp; + result->scalefactor = result_tmp; + result->qzshift = result_tmp; + result->bulkIn = result_tmp; + result->bulkOut = result_tmp; + result->resolutionParam = result_tmp; + result->domainRatio = result_tmp; +} + +static void argInit_struct2_T(RAT::struct2_T *result) +{ + real_T result_tmp; + boolean_T b_result_tmp; + + // Set the value of each structure field. + // Change this value to the value that the application requires. + result_tmp = argInit_real_T(); + result->tolFun = result_tmp; + result->maxFunEvals = result_tmp; + result->maxIter = result_tmp; + result->updateFreq = result_tmp; + result->updatePlotFreq = result_tmp; + result->populationSize = result_tmp; + result->fWeight = result_tmp; + result->crossoverProbability = result_tmp; + result->strategy = result_tmp; + result->targetValue = result_tmp; + result->numGenerations = result_tmp; + result->Nlive = result_tmp; + result->Nmcmc = result_tmp; + result->propScale = result_tmp; + result->nsTolerance = result_tmp; + result->nSamples = result_tmp; + result->nChains = result_tmp; + result->jumpProbability = result_tmp; + result->pUnitGamma = result_tmp; + b_result_tmp = argInit_boolean_T(); + result->adaptPCR = b_result_tmp; + argInit_1xd10000_char_T(result->procedure.data, result->procedure.size); + argInit_1xd10000_char_T(result->parallel.data, result->parallel.size); + argInit_1x2_real_T(result->resamPars); + result->calcSldDuringFit = b_result_tmp; + argInit_1xd10000_char_T(result->display.data, result->display.size); + result->tolX = result_tmp; + argInit_1xd10000_char_T(result->boundHandling.data, result->boundHandling.size); + argInit_struct3_T(&result->checks); +} + +static void argInit_struct3_T(RAT::struct3_T *result) +{ + coder::array result_tmp; + + // Set the value of each structure field. + // Change this value to the value that the application requires. + result_tmp = argInit_1xd10000_real_T(); + result->fitParam = result_tmp; + result->fitBackgroundParam = result_tmp; + result->fitQzshift = result_tmp; + result->fitScalefactor = result_tmp; + result->fitBulkIn = result_tmp; + result->fitBulkOut = result_tmp; + result->fitResolutionParam = result_tmp; + result->fitDomainRatio = result_tmp; +} + +static void argInit_struct4_T(RAT::struct4_T *result) +{ + coder::array result_tmp; + + // Set the value of each structure field. + // Change this value to the value that the application requires. + result_tmp = argInit_Unboundedx1_cell_0(); + result->param = result_tmp; + result->backgroundParam = result_tmp; + result->resolutionParam = result_tmp; + result->bulkIn = result_tmp; + result->bulkOut = result_tmp; + result->qzshift = result_tmp; + result->scalefactor = result_tmp; + result->domainRatio = result_tmp; + result->priorNames = argInit_Unboundedx1_cell_wrap_1(); + result->priorValues = argInit_Unboundedx3_real_T(); +} + +int32_T main(int32_T, char **) +{ + // Initialize the application. + // You do not need to do this more than one time. + RAT::RATMain_initialize(); + + // Invoke the entry-point functions. + // You can call entry-point functions multiple times. + main_RATMain(); + + // Terminate the application. + // You do not need to do this more than one time. + RAT::RATMain_terminate(); + return 0; +} + +void main_RATMain() +{ + static RAT::struct0_T problemStruct; + static RAT::struct2_T controls; + static RAT::struct7_T bayesResults; + RAT::cell_7 problemCells; + RAT::cell_wrap_9 resultCells[6]; + RAT::struct1_T problemLimits; + RAT::struct4_T priors; + RAT::struct5_T contrastParams; + + // Initialize function 'RATMain' input arguments. + // Initialize function input argument 'problemStruct'. + argInit_struct0_T(&problemStruct); + + // Initialize function input argument 'problemCells'. + argInit_cell_7(&problemCells); + + // Initialize function input argument 'problemLimits'. + argInit_struct1_T(&problemLimits); + + // Initialize function input argument 'controls'. + argInit_struct2_T(&controls); + + // Initialize function input argument 'priors'. + argInit_struct4_T(&priors); + + // Call the entry-point 'RATMain'. + RAT::RATMain(&problemStruct, &problemCells, &problemLimits, &controls, &priors, + &contrastParams, resultCells, &bayesResults); +} + +// End of code generation (main.cpp) diff --git a/cpp/RAT/examples/main.h b/cpp/RAT/examples/main.h new file mode 100644 index 00000000..a9288805 --- /dev/null +++ b/cpp/RAT/examples/main.h @@ -0,0 +1,49 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// main.h +// +// Code generation for function 'main' +// + +/*************************************************************************/ +/* This automatically generated example C++ main file shows how to call */ +/* entry-point functions that MATLAB Coder generated. You must customize */ +/* this file for your application. Do not modify this file directly. */ +/* Instead, make a copy of this file, modify it, and integrate it into */ +/* your development environment. */ +/* */ +/* This file initializes entry-point function arguments to a default */ +/* size and value before calling the entry-point functions. It does */ +/* not store or use any values returned from the entry-point functions. */ +/* If necessary, it does pre-allocate memory for returned values. */ +/* You can use this file as a starting point for a main function that */ +/* you can deploy in your application. */ +/* */ +/* After you copy the file, and before you deploy it, you must make the */ +/* following changes: */ +/* * For variable-size function arguments, change the example sizes to */ +/* the sizes that your application requires. */ +/* * Change the example values of function arguments to the values that */ +/* your application requires. */ +/* * If the entry-point functions return values, store these values or */ +/* otherwise use them as required by your application. */ +/* */ +/*************************************************************************/ +#ifndef MAIN_H +#define MAIN_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +extern int32_T main(int32_T argc, char **argv); +extern void main_RATMain(); + +#endif + +// End of code generation (main.h) diff --git a/cpp/RAT/exp.cpp b/cpp/RAT/exp.cpp new file mode 100644 index 00000000..10d2c128 --- /dev/null +++ b/cpp/RAT/exp.cpp @@ -0,0 +1,41 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// exp.cpp +// +// Code generation for function 'exp' +// + +// Include files +#include "exp.h" +#include "rt_nonfinite.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + void b_exp(creal_T *x) + { + if (x->im == 0.0) { + x->re = std::exp(x->re); + x->im = 0.0; + } else if (std::isinf(x->im) && std::isinf(x->re) && (x->re < 0.0)) { + x->re = 0.0; + x->im = 0.0; + } else { + real_T d; + real_T r; + r = std::exp(x->re / 2.0); + d = x->im; + x->re = r * (r * std::cos(x->im)); + x->im = r * (r * std::sin(d)); + } + } + } +} + +// End of code generation (exp.cpp) diff --git a/cpp/RAT/exp.h b/cpp/RAT/exp.h new file mode 100644 index 00000000..ed2149c9 --- /dev/null +++ b/cpp/RAT/exp.h @@ -0,0 +1,29 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// exp.h +// +// Code generation for function 'exp' +// +#ifndef EXP_H +#define EXP_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void b_exp(creal_T *x); + } +} + +#endif + +// End of code generation (exp.h) diff --git a/cpp/RAT/eye.cpp b/cpp/RAT/eye.cpp new file mode 100644 index 00000000..dba0b0a6 --- /dev/null +++ b/cpp/RAT/eye.cpp @@ -0,0 +1,41 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// eye.cpp +// +// Code generation for function 'eye' +// + +// Include files +#include "eye.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + void eye(int32_T varargin_1, ::coder::array &b_I) + { + b_I.set_size(varargin_1, varargin_1); + for (int32_T k{0}; k < varargin_1; k++) { + for (int32_T i{0}; i < varargin_1; i++) { + b_I[i + b_I.size(0) * k].re = 0.0; + b_I[i + b_I.size(0) * k].im = 0.0; + } + } + + if (varargin_1 > 0) { + for (int32_T k{0}; k < varargin_1; k++) { + b_I[k + b_I.size(0) * k].re = 1.0; + b_I[k + b_I.size(0) * k].im = 0.0; + } + } + } + } +} + +// End of code generation (eye.cpp) diff --git a/cpp/RAT/eye.h b/cpp/RAT/eye.h new file mode 100644 index 00000000..ecd70a41 --- /dev/null +++ b/cpp/RAT/eye.h @@ -0,0 +1,30 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// eye.h +// +// Code generation for function 'eye' +// +#ifndef EYE_H +#define EYE_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void eye(int32_T varargin_1, ::coder::array &b_I); + } +} + +#endif + +// End of code generation (eye.h) diff --git a/cpp/RAT/fMinSearch.cpp b/cpp/RAT/fMinSearch.cpp new file mode 100644 index 00000000..088c33e5 --- /dev/null +++ b/cpp/RAT/fMinSearch.cpp @@ -0,0 +1,1130 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// fMinSearch.cpp +// +// Code generation for function 'fMinSearch' +// + +// Include files +#include "fMinSearch.h" +#include "RATMain_internal_types.h" +#include "RATMain_rtwutil.h" +#include "RATMain_types.h" +#include "abs.h" +#include "blockedSummation.h" +#include "eps.h" +#include "minOrMax.h" +#include "rt_nonfinite.h" +#include "simplexIntrafun.h" +#include "sort.h" +#include "sprintf.h" +#include "strcmp.h" +#include "triggerEvent.h" +#include "coder_array.h" +#include "coder_bounded_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3); + static void c_binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, int32_T in3, int32_T in4, int32_T in5); + static void c_binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3); + static void f_binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3); + static void g_binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3); +} + +// Function Definitions +namespace RAT +{ + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3) + { + int32_T b_in3; + int32_T i; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_1_0; + b_in3 = in3.size(1); + if (in3.size(0) == 1) { + i = in2.size(0); + } else { + i = in3.size(0); + } + + in1.set_size(i); + stride_0_0 = (in2.size(0) != 1); + stride_1_0 = (in3.size(0) != 1); + if (in3.size(0) == 1) { + loop_ub = in2.size(0); + } else { + loop_ub = in3.size(0); + } + + for (i = 0; i < loop_ub; i++) { + in1[i] = 3.0 * in2[i * stride_0_0] - 2.0 * in3[i * stride_1_0 + in3.size(0) + * (b_in3 - 1)]; + } + } + + static void c_binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, int32_T in3, int32_T in4, int32_T in5) + { + ::coder::array b_in2; + int32_T aux_0_1; + int32_T i; + int32_T loop_ub; + int32_T stride_0_1; + if (in5 == 1) { + i = (in4 - in3) + 1; + } else { + i = in5; + } + + b_in2.set_size(in2.size(0), i); + stride_0_1 = ((in4 - in3) + 1 != 1); + aux_0_1 = 0; + if (in5 == 1) { + loop_ub = (in4 - in3) + 1; + } else { + loop_ub = in5; + } + + for (i = 0; i < loop_ub; i++) { + int32_T b_loop_ub; + b_loop_ub = in2.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + b_in2[i1 + b_in2.size(0) * i] = in2[i1 + in2.size(0) * (in3 + aux_0_1)] + - in2[i1]; + } + + aux_0_1 += stride_0_1; + } + + coder::c_abs(b_in2, in1); + } + + static void c_binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3) + { + int32_T b_in3; + int32_T i; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_1_0; + b_in3 = in3.size(1); + if (in3.size(0) == 1) { + i = in2.size(0); + } else { + i = in3.size(0); + } + + in1.set_size(i); + stride_0_0 = (in2.size(0) != 1); + stride_1_0 = (in3.size(0) != 1); + if (in3.size(0) == 1) { + loop_ub = in2.size(0); + } else { + loop_ub = in3.size(0); + } + + for (i = 0; i < loop_ub; i++) { + in1[i] = 1.5 * in2[i * stride_0_0] - 0.5 * in3[i * stride_1_0 + in3.size(0) + * (b_in3 - 1)]; + } + } + + static void f_binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3) + { + int32_T b_in3; + int32_T i; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_1_0; + b_in3 = in3.size(1); + if (in3.size(0) == 1) { + i = in2.size(0); + } else { + i = in3.size(0); + } + + in1.set_size(i); + stride_0_0 = (in2.size(0) != 1); + stride_1_0 = (in3.size(0) != 1); + if (in3.size(0) == 1) { + loop_ub = in2.size(0); + } else { + loop_ub = in3.size(0); + } + + for (i = 0; i < loop_ub; i++) { + in1[i] = 0.5 * in2[i * stride_0_0] + 0.5 * in3[i * stride_1_0 + in3.size(0) + * (b_in3 - 1)]; + } + } + + static void g_binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3) + { + int32_T b_in3; + int32_T i; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_1_0; + b_in3 = in3.size(1); + if (in3.size(0) == 1) { + i = in2.size(0); + } else { + i = in3.size(0); + } + + in1.set_size(i); + stride_0_0 = (in2.size(0) != 1); + stride_1_0 = (in3.size(0) != 1); + if (in3.size(0) == 1) { + loop_ub = in2.size(0); + } else { + loop_ub = in3.size(0); + } + + for (i = 0; i < loop_ub; i++) { + in1[i] = 2.0 * in2[i * stride_0_0] - in3[i * stride_1_0 + in3.size(0) * + (b_in3 - 1)]; + } + } + + void fMinSearch(::coder::array &x, real_T options_MaxIter, real_T + options_MaxFunEvals, real_T options_TolX, real_T + options_TolFun, const char_T dis_data[], const int32_T + dis_size[2], const c_struct_T *varargin_1, const ::coder:: + array &varargin_2_f1, const ::coder::array< + cell_wrap_8, 2U> &varargin_2_f2, const ::coder::array< + cell_wrap_2, 2U> &varargin_2_f3, const ::coder::array< + cell_wrap_2, 2U> &varargin_2_f4, const ::coder::array< + cell_wrap_8, 2U> &varargin_2_f5, const ::coder::array< + cell_wrap_8, 1U> &varargin_2_f6, const ::coder::array< + cell_wrap_1, 2U> &varargin_2_f14, const ::coder::array< + cell_wrap_8, 2U> &varargin_2_f19, const struct2_T *varargin_3, + const k_struct_T *varargin_4, real_T *fval, real_T *exitflag, + i_struct_T *output) + { + static const char_T cv6[33]{ 'N', 'e', 'l', 'd', 'e', 'r', '-', 'M', 'e', + 'a', 'd', ' ', 's', 'i', 'm', 'p', 'l', 'e', 'x', ' ', 'd', 'i', 'r', 'e', + 'c', 't', ' ', 's', 'e', 'a', 'r', 'c', 'h' }; + + static const char_T cv11[16]{ 'c', 'o', 'n', 't', 'r', 'a', 'c', 't', ' ', + 'o', 'u', 't', 's', 'i', 'd', 'e' }; + + static const char_T cv10[15]{ 'c', 'o', 'n', 't', 'r', 'a', 'c', 't', ' ', + 'i', 'n', 's', 'i', 'd', 'e' }; + + static const char_T cv5[15]{ 'i', 'n', 'i', 't', 'i', 'a', 'l', ' ', 's', + 'i', 'm', 'p', 'l', 'e', 'x' }; + + static const char_T cv7[7]{ 'r', 'e', 'f', 'l', 'e', 'c', 't' }; + + static const char_T b_cv[6]{ 'n', 'o', 't', 'i', 'f', 'y' }; + + static const char_T cv8[6]{ 'e', 'x', 'p', 'a', 'n', 'd' }; + + static const char_T cv9[6]{ 's', 'h', 'r', 'i', 'n', 'k' }; + + static const char_T cv4[5]{ 'f', 'i', 'n', 'a', 'l' }; + + static const char_T b_cv1[4]{ 'n', 'o', 'n', 'e' }; + + static const char_T cv3[4]{ 'i', 't', 'e', 'r' }; + + static const char_T cv2[3]{ 'o', 'f', 'f' }; + + ::coder::array b_v; + ::coder::array c_fv; + ::coder::array fv; + ::coder::array r; + ::coder::array r1; + ::coder::array r3; + ::coder::array v; + ::coder::array c_v; + ::coder::array r2; + ::coder::array xbar; + ::coder::array xc; + ::coder::array xcc; + ::coder::array xe; + ::coder::array xr; + ::coder::array y; + ::coder::array iidx; + ::coder::array b_varargin_4; + cell_wrap_9 result[6]; + d_struct_T problem; + real_T func_evals; + real_T fxc; + real_T fxcc; + real_T fxe; + real_T fxr; + real_T itercount; + int32_T how_size[2]; + int32_T b_index; + int32_T i; + int32_T i1; + int32_T n; + int32_T prnt; + int32_T x_idx_1; + boolean_T exitg1; + boolean_T printMsg; + + // FMINSEARCH Multidimensional unconstrained nonlinear minimization (Nelder-Mead). + // X = FMINSEARCH(FUN,X0) starts at X0 and attempts to find a local minimizer + // X of the function FUN. FUN is a function handle. FUN accepts input X and + // returns a scalar function value F evaluated at X. X0 can be a scalar, vector + // or matrix. + // + // X = FMINSEARCH(FUN,X0,OPTIONS) minimizes with the default optimization + // parameters replaced by values in the structure OPTIONS, created + // with the OPTIMSET function. See OPTIMSET for details. FMINSEARCH uses + // these options: Display, TolX, TolFun, MaxFunEvals, MaxIter, FunValCheck, + // PlotFcns, and OutputFcn. + // + // X = FMINSEARCH(PROBLEM) finds the minimum for PROBLEM. PROBLEM is a + // structure with the function FUN in PROBLEM.objective, the start point + // in PROBLEM.x0, the options structure in PROBLEM.options, and solver + // name 'fminsearch' in PROBLEM.solver. + // + // [X,FVAL]= FMINSEARCH(...) returns the value of the objective function, + // described in FUN, at X. + // + // [X,FVAL,EXITFLAG] = FMINSEARCH(...) returns an EXITFLAG that describes + // the exit condition. Possible values of EXITFLAG and the corresponding + // exit conditions are + // + // 1 Maximum coordinate difference between current best point and other + // points in simplex is less than or equal to TolX, and corresponding + // difference in function values is less than or equal to TolFun. + // 0 Maximum number of function evaluations or iterations reached. + // -1 Algorithm terminated by the output function. + // + // [X,FVAL,EXITFLAG,OUTPUT] = FMINSEARCH(...) returns a structure + // OUTPUT with the number of iterations taken in OUTPUT.iterations, the + // number of function evaluations in OUTPUT.funcCount, the algorithm name + // in OUTPUT.algorithm, and the exit message in OUTPUT.message. + // + // Examples + // FUN can be specified using @: + // X = fminsearch(@sin,3) + // finds a minimum of the SIN function near 3. + // In this case, SIN is a function that returns a scalar function value + // SIN evaluated at X. + // + // FUN can be an anonymous function: + // X = fminsearch(@(x) norm(x),[1;2;3]) + // returns a point near the minimizer [0;0;0]. + // + // FUN can be a parameterized function. Use an anonymous function to + // capture the problem-dependent parameters: + // f = @(x,c) x(1).^2+c.*x(2).^2; % The parameterized function. + // c = 1.5; % The parameter. + // X = fminsearch(@(x) f(x,c),[0.3;1]) + // + // FMINSEARCH uses the Nelder-Mead simplex (direct search) method. + // + // See also OPTIMSET, FMINBND, FUNCTION_HANDLE. + // Reference: Jeffrey C. Lagarias, James A. Reeds, Margaret H. Wright, + // Paul E. Wright, "Convergence Properties of the Nelder-Mead Simplex + // Method in Low Dimensions", SIAM Journal of Optimization, 9(1): + // p.112-147, 1998. + // Copyright 1984-2018 The MathWorks, Inc. + output->message.set_size(1, 2); + output->message[0] = 'o'; + output->message[1] = 'k'; + + // If just 'defaults' passed in, return the default options in X + // -------- Inputs are standardised for RAT, so no need to check --------- + // Detect problem structure input + // if nargin == 1 + // if isa(funfcn,'struct') + // [funfcn,x,options] = separateOptimStruct(funfcn); + // else % Single input and non-structure + // error('MATLAB:fminsearch:InputArg',... + // sprintf('MATLAB:optimfun:fminsearch:InputArg')); + // end + // end + // + // if nargin == 0 + // error('MATLAB:fminsearch:NotEnoughInputs',... + // sprintf('MATLAB:optimfun:fminsearch:NotEnoughInputs')); + // end + // + // % Check for non-double inputs + // if ~isa(x,'double') + // error('MATLAB:fminsearch:NonDoubleInput',... + // sprintf('MATLAB:optimfun:fminsearch:NonDoubleInput')); + // end + // ------------------------------------------------------------------- + // n = numel(x); + // numberOfVariables = n; + // ------------- Check is done upstream ---------------- + // Check that options is a struct + // if ~isempty(options) && ~isa(options,'struct') + // error('MATLAB:fminsearch:ArgNotStruct',... + // getString(message('MATLAB:optimfun:commonMessages:ArgNotStruct', 3))); + // end + // ------------------- AVH ----------------------------- + // printtype = optimget(options,'Display',defaultopt,'fast'); + // In case the defaults were gathered from calling: optimset('fminsearch'): + // if ischar(maxfun) || isstring(maxfun) + // if strcmpi(maxfun,'200*numberofvariables') + // maxfun = 200*numberOfVariables; + // else + // error('MATLAB:fminsearch:OptMaxFunEvalsNotInteger',... + // getString(message('MATLAB:optimfun:fminsearch:OptMaxFunEvalsNotInteger'))); + // end + // end + // if ischar(maxiter) || isstring(maxiter) + // if strcmpi(maxiter,'200*numberofvariables') + // maxiter = 200*numberOfVariables; + // else + // error('MATLAB:fminsearch:OptMaxIterNotInteger',... + // getString(message('MATLAB:optimfun:fminsearch:OptMaxIterNotInteger'))); + // end + // end + if (coder::internal::b_strcmp(dis_data, dis_size, b_cv)) { + b_index = 0; + } else if (coder::internal::c_strcmp(dis_data, dis_size, b_cv1)) { + b_index = 1; + } else if (coder::internal::d_strcmp(dis_data, dis_size, cv2)) { + b_index = 1; + } else if (coder::internal::c_strcmp(dis_data, dis_size, cv3)) { + b_index = 2; + } else if (coder::internal::e_strcmp(dis_data, dis_size, cv4)) { + b_index = 3; + } else { + b_index = -1; + } + + switch (b_index) { + case 0: + // Changed from TMW fminsearch + prnt = 1; + break; + + case 1: + prnt = 0; + break; + + case 2: + prnt = 3; + break; + + case 3: + prnt = 2; + + // case 'simplex' + // prnt = 4; + break; + + default: + prnt = 1; + break; + } + + // ----------------- Not using output functions for RAT --------- + // % Handle the output + // outputfcn = optimget(options,'OutputFcn',defaultopt,'fast'); + // if isempty(outputfcn) + // haveoutputfcn = false; + // else + // haveoutputfcn = true; + // xOutputfcn = x; % Last x passed to outputfcn; has the input x's shape + // % Parse OutputFcn which is needed to support cell array syntax for OutputFcn. + // outputfcn = createCellArrayOfFunctions(outputfcn,'OutputFcn'); + // end + // + // % Handle the plot + // plotfcns = optimget(options,'PlotFcns',defaultopt,'fast'); + // if isempty(plotfcns) + // haveplotfcn = false; + // else + // haveplotfcn = true; + // xOutputfcn = x; % Last x passed to plotfcns; has the input x's shape + // % Parse PlotFcns which is needed to support cell array syntax for PlotFcns. + // plotfcns = createCellArrayOfFunctions(plotfcns,'PlotFcns'); + // end + // ---------------------- AVH ------------------------------ + // Convert to function handle as needed. + // funfcn = fcnchk(funfcn,length(varargin)); + // Add a wrapper function to check for Inf/NaN/complex values + // + n = x.size(0); + + // Initialize parameters + // two2np1 = 2:n+1; + // one2n = 1:n; + // Set up a simplex near the initial guess. + // Force xin to be a column vector + b_index = x.size(0); + x_idx_1 = x.size(0) + 1; + v.set_size(b_index, x_idx_1); + for (i = 0; i < x_idx_1; i++) { + for (i1 = 0; i1 < b_index; i1++) { + v[i1 + v.size(0) * i] = 0.0; + } + } + + x_idx_1 = x.size(0) + 1; + fv.set_size(1, x_idx_1); + for (i = 0; i < x_idx_1; i++) { + fv[i] = 0.0; + } + + x_idx_1 = x.size(0); + for (i = 0; i < x_idx_1; i++) { + v[i] = x[i]; + } + + // Place input guess in the simplex! (credit L.Pfeffer at Stanford) + // Change x to the form expected by funfcn + simplexIntrafun(x, varargin_1, varargin_2_f1, varargin_2_f2, varargin_2_f3, + varargin_2_f4, varargin_2_f5, varargin_2_f6, varargin_2_f14, + varargin_2_f19, varargin_3, varargin_4, &fv[0], &problem, + result); + + // Initial simplex setup continues later + // Initialize the output and plot functions. + // + // ---------------------------------------- + // RAT doesn't use output or plot functions... + // + // --------------------- AVH ----------- + // if haveoutputfcn || haveplotfcn + // [xOutputfcn, optimValues, stop] = callOutputAndPlotFcns(outputfcn,plotfcns,v(:,1),xOutputfcn,'init',itercount, ... + // func_evals, how, fv(:,1),varargin{:}); + // if stop + // [x,fval,exitflag,output] = cleanUpInterrupt(xOutputfcn,optimValues); + // if prnt > 0 + // fprintf('%s \n', output.message) + // end + // return; + // end + // end + // Print out initial f(x) as 0th iteration + if (prnt == 3) { + printf("\n%s\n", " Iteration Func-count min f(x) Procedure"); + fflush(stdout); + b_varargin_4.set_size(1, 1); + b_varargin_4[0] = '\x00'; + printf(" %5.0f %5.0f %12.6g %s\n", 0.0, 1.0, fv[0], + &b_varargin_4[0]); + fflush(stdout); + + // elseif prnt == 4 + // Option never used in RAT + // formatsave.format = get(0,'format'); + // formatsave.formatspacing = get(0,'formatspacing'); + // % reset format when done + // oc1 = onCleanup(@()set(0,'format',formatsave.format)); + // oc2 = onCleanup(@()set(0,'formatspacing',formatsave.formatspacing)); + // format compact + // format short e + // fprintf('%s \n', ' ') + // fprintf('%s \n', how) + // fprintf('%s \n', 'v = ') + // fprintf('%g \n', v) + // fprintf('%s \n', 'fv = ') + // fprintf('%g \n', fv) + // fprintf('%s \n', 'func_evals = ') + // fprintf('%g \n', func_evals) + } + + triggerEvent(result, problem.ssubs, varargin_1->TF.data, varargin_1->TF.size, + varargin_1->resample, varargin_1->dataPresent, + varargin_1->modelType.data, varargin_1->modelType.size); + + // OutputFcn and PlotFcns call + // if haveoutputfcn || haveplotfcn + // [xOutputfcn, optimValues, stop] = callOutputAndPlotFcns(outputfcn,plotfcns,v(:,1),xOutputfcn,'iter',itercount, ... + // func_evals, how, fv(:,1),varargin{:}); + // if stop % Stop per user request. + // [x,fval,exitflag,output] = cleanUpInterrupt(xOutputfcn,optimValues); + // if prnt > 0 + // fprintf('%s \n', output.message) + // end + // return; + // end + // end + // Continue setting up the initial simplex. + // Following improvement suggested by L.Pfeffer at Stanford + // 5 percent deltas for non-zero terms + // Even smaller delta for zero elements of x + i = x.size(0); + for (int32_T j{0}; j < i; j++) { + x_idx_1 = x.size(0); + y.set_size(x_idx_1); + for (i1 = 0; i1 < x_idx_1; i1++) { + y[i1] = x[i1]; + } + + if (x[j] != 0.0) { + y[j] = 1.05 * x[j]; + } else { + y[j] = 0.00025; + } + + x_idx_1 = y.size(0); + for (i1 = 0; i1 < x_idx_1; i1++) { + v[i1 + v.size(0) * (j + 1)] = y[i1]; + } + + simplexIntrafun(y, varargin_1, varargin_2_f1, varargin_2_f2, varargin_2_f3, + varargin_2_f4, varargin_2_f5, varargin_2_f6, + varargin_2_f14, varargin_2_f19, varargin_3, varargin_4, + &fv[j + 1], &problem, result); + } + + // sort so v(1,:) has the lowest function value + coder::internal::sort(fv, iidx); + b_index = v.size(0); + b_v.set_size(v.size(0), iidx.size(1)); + x_idx_1 = iidx.size(1); + for (i = 0; i < x_idx_1; i++) { + for (i1 = 0; i1 < b_index; i1++) { + b_v[i1 + b_v.size(0) * i] = v[i1 + v.size(0) * (iidx[i] - 1)]; + } + } + + v.set_size(b_v.size(0), b_v.size(1)); + x_idx_1 = b_v.size(1); + for (i = 0; i < x_idx_1; i++) { + b_index = b_v.size(0); + for (i1 = 0; i1 < b_index; i1++) { + v[i1 + v.size(0) * i] = b_v[i1 + b_v.size(0) * i]; + } + } + + itercount = 1.0; + func_evals = static_cast(x.size(0)) + 1.0; + if (prnt == 3) { + b_varargin_4.set_size(1, 16); + for (i = 0; i < 15; i++) { + b_varargin_4[i] = cv5[i]; + } + + b_varargin_4[15] = '\x00'; + printf(" %5.0f %5.0f %12.6g %s\n", 1.0, + static_cast(x.size(0)) + 1.0, fv[0], &b_varargin_4[0]); + fflush(stdout); + + // elseif prnt == 4 + // fprintf('%s \n', ' ') + // fprintf('%s \n', how) + // fprintf('%s \n', 'v = ') + // fprintf('%g \n', v) + // fprintf('%s \n', 'fv = ') + // fprintf('%g \n', fv) + // fprintf('%s \n', 'func_evals = ') + // fprintf('%g \n', func_evals) + } + + if (rt_remd_snf(1.0, varargin_3->updatePlotFreq) == 0.0) { + triggerEvent(result, problem.ssubs, varargin_1->TF.data, + varargin_1->TF.size, varargin_1->resample, + varargin_1->dataPresent, varargin_1->modelType.data, + varargin_1->modelType.size); + } + + // OutputFcn and PlotFcns call + // if haveoutputfcn || haveplotfcn + // [xOutputfcn, optimValues, stop] = callOutputAndPlotFcns(outputfcn,plotfcns,v(:,1),xOutputfcn,'iter',itercount, ... + // func_evals, how, fv(:,1),varargin{:}); + // if stop % Stop per user request. + // [x,fval,exitflag,output] = cleanUpInterrupt(xOutputfcn,optimValues); + // if prnt > 0 + // fprintf('%s \n', output.message) + // end + // return; + // end + // end + // exitflag = 1; + // Main algorithm: iterate until + // (a) the maximum coordinate difference between the current best point and the + // other points in the simplex is less than or equal to TolX. Specifically, + // until max(||v2-v1||,||v3-v1||,...,||v(n+1)-v1||) <= TolX, + // where ||.|| is the infinity-norm, and v1 holds the + // vertex with the current lowest value; AND + // (b) the corresponding difference in function values is less than or equal + // to TolFun. (Cannot use OR instead of AND.) + // The iteration stops if the maximum number of iterations or function evaluations + // are exceeded + exitg1 = false; + while ((!exitg1) && ((func_evals < options_MaxFunEvals) && (itercount < + options_MaxIter))) { + real_T b_fv; + boolean_T guard1; + if (n + 1 < 2) { + i = 0; + i1 = -1; + } else { + i = 1; + i1 = n; + } + + b_fv = fv[0]; + x_idx_1 = i1 - i; + c_fv.set_size(1, x_idx_1 + 1); + for (i1 = 0; i1 <= x_idx_1; i1++) { + c_fv[i1] = b_fv - fv[i + i1]; + } + + coder::b_abs(c_fv, r); + guard1 = false; + if (coder::internal::maximum(r) <= std::fmax(options_TolFun, 10.0 * coder:: + eps(fv[0]))) { + if (n + 1 < 2) { + i = 0; + i1 = -1; + } else { + i = 1; + i1 = n; + } + + x_idx_1 = i1 - i; + if (x_idx_1 + 1 == n) { + b_v.set_size(v.size(0), x_idx_1 + 1); + for (i1 = 0; i1 <= x_idx_1; i1++) { + b_index = v.size(0); + for (int32_T i2{0}; i2 < b_index; i2++) { + b_v[i2 + b_v.size(0) * i1] = v[i2 + v.size(0) * (i + i1)] - v[i2]; + } + } + + coder::c_abs(b_v, r1); + } else { + c_binary_expand_op(r1, v, i, i1, n); + } + + c_v.set_size(v.size(0)); + x_idx_1 = v.size(0); + for (i = 0; i < x_idx_1; i++) { + c_v[i] = v[i]; + } + + coder::internal::maximum(r1, r3); + if (coder::internal::maximum(r3) <= std::fmax(options_TolX, 10.0 * coder:: + eps(coder::internal::maximum(c_v)))) { + exitg1 = true; + } else { + guard1 = true; + } + } else { + guard1 = true; + } + + if (guard1) { + char_T how_data[16]; + + // Compute the reflection point + // xbar = average of the n (NOT n+1) best points + if (n < 1) { + x_idx_1 = 0; + } else { + x_idx_1 = n; + } + + b_v.set_size(v.size(0), x_idx_1); + for (i = 0; i < x_idx_1; i++) { + b_index = v.size(0); + for (i1 = 0; i1 < b_index; i1++) { + b_v[i1 + b_v.size(0) * i] = v[i1 + v.size(0) * i]; + } + } + + coder::blockedSummation(b_v, x_idx_1, r2); + xbar.set_size(r2.size(0)); + x_idx_1 = r2.size(0); + for (i = 0; i < x_idx_1; i++) { + xbar[i] = r2[i] / static_cast(n); + } + + if (xbar.size(0) == v.size(0)) { + xr.set_size(xbar.size(0)); + x_idx_1 = xbar.size(0); + for (i = 0; i < x_idx_1; i++) { + xr[i] = 2.0 * xbar[i] - v[i + v.size(0) * (v.size(1) - 1)]; + } + } else { + g_binary_expand_op(xr, xbar, v); + } + + simplexIntrafun(xr, varargin_1, varargin_2_f1, varargin_2_f2, + varargin_2_f3, varargin_2_f4, varargin_2_f5, + varargin_2_f6, varargin_2_f14, varargin_2_f19, + varargin_3, varargin_4, &fxr, &problem, result); + func_evals++; + if (fxr < fv[0]) { + // Calculate the expansion point + if (xbar.size(0) == v.size(0)) { + xe.set_size(xbar.size(0)); + x_idx_1 = xbar.size(0); + for (i = 0; i < x_idx_1; i++) { + xe[i] = 3.0 * xbar[i] - 2.0 * v[i + v.size(0) * (v.size(1) - 1)]; + } + } else { + binary_expand_op(xe, xbar, v); + } + + simplexIntrafun(xe, varargin_1, varargin_2_f1, varargin_2_f2, + varargin_2_f3, varargin_2_f4, varargin_2_f5, + varargin_2_f6, varargin_2_f14, varargin_2_f19, + varargin_3, varargin_4, &fxe, &problem, result); + func_evals++; + if (fxe < fxr) { + x_idx_1 = xe.size(0); + for (i = 0; i < x_idx_1; i++) { + v[i + v.size(0) * (v.size(1) - 1)] = xe[i]; + } + + fv[fv.size(1) - 1] = fxe; + how_size[1] = 6; + for (i = 0; i < 6; i++) { + how_data[i] = cv8[i]; + } + } else { + x_idx_1 = xr.size(0); + for (i = 0; i < x_idx_1; i++) { + v[i + v.size(0) * (v.size(1) - 1)] = xr[i]; + } + + fv[fv.size(1) - 1] = fxr; + how_size[1] = 7; + for (i = 0; i < 7; i++) { + how_data[i] = cv7[i]; + } + } + + // fv(:,1) <= fxr + } else if (fxr < fv[n - 1]) { + x_idx_1 = xr.size(0); + for (i = 0; i < x_idx_1; i++) { + v[i + v.size(0) * (v.size(1) - 1)] = xr[i]; + } + + fv[fv.size(1) - 1] = fxr; + how_size[1] = 7; + for (i = 0; i < 7; i++) { + how_data[i] = cv7[i]; + } + } else { + // fxr >= fv(:,n) + // Perform contraction + if (fxr < fv[fv.size(1) - 1]) { + // Perform an outside contraction + if (xbar.size(0) == v.size(0)) { + xc.set_size(xbar.size(0)); + x_idx_1 = xbar.size(0); + for (i = 0; i < x_idx_1; i++) { + xc[i] = 1.5 * xbar[i] - 0.5 * v[i + v.size(0) * (v.size(1) - 1)]; + } + } else { + c_binary_expand_op(xc, xbar, v); + } + + simplexIntrafun(xc, varargin_1, varargin_2_f1, varargin_2_f2, + varargin_2_f3, varargin_2_f4, varargin_2_f5, + varargin_2_f6, varargin_2_f14, varargin_2_f19, + varargin_3, varargin_4, &fxc, &problem, result); + func_evals++; + if (fxc <= fxr) { + x_idx_1 = xc.size(0); + for (i = 0; i < x_idx_1; i++) { + v[i + v.size(0) * (v.size(1) - 1)] = xc[i]; + } + + fv[fv.size(1) - 1] = fxc; + how_size[0] = 1; + how_size[1] = 16; + for (i = 0; i < 16; i++) { + how_data[i] = cv11[i]; + } + } else { + // perform a shrink + how_size[0] = 1; + how_size[1] = 6; + for (i = 0; i < 6; i++) { + how_data[i] = cv9[i]; + } + } + } else { + // Perform an inside contraction + if (xbar.size(0) == v.size(0)) { + xcc.set_size(xbar.size(0)); + x_idx_1 = xbar.size(0); + for (i = 0; i < x_idx_1; i++) { + xcc[i] = 0.5 * xbar[i] + 0.5 * v[i + v.size(0) * (v.size(1) - 1)]; + } + } else { + f_binary_expand_op(xcc, xbar, v); + } + + simplexIntrafun(xcc, varargin_1, varargin_2_f1, varargin_2_f2, + varargin_2_f3, varargin_2_f4, varargin_2_f5, + varargin_2_f6, varargin_2_f14, varargin_2_f19, + varargin_3, varargin_4, &fxcc, &problem, result); + func_evals++; + if (fxcc < fv[fv.size(1) - 1]) { + x_idx_1 = xcc.size(0); + for (i = 0; i < x_idx_1; i++) { + v[i + v.size(0) * (v.size(1) - 1)] = xcc[i]; + } + + fv[fv.size(1) - 1] = fxcc; + how_size[0] = 1; + how_size[1] = 15; + for (i = 0; i < 15; i++) { + how_data[i] = cv10[i]; + } + } else { + // perform a shrink + how_size[0] = 1; + how_size[1] = 6; + for (i = 0; i < 6; i++) { + how_data[i] = cv9[i]; + } + } + } + + if (coder::internal::v_strcmp(how_data, how_size)) { + for (int32_T j{0}; j < n; j++) { + x_idx_1 = v.size(0); + c_v.set_size(v.size(0)); + for (i = 0; i < x_idx_1; i++) { + b_fv = v[i]; + c_v[i] = b_fv + 0.5 * (v[i + v.size(0) * (j + 1)] - b_fv); + } + + x_idx_1 = c_v.size(0); + for (i = 0; i < x_idx_1; i++) { + v[i + v.size(0) * (j + 1)] = c_v[i]; + } + + x_idx_1 = v.size(0); + c_v.set_size(v.size(0)); + for (i = 0; i < x_idx_1; i++) { + c_v[i] = v[i + v.size(0) * (j + 1)]; + } + + simplexIntrafun(c_v, varargin_1, varargin_2_f1, varargin_2_f2, + varargin_2_f3, varargin_2_f4, varargin_2_f5, + varargin_2_f6, varargin_2_f14, varargin_2_f19, + varargin_3, varargin_4, &fv[j + 1], &problem, + result); + } + + func_evals += static_cast(n); + } + } + + coder::internal::sort(fv, iidx); + b_index = v.size(0); + b_v.set_size(v.size(0), iidx.size(1)); + x_idx_1 = iidx.size(1); + for (i = 0; i < x_idx_1; i++) { + for (i1 = 0; i1 < b_index; i1++) { + b_v[i1 + b_v.size(0) * i] = v[i1 + v.size(0) * (iidx[i] - 1)]; + } + } + + v.set_size(b_v.size(0), b_v.size(1)); + x_idx_1 = b_v.size(1); + for (i = 0; i < x_idx_1; i++) { + b_index = b_v.size(0); + for (i1 = 0; i1 < b_index; i1++) { + v[i1 + v.size(0) * i] = b_v[i1 + b_v.size(0) * i]; + } + } + + itercount++; + if (prnt == 3) { + b_varargin_4.set_size(1, how_size[1] + 1); + x_idx_1 = how_size[1]; + for (i = 0; i < x_idx_1; i++) { + b_varargin_4[i] = how_data[i]; + } + + b_varargin_4[how_size[1]] = '\x00'; + printf(" %5.0f %5.0f %12.6g %s\n", itercount, + func_evals, fv[0], &b_varargin_4[0]); + fflush(stdout); + + // elseif prnt == 4 + // fprintf('%s \n', ' ') + // fprintf('%s \n', num2str(how)) + // fprintf('%s \n', 'v = ') + // fprintf('%s \n', v) + // fprintf('%s \n', 'fv = ') + // fprintf('%s \n', fv) + // fprintf('%s \n', 'func_evals = ') + // fprintf('%s \n', num2str(func_evals)) + } + + if (rt_remd_snf(itercount, varargin_3->updatePlotFreq) == 0.0) { + triggerEvent(result, problem.ssubs, varargin_1->TF.data, + varargin_1->TF.size, varargin_1->resample, + varargin_1->dataPresent, varargin_1->modelType.data, + varargin_1->modelType.size); + } + + // OutputFcn and PlotFcns call + // if haveoutputfcn || haveplotfcn + // [xOutputfcn, optimValues, stop] = callOutputAndPlotFcns(outputfcn,plotfcns,v(:,1),xOutputfcn,'iter',itercount, ... + // func_evals, how, fv(:,1),varargin{:}); + // if stop % Stop per user request. + // [x,fval,exitflag,output] = cleanUpInterrupt(xOutputfcn,optimValues); + // if prnt > 0 + // fprintf('%s \n', output.message) + // end + // return; + // end + // end + } + } + + // while + x.set_size(v.size(0)); + x_idx_1 = v.size(0); + for (i = 0; i < x_idx_1; i++) { + x[i] = v[i]; + } + + *fval = fv[0]; + + // OutputFcn and PlotFcns call + // if haveoutputfcn || haveplotfcn + // callOutputAndPlotFcns(outputfcn,plotfcns,x,xOutputfcn,'done',itercount, func_evals, how, fval, varargin{:}); + // end + if (func_evals >= options_MaxFunEvals) { + printMsg = (prnt > 0); + + // msg = getString(message('MATLAB:optimfun:fminsearch:ExitingMaxFunctionEvals', sprintf('%f',fval))); + b_index = 0; + } else if (itercount >= options_MaxIter) { + printMsg = (prnt > 0); + + // msg = getString(message('MATLAB:optimfun:fminsearch:ExitingMaxIterations', sprintf('%f',fval))); + b_index = 0; + } else { + printMsg = (prnt > 1); + coder::b_sprintf(options_TolX, options_TolFun, output->message); + b_index = 1; + } + + output->iterations = itercount; + output->funcCount = func_evals; + for (i = 0; i < 33; i++) { + output->algorithm[i] = cv6[i]; + } + + if (printMsg) { + b_varargin_4.set_size(1, output->message.size(1) + 1); + x_idx_1 = output->message.size(1); + for (i = 0; i < x_idx_1; i++) { + b_varargin_4[i] = output->message[i]; + } + + b_varargin_4[output->message.size(1)] = '\x00'; + printf("\n%s\n", &b_varargin_4[0]); + fflush(stdout); + } + + // -------------------------------------------------------------------------- + // function [xOutputfcn, optimValues, stop] = callOutputAndPlotFcns(outputfcn,plotfcns,x,xOutputfcn,state,iter,... + // numf,how,f,varargin) + // CALLOUTPUTANDPLOTFCNS assigns values to the struct OptimValues and then calls the + // outputfcn/plotfcns. + // + // state - can have the values 'init','iter', or 'done'. + // For the 'done' state we do not check the value of 'stop' because the + // optimization is already done. + // optimValues.iteration = iter; + // optimValues.funccount = numf; + // optimValues.fval = f; + // optimValues.procedure = how; + // xOutputfcn(:) = x; % Set x to have user expected size + // stop = false; + // state = char(state); + // Call output functions + // ---- Remove these from function for compile - AVH + // if ~isempty(outputfcn) + // switch state + // case {'iter','init'} + // stop = callAllOptimOutputFcns(outputfcn,xOutputfcn,optimValues,state,varargin{:}) || stop; + // case 'done' + // callAllOptimOutputFcns(outputfcn,xOutputfcn,optimValues,state,varargin{:}); + // end + // end + // % Call plot functions + // if ~isempty(plotfcns) + // switch state + // case {'iter','init'} + // stop = callAllOptimPlotFcns(plotfcns,xOutputfcn,optimValues,state,varargin{:}) || stop; + // case 'done' + // callAllOptimPlotFcns(plotfcns,xOutputfcn,optimValues,state,varargin{:}); + // end + // end + // ----------------------------------- + // -------------------------------------------------------------------------- + // function [x,FVAL,EXITFLAG,OUTPUT] = cleanUpInterrupt(xOutputfcn,optimValues) + // CLEANUPINTERRUPT updates or sets all the output arguments of FMINBND when the optimization + // is interrupted. + // Call plot function driver to finalize the plot function figure window. If + // no plot functions have been specified or the plot function figure no + // longer exists, this call just returns. + // callAllOptimPlotFcns('cleanuponstopsignal'); + // x = xOutputfcn; + // FVAL = optimValues.fval; + // EXITFLAG = -1; + // OUTPUT.iterations = optimValues.iteration; + // OUTPUT.funcCount = optimValues.funccount; + // OUTPUT.algorithm = 'Nelder-Mead simplex direct search'; + // OUTPUT.message = fprintf('Optimisation terminated by user'); %getString(message('MATLAB:optimfun:fminsearch:OptimizationTerminatedPrematurelyByUser')); + // -------------------------------------------------------------------------- + // function f = checkfun(x,userfcn,varargin) + // CHECKFUN checks for complex or NaN results from userfcn. + // f = userfcn(x,varargin{:}); + // Note: we do not check for Inf as FMINSEARCH handles it naturally. + // if isnan(f) + // error('MATLAB:fminsearch:checkfun:NaNFval','Target function is NaN'); + // elseif ~isreal(f) + // error('MATLAB:fminsearch:checkfun:ComplexFval',... + // getString(message('MATLAB:optimfun:fminsearch:checkfun:ComplexFval', localChar( userfcn )))); + // error(sprintf('Target function is complex')); + // end + // -------------------------------------------------------------------------- + // function strfcn = localChar(fcn) + // % Convert the fcn to a character array for printing + // + // if ischar(fcn) + // strfcn = fcn; + // elseif isstring(fcn) || isa(fcn,'inline') + // strfcn = char(fcn); + // elseif isa(fcn,'function_handle') + // strfcn = func2str(fcn); + // else + // try + // strfcn = char(fcn); + // catch + // strfcn = getString(message('MATLAB:optimfun:fminsearch:NameNotPrintable')); + // end + // end + *exitflag = b_index; + } +} + +// End of code generation (fMinSearch.cpp) diff --git a/cpp/RAT/fMinSearch.h b/cpp/RAT/fMinSearch.h new file mode 100644 index 00000000..2e7b5a03 --- /dev/null +++ b/cpp/RAT/fMinSearch.h @@ -0,0 +1,49 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// fMinSearch.h +// +// Code generation for function 'fMinSearch' +// +#ifndef FMINSEARCH_H +#define FMINSEARCH_H + +// Include files +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct c_struct_T; + struct k_struct_T; + struct i_struct_T; +} + +// Function Declarations +namespace RAT +{ + void fMinSearch(::coder::array &x, real_T options_MaxIter, real_T + options_MaxFunEvals, real_T options_TolX, real_T + options_TolFun, const char_T dis_data[], const int32_T + dis_size[2], const c_struct_T *varargin_1, const ::coder:: + array &varargin_2_f1, const ::coder::array< + cell_wrap_8, 2U> &varargin_2_f2, const ::coder::array< + cell_wrap_2, 2U> &varargin_2_f3, const ::coder::array< + cell_wrap_2, 2U> &varargin_2_f4, const ::coder::array< + cell_wrap_8, 2U> &varargin_2_f5, const ::coder::array< + cell_wrap_8, 1U> &varargin_2_f6, const ::coder::array< + cell_wrap_1, 2U> &varargin_2_f14, const ::coder::array< + cell_wrap_8, 2U> &varargin_2_f19, const struct2_T *varargin_3, + const k_struct_T *varargin_4, real_T *fval, real_T *exitflag, + i_struct_T *output); +} + +#endif + +// End of code generation (fMinSearch.h) diff --git a/cpp/RAT/fileManager.cpp b/cpp/RAT/fileManager.cpp new file mode 100644 index 00000000..603a3660 --- /dev/null +++ b/cpp/RAT/fileManager.cpp @@ -0,0 +1,57 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// fileManager.cpp +// +// Code generation for function 'fileManager' +// + +// Include files +#include "fileManager.h" +#include "rt_nonfinite.h" +#include + +// Variable Definitions +namespace RAT +{ + static FILE* eml_openfiles[20]; +} + +// Function Definitions +namespace RAT +{ + namespace coder + { + int32_T fileManager() + { + int32_T f; + f = 0; + for (int32_T j{0}; j < 20; j++) { + if (eml_openfiles[j] != NULL) { + int32_T cst; + cst = fclose(eml_openfiles[j]); + if (cst == 0) { + eml_openfiles[j] = NULL; + } else { + f = -1; + } + } + } + + return f; + } + } + + void filedata_init() + { + FILE* a; + a = NULL; + for (int32_T i{0}; i < 20; i++) { + eml_openfiles[i] = a; + } + } +} + +// End of code generation (fileManager.cpp) diff --git a/cpp/RAT/fileManager.h b/cpp/RAT/fileManager.h new file mode 100644 index 00000000..e81a98b6 --- /dev/null +++ b/cpp/RAT/fileManager.h @@ -0,0 +1,31 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// fileManager.h +// +// Code generation for function 'fileManager' +// +#ifndef FILEMANAGER_H +#define FILEMANAGER_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + int32_T fileManager(); + } + + void filedata_init(); +} + +#endif + +// End of code generation (fileManager.h) diff --git a/cpp/RAT/find.cpp b/cpp/RAT/find.cpp new file mode 100644 index 00000000..3322d1b1 --- /dev/null +++ b/cpp/RAT/find.cpp @@ -0,0 +1,318 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// find.cpp +// +// Code generation for function 'find' +// + +// Include files +#include "find.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 1U> &in2, const ::coder::array &in3) + { + ::coder::array b_in2; + int32_T i; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_1_0; + if (in3.size(0) == 1) { + i = in2.size(0); + } else { + i = in3.size(0); + } + + b_in2.set_size(i); + stride_0_0 = (in2.size(0) != 1); + stride_1_0 = (in3.size(0) != 1); + if (in3.size(0) == 1) { + loop_ub = in2.size(0); + } else { + loop_ub = in3.size(0); + } + + for (i = 0; i < loop_ub; i++) { + b_in2[i] = (in2[i * stride_0_0] > in3[i * stride_1_0]); + } + + coder::eml_find(b_in2, in1); + } + + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in2, const ::coder::array &in3) + { + ::coder::array b_in2; + int32_T aux_0_1; + int32_T aux_1_1; + int32_T i; + int32_T i1; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_0_1; + int32_T stride_1_0; + int32_T stride_1_1; + if (in3.size(0) == 1) { + i = in2.size(0); + } else { + i = in3.size(0); + } + + if (in3.size(1) == 1) { + i1 = in2.size(1); + } else { + i1 = in3.size(1); + } + + b_in2.set_size(i, i1); + stride_0_0 = (in2.size(0) != 1); + stride_0_1 = (in2.size(1) != 1); + stride_1_0 = (in3.size(0) != 1); + stride_1_1 = (in3.size(1) != 1); + aux_0_1 = 0; + aux_1_1 = 0; + if (in3.size(1) == 1) { + loop_ub = in2.size(1); + } else { + loop_ub = in3.size(1); + } + + for (i = 0; i < loop_ub; i++) { + int32_T b_loop_ub; + i1 = in3.size(0); + if (i1 == 1) { + b_loop_ub = in2.size(0); + } else { + b_loop_ub = i1; + } + + for (i1 = 0; i1 < b_loop_ub; i1++) { + b_in2[i1 + b_in2.size(0) * i] = (in2[i1 * stride_0_0 + in2.size(0) * + aux_0_1] > in3[i1 * stride_1_0 + in3.size(0) * aux_1_1]); + } + + aux_1_1 += stride_1_1; + aux_0_1 += stride_0_1; + } + + coder::c_eml_find(b_in2, in1); + } + + void c_binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in2, const ::coder::array &in3) + { + ::coder::array b_in2; + int32_T aux_0_1; + int32_T aux_1_1; + int32_T i; + int32_T i1; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_0_1; + int32_T stride_1_0; + int32_T stride_1_1; + if (in3.size(0) == 1) { + i = in2.size(0); + } else { + i = in3.size(0); + } + + if (in3.size(1) == 1) { + i1 = in2.size(1); + } else { + i1 = in3.size(1); + } + + b_in2.set_size(i, i1); + stride_0_0 = (in2.size(0) != 1); + stride_0_1 = (in2.size(1) != 1); + stride_1_0 = (in3.size(0) != 1); + stride_1_1 = (in3.size(1) != 1); + aux_0_1 = 0; + aux_1_1 = 0; + if (in3.size(1) == 1) { + loop_ub = in2.size(1); + } else { + loop_ub = in3.size(1); + } + + for (i = 0; i < loop_ub; i++) { + int32_T b_loop_ub; + i1 = in3.size(0); + if (i1 == 1) { + b_loop_ub = in2.size(0); + } else { + b_loop_ub = i1; + } + + for (i1 = 0; i1 < b_loop_ub; i1++) { + b_in2[i1 + b_in2.size(0) * i] = (in2[i1 * stride_0_0 + in2.size(0) * + aux_0_1] < in3[i1 * stride_1_0 + in3.size(0) * aux_1_1]); + } + + aux_1_1 += stride_1_1; + aux_0_1 += stride_0_1; + } + + coder::c_eml_find(b_in2, in1); + } + + namespace coder + { + void b_eml_find(const boolean_T x[2], int32_T i_data[], int32_T i_size[2]) + { + int32_T idx; + int32_T ii; + boolean_T exitg1; + idx = 0; + i_size[0] = 1; + ii = 0; + exitg1 = false; + while ((!exitg1) && (ii < 2)) { + if (x[ii]) { + idx++; + i_data[idx - 1] = ii + 1; + if (idx >= 2) { + exitg1 = true; + } else { + ii++; + } + } else { + ii++; + } + } + + if (idx < 1) { + i_size[1] = 0; + } else { + i_size[1] = idx; + } + } + + void c_eml_find(const ::coder::array &x, ::coder::array< + int32_T, 1U> &i) + { + int32_T idx; + int32_T ii; + int32_T nx; + boolean_T exitg1; + nx = x.size(0) * x.size(1); + idx = 0; + i.set_size(nx); + ii = 0; + exitg1 = false; + while ((!exitg1) && (ii <= nx - 1)) { + if (x[ii]) { + idx++; + i[idx - 1] = ii + 1; + if (idx >= nx) { + exitg1 = true; + } else { + ii++; + } + } else { + ii++; + } + } + + if (nx == 1) { + if (idx == 0) { + i.set_size(0); + } + } else { + if (idx < 1) { + idx = 0; + } + + i.set_size(idx); + } + } + + void d_eml_find(const ::coder::array &x, ::coder::array< + int32_T, 2U> &i) + { + int32_T idx; + int32_T ii; + int32_T nx; + boolean_T exitg1; + nx = x.size(1); + idx = 0; + i.set_size(1, x.size(1)); + ii = 0; + exitg1 = false; + while ((!exitg1) && (ii <= nx - 1)) { + if (x[ii]) { + idx++; + i[idx - 1] = ii + 1; + if (idx >= nx) { + exitg1 = true; + } else { + ii++; + } + } else { + ii++; + } + } + + if (x.size(1) == 1) { + if (idx == 0) { + i.set_size(1, 0); + } + } else { + if (idx < 1) { + idx = 0; + } + + i.set_size(i.size(0), idx); + } + } + + void eml_find(const ::coder::array &x, ::coder::array &i) + { + int32_T idx; + int32_T ii; + int32_T nx; + boolean_T exitg1; + nx = x.size(0); + idx = 0; + i.set_size(x.size(0)); + ii = 0; + exitg1 = false; + while ((!exitg1) && (ii <= nx - 1)) { + if (x[ii]) { + idx++; + i[idx - 1] = ii + 1; + if (idx >= nx) { + exitg1 = true; + } else { + ii++; + } + } else { + ii++; + } + } + + if (x.size(0) == 1) { + if (idx == 0) { + i.set_size(0); + } + } else { + if (idx < 1) { + idx = 0; + } + + i.set_size(idx); + } + } + } +} + +// End of code generation (find.cpp) diff --git a/cpp/RAT/find.h b/cpp/RAT/find.h new file mode 100644 index 00000000..8f62d5b3 --- /dev/null +++ b/cpp/RAT/find.h @@ -0,0 +1,42 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// find.h +// +// Code generation for function 'find' +// +#ifndef FIND_H +#define FIND_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 1U> &in2, const ::coder::array &in3); + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in2, const ::coder::array &in3); + void c_binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in2, const ::coder::array &in3); + namespace coder + { + void b_eml_find(const boolean_T x[2], int32_T i_data[], int32_T i_size[2]); + void c_eml_find(const ::coder::array &x, ::coder::array< + int32_T, 1U> &i); + void d_eml_find(const ::coder::array &x, ::coder::array< + int32_T, 2U> &i); + void eml_find(const ::coder::array &x, ::coder::array &i); + } +} + +#endif + +// End of code generation (find.h) diff --git a/cpp/RAT/flip.cpp b/cpp/RAT/flip.cpp new file mode 100644 index 00000000..9041449a --- /dev/null +++ b/cpp/RAT/flip.cpp @@ -0,0 +1,39 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// flip.cpp +// +// Code generation for function 'flip' +// + +// Include files +#include "flip.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + void flip(::coder::array &x) + { + if (x.size(0) > 1) { + int32_T i; + i = x.size(0) >> 1; + for (int32_T k{0}; k < i; k++) { + real_T tmp; + int16_T i1; + i1 = static_cast(x.size(0) - k); + tmp = x[k]; + x[k] = x[i1 - 1]; + x[i1 - 1] = tmp; + } + } + } + } +} + +// End of code generation (flip.cpp) diff --git a/cpp/RAT/flip.h b/cpp/RAT/flip.h new file mode 100644 index 00000000..a5197d80 --- /dev/null +++ b/cpp/RAT/flip.h @@ -0,0 +1,30 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// flip.h +// +// Code generation for function 'flip' +// +#ifndef FLIP_H +#define FLIP_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void flip(::coder::array &x); + } +} + +#endif + +// End of code generation (flip.h) diff --git a/cpp/RAT/gamma.cpp b/cpp/RAT/gamma.cpp new file mode 100644 index 00000000..0a15a479 --- /dev/null +++ b/cpp/RAT/gamma.cpp @@ -0,0 +1,93 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// gamma.cpp +// +// Code generation for function 'gamma' +// + +// Include files +#include "gamma.h" +#include "rt_nonfinite.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + void b_gamma(real_T *x) + { + static const real_T gam[23]{ 1.0, 1.0, 2.0, 6.0, 24.0, 120.0, 720.0, + 5040.0, 40320.0, 362880.0, 3.6288E+6, 3.99168E+7, 4.790016E+8, + 6.2270208E+9, 8.71782912E+10, 1.307674368E+12, 2.0922789888E+13, + 3.55687428096E+14, 6.402373705728E+15, 1.21645100408832E+17, + 2.43290200817664E+18, 5.109094217170944E+19, 1.1240007277776077E+21 }; + + static const real_T p[8]{ -1.716185138865495, 24.76565080557592, + -379.80425647094563, 629.3311553128184, 866.96620279041326, + -31451.272968848367, -36144.413418691176, 66456.143820240541 }; + + static const real_T q[8]{ -30.840230011973897, 315.35062697960416, + -1015.1563674902192, -3107.7716715723109, 22538.11842098015, + 4755.8462775278813, -134659.95986496931, -115132.25967555349 }; + + static const real_T c[7]{ -0.001910444077728, 0.00084171387781295, + -0.00059523799130430121, 0.0007936507935003503, -0.0027777777777776816, + 0.083333333333333329, 0.0057083835261 }; + + if ((*x <= 23.0) && (*x == std::floor(*x))) { + *x = gam[static_cast(*x) - 1]; + } else if (std::isnan(*x)) { + *x = rtNaN; + } else if (std::isinf(*x)) { + *x = rtInf; + } else { + real_T ysq; + if (*x < 12.0) { + real_T b_sum; + real_T b_x; + real_T xkold; + int32_T i; + xkold = *x; + b_x = std::floor(*x); + *x -= b_x - 1.0; + ysq = 0.0 * (*x - 1.0); + b_sum = 1.0; + for (i = 0; i < 8; i++) { + ysq = (ysq + p[i]) * (*x - 1.0); + b_sum = b_sum * (*x - 1.0) + q[i]; + } + + ysq = ysq / b_sum + 1.0; + if (xkold < *x) { + ysq /= xkold; + } else if (xkold > *x) { + i = static_cast(b_x - 1.0); + for (int32_T j{0}; j < i; j++) { + ysq *= *x; + (*x)++; + } + } + } else { + real_T b_sum; + ysq = *x * *x; + b_sum = 0.0057083835261; + for (int32_T i{0}; i < 6; i++) { + b_sum = b_sum / ysq + c[i]; + } + + b_sum = (b_sum / *x - *x) + 0.91893853320467278; + b_sum += (*x - 0.5) * std::log(*x); + ysq = std::exp(b_sum); + } + + *x = ysq; + } + } + } +} + +// End of code generation (gamma.cpp) diff --git a/cpp/RAT/gamma.h b/cpp/RAT/gamma.h new file mode 100644 index 00000000..8696f6bd --- /dev/null +++ b/cpp/RAT/gamma.h @@ -0,0 +1,29 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// gamma.h +// +// Code generation for function 'gamma' +// +#ifndef GAMMA_H +#define GAMMA_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void b_gamma(real_T *x); + } +} + +#endif + +// End of code generation (gamma.h) diff --git a/cpp/RAT/gelman.cpp b/cpp/RAT/gelman.cpp new file mode 100644 index 00000000..6b830dd5 --- /dev/null +++ b/cpp/RAT/gelman.cpp @@ -0,0 +1,190 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// gelman.cpp +// +// Code generation for function 'gelman' +// + +// Include files +#include "gelman.h" +#include "RATMain_types.h" +#include "mean.h" +#include "rt_nonfinite.h" +#include "sqrt1.h" +#include "var.h" +#include "coder_array.h" + +// Function Declarations +namespace RAT +{ + static void binary_expand_op(::coder::array &in1, real_T in2, + real_T in3, const ::coder::array &in4, real_T in5, const ::coder:: + array &in6, const ::coder::array &in7); +} + +// Function Definitions +namespace RAT +{ + static void binary_expand_op(::coder::array &in1, real_T in2, + real_T in3, const ::coder::array &in4, real_T in5, const ::coder:: + array &in6, const ::coder::array &in7) + { + real_T c_in6; + int32_T b_in6; + int32_T i; + int32_T loop_ub; + int32_T stride_0_1; + int32_T stride_1_1; + int32_T stride_2_1; + b_in6 = in6.size(0); + c_in6 = (static_cast(in6.size(0)) - 1.0) / static_cast + (in6.size(2)) / static_cast(in6.size(0)); + if (in4.size(1) == 1) { + if (in7.size(1) == 1) { + i = in4.size(1); + } else { + i = in7.size(1); + } + } else { + i = in4.size(1); + } + + in1.set_size(1, i); + stride_0_1 = (in4.size(1) != 1); + stride_1_1 = (in7.size(1) != 1); + stride_2_1 = (in4.size(1) != 1); + if (in4.size(1) == 1) { + if (in7.size(1) == 1) { + loop_ub = in4.size(1); + } else { + loop_ub = in7.size(1); + } + } else { + loop_ub = in4.size(1); + } + + for (i = 0; i < loop_ub; i++) { + in1[i] = in2 * (in3 * in4[i * stride_0_1] + in5 * (static_cast + (b_in6) * in7[i * stride_1_1])) / in4[i * stride_2_1] - c_in6; + } + } + + void gelman(const ::coder::array &chain, const struct13_T + *DREAMPar, ::coder::array &R_stat) + { + ::coder::array r1; + ::coder::array W; + ::coder::array b_chain; + ::coder::array r; + ::coder::array var_chain; + int32_T b_loop_ub_tmp; + int32_T i; + int32_T loop_ub_tmp; + + // Calculates the R-statistic convergence diagnostic + // ---------------------------------------------------- + // For more information please refer to: Gelman, A. and D.R. Rubin, 1992. + // Inference from Iterative Simulation Using Multiple chain, + // Statistical Science, Volume 7, Issue 4, 457-472. + // + // Written by Jasper A. Vrugt + // Los Alamos, August 2007 + // ---------------------------------------------------- + // Compute the dimensions of chain + loop_ub_tmp = static_cast(DREAMPar->N); + b_loop_ub_tmp = static_cast(DREAMPar->d); + var_chain.set_size(loop_ub_tmp, b_loop_ub_tmp); + for (i = 0; i < b_loop_ub_tmp; i++) { + for (int32_T i1{0}; i1 < loop_ub_tmp; i1++) { + var_chain[i1 + var_chain.size(0) * i] = 0.0; + } + } + + if (chain.size(0) < 10) { + // Set the R-statistic to a large value + R_stat.set_size(1, b_loop_ub_tmp); + for (i = 0; i < b_loop_ub_tmp; i++) { + R_stat[i] = rtNaN; + } + } else { + real_T a; + real_T b_a; + real_T c_a; + int32_T loop_ub; + + // Step 1: Determine the _chainuence means + // Step 1: Determine the variance between the _chainuence means + // Step 2: Compute the variance of the various chain + for (int32_T zz{0}; zz < loop_ub_tmp; zz++) { + loop_ub = chain.size(1); + b_chain.set_size(chain.size(0), chain.size(1)); + for (i = 0; i < loop_ub; i++) { + int32_T b_loop_ub; + b_loop_ub = chain.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + b_chain[i1 + b_chain.size(0) * i] = chain[(i1 + chain.size(0) * i) + + chain.size(0) * chain.size(1) * zz]; + } + } + + coder::var(b_chain, r); + loop_ub = r.size(1); + for (i = 0; i < loop_ub; i++) { + var_chain[zz + var_chain.size(0) * i] = r[i]; + } + } + + // Step 2: Calculate the average of the within _chainuence variances + coder::mean(var_chain, W); + + // Step 3: Estimate the target mean + // mu = mean(mean_chain); + // Step 4: Estimate the target variance + a = (static_cast(chain.size(0)) - 1.0) / static_cast + (chain.size(0)); + b_a = 1.0 / static_cast(chain.size(0)); + + // Step 5: Compute the R-statistic + c_a = (static_cast(chain.size(2)) + 1.0) / static_cast + (chain.size(2)); + coder::mean(chain, r1); + loop_ub_tmp = chain.size(2); + b_chain.set_size(chain.size(2), b_loop_ub_tmp); + for (i = 0; i < b_loop_ub_tmp; i++) { + for (int32_T i1{0}; i1 < loop_ub_tmp; i1++) { + b_chain[i1 + b_chain.size(0) * i] = r1[i + b_loop_ub_tmp * i1]; + } + } + + coder::var(b_chain, r); + if (W.size(1) == 1) { + i = r.size(1); + } else { + i = W.size(1); + } + + if ((W.size(1) == r.size(1)) && (i == W.size(1))) { + real_T c_chain; + c_chain = (static_cast(chain.size(0)) - 1.0) / + static_cast(chain.size(2)) / static_cast(chain.size(0)); + R_stat.set_size(1, W.size(1)); + loop_ub = W.size(1); + for (i = 0; i < loop_ub; i++) { + real_T d; + d = W[i]; + R_stat[i] = c_a * (a * d + b_a * (static_cast(chain.size(0)) * + r[i])) / d - c_chain; + } + } else { + binary_expand_op(R_stat, c_a, a, W, b_a, chain, r); + } + + coder::c_sqrt(R_stat); + } + } +} + +// End of code generation (gelman.cpp) diff --git a/cpp/RAT/gelman.h b/cpp/RAT/gelman.h new file mode 100644 index 00000000..db085b8d --- /dev/null +++ b/cpp/RAT/gelman.h @@ -0,0 +1,34 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// gelman.h +// +// Code generation for function 'gelman' +// +#ifndef GELMAN_H +#define GELMAN_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct struct13_T; +} + +// Function Declarations +namespace RAT +{ + void gelman(const ::coder::array &chain, const struct13_T + *DREAMPar, ::coder::array &R_stat); +} + +#endif + +// End of code generation (gelman.h) diff --git a/cpp/RAT/getFittedPriors.cpp b/cpp/RAT/getFittedPriors.cpp new file mode 100644 index 00000000..969a491f --- /dev/null +++ b/cpp/RAT/getFittedPriors.cpp @@ -0,0 +1,85 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// getFittedPriors.cpp +// +// Code generation for function 'getFittedPriors' +// + +// Include files +#include "getFittedPriors.h" +#include "RATMain_types.h" +#include "find.h" +#include "rt_nonfinite.h" +#include "strcmp.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void getFittedPriors(const ::coder::array ¶mNames, const :: + coder::array &priors_priorNames, const :: + coder::array &priors_priorValues, const :: + coder::array &fitLimits, ::coder::array< + real_T, 2U> &priorFitList) + { + ::coder::array indices; + ::coder::array f1; + ::coder::array r1; + cell_wrap_1 r; + int32_T i; + int32_T loop_ub; + + // Get the list of all the priors.. + // Find the values for fitParams + // priorFitList = cell(numberOfParams,5); + // for i = 1:numberOfParams + // priorFitList{i,1} = 0; + // priorFitList{i,2} = 0; + // priorFitList{i,3} = 0; + // priorFitList{i,4} = 0; + // priorFitList{i,5} = 0; + // end + priorFitList.set_size(paramNames.size(0), 5); + loop_ub = paramNames.size(0); + for (i = 0; i < 5; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + priorFitList[i1 + priorFitList.size(0) * i] = 0.0; + } + } + + // In order to keep 'priorFitList' homogenous (otherwise we would need to + // use a struct), we change the prior type to a numeric flag. So.... + // 'uniform' = 1 + // 'gaussian' = 2 + // 'jeffreys' = 3 + i = paramNames.size(0); + for (int32_T b_i{0}; b_i < i; b_i++) { + loop_ub = paramNames[b_i].f1.size(1); + f1.set_size(1, paramNames[b_i].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + f1[i1] = paramNames[b_i].f1[i1]; + } + + r.f1 = f1; + coder::internal::x_strcmp(&r, priors_priorNames, r1); + coder::eml_find(r1, indices); + if (indices.size(0) != 0) { + priorFitList[b_i] = priors_priorValues[indices[0] - 1]; + priorFitList[b_i + priorFitList.size(0)] = priors_priorValues[(indices[0] + + priors_priorValues.size(0)) - 1]; + priorFitList[b_i + priorFitList.size(0) * 2] = priors_priorValues + [(indices[0] + priors_priorValues.size(0) * 2) - 1]; + priorFitList[b_i + priorFitList.size(0) * 3] = fitLimits[b_i]; + priorFitList[b_i + priorFitList.size(0) * 4] = fitLimits[b_i + + fitLimits.size(0)]; + } else { + priorFitList[b_i] = 1.0; + } + } + } +} + +// End of code generation (getFittedPriors.cpp) diff --git a/cpp/RAT/getFittedPriors.h b/cpp/RAT/getFittedPriors.h new file mode 100644 index 00000000..c740875f --- /dev/null +++ b/cpp/RAT/getFittedPriors.h @@ -0,0 +1,32 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// getFittedPriors.h +// +// Code generation for function 'getFittedPriors' +// +#ifndef GETFITTEDPRIORS_H +#define GETFITTEDPRIORS_H + +// Include files +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void getFittedPriors(const ::coder::array ¶mNames, const :: + coder::array &priors_priorNames, const :: + coder::array &priors_priorValues, const :: + coder::array &fitLimits, ::coder::array< + real_T, 2U> &priorFitList); +} + +#endif + +// End of code generation (getFittedPriors.h) diff --git a/cpp/RAT/getTime.cpp b/cpp/RAT/getTime.cpp new file mode 100644 index 00000000..6936f7e8 --- /dev/null +++ b/cpp/RAT/getTime.cpp @@ -0,0 +1,43 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// getTime.cpp +// +// Code generation for function 'getTime' +// + +// Include files +#include "getTime.h" +#include "RATMain_data.h" +#include "rt_nonfinite.h" +#include "coder_posix_time.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace time + { + void getTime(real_T *t_tv_sec, real_T *t_tv_nsec) + { + coderTimespec b_timespec; + if (!freq_not_empty) { + freq_not_empty = true; + coderInitTimeFunctions(&freq); + } + + coderTimeClockGettimeMonotonic(&b_timespec, freq); + *t_tv_sec = b_timespec.tv_sec; + *t_tv_nsec = b_timespec.tv_nsec; + } + } + } + } +} + +// End of code generation (getTime.cpp) diff --git a/cpp/RAT/getTime.h b/cpp/RAT/getTime.h new file mode 100644 index 00000000..2a7552f1 --- /dev/null +++ b/cpp/RAT/getTime.h @@ -0,0 +1,35 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// getTime.h +// +// Code generation for function 'getTime' +// +#ifndef GETTIME_H +#define GETTIME_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace time + { + void getTime(real_T *t_tv_sec, real_T *t_tv_nsec); + } + } + } +} + +#endif + +// End of code generation (getTime.h) diff --git a/cpp/RAT/getenv.cpp b/cpp/RAT/getenv.cpp new file mode 100644 index 00000000..5f80679b --- /dev/null +++ b/cpp/RAT/getenv.cpp @@ -0,0 +1,41 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// getenv.cpp +// +// Code generation for function 'getenv' +// + +// Include files +#include "getenv.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include +#include +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + void b_getenv(::coder::array &value) + { + char *rawValue; + rawValue = getenv("RAT_PATH"); + if (rawValue == NULL) { + value.set_size(1, 0); + } else { + size_t length; + length = strlen(rawValue); + value.set_size(1, (int32_T)length); + memcpy((void *)&value[0], (void *)rawValue, (size_t)(int32_T)length * + sizeof(char)); + } + } + } +} + +// End of code generation (getenv.cpp) diff --git a/cpp/RAT/getenv.h b/cpp/RAT/getenv.h new file mode 100644 index 00000000..35a61aaa --- /dev/null +++ b/cpp/RAT/getenv.h @@ -0,0 +1,30 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// getenv.h +// +// Code generation for function 'getenv' +// +#ifndef GETENV_H +#define GETENV_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void b_getenv(::coder::array &value); + } +} + +#endif + +// End of code generation (getenv.h) diff --git a/cpp/RAT/groupLayersMod.cpp b/cpp/RAT/groupLayersMod.cpp new file mode 100644 index 00000000..c59325f3 --- /dev/null +++ b/cpp/RAT/groupLayersMod.cpp @@ -0,0 +1,172 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// groupLayersMod.cpp +// +// Code generation for function 'groupLayersMod' +// + +// Include files +#include "groupLayersMod.h" +#include "rt_nonfinite.h" +#include "strcmp.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + void groupLayersMod(const ::coder::array &allLayers, real_T + allRoughs, const char_T geometry_data[], const int32_T + geometry_size[2], real_T bulkIns, real_T bulkOuts, ::coder:: + array &outLayers, real_T *outSsubs) + { + ::coder::array layers; + ::coder::array roughs; + int32_T b_loop_ub; + int32_T i; + int32_T loop_ub; + uint32_T unnamed_idx_0; + + // Arrange layers according to geometry and apply any coverage correction. The paratt calculation proceeds through the + // z,rho,rough stack, and the parameter 'ssub' in callParatt is the final roughness encountered. + // + // * For air liquid 'ssub' is therefore the substrate roughness. + // * For solid liquid, the substrate roughness is the first roughness encountered, and 'ssub' is then the roughness of the outermost layer + // + // USAGE:: + // + // [outLayers, outSsubs] = groupLayersMod(allLayers,allRoughs,geometry,bulkIns,bulkOuts) + // + // INPUTS: + // * allLayers: cell array, one for each contrast. Each cell is the list of layer values for each contrast. + // * allRoughs: Double of substrate roughness for each contrast. + // * geometry: 'Air / Liquid (or solid)' or 'Solid / Liquid' + // * bulkIns: vector of bulkIn values. + // * bulkOuts: vector of bulkOut values. + // + // Outputs: + // * outLayers: cell array of layers param values for each contrast. + // * outSsubs: vector of substrate roughness values. + // outLayers = cell(1,numberOfContrasts); + // outSsubs = zeros(1,numberOfContrasts); + // for i = 1:numberOfContrasts + *outSsubs = allRoughs; + unnamed_idx_0 = static_cast(allLayers.size(0)); + layers.set_size(allLayers.size(0), allLayers.size(1)); + loop_ub = allLayers.size(1); + for (i = 0; i < loop_ub; i++) { + b_loop_ub = static_cast(unnamed_idx_0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + layers[i1 + layers.size(0) * i] = 0.0; + } + } + + if ((allLayers.size(0) != 0) && (allLayers.size(1) != 0)) { + if (coder::internal::q_strcmp(geometry_data, geometry_size)) { + layers.set_size(allLayers.size(0), allLayers.size(1)); + loop_ub = allLayers.size(1); + b_loop_ub = allLayers.size(0); + for (i = 0; i < loop_ub; i++) { + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + layers[i1 + layers.size(0) * i] = allLayers[i1 + allLayers.size(0) * + i]; + } + } + + // s_sub = rsub; + } else { + *outSsubs = allLayers[(allLayers.size(0) + allLayers.size(0) * 2) - 1]; + if (allLayers.size(0) > 1) { + roughs.set_size(allLayers.size(0)); + roughs[0] = allRoughs; + loop_ub = allLayers.size(0); + for (i = 0; i <= loop_ub - 2; i++) { + roughs[i + 1] = allLayers[i + allLayers.size(0) * 2]; + } + } else { + roughs.set_size(1); + roughs[0] = allRoughs; + } + + if (allLayers.size(1) == 5) { + layers.set_size(allLayers.size(0), 4); + loop_ub = allLayers.size(0); + for (i = 0; i < loop_ub; i++) { + layers[i] = allLayers[i]; + } + + loop_ub = allLayers.size(0); + for (i = 0; i < loop_ub; i++) { + layers[i + layers.size(0)] = allLayers[i + allLayers.size(0)]; + } + + loop_ub = roughs.size(0); + for (i = 0; i < loop_ub; i++) { + layers[i + layers.size(0) * 2] = roughs[i]; + } + + loop_ub = allLayers.size(0); + for (i = 0; i < loop_ub; i++) { + layers[i + layers.size(0) * 3] = allLayers[i + allLayers.size(0) * 3]; + } + } else { + layers.set_size(allLayers.size(0), 3); + loop_ub = allLayers.size(0); + for (i = 0; i < loop_ub; i++) { + layers[i] = allLayers[i]; + } + + loop_ub = allLayers.size(0); + for (i = 0; i < loop_ub; i++) { + layers[i + layers.size(0)] = allLayers[i + allLayers.size(0)]; + } + + loop_ub = roughs.size(0); + for (i = 0; i < loop_ub; i++) { + layers[i + layers.size(0) * 2] = roughs[i]; + } + } + } + + // Deal with the %coverage if present + if (allLayers.size(1) == 5) { + i = allLayers.size(0); + for (int32_T j{0}; j < i; j++) { + real_T this_pcw; + this_pcw = allLayers[j + allLayers.size(0) * 3]; + if (!std::isnan(this_pcw)) { + real_T d; + if (allLayers[j + allLayers.size(0) * 4] == 1.0) { + d = bulkIns; + } else { + d = bulkOuts; + } + + layers[j + layers.size(0)] = d * (this_pcw / 100.0) + (1.0 - + this_pcw / 100.0) * layers[j + layers.size(0)]; + } + } + } + } + + if ((layers.size(0) != 0) && (layers.size(1) != 0)) { + outLayers.set_size(layers.size(0), 3); + loop_ub = layers.size(0); + for (i = 0; i < 3; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + outLayers[i1 + outLayers.size(0) * i] = layers[i1 + layers.size(0) * i]; + } + } + } else { + outLayers.set_size(1, 3); + outLayers[0] = 0.0; + outLayers[outLayers.size(0)] = 0.0; + outLayers[outLayers.size(0) * 2] = 0.0; + } + } +} + +// End of code generation (groupLayersMod.cpp) diff --git a/cpp/RAT/groupLayersMod.h b/cpp/RAT/groupLayersMod.h new file mode 100644 index 00000000..d6631fd5 --- /dev/null +++ b/cpp/RAT/groupLayersMod.h @@ -0,0 +1,30 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// groupLayersMod.h +// +// Code generation for function 'groupLayersMod' +// +#ifndef GROUPLAYERSMOD_H +#define GROUPLAYERSMOD_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void groupLayersMod(const ::coder::array &allLayers, real_T + allRoughs, const char_T geometry_data[], const int32_T + geometry_size[2], real_T bulkIns, real_T bulkOuts, ::coder:: + array &outLayers, real_T *outSsubs); +} + +#endif + +// End of code generation (groupLayersMod.h) diff --git a/cpp/RAT/groupLayersModImaginary.cpp b/cpp/RAT/groupLayersModImaginary.cpp new file mode 100644 index 00000000..ea722b9c --- /dev/null +++ b/cpp/RAT/groupLayersModImaginary.cpp @@ -0,0 +1,213 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// groupLayersModImaginary.cpp +// +// Code generation for function 'groupLayersModImaginary' +// + +// Include files +#include "groupLayersModImaginary.h" +#include "rt_nonfinite.h" +#include "strcmp.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + void groupLayersModImaginary(const ::coder::array &allLayers, + real_T allRoughs, const char_T geometry_data[], const int32_T geometry_size + [2], real_T bulkIns, real_T bulkOuts, ::coder::array &outLayers, + real_T *outSsubs) + { + ::coder::array layers; + ::coder::array sldss; + ::coder::array b_allLayers; + ::coder::array c_allLayers; + ::coder::array roughs; + int32_T b_loop_ub; + int32_T i; + int32_T loop_ub; + uint32_T unnamed_idx_0; + + // Arrange layers according to geometry and apply any coverage correction. The paratt calculation proceeds through the + // z,rho,rough stack, and the parameter 'ssub' in callParatt is the final roughness encountered. + // + // * For air liquid 'ssub' is therefore the substrate roughness. + // * For solid liquid, the substrate roughness is the first roughness encountered, and 'ssub' is then the roughness of the outermost layer + // + // USAGE:: + // + // [outLayers, outSsubs] = groupLayersModImaginary(allLayers,allRoughs,geometry,bulkIns,bulkOuts) + // + // INPUTS: + // * allLayers: cell array, one for each contrast. Each cell is the list of layer values for each contrast. + // * allRoughs: Double of substrate roughness for each contrast. + // * geometry: 'Air / Liquid (or solid)' or 'Solid / Liquid' + // * bulkIns: vector of bulkIn values. + // * bulkOuts: vector of bulkOut values. + // + // Outputs: + // * outLayers: cell array of layers param values for each contrast. + // * outSsubs: vector of substrate roughness values. + // outLayers = cell(1,numberOfContrasts); + // outSsubs = zeros(1,numberOfContrasts); + // for i = 1:numberOfContrasts + *outSsubs = allRoughs; + unnamed_idx_0 = static_cast(allLayers.size(0)); + layers.set_size(allLayers.size(0), allLayers.size(1)); + loop_ub = allLayers.size(1); + for (i = 0; i < loop_ub; i++) { + b_loop_ub = static_cast(unnamed_idx_0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + layers[i1 + layers.size(0) * i] = 0.0; + } + } + + if ((allLayers.size(0) != 0) && (allLayers.size(1) != 0)) { + if (coder::internal::q_strcmp(geometry_data, geometry_size)) { + layers.set_size(allLayers.size(0), allLayers.size(1)); + loop_ub = allLayers.size(1); + b_loop_ub = allLayers.size(0); + for (i = 0; i < loop_ub; i++) { + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + layers[i1 + layers.size(0) * i] = allLayers[i1 + allLayers.size(0) * + i]; + } + } + + // s_sub = rsub; + } else { + sldss.set_size(allLayers.size(0), 2); + loop_ub = allLayers.size(0); + for (i = 0; i < 2; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + sldss[i1 + sldss.size(0) * i] = allLayers[i1 + allLayers.size(0) * + (i + 1)]; + } + } + + *outSsubs = allLayers[(allLayers.size(0) + allLayers.size(0) * 3) - 1]; + if (allLayers.size(0) > 1) { + roughs.set_size(allLayers.size(0)); + roughs[0] = allRoughs; + loop_ub = allLayers.size(0); + for (i = 0; i <= loop_ub - 2; i++) { + roughs[i + 1] = allLayers[i + allLayers.size(0) * 3]; + } + } else { + roughs.set_size(1); + roughs[0] = allRoughs; + } + + if (allLayers.size(1) == 5) { + int32_T b_sizes_idx_0; + int32_T sizes_idx_0; + b_allLayers.set_size(allLayers.size(0)); + loop_ub = allLayers.size(0); + for (i = 0; i < loop_ub; i++) { + b_allLayers[i] = allLayers[i]; + } + + b_loop_ub = allLayers.size(0); + sizes_idx_0 = allLayers.size(0); + b_sizes_idx_0 = allLayers.size(0); + c_allLayers.set_size(allLayers.size(0)); + loop_ub = allLayers.size(0); + for (i = 0; i < loop_ub; i++) { + c_allLayers[i] = allLayers[i + allLayers.size(0) * 4]; + } + + loop_ub = allLayers.size(0); + layers.set_size(allLayers.size(0), 5); + for (i = 0; i < b_loop_ub; i++) { + layers[i] = b_allLayers[i]; + } + + for (i = 0; i < 2; i++) { + for (int32_T i1{0}; i1 < sizes_idx_0; i1++) { + layers[i1 + layers.size(0) * (i + 1)] = sldss[i1 + sizes_idx_0 * i]; + } + } + + for (i = 0; i < b_sizes_idx_0; i++) { + layers[i + layers.size(0) * 3] = roughs[i]; + } + + for (i = 0; i < loop_ub; i++) { + layers[i + layers.size(0) * 4] = c_allLayers[i]; + } + } else { + int32_T b_sizes_idx_0; + int32_T sizes_idx_0; + b_allLayers.set_size(allLayers.size(0)); + loop_ub = allLayers.size(0); + for (i = 0; i < loop_ub; i++) { + b_allLayers[i] = allLayers[i]; + } + + b_loop_ub = allLayers.size(0); + sizes_idx_0 = allLayers.size(0); + b_sizes_idx_0 = allLayers.size(0); + layers.set_size(allLayers.size(0), 4); + for (i = 0; i < b_loop_ub; i++) { + layers[i] = b_allLayers[i]; + } + + for (i = 0; i < 2; i++) { + for (int32_T i1{0}; i1 < sizes_idx_0; i1++) { + layers[i1 + layers.size(0) * (i + 1)] = sldss[i1 + sizes_idx_0 * i]; + } + } + + for (i = 0; i < b_sizes_idx_0; i++) { + layers[i + layers.size(0) * 3] = roughs[i]; + } + } + } + + // Deal with the %coverage if present + if (allLayers.size(1) == 6) { + i = allLayers.size(0); + for (int32_T j{0}; j < i; j++) { + real_T d; + d = allLayers[j + allLayers.size(0) * 4]; + if (!std::isnan(d)) { + real_T d1; + if (d == 1.0) { + d1 = bulkIns; + } else { + d1 = bulkOuts; + } + + layers[j + layers.size(0)] = d1 * (d / 100.0) + (1.0 - d / 100.0) * + layers[j + layers.size(0)]; + + // layers(j,3) = pc_add*(this_pcw/100) + (1-(this_pcw/100))*layers(j,3); + } + } + } + } + + if ((layers.size(0) != 0) && (layers.size(1) != 0)) { + outLayers.set_size(layers.size(0), 4); + loop_ub = layers.size(0); + for (i = 0; i < 4; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + outLayers[i1 + outLayers.size(0) * i] = layers[i1 + layers.size(0) * i]; + } + } + } else { + outLayers.set_size(1, 4); + outLayers[0] = 0.0; + outLayers[outLayers.size(0)] = 0.0; + outLayers[outLayers.size(0) * 2] = 0.0; + outLayers[outLayers.size(0) * 3] = 0.0; + } + } +} + +// End of code generation (groupLayersModImaginary.cpp) diff --git a/cpp/RAT/groupLayersModImaginary.h b/cpp/RAT/groupLayersModImaginary.h new file mode 100644 index 00000000..9e03c660 --- /dev/null +++ b/cpp/RAT/groupLayersModImaginary.h @@ -0,0 +1,30 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// groupLayersModImaginary.h +// +// Code generation for function 'groupLayersModImaginary' +// +#ifndef GROUPLAYERSMODIMAGINARY_H +#define GROUPLAYERSMODIMAGINARY_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void groupLayersModImaginary(const ::coder::array &allLayers, + real_T allRoughs, const char_T geometry_data[], const int32_T geometry_size + [2], real_T bulkIns, real_T bulkOuts, ::coder::array &outLayers, + real_T *outSsubs); +} + +#endif + +// End of code generation (groupLayersModImaginary.h) diff --git a/cpp/RAT/histc.cpp b/cpp/RAT/histc.cpp new file mode 100644 index 00000000..1cce4094 --- /dev/null +++ b/cpp/RAT/histc.cpp @@ -0,0 +1,115 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// histc.cpp +// +// Code generation for function 'histc' +// + +// Include files +#include "histc.h" +#include "bsearch.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + static int32_T b_findbin(real_T x, const real_T bin_edges[3]); + static int32_T findbin(real_T x, const real_T bin_edges_data[]); + } +} + +// Function Definitions +namespace RAT +{ + namespace coder + { + static int32_T b_findbin(real_T x, const real_T bin_edges[3]) + { + int32_T k; + k = 0; + if (!std::isnan(x)) { + k = internal::c_bsearch(bin_edges, x); + } + + return k; + } + + static int32_T findbin(real_T x, const real_T bin_edges_data[]) + { + int32_T k; + k = 0; + if (!std::isnan(x)) { + if ((x >= bin_edges_data[0]) && (x < bin_edges_data[3])) { + k = internal::b_bsearch(bin_edges_data, x); + } + + if (x == bin_edges_data[3]) { + k = 4; + } + } + + return k; + } + + void histc(const ::coder::array &X, const real_T edges[3], + real_T N[3], ::coder::array &BIN) + { + int32_T bin; + int32_T i; + N[0] = 0.0; + N[1] = 0.0; + N[2] = 0.0; + BIN.set_size(X.size(0)); + bin = X.size(0); + for (i = 0; i < bin; i++) { + BIN[i] = 0.0; + } + + i = X.size(0); + for (int32_T k{0}; k < i; k++) { + bin = b_findbin(X[k], edges); + if (bin > 0) { + N[bin - 1]++; + } + + BIN[k] = bin; + } + } + + void histc(const ::coder::array &X, const real_T edges_data[], + real_T N_data[], int32_T *N_size, ::coder::array &BIN) + { + int32_T bin; + int32_T i; + *N_size = 4; + N_data[0] = 0.0; + N_data[1] = 0.0; + N_data[2] = 0.0; + N_data[3] = 0.0; + BIN.set_size(X.size(0)); + bin = X.size(0); + for (i = 0; i < bin; i++) { + BIN[i] = 0.0; + } + + i = X.size(0); + for (int32_T k{0}; k < i; k++) { + bin = findbin(X[k], edges_data); + if (bin > 0) { + N_data[bin - 1]++; + } + + BIN[k] = bin; + } + } + } +} + +// End of code generation (histc.cpp) diff --git a/cpp/RAT/histc.h b/cpp/RAT/histc.h new file mode 100644 index 00000000..3fd3eddf --- /dev/null +++ b/cpp/RAT/histc.h @@ -0,0 +1,33 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// histc.h +// +// Code generation for function 'histc' +// +#ifndef HISTC_H +#define HISTC_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void histc(const ::coder::array &X, const real_T edges[3], + real_T N[3], ::coder::array &BIN); + void histc(const ::coder::array &X, const real_T edges_data[], + real_T N_data[], int32_T *N_size, ::coder::array &BIN); + } +} + +#endif + +// End of code generation (histc.h) diff --git a/cpp/RAT/ifWhileCond.cpp b/cpp/RAT/ifWhileCond.cpp new file mode 100644 index 00000000..d9791160 --- /dev/null +++ b/cpp/RAT/ifWhileCond.cpp @@ -0,0 +1,71 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// ifWhileCond.cpp +// +// Code generation for function 'ifWhileCond' +// + +// Include files +#include "ifWhileCond.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + static boolean_T checkNoNaNs(const ::coder::array &x); + } + } +} + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + static boolean_T checkNoNaNs(const ::coder::array &x) + { + int32_T i; + int32_T k; + boolean_T exitg1; + boolean_T y; + y = true; + i = x.size(0) * x.size(1); + k = 0; + exitg1 = false; + while ((!exitg1) && (k <= i - 1)) { + if (!x[k]) { + y = false; + exitg1 = true; + } else { + k++; + } + } + + return y; + } + + boolean_T ifWhileCond(const ::coder::array &x) + { + boolean_T y; + y = ((x.size(0) != 0) && (x.size(1) != 0)); + if (y) { + y = checkNoNaNs(x); + } + + return y; + } + } + } +} + +// End of code generation (ifWhileCond.cpp) diff --git a/cpp/RAT/ifWhileCond.h b/cpp/RAT/ifWhileCond.h new file mode 100644 index 00000000..597b1ee5 --- /dev/null +++ b/cpp/RAT/ifWhileCond.h @@ -0,0 +1,33 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// ifWhileCond.h +// +// Code generation for function 'ifWhileCond' +// +#ifndef IFWHILECOND_H +#define IFWHILECOND_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + boolean_T ifWhileCond(const ::coder::array &x); + } + } +} + +#endif + +// End of code generation (ifWhileCond.h) diff --git a/cpp/RAT/inEllipsoids.cpp b/cpp/RAT/inEllipsoids.cpp new file mode 100644 index 00000000..68cf5df8 --- /dev/null +++ b/cpp/RAT/inEllipsoids.cpp @@ -0,0 +1,219 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// inEllipsoids.cpp +// +// Code generation for function 'inEllipsoids' +// + +// Include files +#include "inEllipsoids.h" +#include "RATMain_data.h" +#include "diag.h" +#include "eig.h" +#include "rt_nonfinite.h" +#include "sqrt.h" +#include "sum.h" +#include "unsafeSxfun.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + real_T inEllipsoids(const ::coder::array &pnt, const ::coder:: + array &Bs, const ::coder::array + &mus) + { + ::coder::array E; + ::coder::array V; + ::coder::array b_pnt; + ::coder::array c_pnt; + ::coder::array r; + ::coder::array b_Bs; + creal_T varargin_1; + real_T N; + int32_T b_loop_ub; + int32_T i; + int32_T loop_ub; + int32_T ndims; + + // function N = inEllipsoids(pnt, Bs, mus) + // + // This function works out how many of the ellipsoids (defined by the + // bounding matrices Bs and centroids mus) contain the point pnt. + // This number is returned in N. + // + // Bs is a [(Kxndims) x ndims] array, where K=total number of ellipsoids + // and ndims = dimension of the parameter space. + // mus is a [K x ndims] array. + // pnt is a ndims-dimensional vector. + // + // NOTE: in the future it may be quicker to input precalculated eigenvalues + // and eigenvectors into this function rather than the bounding matrices + // + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + N = 0.0; + + // total number of ellipsoids and number of dimensions + ndims = mus.size(1); + + // loop over number of ellipsiods and work out whether it contains the point + i = mus.size(0); + if (i - 1 >= 0) { + loop_ub = Bs.size(1); + b_loop_ub = pnt.size(1); + } + + for (int32_T k{0}; k < i; k++) { + int32_T b_k; + int32_T c_loop_ub; + int32_T i1; + int32_T i2; + + // set the point to have the same origin as the ellipsoid + // extract the bounding matrix + i1 = k * ndims; + i2 = (k + 1) * ndims; + if (i1 + 1 > i2) { + i1 = 0; + i2 = 0; + } + + // get the eigenvalues and eigenvectors of the ellipsoid + c_loop_ub = i2 - i1; + b_Bs.set_size(c_loop_ub, Bs.size(1)); + for (i2 = 0; i2 < loop_ub; i2++) { + for (b_k = 0; b_k < c_loop_ub; b_k++) { + b_Bs[b_k + b_Bs.size(0) * i2] = Bs[(i1 + b_k) + Bs.size(0) * i2]; + } + } + + coder::eig(b_Bs, V, E); + + // V is matrix of eigenvectors (as columns) + // rotate points to be on coordinate axes of the ellipsiod + // scale points so that it's equivalent to having unit hyper-spheroids + // rather than ellipsiods + // get distance to point from centre of hyper-sphere + coder::diag(E, r); + i1 = r.size(0); + for (b_k = 0; b_k < i1; b_k++) { + coder::internal::scalar::d_sqrt(&r[b_k]); + } + + if ((pnt.size(1) == mus.size(1)) && (r.size(0) == V.size(1))) { + real_T pnt_re_tmp; + c_pnt.set_size(1, pnt.size(1)); + for (i1 = 0; i1 < b_loop_ub; i1++) { + c_pnt[i1].re = pnt[i1] - mus[k + mus.size(0) * i1]; + c_pnt[i1].im = 0.0; + } + + c_loop_ub = V.size(1); + b_pnt.set_size(1, V.size(1)); + for (i1 = 0; i1 < c_loop_ub; i1++) { + real_T b_pnt_re_tmp; + real_T c_pnt_re_tmp; + real_T d_pnt_re_tmp; + real_T im; + real_T re; + re = 0.0; + im = 0.0; + b_k = c_pnt.size(1); + for (i2 = 0; i2 < b_k; i2++) { + pnt_re_tmp = c_pnt[i2].re; + d_pnt_re_tmp = V[i2 + V.size(0) * i1].im; + b_pnt_re_tmp = c_pnt[i2].im; + c_pnt_re_tmp = V[i2 + V.size(0) * i1].re; + re += pnt_re_tmp * c_pnt_re_tmp - b_pnt_re_tmp * d_pnt_re_tmp; + im += pnt_re_tmp * d_pnt_re_tmp + b_pnt_re_tmp * c_pnt_re_tmp; + } + + b_pnt_re_tmp = r[i1].re; + c_pnt_re_tmp = -r[i1].im; + if (c_pnt_re_tmp == 0.0) { + if (im == 0.0) { + b_pnt[i1].re = re / b_pnt_re_tmp; + b_pnt[i1].im = 0.0; + } else if (re == 0.0) { + b_pnt[i1].re = 0.0; + b_pnt[i1].im = im / b_pnt_re_tmp; + } else { + b_pnt[i1].re = re / b_pnt_re_tmp; + b_pnt[i1].im = im / b_pnt_re_tmp; + } + } else if (b_pnt_re_tmp == 0.0) { + if (re == 0.0) { + b_pnt[i1].re = im / c_pnt_re_tmp; + b_pnt[i1].im = 0.0; + } else if (im == 0.0) { + b_pnt[i1].re = 0.0; + b_pnt[i1].im = -(re / c_pnt_re_tmp); + } else { + b_pnt[i1].re = im / c_pnt_re_tmp; + b_pnt[i1].im = -(re / c_pnt_re_tmp); + } + } else { + real_T brm; + brm = std::abs(b_pnt_re_tmp); + pnt_re_tmp = std::abs(c_pnt_re_tmp); + if (brm > pnt_re_tmp) { + d_pnt_re_tmp = c_pnt_re_tmp / b_pnt_re_tmp; + pnt_re_tmp = b_pnt_re_tmp + d_pnt_re_tmp * c_pnt_re_tmp; + b_pnt[i1].re = (re + d_pnt_re_tmp * im) / pnt_re_tmp; + b_pnt[i1].im = (im - d_pnt_re_tmp * re) / pnt_re_tmp; + } else if (pnt_re_tmp == brm) { + if (b_pnt_re_tmp > 0.0) { + d_pnt_re_tmp = 0.5; + } else { + d_pnt_re_tmp = -0.5; + } + + if (c_pnt_re_tmp > 0.0) { + pnt_re_tmp = 0.5; + } else { + pnt_re_tmp = -0.5; + } + + b_pnt[i1].re = (re * d_pnt_re_tmp + im * pnt_re_tmp) / brm; + b_pnt[i1].im = (im * d_pnt_re_tmp - re * pnt_re_tmp) / brm; + } else { + d_pnt_re_tmp = b_pnt_re_tmp / c_pnt_re_tmp; + pnt_re_tmp = c_pnt_re_tmp + d_pnt_re_tmp * b_pnt_re_tmp; + b_pnt[i1].re = (d_pnt_re_tmp * re + im) / pnt_re_tmp; + b_pnt[i1].im = (d_pnt_re_tmp * im - re) / pnt_re_tmp; + } + } + } + + b_pnt.set_size(1, b_pnt.size(1)); + c_loop_ub = b_pnt.size(1); + for (i1 = 0; i1 < c_loop_ub; i1++) { + creal_T varargout_1; + varargin_1 = b_pnt[i1]; + varargout_1.re = varargin_1.re * varargin_1.re - varargin_1.im * + varargin_1.im; + pnt_re_tmp = varargin_1.re * varargin_1.im; + varargout_1.im = pnt_re_tmp + pnt_re_tmp; + b_pnt[i1] = varargout_1; + } + } else { + binary_expand_op(b_pnt, pnt, mus, k, V, r); + } + + varargin_1 = coder::sum(b_pnt); + coder::internal::scalar::d_sqrt(&varargin_1); + if (varargin_1.re <= 1.0) { + // values is within the ellipsiod + N++; + } + } + + return N; + } +} + +// End of code generation (inEllipsoids.cpp) diff --git a/cpp/RAT/inEllipsoids.h b/cpp/RAT/inEllipsoids.h new file mode 100644 index 00000000..d8b23ed6 --- /dev/null +++ b/cpp/RAT/inEllipsoids.h @@ -0,0 +1,29 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// inEllipsoids.h +// +// Code generation for function 'inEllipsoids' +// +#ifndef INELLIPSOIDS_H +#define INELLIPSOIDS_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + real_T inEllipsoids(const ::coder::array &pnt, const ::coder:: + array &Bs, const ::coder::array + &mus); +} + +#endif + +// End of code generation (inEllipsoids.h) diff --git a/cpp/RAT/initializeDREAM.cpp b/cpp/RAT/initializeDREAM.cpp new file mode 100644 index 00000000..2f0dfffd --- /dev/null +++ b/cpp/RAT/initializeDREAM.cpp @@ -0,0 +1,419 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// initializeDREAM.cpp +// +// Code generation for function 'initializeDREAM' +// + +// Include files +#include "initializeDREAM.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "boundaryHandling.h" +#include "calcDensity.h" +#include "drawCR.h" +#include "evaluateModel.h" +#include "rand.h" +#include "repmat.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Declarations +namespace RAT +{ + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3, const + struct13_T *in4); + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3, const ::coder:: + array &in4); +} + +// Function Definitions +namespace RAT +{ + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3, const + struct13_T *in4) + { + ::coder::array b_in2; + int32_T i; + int32_T loop_ub; + int32_T stride_0_1; + int32_T stride_1_1; + if (in3.size(1) == 1) { + i = in2.size(1); + } else { + i = in3.size(1); + } + + b_in2.set_size(1, i); + stride_0_1 = (in2.size(1) != 1); + stride_1_1 = (in3.size(1) != 1); + if (in3.size(1) == 1) { + loop_ub = in2.size(1); + } else { + loop_ub = in3.size(1); + } + + for (i = 0; i < loop_ub; i++) { + b_in2[i] = in2[i * stride_0_1] - in3[i * stride_1_1]; + } + + coder::repmat(b_in2, in4->N, in1); + } + + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3, const ::coder:: + array &in4) + { + int32_T aux_0_1; + int32_T aux_1_1; + int32_T aux_2_1; + int32_T i; + int32_T i1; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_0_1; + int32_T stride_1_0; + int32_T stride_1_1; + int32_T stride_2_0; + int32_T stride_2_1; + if (in4.size(0) == 1) { + i = in3.size(0); + } else { + i = in4.size(0); + } + + if (i == 1) { + i = in2.size(0); + } else if (in4.size(0) == 1) { + i = in3.size(0); + } else { + i = in4.size(0); + } + + if (in4.size(1) == 1) { + i1 = in3.size(1); + } else { + i1 = in4.size(1); + } + + if (i1 == 1) { + i1 = in2.size(1); + } else if (in4.size(1) == 1) { + i1 = in3.size(1); + } else { + i1 = in4.size(1); + } + + in1.set_size(i, i1); + stride_0_0 = (in2.size(0) != 1); + stride_0_1 = (in2.size(1) != 1); + stride_1_0 = (in3.size(0) != 1); + stride_1_1 = (in3.size(1) != 1); + stride_2_0 = (in4.size(0) != 1); + stride_2_1 = (in4.size(1) != 1); + aux_0_1 = 0; + aux_1_1 = 0; + aux_2_1 = 0; + if (in4.size(1) == 1) { + i = in3.size(1); + } else { + i = in4.size(1); + } + + if (i == 1) { + loop_ub = in2.size(1); + } else if (in4.size(1) == 1) { + loop_ub = in3.size(1); + } else { + loop_ub = in4.size(1); + } + + for (i = 0; i < loop_ub; i++) { + int32_T b_loop_ub; + int32_T i2; + i1 = in4.size(0); + b_loop_ub = in3.size(0); + if (i1 == 1) { + i2 = b_loop_ub; + } else { + i2 = i1; + } + + if (i2 == 1) { + b_loop_ub = in2.size(0); + } else if (i1 != 1) { + b_loop_ub = i1; + } + + for (i1 = 0; i1 < b_loop_ub; i1++) { + in1[i1 + in1.size(0) * i] = in2[i1 * stride_0_0 + in2.size(0) * aux_0_1] + + in3[i1 * stride_1_0 + in3.size(0) * aux_1_1] * in4[i1 * stride_2_0 + + in4.size(0) * aux_2_1]; + } + + aux_2_1 += stride_2_1; + aux_1_1 += stride_1_1; + aux_0_1 += stride_0_1; + } + } + + void initializeDREAM(const struct13_T *DREAMPar, const ::coder::array &Par_info_min, const ::coder::array + &Par_info_max, const char_T Par_info_boundhandling_data[], + const int32_T Par_info_boundhandling_size[2], ::coder:: + array &chain, struct12_T *output, ::coder:: + array &log_L, const c_struct_T + *ratInputs_problemStruct, const cell_11 + *ratInputs_problemCells, const struct2_T + *ratInputs_controls, const ::coder::array + &ratInputs_priors, ::coder::array &X, ::coder:: + array &fx, ::coder::array &CR, + real_T pCR_data[], int32_T pCR_size[2], real_T lCR_data[], + int32_T lCR_size[2], real_T delta_tot_data[], int32_T + delta_tot_size[2]) + { + ::coder::array b_Par_info_max; + ::coder::array b_X; + ::coder::array r; + ::coder::array r1; + ::coder::array x; + ::coder::array log_L_x; + ::coder::array log_PR_x; + int32_T b_loop_ub; + int32_T i; + int32_T i1; + int32_T input_sizes_idx_1; + int32_T loop_ub; + int8_T b_input_sizes_idx_1; + int8_T sizes_idx_1; + boolean_T empty_non_axis_sizes; + + // Initializes the starting positions of the Markov chains + // Create the initial positions of the chains + // switch Par_info.prior + // + // case {'uniform'} + // Random sampling + coder::b_rand(DREAMPar->N, DREAMPar->d, b_X); + if (Par_info_max.size(1) == Par_info_min.size(1)) { + b_Par_info_max.set_size(1, Par_info_max.size(1)); + loop_ub = Par_info_max.size(1); + for (i = 0; i < loop_ub; i++) { + b_Par_info_max[i] = Par_info_max[i] - Par_info_min[i]; + } + + coder::repmat(b_Par_info_max, DREAMPar->N, r); + } else { + binary_expand_op(r, Par_info_max, Par_info_min, DREAMPar); + } + + coder::repmat(Par_info_min, DREAMPar->N, r1); + + // case {'latin'} + // % Initialize chains with latinHypercubeSampling hypercube sampling + // if isfield(Par_info,'min_initial') && isfield(Par_info,'max_initial') + // [x] = latinHypercubeSampling(Par_info.min_initial,Par_info.max_initial,DREAMPar.N); + // else + // [x] = latinHypercubeSampling(Par_info.min,Par_info.max,DREAMPar.N); + // end + // case {'normal'} + // + // % Initialize chains with (multi)-normal distribution + // [x] = repmat(Par_info.mu,DREAMPar.N,1) + randn(DREAMPar.N,DREAMPar.d) * chol(Par_info.cov); + // + // case {'prior'} + // + // % Create the initial position of each chain by drawing each parameter individually from the prior + // for qq = 1:DREAMPar.d + // for zz = 1:DREAMPar.N + // x(zz,qq) = eval(char(Par_info.prior_marginal(qq))); + // end + // end + // + // otherwise + // + // error('unknown initial sampling method'); + // end + // If specified do boundary handling ( "Bound","Reflect","Fold") + if (b_X.size(0) == 1) { + i = r.size(0); + } else { + i = b_X.size(0); + } + + if (b_X.size(1) == 1) { + i1 = r.size(1); + } else { + i1 = b_X.size(1); + } + + if ((b_X.size(0) == r.size(0)) && (b_X.size(1) == r.size(1)) && (r1.size(0) == + i) && (r1.size(1) == i1)) { + x.set_size(r1.size(0), r1.size(1)); + loop_ub = r1.size(1); + for (i = 0; i < loop_ub; i++) { + b_loop_ub = r1.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + x[i1 + x.size(0) * i] = r1[i1 + r1.size(0) * i] + b_X[i1 + b_X.size(0) + * i] * r[i1 + r.size(0) * i]; + } + } + } else { + binary_expand_op(x, r1, b_X, r); + } + + boundaryHandling(x, Par_info_min, Par_info_max, Par_info_boundhandling_data, + Par_info_boundhandling_size); + + // Now evaluate the model ( = pdf ) and return fx + evaluateModel(x, DREAMPar, ratInputs_problemStruct, ratInputs_problemCells, + ratInputs_controls, fx); + + // Calculate the log-likelihood and log-prior of x (fx) + calcDensity(x, fx, DREAMPar, ratInputs_problemStruct->fitLimits, + ratInputs_priors, log_L_x, log_PR_x); + + // Define starting x values, corresponding density, log densty and simulations (Xfx) + if ((x.size(0) != 0) && (x.size(1) != 0)) { + b_loop_ub = x.size(0); + } else if (log_PR_x.size(0) != 0) { + b_loop_ub = log_PR_x.size(0); + } else if (log_L_x.size(0) != 0) { + b_loop_ub = log_L_x.size(0); + } else { + b_loop_ub = x.size(0); + } + + empty_non_axis_sizes = (b_loop_ub == 0); + if (empty_non_axis_sizes || ((x.size(0) != 0) && (x.size(1) != 0))) { + input_sizes_idx_1 = x.size(1); + } else { + input_sizes_idx_1 = 0; + } + + if (empty_non_axis_sizes || (log_PR_x.size(0) != 0)) { + b_input_sizes_idx_1 = 1; + } else { + b_input_sizes_idx_1 = 0; + } + + if (empty_non_axis_sizes || (log_L_x.size(0) != 0)) { + sizes_idx_1 = 1; + } else { + sizes_idx_1 = 0; + } + + X.set_size(b_loop_ub, (input_sizes_idx_1 + b_input_sizes_idx_1) + + sizes_idx_1); + for (i = 0; i < input_sizes_idx_1; i++) { + for (i1 = 0; i1 < b_loop_ub; i1++) { + X[i1 + X.size(0) * i] = x[i1 + b_loop_ub * i]; + } + } + + loop_ub = b_input_sizes_idx_1; + for (i = 0; i < loop_ub; i++) { + for (i1 = 0; i1 < b_loop_ub; i1++) { + X[i1 + X.size(0) * input_sizes_idx_1] = log_PR_x[i1]; + } + } + + loop_ub = sizes_idx_1; + for (i = 0; i < loop_ub; i++) { + for (i1 = 0; i1 < b_loop_ub; i1++) { + X[i1 + X.size(0) * (input_sizes_idx_1 + b_input_sizes_idx_1)] = + log_L_x[i1]; + } + } + + // Store the model simulations (if appropriate) + // storeDREAMResults(DREAMPar,fx,Meas_info,'w+'); + // Set the first point of each of the DREAMPar.N chain equal to the initial X values + b_X.set_size(X.size(1), X.size(0)); + loop_ub = X.size(0); + for (i = 0; i < loop_ub; i++) { + b_loop_ub = X.size(1); + for (i1 = 0; i1 < b_loop_ub; i1++) { + b_X[i1 + b_X.size(0) * i] = X[i + X.size(0) * i1]; + } + } + + b_loop_ub = static_cast(DREAMPar->d + 2.0); + loop_ub = static_cast(DREAMPar->N); + for (i = 0; i < loop_ub; i++) { + for (i1 = 0; i1 < b_loop_ub; i1++) { + chain[chain.size(0) * i1 + chain.size(0) * chain.size(1) * i] = b_X[i1 + + b_loop_ub * i]; + } + } + + int32_T iv[2]; + + // Define selection probability of each crossover + b_Par_info_max.set_size(1, 3); + pCR_size[0] = 1; + pCR_size[1] = 3; + b_Par_info_max[0] = 0.33333333333333331; + pCR_data[0] = 0.33333333333333331; + b_Par_info_max[1] = 0.33333333333333331; + pCR_data[1] = 0.33333333333333331; + b_Par_info_max[2] = 0.33333333333333331; + pCR_data[2] = 0.33333333333333331; + + // Generate the actula CR value, lCR and delta_tot + iv[0] = (*(int32_T (*)[2])b_Par_info_max.size())[0]; + iv[1] = (*(int32_T (*)[2])b_Par_info_max.size())[1]; + drawCR(DREAMPar, (const real_T *)b_Par_info_max.data(), iv, CR); + + // coder.varsize('CR',[100 1e4],[1 1]); + lCR_size[0] = 1; + lCR_size[1] = 3; + delta_tot_size[0] = 1; + delta_tot_size[1] = 3; + lCR_data[0] = 0.0; + delta_tot_data[0] = 0.0; + lCR_data[1] = 0.0; + delta_tot_data[1] = 0.0; + lCR_data[2] = 0.0; + delta_tot_data[2] = 0.0; + + // Save pCR values in memory + output->CR[0] = DREAMPar->N; + for (i = 0; i < 3; i++) { + output->CR[output->CR.size(0) * (i + 1)] = 0.33333333333333331; + } + + // Save history log density of individual chains + log_L[0] = DREAMPar->N; + loop_ub = log_L_x.size(0); + for (i = 0; i < loop_ub; i++) { + log_L[log_L.size(0) * (i + 1)] = log_L_x[i]; + } + + // Compute the R-statistic + // Calculates the R-statistic convergence diagnostic + // ---------------------------------------------------- + // For more information please refer to: Gelman, A. and D.R. Rubin, 1992. + // Inference from Iterative Simulation Using Multiple chain, + // Statistical Science, Volume 7, Issue 4, 457-472. + // + // Written by Jasper A. Vrugt + // Los Alamos, August 2007 + // ---------------------------------------------------- + // Compute the dimensions of chain + // Set the R-statistic to a large value + output->R_stat[0] = DREAMPar->N; + loop_ub = static_cast(DREAMPar->d); + for (i = 0; i < loop_ub; i++) { + output->R_stat[output->R_stat.size(0) * (i + 1)] = rtNaN; + } + } +} + +// End of code generation (initializeDREAM.cpp) diff --git a/cpp/RAT/initializeDREAM.h b/cpp/RAT/initializeDREAM.h new file mode 100644 index 00000000..4a6354d4 --- /dev/null +++ b/cpp/RAT/initializeDREAM.h @@ -0,0 +1,50 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// initializeDREAM.h +// +// Code generation for function 'initializeDREAM' +// +#ifndef INITIALIZEDREAM_H +#define INITIALIZEDREAM_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct struct13_T; + struct struct12_T; + struct c_struct_T; + struct cell_11; + struct struct2_T; +} + +// Function Declarations +namespace RAT +{ + void initializeDREAM(const struct13_T *DREAMPar, const ::coder::array &Par_info_min, const ::coder::array + &Par_info_max, const char_T Par_info_boundhandling_data[], + const int32_T Par_info_boundhandling_size[2], ::coder:: + array &chain, struct12_T *output, ::coder:: + array &log_L, const c_struct_T + *ratInputs_problemStruct, const cell_11 + *ratInputs_problemCells, const struct2_T + *ratInputs_controls, const ::coder::array + &ratInputs_priors, ::coder::array &X, ::coder:: + array &fx, ::coder::array &CR, + real_T pCR_data[], int32_T pCR_size[2], real_T lCR_data[], + int32_T lCR_size[2], real_T delta_tot_data[], int32_T + delta_tot_size[2]); +} + +#endif + +// End of code generation (initializeDREAM.h) diff --git a/cpp/RAT/interp1.cpp b/cpp/RAT/interp1.cpp new file mode 100644 index 00000000..d3eb7e16 --- /dev/null +++ b/cpp/RAT/interp1.cpp @@ -0,0 +1,355 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// interp1.cpp +// +// Code generation for function 'interp1' +// + +// Include files +#include "interp1.h" +#include "bsearch.h" +#include "flip.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include "omp.h" +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + static void interp1Linear(const ::coder::array &y, int32_T + nyrows, const ::coder::array &xi, ::coder::array + &yi, const ::coder::array &varargin_1); + static void interp1Linear(const ::coder::array &y, const ::coder:: + array &xi, ::coder::array &yi, const ::coder:: + array &varargin_1); + static void interp1Linear(const ::coder::array &y, const ::coder:: + array &xi, ::coder::array &yi, const ::coder:: + array &varargin_1); + } +} + +// Function Definitions +namespace RAT +{ + namespace coder + { + static void interp1Linear(const ::coder::array &y, int32_T + nyrows, const ::coder::array &xi, ::coder::array + &yi, const ::coder::array &varargin_1) + { + real_T d; + real_T maxx; + real_T minx; + real_T penx; + real_T r; + int32_T n; + int32_T ub_loop; + minx = varargin_1[0]; + penx = varargin_1[varargin_1.size(0) - 2]; + maxx = varargin_1[varargin_1.size(0) - 1]; + ub_loop = xi.size(1) - 1; + +#pragma omp parallel for \ + num_threads(omp_get_max_threads()) \ + private(d,r,n) + + for (int32_T k = 0; k <= ub_loop; k++) { + d = xi[k]; + if (std::isnan(d)) { + yi[k] = rtNaN; + } else if (d > maxx) { + if (nyrows > 1) { + r = y[nyrows - 1]; + yi[k] = r + (d - maxx) / (maxx - penx) * (r - y[nyrows - 2]); + } + } else if (d < minx) { + yi[k] = y[0] + (d - minx) / (varargin_1[1] - minx) * (y[1] - y[0]); + } else { + n = internal::b_bsearch(varargin_1, d) - 1; + r = (d - varargin_1[n]) / (varargin_1[n + 1] - varargin_1[n]); + if (r == 0.0) { + yi[k] = y[n]; + } else if (r == 1.0) { + yi[k] = y[n + 1]; + } else { + d = y[n + 1]; + if (y[n] == d) { + yi[k] = y[n]; + } else { + yi[k] = (1.0 - r) * y[n] + r * d; + } + } + } + } + } + + static void interp1Linear(const ::coder::array &y, const ::coder:: + array &xi, ::coder::array &yi, const ::coder:: + array &varargin_1) + { + real_T d; + real_T maxx; + real_T minx; + real_T r; + int32_T n; + int32_T ub_loop; + minx = varargin_1[0]; + maxx = varargin_1[varargin_1.size(0) - 1]; + ub_loop = xi.size(1) - 1; + +#pragma omp parallel for \ + num_threads(omp_get_max_threads()) \ + private(d,n,r) + + for (int32_T k = 0; k <= ub_loop; k++) { + d = xi[k]; + if (std::isnan(d)) { + yi[k] = rtNaN; + } else if ((!(d > maxx)) && (!(d < minx))) { + n = internal::b_bsearch(varargin_1, d) - 1; + r = (d - varargin_1[n]) / (varargin_1[n + 1] - varargin_1[n]); + if (r == 0.0) { + yi[k] = y[n]; + } else if (r == 1.0) { + yi[k] = y[n + 1]; + } else { + d = y[n + 1]; + if (y[n] == d) { + yi[k] = y[n]; + } else { + yi[k] = (1.0 - r) * y[n] + r * d; + } + } + } + } + } + + static void interp1Linear(const ::coder::array &y, const ::coder:: + array &xi, ::coder::array &yi, const ::coder:: + array &varargin_1) + { + real_T maxx; + real_T minx; + real_T r; + int32_T n; + int32_T ub_loop; + minx = varargin_1[0]; + maxx = varargin_1[varargin_1.size(0) - 1]; + ub_loop = xi.size(0) - 1; + +#pragma omp parallel for \ + num_threads(omp_get_max_threads()) \ + private(n,r) + + for (int32_T k = 0; k <= ub_loop; k++) { + if (std::isnan(xi[k])) { + yi[k] = rtNaN; + } else if ((!(xi[k] > maxx)) && (!(xi[k] < minx))) { + n = internal::b_bsearch(varargin_1, xi[k]) - 1; + r = (xi[k] - varargin_1[n]) / (varargin_1[n + 1] - varargin_1[n]); + if (r == 0.0) { + yi[k] = y[n]; + } else if (r == 1.0) { + yi[k] = y[n + 1]; + } else if (y[n] == y[n + 1]) { + yi[k] = y[n]; + } else { + yi[k] = (1.0 - r) * y[n] + r * y[n + 1]; + } + } + } + } + + void b_interp1(const ::coder::array &varargin_1, const ::coder:: + array &varargin_2, const ::coder::array &varargin_3, ::coder::array &Vq) + { + ::coder::array x; + ::coder::array y; + int32_T i; + int32_T k; + int32_T nx; + boolean_T b; + y.set_size(varargin_2.size(0)); + k = varargin_2.size(0); + for (i = 0; i < k; i++) { + y[i] = varargin_2[i]; + } + + x.set_size(varargin_1.size(0)); + k = varargin_1.size(0); + for (i = 0; i < k; i++) { + x[i] = varargin_1[i]; + } + + nx = varargin_1.size(0) - 1; + Vq.set_size(1, static_cast(static_cast(varargin_3.size(1)))); + k = static_cast(varargin_3.size(1)); + for (i = 0; i < k; i++) { + Vq[i] = rtNaN; + } + + b = (varargin_3.size(1) == 0); + if (!b) { + k = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (k <= nx) { + if (std::isnan(varargin_1[k])) { + exitg1 = 1; + } else { + k++; + } + } else { + if (varargin_1[1] < varargin_1[0]) { + i = (nx + 1) >> 1; + for (int32_T b_j1{0}; b_j1 < i; b_j1++) { + real_T xtmp; + xtmp = x[b_j1]; + k = nx - b_j1; + x[b_j1] = x[k]; + x[k] = xtmp; + } + + flip(y); + } + + interp1Linear(y, varargin_3, Vq, x); + exitg1 = 1; + } + } while (exitg1 == 0); + } + } + + void interp1(const ::coder::array &varargin_1, const ::coder:: + array &varargin_2, const ::coder::array + &varargin_3, ::coder::array &Vq) + { + ::coder::array x; + ::coder::array y; + int32_T i; + int32_T k; + int32_T nx; + boolean_T b; + y.set_size(varargin_2.size(0)); + k = varargin_2.size(0); + for (i = 0; i < k; i++) { + y[i] = varargin_2[i]; + } + + x.set_size(varargin_1.size(0)); + k = varargin_1.size(0); + for (i = 0; i < k; i++) { + x[i] = varargin_1[i]; + } + + nx = varargin_1.size(0) - 1; + Vq.set_size(1, static_cast(static_cast(varargin_3.size(1)))); + k = static_cast(varargin_3.size(1)); + for (i = 0; i < k; i++) { + Vq[i] = 0.0; + } + + b = (varargin_3.size(1) == 0); + if (!b) { + k = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (k <= nx) { + if (std::isnan(varargin_1[k])) { + exitg1 = 1; + } else { + k++; + } + } else { + if (varargin_1[1] < varargin_1[0]) { + i = (nx + 1) >> 1; + for (int32_T b_j1{0}; b_j1 < i; b_j1++) { + real_T xtmp; + xtmp = x[b_j1]; + k = nx - b_j1; + x[b_j1] = x[k]; + x[k] = xtmp; + } + + flip(y); + } + + interp1Linear(y, varargin_2.size(0), varargin_3, Vq, x); + exitg1 = 1; + } + } while (exitg1 == 0); + } + } + + void interp1(const ::coder::array &varargin_1, const ::coder:: + array &varargin_2, const ::coder::array + &varargin_3, ::coder::array &Vq) + { + ::coder::array x; + ::coder::array y; + int32_T i; + int32_T k; + int32_T nx; + y.set_size(varargin_2.size(0)); + k = varargin_2.size(0); + for (i = 0; i < k; i++) { + y[i] = varargin_2[i]; + } + + x.set_size(varargin_1.size(0)); + k = varargin_1.size(0); + for (i = 0; i < k; i++) { + x[i] = varargin_1[i]; + } + + nx = varargin_1.size(0) - 1; + Vq.set_size(varargin_3.size(0)); + k = varargin_3.size(0); + for (i = 0; i < k; i++) { + Vq[i] = rtNaN; + } + + if (varargin_3.size(0) != 0) { + k = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (k <= nx) { + if (std::isnan(varargin_1[k])) { + exitg1 = 1; + } else { + k++; + } + } else { + if (varargin_1[1] < varargin_1[0]) { + i = (nx + 1) >> 1; + for (int32_T b_j1{0}; b_j1 < i; b_j1++) { + real_T xtmp; + xtmp = x[b_j1]; + k = nx - b_j1; + x[b_j1] = x[k]; + x[k] = xtmp; + } + + flip(y); + } + + interp1Linear(y, varargin_3, Vq, x); + exitg1 = 1; + } + } while (exitg1 == 0); + } + } + } +} + +// End of code generation (interp1.cpp) diff --git a/cpp/RAT/interp1.h b/cpp/RAT/interp1.h new file mode 100644 index 00000000..4c367cea --- /dev/null +++ b/cpp/RAT/interp1.h @@ -0,0 +1,38 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// interp1.h +// +// Code generation for function 'interp1' +// +#ifndef INTERP1_H +#define INTERP1_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void b_interp1(const ::coder::array &varargin_1, const ::coder:: + array &varargin_2, const ::coder::array &varargin_3, ::coder::array &Vq); + void interp1(const ::coder::array &varargin_1, const ::coder:: + array &varargin_2, const ::coder::array + &varargin_3, ::coder::array &Vq); + void interp1(const ::coder::array &varargin_1, const ::coder:: + array &varargin_2, const ::coder::array + &varargin_3, ::coder::array &Vq); + } +} + +#endif + +// End of code generation (interp1.h) diff --git a/cpp/RAT/ishermitian.cpp b/cpp/RAT/ishermitian.cpp new file mode 100644 index 00000000..ddbd31cf --- /dev/null +++ b/cpp/RAT/ishermitian.cpp @@ -0,0 +1,97 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// ishermitian.cpp +// +// Code generation for function 'ishermitian' +// + +// Include files +#include "ishermitian.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + boolean_T b_ishermitian(const ::coder::array &A) + { + boolean_T p; + p = (A.size(0) == A.size(1)); + if (p) { + int32_T j; + boolean_T exitg2; + j = 0; + exitg2 = false; + while ((!exitg2) && (j <= A.size(1) - 1)) { + int32_T exitg1; + int32_T i; + i = 0; + do { + exitg1 = 0; + if (i <= j) { + if (!(A[i + A.size(0) * j] == -A[j + A.size(0) * i])) { + p = false; + exitg1 = 1; + } else { + i++; + } + } else { + j++; + exitg1 = 2; + } + } while (exitg1 == 0); + + if (exitg1 == 1) { + exitg2 = true; + } + } + } + + return p; + } + + boolean_T ishermitian(const ::coder::array &A) + { + boolean_T p; + p = (A.size(0) == A.size(1)); + if (p) { + int32_T j; + boolean_T exitg2; + j = 0; + exitg2 = false; + while ((!exitg2) && (j <= A.size(1) - 1)) { + int32_T exitg1; + int32_T i; + i = 0; + do { + exitg1 = 0; + if (i <= j) { + if (!(A[i + A.size(0) * j] == A[j + A.size(0) * i])) { + p = false; + exitg1 = 1; + } else { + i++; + } + } else { + j++; + exitg1 = 2; + } + } while (exitg1 == 0); + + if (exitg1 == 1) { + exitg2 = true; + } + } + } + + return p; + } + } +} + +// End of code generation (ishermitian.cpp) diff --git a/cpp/RAT/ishermitian.h b/cpp/RAT/ishermitian.h new file mode 100644 index 00000000..dd2c94ac --- /dev/null +++ b/cpp/RAT/ishermitian.h @@ -0,0 +1,31 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// ishermitian.h +// +// Code generation for function 'ishermitian' +// +#ifndef ISHERMITIAN_H +#define ISHERMITIAN_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + boolean_T b_ishermitian(const ::coder::array &A); + boolean_T ishermitian(const ::coder::array &A); + } +} + +#endif + +// End of code generation (ishermitian.h) diff --git a/cpp/RAT/isrow.cpp b/cpp/RAT/isrow.cpp new file mode 100644 index 00000000..8b3cf3f5 --- /dev/null +++ b/cpp/RAT/isrow.cpp @@ -0,0 +1,28 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// isrow.cpp +// +// Code generation for function 'isrow' +// + +// Include files +#include "isrow.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + boolean_T isrow(const ::coder::array &x) + { + return x.size(0) == 1; + } + } +} + +// End of code generation (isrow.cpp) diff --git a/cpp/RAT/isrow.h b/cpp/RAT/isrow.h new file mode 100644 index 00000000..52f3a6cf --- /dev/null +++ b/cpp/RAT/isrow.h @@ -0,0 +1,30 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// isrow.h +// +// Code generation for function 'isrow' +// +#ifndef ISROW_H +#define ISROW_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + boolean_T isrow(const ::coder::array &x); + } +} + +#endif + +// End of code generation (isrow.h) diff --git a/cpp/RAT/ixamax.cpp b/cpp/RAT/ixamax.cpp new file mode 100644 index 00000000..07d2c047 --- /dev/null +++ b/cpp/RAT/ixamax.cpp @@ -0,0 +1,80 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// ixamax.cpp +// +// Code generation for function 'ixamax' +// + +// Include files +#include "ixamax.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace blas + { + int32_T ixamax(int32_T n, const ::coder::array &x, int32_T + ix0) + { + int32_T idxmax; + if (n < 1) { + idxmax = 0; + } else { + idxmax = 1; + if (n > 1) { + real_T smax; + smax = std::abs(x[ix0 - 1]); + for (int32_T k{2}; k <= n; k++) { + real_T s; + s = std::abs(x[(ix0 + k) - 2]); + if (s > smax) { + idxmax = k; + smax = s; + } + } + } + } + + return idxmax; + } + + int32_T ixamax(int32_T n, const ::coder::array &x, int32_T + ix0) + { + int32_T idxmax; + if (n < 1) { + idxmax = 0; + } else { + idxmax = 1; + if (n > 1) { + real_T smax; + smax = std::abs(x[ix0 - 1]); + for (int32_T k{2}; k <= n; k++) { + real_T s; + s = std::abs(x[(ix0 + k) - 2]); + if (s > smax) { + idxmax = k; + smax = s; + } + } + } + } + + return idxmax; + } + } + } + } +} + +// End of code generation (ixamax.cpp) diff --git a/cpp/RAT/ixamax.h b/cpp/RAT/ixamax.h new file mode 100644 index 00000000..7a005d91 --- /dev/null +++ b/cpp/RAT/ixamax.h @@ -0,0 +1,39 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// ixamax.h +// +// Code generation for function 'ixamax' +// +#ifndef IXAMAX_H +#define IXAMAX_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace blas + { + int32_T ixamax(int32_T n, const ::coder::array &x, int32_T + ix0); + int32_T ixamax(int32_T n, const ::coder::array &x, int32_T + ix0); + } + } + } +} + +#endif + +// End of code generation (ixamax.h) diff --git a/cpp/RAT/ixfun.cpp b/cpp/RAT/ixfun.cpp new file mode 100644 index 00000000..3a8b6725 --- /dev/null +++ b/cpp/RAT/ixfun.cpp @@ -0,0 +1,72 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// ixfun.cpp +// +// Code generation for function 'ixfun' +// + +// Include files +#include "ixfun.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + void expand_max(const ::coder::array &a, const ::coder::array< + real_T, 1U> &b, ::coder::array &c) + { + int32_T csz_idx_0; + int32_T k; + int32_T u0; + u0 = a.size(0); + k = b.size(0); + if (u0 <= k) { + k = u0; + } + + if (b.size(0) == 1) { + csz_idx_0 = a.size(0); + } else if (a.size(0) == 1) { + csz_idx_0 = b.size(0); + } else { + csz_idx_0 = k; + } + + u0 = a.size(0); + k = b.size(0); + if (u0 <= k) { + k = u0; + } + + if (b.size(0) == 1) { + k = a.size(0); + } else if (a.size(0) == 1) { + k = b.size(0); + } + + c.set_size(k); + if (csz_idx_0 != 0) { + boolean_T b1; + boolean_T b_b; + b_b = (a.size(0) != 1); + b1 = (b.size(0) != 1); + u0 = csz_idx_0 - 1; + for (k = 0; k <= u0; k++) { + c[k] = std::fmax(a[b_b * k], b[b1 * k]); + } + } + } + } + } +} + +// End of code generation (ixfun.cpp) diff --git a/cpp/RAT/ixfun.h b/cpp/RAT/ixfun.h new file mode 100644 index 00000000..3fc94c07 --- /dev/null +++ b/cpp/RAT/ixfun.h @@ -0,0 +1,34 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// ixfun.h +// +// Code generation for function 'ixfun' +// +#ifndef IXFUN_H +#define IXFUN_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + void expand_max(const ::coder::array &a, const ::coder::array< + real_T, 1U> &b, ::coder::array &c); + } + } +} + +#endif + +// End of code generation (ixfun.h) diff --git a/cpp/RAT/kmeans.cpp b/cpp/RAT/kmeans.cpp new file mode 100644 index 00000000..a92081f5 --- /dev/null +++ b/cpp/RAT/kmeans.cpp @@ -0,0 +1,316 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// kmeans.cpp +// +// Code generation for function 'kmeans' +// + +// Include files +#include "kmeans.h" +#include "find.h" +#include "mean.h" +#include "minOrMax.h" +#include "norm.h" +#include "rand.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Declarations +namespace RAT +{ + static real_T binary_expand_op(const ::coder::array &in1, int32_T + in2, const ::coder::array &in3, int32_T in4); + static void binary_expand_op(::coder::array &in1, const int32_T + in2_data[], real_T in3, const ::coder::array &in4, int32_T in5); + static real_T binary_expand_op(const ::coder::array &in1, int32_T + in2, const ::coder::array &in3); +} + +// Function Definitions +namespace RAT +{ + static real_T binary_expand_op(const ::coder::array &in1, int32_T + in2, const ::coder::array &in3, int32_T in4) + { + ::coder::array b_in1; + int32_T i; + int32_T loop_ub; + int32_T stride_0_1; + int32_T stride_1_1; + if (in3.size(1) == 1) { + i = in1.size(1); + } else { + i = in3.size(1); + } + + b_in1.set_size(1, i); + stride_0_1 = (in1.size(1) != 1); + stride_1_1 = (in3.size(1) != 1); + if (in3.size(1) == 1) { + loop_ub = in1.size(1); + } else { + loop_ub = in3.size(1); + } + + for (i = 0; i < loop_ub; i++) { + b_in1[i] = in1[in2 + in1.size(0) * (i * stride_0_1)] - in3[in4 + 2 * (i * + stride_1_1)]; + } + + return coder::c_norm(b_in1); + } + + static void binary_expand_op(::coder::array &in1, const int32_T + in2_data[], real_T in3, const ::coder::array &in4, int32_T in5) + { + ::coder::array b_in1; + int32_T i; + int32_T in2_tmp; + int32_T loop_ub; + int32_T stride_0_1; + int32_T stride_1_1; + in2_tmp = in2_data[static_cast(in3) - 1]; + if (in4.size(1) == 1) { + i = in1.size(1); + } else { + i = in4.size(1); + } + + b_in1.set_size(1, i); + stride_0_1 = (in1.size(1) != 1); + stride_1_1 = (in4.size(1) != 1); + if (in4.size(1) == 1) { + loop_ub = in1.size(1); + } else { + loop_ub = in4.size(1); + } + + for (i = 0; i < loop_ub; i++) { + b_in1[i] = in1[(in2_tmp + 2 * (i * stride_0_1)) - 1] + in4[in5 + in4.size + (0) * (i * stride_1_1)]; + } + + loop_ub = b_in1.size(1); + for (i = 0; i < loop_ub; i++) { + in1[(in2_tmp + 2 * i) - 1] = b_in1[i]; + } + } + + static real_T binary_expand_op(const ::coder::array &in1, int32_T + in2, const ::coder::array &in3) + { + ::coder::array b_in1; + int32_T i; + int32_T loop_ub; + int32_T stride_0_1; + int32_T stride_1_1; + if (in3.size(1) == 1) { + i = in1.size(1); + } else { + i = in3.size(1); + } + + b_in1.set_size(1, i); + stride_0_1 = (in1.size(1) != 1); + stride_1_1 = (in3.size(1) != 1); + if (in3.size(1) == 1) { + loop_ub = in1.size(1); + } else { + loop_ub = in3.size(1); + } + + for (i = 0; i < loop_ub; i++) { + b_in1[i] = in1[in2 + 2 * (i * stride_0_1)] - in3[in2 + 2 * (i * stride_1_1)]; + } + + return coder::c_norm(b_in1); + } + + void kmeans(const ::coder::array &X, ::coder::array + &means, real_T Nmeans[2]) + { + ::coder::array b_X; + ::coder::array b_class; + ::coder::array c_X; + real_T cmp; + int32_T index_min_data[2]; + int32_T b_loop_ub; + int32_T i; + int32_T i1; + int32_T index_min_tmp; + int32_T loop_ub; + + // Finds K prototypes representing the samples in data matrix X, + // where each row of X represents a sample. + // Iterates until maximum norm difference between + // prototypes found in successive iterations is < maxerr + // + // This script uses square Euclidean distance, + // but can be easily modified to use other metrics + // + // Output arguments + // means: matrix with each row a cluster prototype + // Nmeans: Number of samples in each cluster + // membership: Assigned class for each sample + // + // Example: + // X = [randn(100,1) ; 2+randn(100,1)]; + // K = 2; + // [means Nmeans] = kmeans(X,K,0) + // + // Mauricio Martinez-Garcia, 2003, 2007, 2016 + Nmeans[0] = 0.0; + Nmeans[1] = 0.0; + + // coder.varsize('Nclass'); + // coder.varsize('class'); + means.set_size(2, X.size(1)); + loop_ub = X.size(1); + for (i = 0; i < loop_ub; i++) { + means[2 * i] = 0.0; + means[2 * i + 1] = 0.0; + } + + // Initial prototype assignment (arbitrary) + loop_ub = X.size(1); + for (i = 0; i < loop_ub; i++) { + means[2 * i] = X[X.size(0) * i]; + } + + if (X.size(0) < 2) { + i = 0; + i1 = 0; + } else { + i = 1; + i1 = X.size(0); + } + + loop_ub = i1 - i; + b_X.set_size(loop_ub, X.size(1)); + b_loop_ub = X.size(1); + for (i1 = 0; i1 < b_loop_ub; i1++) { + for (index_min_tmp = 0; index_min_tmp < loop_ub; index_min_tmp++) { + b_X[index_min_tmp + b_X.size(0) * i1] = X[(i + index_min_tmp) + X.size(0) + * i1]; + } + } + + coder::mean(b_X, c_X); + loop_ub = c_X.size(1); + for (i = 0; i < loop_ub; i++) { + means[2 * i + 1] = c_X[i]; + } + + loop_ub = X.size(1); + i = X.size(0); + cmp = 1.0; + while (cmp > 0.0) { + // Sums (class) and data counters (Nclass) initialization + b_class.set_size(2, X.size(1)); + for (i1 = 0; i1 < loop_ub; i1++) { + b_class[2 * i1] = 0.0; + b_class[2 * i1 + 1] = 0.0; + } + + Nmeans[0] = 0.0; + Nmeans[1] = 0.0; + + // Groups each elements to the nearest prototype + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T dist[2]; + real_T a; + b_loop_ub = X.size(1); + for (int32_T j{0}; j < 2; j++) { + // Euclidean distance from data to each prototype + if (X.size(1) == means.size(1)) { + c_X.set_size(1, X.size(1)); + for (i1 = 0; i1 < b_loop_ub; i1++) { + c_X[i1] = X[b_i + X.size(0) * i1] - means[j + 2 * i1]; + } + + a = coder::c_norm(c_X); + } else { + a = binary_expand_op(X, b_i, means, j); + } + + dist[j] = a * a; + } + + int32_T index_min_size[2]; + boolean_T b_dist[2]; + + // Find indices of minimum distance + a = coder::internal::minimum(dist); + b_dist[0] = !(dist[0] - a != 0.0); + b_dist[1] = !(dist[1] - a != 0.0); + coder::b_eml_find(b_dist, index_min_data, index_min_size); + + // If there are multiple min distances, decide randomly + a = static_cast(index_min_size[1]) * coder::b_rand(); + a = std::ceil(a); + b_loop_ub = b_class.size(1); + if (b_class.size(1) == X.size(1)) { + index_min_tmp = index_min_data[static_cast(a) - 1]; + c_X.set_size(1, b_class.size(1)); + for (i1 = 0; i1 < b_loop_ub; i1++) { + c_X[i1] = b_class[(index_min_tmp + 2 * i1) - 1] + X[b_i + X.size(0) * + i1]; + } + + b_loop_ub = c_X.size(1); + for (i1 = 0; i1 < b_loop_ub; i1++) { + b_class[(index_min_tmp + 2 * i1) - 1] = c_X[i1]; + } + } else { + binary_expand_op(b_class, index_min_data, a, X, b_i); + } + + index_min_tmp = index_min_data[static_cast(a) - 1] - 1; + Nmeans[index_min_tmp]++; + } + + for (int32_T b_i{0}; b_i < 2; b_i++) { + b_loop_ub = b_class.size(1); + c_X.set_size(1, b_class.size(1)); + for (i1 = 0; i1 < b_loop_ub; i1++) { + c_X[i1] = b_class[b_i + 2 * i1] / Nmeans[b_i]; + } + + b_loop_ub = c_X.size(1); + for (i1 = 0; i1 < b_loop_ub; i1++) { + b_class[b_i + 2 * i1] = c_X[i1]; + } + } + + // Compare results with previous iteration + cmp = 0.0; + b_loop_ub = b_class.size(1); + for (int32_T b_i{0}; b_i < 2; b_i++) { + if (b_class.size(1) == means.size(1)) { + c_X.set_size(1, b_class.size(1)); + for (i1 = 0; i1 < b_loop_ub; i1++) { + c_X[i1] = b_class[b_i + 2 * i1] - means[b_i + 2 * i1]; + } + + cmp = coder::c_norm(c_X); + } else { + cmp = binary_expand_op(b_class, b_i, means); + } + } + + // Prototype update + means.set_size(2, b_class.size(1)); + b_loop_ub = b_class.size(1); + for (i1 = 0; i1 < b_loop_ub; i1++) { + means[2 * i1] = b_class[2 * i1]; + means[2 * i1 + 1] = b_class[2 * i1 + 1]; + } + } + } +} + +// End of code generation (kmeans.cpp) diff --git a/cpp/RAT/kmeans.h b/cpp/RAT/kmeans.h new file mode 100644 index 00000000..6ea19ffb --- /dev/null +++ b/cpp/RAT/kmeans.h @@ -0,0 +1,28 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// kmeans.h +// +// Code generation for function 'kmeans' +// +#ifndef KMEANS_H +#define KMEANS_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void kmeans(const ::coder::array &X, ::coder::array + &means, real_T Nmeans[2]); +} + +#endif + +// End of code generation (kmeans.h) diff --git a/cpp/RAT/leftWin.cpp b/cpp/RAT/leftWin.cpp new file mode 100644 index 00000000..221543e4 --- /dev/null +++ b/cpp/RAT/leftWin.cpp @@ -0,0 +1,51 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// leftWin.cpp +// +// Code generation for function 'leftWin' +// + +// Include files +#include "leftWin.h" +#include "rt_nonfinite.h" + +// Function Definitions +namespace RAT +{ + real_T leftWin(real_T S_x_I_no, real_T S_x_FVr_oa, real_T S_y_FVr_oa) + { + real_T I_z; + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // Function: I_z = left_win(S_x,S_y) + // Author: Rainer Storn + // Description: left_win(S_x,S_y) takes structures S_x and S_y as an argument. + // The function returns 1 if the left structure of the input structures, + // i.e. S_x, wins. If the right structure, S_y, wins, the result is 0. + // Parameters: S_x.I_nc (I) Number of constraints (must be the same for x and y). + // S_x.I_no (I) Number of objectives (must be the same for x and y). + // S_x.FVr_ca (I) Constraint array containing the constraint violation values. + // If the value is 0 the constraint is met. If it is > 0 it is + // still violated. + // S_x.FVr_oa (I) Objective array containing cost values which are supposed to be + // minimized. + // Return value: I_z (O) If S_x wins over S_y then I_z=1 else I_z=0. + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + I_z = 1.0; + + // start with I_z=1 + // ----deal with the constraints first. If constraints are not met------ + // ----S_x can't win.--------------------------------------------------- + if ((S_x_I_no > 0.0) && (S_x_FVr_oa > S_y_FVr_oa)) { + // if just one objective of S_x is less + I_z = 0.0; + } + + return I_z; + } +} + +// End of code generation (leftWin.cpp) diff --git a/cpp/RAT/leftWin.h b/cpp/RAT/leftWin.h new file mode 100644 index 00000000..6f63e5a7 --- /dev/null +++ b/cpp/RAT/leftWin.h @@ -0,0 +1,26 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// leftWin.h +// +// Code generation for function 'leftWin' +// +#ifndef LEFTWIN_H +#define LEFTWIN_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + real_T leftWin(real_T S_x_I_no, real_T S_x_FVr_oa, real_T S_y_FVr_oa); +} + +#endif + +// End of code generation (leftWin.h) diff --git a/cpp/RAT/length.cpp b/cpp/RAT/length.cpp new file mode 100644 index 00000000..7167b86c --- /dev/null +++ b/cpp/RAT/length.cpp @@ -0,0 +1,39 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// length.cpp +// +// Code generation for function 'length' +// + +// Include files +#include "length.h" +#include "rt_nonfinite.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + int32_T intlength(int32_T varargin_1, int32_T varargin_2) + { + int32_T n; + if ((varargin_1 == 0) || (varargin_2 == 0)) { + n = 0; + } else if (varargin_1 >= varargin_2) { + n = varargin_1; + } else { + n = varargin_2; + } + + return n; + } + } + } +} + +// End of code generation (length.cpp) diff --git a/cpp/RAT/length.h b/cpp/RAT/length.h new file mode 100644 index 00000000..2bc62c03 --- /dev/null +++ b/cpp/RAT/length.h @@ -0,0 +1,32 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// length.h +// +// Code generation for function 'length' +// +#ifndef LENGTH_H +#define LENGTH_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + int32_T intlength(int32_T varargin_1, int32_T varargin_2); + } + } +} + +#endif + +// End of code generation (length.h) diff --git a/cpp/RAT/linspace.cpp b/cpp/RAT/linspace.cpp new file mode 100644 index 00000000..f0a2e73e --- /dev/null +++ b/cpp/RAT/linspace.cpp @@ -0,0 +1,105 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// linspace.cpp +// +// Code generation for function 'linspace' +// + +// Include files +#include "linspace.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + void linspace(real_T d1, real_T d2, real_T n, ::coder::array &y) + { + if (!(n >= 0.0)) { + y.set_size(1, 0); + } else { + real_T delta1; + delta1 = std::floor(n); + y.set_size(1, static_cast(delta1)); + if (static_cast(delta1) >= 1) { + y[static_cast(delta1) - 1] = d2; + if (y.size(1) >= 2) { + y[0] = d1; + if (y.size(1) >= 3) { + if (d1 == -d2) { + int32_T i; + delta1 = d2 / (static_cast(y.size(1)) - 1.0); + i = y.size(1) - 1; + for (int32_T k{2}; k <= i; k++) { + y[k - 1] = static_cast(((k << 1) - y.size(1)) - 1) * + delta1; + } + + if ((y.size(1) & 1) == 1) { + y[y.size(1) >> 1] = 0.0; + } + } else if (((d1 < 0.0) != (d2 < 0.0)) && ((std::abs(d1) > + 8.9884656743115785E+307) || (std::abs(d2) > + 8.9884656743115785E+307))) { + real_T delta2; + int32_T i; + delta1 = d1 / (static_cast(y.size(1)) - 1.0); + delta2 = d2 / (static_cast(y.size(1)) - 1.0); + i = y.size(1); + for (int32_T k{0}; k <= i - 3; k++) { + y[k + 1] = (d1 + delta2 * (static_cast(k) + 1.0)) - + delta1 * (static_cast(k) + 1.0); + } + } else { + int32_T i; + delta1 = (d2 - d1) / (static_cast(y.size(1)) - 1.0); + i = y.size(1); + for (int32_T k{0}; k <= i - 3; k++) { + y[k + 1] = d1 + (static_cast(k) + 1.0) * delta1; + } + } + } + } + } + } + } + + void linspace(real_T d1, real_T d2, real_T y[500]) + { + y[499] = d2; + y[0] = d1; + if (d1 == -d2) { + real_T delta1; + delta1 = d2 / 499.0; + for (int32_T k{0}; k < 498; k++) { + y[k + 1] = (2.0 * (static_cast(k) + 2.0) - 501.0) * delta1; + } + } else if (((d1 < 0.0) != (d2 < 0.0)) && ((std::abs(d1) > + 8.9884656743115785E+307) || (std::abs(d2) > + 8.9884656743115785E+307))) { + real_T delta1; + real_T delta2; + delta1 = d1 / 499.0; + delta2 = d2 / 499.0; + for (int32_T k{0}; k < 498; k++) { + y[k + 1] = (d1 + delta2 * (static_cast(k) + 1.0)) - delta1 * ( + static_cast(k) + 1.0); + } + } else { + real_T delta1; + delta1 = (d2 - d1) / 499.0; + for (int32_T k{0}; k < 498; k++) { + y[k + 1] = d1 + (static_cast(k) + 1.0) * delta1; + } + } + } + } +} + +// End of code generation (linspace.cpp) diff --git a/cpp/RAT/linspace.h b/cpp/RAT/linspace.h new file mode 100644 index 00000000..3ced8174 --- /dev/null +++ b/cpp/RAT/linspace.h @@ -0,0 +1,31 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// linspace.h +// +// Code generation for function 'linspace' +// +#ifndef LINSPACE_H +#define LINSPACE_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void linspace(real_T d1, real_T d2, real_T n, ::coder::array &y); + void linspace(real_T d1, real_T d2, real_T y[500]); + } +} + +#endif + +// End of code generation (linspace.h) diff --git a/cpp/RAT/log1p.cpp b/cpp/RAT/log1p.cpp new file mode 100644 index 00000000..89e7571c --- /dev/null +++ b/cpp/RAT/log1p.cpp @@ -0,0 +1,42 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// log1p.cpp +// +// Code generation for function 'log1p' +// + +// Include files +#include "log1p.h" +#include "rt_nonfinite.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace scalar + { + void b_log1p(real_T *z) + { + real_T absz; + absz = std::abs(*z); + if ((absz > 4.503599627370496E+15) || (std::isinf(*z) || std::isnan(*z))) + { + (*z)++; + *z = std::log(*z); + } else if (!(absz < 2.2204460492503131E-16)) { + *z = std::log(*z + 1.0) * (*z / ((*z + 1.0) - 1.0)); + } + } + } + } + } +} + +// End of code generation (log1p.cpp) diff --git a/cpp/RAT/log1p.h b/cpp/RAT/log1p.h new file mode 100644 index 00000000..c761da5f --- /dev/null +++ b/cpp/RAT/log1p.h @@ -0,0 +1,35 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// log1p.h +// +// Code generation for function 'log1p' +// +#ifndef LOG1P_H +#define LOG1P_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace scalar + { + void b_log1p(real_T *z); + } + } + } +} + +#endif + +// End of code generation (log1p.h) diff --git a/cpp/RAT/log2.cpp b/cpp/RAT/log2.cpp new file mode 100644 index 00000000..9eff7e8f --- /dev/null +++ b/cpp/RAT/log2.cpp @@ -0,0 +1,50 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// log2.cpp +// +// Code generation for function 'log2' +// + +// Include files +#include "log2.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + void b_log2(const ::coder::array &x, ::coder::array + &f, ::coder::array &e) + { + f.set_size(x.size(0)); + e.set_size(x.size(0)); + if (x.size(0) != 0) { + int32_T i; + i = x.size(0); + for (int32_T k{0}; k < i; k++) { + b_log2(x[k], &f[k], &e[k]); + } + } + } + + void b_log2(real_T x, real_T *f, real_T *e) + { + int32_T eint; + if ((!std::isinf(x)) && (!std::isnan(x))) { + *f = std::frexp(x, &eint); + *e = eint; + } else { + *f = x; + *e = 0.0; + } + } + } +} + +// End of code generation (log2.cpp) diff --git a/cpp/RAT/log2.h b/cpp/RAT/log2.h new file mode 100644 index 00000000..3198b204 --- /dev/null +++ b/cpp/RAT/log2.h @@ -0,0 +1,32 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// log2.h +// +// Code generation for function 'log2' +// +#ifndef LOG2_H +#define LOG2_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void b_log2(const ::coder::array &x, ::coder::array + &f, ::coder::array &e); + void b_log2(real_T x, real_T *f, real_T *e); + } +} + +#endif + +// End of code generation (log2.h) diff --git a/cpp/RAT/logPlus.cpp b/cpp/RAT/logPlus.cpp new file mode 100644 index 00000000..2ba15119 --- /dev/null +++ b/cpp/RAT/logPlus.cpp @@ -0,0 +1,43 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// logPlus.cpp +// +// Code generation for function 'logPlus' +// + +// Include files +#include "logPlus.h" +#include "rt_nonfinite.h" +#include + +// Function Definitions +namespace RAT +{ + real_T logPlus(real_T logx, real_T logy) + { + real_T logz; + + // + // logz = logPlus(logx, logy) + // + // Given logx and logy, this function returns logz=log(x+y). + // It avoids problems of dynamic range when the + // exponentiated values of x or y are very large or small. + // + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + if (std::isinf(logx) && std::isinf(logy)) { + logz = rtMinusInf; + } else if (logx > logy) { + logz = logx + std::log(std::exp(logy - logx) + 1.0); + } else { + logz = logy + std::log(std::exp(logx - logy) + 1.0); + } + + return logz; + } +} + +// End of code generation (logPlus.cpp) diff --git a/cpp/RAT/logPlus.h b/cpp/RAT/logPlus.h new file mode 100644 index 00000000..532712f8 --- /dev/null +++ b/cpp/RAT/logPlus.h @@ -0,0 +1,26 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// logPlus.h +// +// Code generation for function 'logPlus' +// +#ifndef LOGPLUS_H +#define LOGPLUS_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + real_T logPlus(real_T logx, real_T logy); +} + +#endif + +// End of code generation (logPlus.h) diff --git a/cpp/RAT/lower.cpp b/cpp/RAT/lower.cpp new file mode 100644 index 00000000..573d2626 --- /dev/null +++ b/cpp/RAT/lower.cpp @@ -0,0 +1,35 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// lower.cpp +// +// Code generation for function 'lower' +// + +// Include files +#include "lower.h" +#include "RATMain_data.h" +#include "rt_nonfinite.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + void lower(const char_T x_data[], const int32_T x_size[2], char_T y_data[], + int32_T y_size[2]) + { + int32_T i; + y_size[0] = 1; + y_size[1] = x_size[1]; + i = x_size[1]; + for (int32_T k{0}; k < i; k++) { + y_data[k] = cv[static_cast(x_data[k]) & 127]; + } + } + } +} + +// End of code generation (lower.cpp) diff --git a/cpp/RAT/lower.h b/cpp/RAT/lower.h new file mode 100644 index 00000000..9663d0ae --- /dev/null +++ b/cpp/RAT/lower.h @@ -0,0 +1,30 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// lower.h +// +// Code generation for function 'lower' +// +#ifndef LOWER_H +#define LOWER_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void lower(const char_T x_data[], const int32_T x_size[2], char_T y_data[], + int32_T y_size[2]); + } +} + +#endif + +// End of code generation (lower.h) diff --git a/cpp/RAT/lusolve.cpp b/cpp/RAT/lusolve.cpp new file mode 100644 index 00000000..1879f52d --- /dev/null +++ b/cpp/RAT/lusolve.cpp @@ -0,0 +1,74 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// lusolve.cpp +// +// Code generation for function 'lusolve' +// + +// Include files +#include "lusolve.h" +#include "rt_nonfinite.h" +#include "xgetrf.h" +#include "xtrsm.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + void lusolve(const ::coder::array &A, const ::coder::array< + real_T, 2U> &B, ::coder::array &X) + { + ::coder::array b_A; + ::coder::array ipiv; + int32_T b_i; + int32_T i; + int32_T i1; + int32_T info; + int32_T nb; + b_A.set_size(A.size(0), A.size(1)); + info = A.size(1); + for (i = 0; i < info; i++) { + b_i = A.size(0); + for (i1 = 0; i1 < b_i; i1++) { + b_A[i1 + b_A.size(0) * i] = A[i1 + A.size(0) * i]; + } + } + + lapack::xgetrf(A.size(1), A.size(1), b_A, A.size(1), ipiv, &info); + nb = B.size(0); + X.set_size(B.size(0), B.size(1)); + info = B.size(1); + for (i = 0; i < info; i++) { + b_i = B.size(0); + for (i1 = 0; i1 < b_i; i1++) { + X[X.size(0) * i] = B[B.size(0) * i]; + } + } + + blas::xtrsm(B.size(0), A.size(1), b_A, A.size(1), X, B.size(0)); + blas::b_xtrsm(B.size(0), A.size(1), b_A, A.size(1), X, B.size(0)); + i = A.size(1) - 1; + for (info = i; info >= 1; info--) { + i1 = ipiv[info - 1]; + if (i1 != info) { + for (b_i = 0; b_i < nb; b_i++) { + real_T temp; + temp = X[X.size(0) * (info - 1)]; + X[X.size(0) * (info - 1)] = X[X.size(0) * (i1 - 1)]; + X[X.size(0) * (i1 - 1)] = temp; + } + } + } + } + } + } +} + +// End of code generation (lusolve.cpp) diff --git a/cpp/RAT/lusolve.h b/cpp/RAT/lusolve.h new file mode 100644 index 00000000..8c3118a3 --- /dev/null +++ b/cpp/RAT/lusolve.h @@ -0,0 +1,34 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// lusolve.h +// +// Code generation for function 'lusolve' +// +#ifndef LUSOLVE_H +#define LUSOLVE_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + void lusolve(const ::coder::array &A, const ::coder::array< + real_T, 2U> &B, ::coder::array &X); + } + } +} + +#endif + +// End of code generation (lusolve.h) diff --git a/cpp/RAT/makeCell.cpp b/cpp/RAT/makeCell.cpp new file mode 100644 index 00000000..81cf1310 --- /dev/null +++ b/cpp/RAT/makeCell.cpp @@ -0,0 +1,221 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// makeCell.cpp +// +// Code generation for function 'makeCell' +// + +// Include files +#include "makeCell.h" +#include "RATMain_types.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void b_makeCell(real_T m, const real_T vals_data[], ::coder::array< + cell_wrap_22, 2U> &x) + { + int32_T i; + + // Creates a m by n cell array and initialise each cell with given + // value + // + // array = makeCell(5, 2, [1, 1]) + i = static_cast(m); + x.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T d; + real_T d1; + real_T d2; + d = vals_data[0]; + d1 = vals_data[1]; + d2 = vals_data[2]; + for (int32_T j{0}; j < 2; j++) { + x[b_i + x.size(0) * j].f1.set_size(1, 3); + x[b_i + x.size(0) * j].f1[0] = d; + x[b_i + x.size(0) * j].f1[1] = d1; + x[b_i + x.size(0) * j].f1[2] = d2; + } + } + } + + void b_makeCell(real_T m, const real_T vals_data[], ::coder::array &x) + { + int32_T i; + + // Creates a m by n cell array and initialise each cell with given + // value + // + // array = makeCell(5, 2, [1, 1]) + i = static_cast(m); + x.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T d; + real_T d1; + real_T d2; + d = vals_data[0]; + d1 = vals_data[1]; + d2 = vals_data[2]; + for (int32_T j{0}; j < 2; j++) { + x[b_i + x.size(0) * j].f1.set_size(1, 3); + x[b_i + x.size(0) * j].f1[0] = d; + x[b_i + x.size(0) * j].f1[x[b_i + x.size(0) * j].f1.size(0)] = d1; + x[b_i + x.size(0) * j].f1[x[b_i + x.size(0) * j].f1.size(0) * 2] = d2; + } + } + } + + void makeCell(cell_wrap_8 x[50]) + { + // Creates a m by n cell array and initialise each cell with given + // value + // + // array = makeCell(5, 2, [1, 1]) + x[0].f1.set_size(1, 1); + x[0].f1[0] = 1.0; + x[1].f1.set_size(1, 1); + x[1].f1[0] = 1.0; + x[2].f1.set_size(1, 1); + x[2].f1[0] = 1.0; + x[3].f1.set_size(1, 1); + x[3].f1[0] = 1.0; + x[4].f1.set_size(1, 1); + x[4].f1[0] = 1.0; + x[5].f1.set_size(1, 1); + x[5].f1[0] = 1.0; + x[6].f1.set_size(1, 1); + x[6].f1[0] = 1.0; + x[7].f1.set_size(1, 1); + x[7].f1[0] = 1.0; + x[8].f1.set_size(1, 1); + x[8].f1[0] = 1.0; + x[9].f1.set_size(1, 1); + x[9].f1[0] = 1.0; + x[10].f1.set_size(1, 1); + x[10].f1[0] = 1.0; + x[11].f1.set_size(1, 1); + x[11].f1[0] = 1.0; + x[12].f1.set_size(1, 1); + x[12].f1[0] = 1.0; + x[13].f1.set_size(1, 1); + x[13].f1[0] = 1.0; + x[14].f1.set_size(1, 1); + x[14].f1[0] = 1.0; + x[15].f1.set_size(1, 1); + x[15].f1[0] = 1.0; + x[16].f1.set_size(1, 1); + x[16].f1[0] = 1.0; + x[17].f1.set_size(1, 1); + x[17].f1[0] = 1.0; + x[18].f1.set_size(1, 1); + x[18].f1[0] = 1.0; + x[19].f1.set_size(1, 1); + x[19].f1[0] = 1.0; + x[20].f1.set_size(1, 1); + x[20].f1[0] = 1.0; + x[21].f1.set_size(1, 1); + x[21].f1[0] = 1.0; + x[22].f1.set_size(1, 1); + x[22].f1[0] = 1.0; + x[23].f1.set_size(1, 1); + x[23].f1[0] = 1.0; + x[24].f1.set_size(1, 1); + x[24].f1[0] = 1.0; + x[25].f1.set_size(1, 1); + x[25].f1[0] = 1.0; + x[26].f1.set_size(1, 1); + x[26].f1[0] = 1.0; + x[27].f1.set_size(1, 1); + x[27].f1[0] = 1.0; + x[28].f1.set_size(1, 1); + x[28].f1[0] = 1.0; + x[29].f1.set_size(1, 1); + x[29].f1[0] = 1.0; + x[30].f1.set_size(1, 1); + x[30].f1[0] = 1.0; + x[31].f1.set_size(1, 1); + x[31].f1[0] = 1.0; + x[32].f1.set_size(1, 1); + x[32].f1[0] = 1.0; + x[33].f1.set_size(1, 1); + x[33].f1[0] = 1.0; + x[34].f1.set_size(1, 1); + x[34].f1[0] = 1.0; + x[35].f1.set_size(1, 1); + x[35].f1[0] = 1.0; + x[36].f1.set_size(1, 1); + x[36].f1[0] = 1.0; + x[37].f1.set_size(1, 1); + x[37].f1[0] = 1.0; + x[38].f1.set_size(1, 1); + x[38].f1[0] = 1.0; + x[39].f1.set_size(1, 1); + x[39].f1[0] = 1.0; + x[40].f1.set_size(1, 1); + x[40].f1[0] = 1.0; + x[41].f1.set_size(1, 1); + x[41].f1[0] = 1.0; + x[42].f1.set_size(1, 1); + x[42].f1[0] = 1.0; + x[43].f1.set_size(1, 1); + x[43].f1[0] = 1.0; + x[44].f1.set_size(1, 1); + x[44].f1[0] = 1.0; + x[45].f1.set_size(1, 1); + x[45].f1[0] = 1.0; + x[46].f1.set_size(1, 1); + x[46].f1[0] = 1.0; + x[47].f1.set_size(1, 1); + x[47].f1[0] = 1.0; + x[48].f1.set_size(1, 1); + x[48].f1[0] = 1.0; + x[49].f1.set_size(1, 1); + x[49].f1[0] = 1.0; + } + + void makeCell(real_T m, const real_T vals_data[], ::coder::array &x) + { + int32_T i; + + // Creates a m by n cell array and initialise each cell with given + // value + // + // array = makeCell(5, 2, [1, 1]) + i = static_cast(m); + x.set_size(i, 1); + for (int32_T b_i{0}; b_i < i; b_i++) { + x[b_i].f1.set_size(1, 3); + x[b_i].f1[0] = vals_data[0]; + x[b_i].f1[1] = vals_data[1]; + x[b_i].f1[2] = vals_data[2]; + } + } + + void makeCell(real_T m, const real_T vals_data[], ::coder::array &x) + { + int32_T i; + + // Creates a m by n cell array and initialise each cell with given + // value + // + // array = makeCell(5, 2, [1, 1]) + i = static_cast(m); + x.set_size(i, 1); + for (int32_T b_i{0}; b_i < i; b_i++) { + x[b_i].f1.set_size(1, 3); + x[b_i].f1[0] = vals_data[0]; + x[b_i].f1[x[b_i].f1.size(0)] = vals_data[1]; + x[b_i].f1[x[b_i].f1.size(0) * 2] = vals_data[2]; + } + } +} + +// End of code generation (makeCell.cpp) diff --git a/cpp/RAT/makeCell.h b/cpp/RAT/makeCell.h new file mode 100644 index 00000000..84429f32 --- /dev/null +++ b/cpp/RAT/makeCell.h @@ -0,0 +1,36 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// makeCell.h +// +// Code generation for function 'makeCell' +// +#ifndef MAKECELL_H +#define MAKECELL_H + +// Include files +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void b_makeCell(real_T m, const real_T vals_data[], ::coder::array< + cell_wrap_22, 2U> &x); + void b_makeCell(real_T m, const real_T vals_data[], ::coder::array &x); + void makeCell(cell_wrap_8 x[50]); + void makeCell(real_T m, const real_T vals_data[], ::coder::array &x); + void makeCell(real_T m, const real_T vals_data[], ::coder::array &x); +} + +#endif + +// End of code generation (makeCell.h) diff --git a/cpp/RAT/makeD.cpp b/cpp/RAT/makeD.cpp new file mode 100644 index 00000000..af7dab86 --- /dev/null +++ b/cpp/RAT/makeD.cpp @@ -0,0 +1,111 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// makeD.cpp +// +// Code generation for function 'makeD' +// + +// Include files +#include "makeD.h" +#include "RATMain_data.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + void makeD(const ::coder::array &alpha1, const ::coder::array< + creal_T, 1U> &beta1, ::coder::array &D) + { + int32_T i; + int32_T k; + D.set_size(alpha1.size(0), alpha1.size(0)); + k = alpha1.size(0); + for (i = 0; i < k; i++) { + int32_T loop_ub; + loop_ub = alpha1.size(0); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + D[i1 + D.size(0) * i].re = 0.0; + D[i1 + D.size(0) * i].im = 0.0; + } + } + + i = alpha1.size(0); + for (k = 0; k < i; k++) { + real_T ai; + real_T ar; + real_T bi; + real_T br; + ar = alpha1[k].re; + ai = alpha1[k].im; + br = beta1[k].re; + bi = beta1[k].im; + if (bi == 0.0) { + if (ai == 0.0) { + D[k + D.size(0) * k].re = ar / br; + D[k + D.size(0) * k].im = 0.0; + } else if (ar == 0.0) { + D[k + D.size(0) * k].re = 0.0; + D[k + D.size(0) * k].im = ai / br; + } else { + D[k + D.size(0) * k].re = ar / br; + D[k + D.size(0) * k].im = ai / br; + } + } else if (br == 0.0) { + if (ar == 0.0) { + D[k + D.size(0) * k].re = ai / bi; + D[k + D.size(0) * k].im = 0.0; + } else if (ai == 0.0) { + D[k + D.size(0) * k].re = 0.0; + D[k + D.size(0) * k].im = -(ar / bi); + } else { + D[k + D.size(0) * k].re = ai / bi; + D[k + D.size(0) * k].im = -(ar / bi); + } + } else { + real_T bim; + real_T brm; + brm = std::abs(br); + bim = std::abs(bi); + if (brm > bim) { + real_T s; + s = bi / br; + bim = br + s * bi; + D[k + D.size(0) * k].re = (ar + s * ai) / bim; + D[k + D.size(0) * k].im = (ai - s * ar) / bim; + } else if (bim == brm) { + real_T s; + if (br > 0.0) { + s = 0.5; + } else { + s = -0.5; + } + + if (bi > 0.0) { + bim = 0.5; + } else { + bim = -0.5; + } + + D[k + D.size(0) * k].re = (ar * s + ai * bim) / brm; + D[k + D.size(0) * k].im = (ai * s - ar * bim) / brm; + } else { + real_T s; + s = br / bi; + bim = bi + s * br; + D[k + D.size(0) * k].re = (s * ar + ai) / bim; + D[k + D.size(0) * k].im = (s * ai - ar) / bim; + } + } + } + } + } +} + +// End of code generation (makeD.cpp) diff --git a/cpp/RAT/makeD.h b/cpp/RAT/makeD.h new file mode 100644 index 00000000..e3b2e8e8 --- /dev/null +++ b/cpp/RAT/makeD.h @@ -0,0 +1,31 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// makeD.h +// +// Code generation for function 'makeD' +// +#ifndef MAKED_H +#define MAKED_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void makeD(const ::coder::array &alpha1, const ::coder::array< + creal_T, 1U> &beta1, ::coder::array &D); + } +} + +#endif + +// End of code generation (makeD.h) diff --git a/cpp/RAT/makeEmptyBayesResultsStruct.cpp b/cpp/RAT/makeEmptyBayesResultsStruct.cpp new file mode 100644 index 00000000..e502ad91 --- /dev/null +++ b/cpp/RAT/makeEmptyBayesResultsStruct.cpp @@ -0,0 +1,688 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// makeEmptyBayesResultsStruct.cpp +// +// Code generation for function 'makeEmptyBayesResultsStruct' +// + +// Include files +#include "makeEmptyBayesResultsStruct.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rt_nonfinite.h" +#include "structConstructorHelper.h" +#include "coder_array.h" +#include "coder_bounded_array.h" + +// Function Declarations +namespace RAT +{ + static void cast(const ::coder::array &t2_outlier, const + struct13_T *t2_DREAMPar, const struct14_T t2_Meas_info, const + ::coder::array &t2_AR, const ::coder::array< + real_T, 2U> &t2_R_stat, const ::coder::array + &t2_CR, struct12_T *r); + static void cast(const real_T t0_par95_data[], const int32_T t0_par95_size[2], + const real_T t0_par65_data[], const int32_T t0_par65_size[2], + const real_T t0_mean_data[], const int32_T t0_mean_size[2], :: + coder::array &t1_par95, ::coder::array + &t1_par65, ::coder::array &t1_mean); +} + +// Function Definitions +namespace RAT +{ + static void cast(const ::coder::array &t2_outlier, const + struct13_T *t2_DREAMPar, const struct14_T t2_Meas_info, const + ::coder::array &t2_AR, const ::coder::array< + real_T, 2U> &t2_R_stat, const ::coder::array + &t2_CR, struct12_T *r) + { + int32_T b_loop_ub; + int32_T loop_ub; + r->outlier.size[0] = t2_outlier.size(0); + r->outlier.size[1] = t2_outlier.size(1); + loop_ub = t2_outlier.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = t2_outlier.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + r->outlier.data[i1 + r->outlier.size[0] * i] = t2_outlier[i1 + + t2_outlier.size(0) * i]; + } + } + + r->RunTime = 100.0; + r->DREAMPar = *t2_DREAMPar; + r->Meas_info = t2_Meas_info; + r->iteration = 0.0; + r->iloc = 0.0; + r->fx = 0.0; + r->AR.size[0] = t2_AR.size(0); + r->AR.size[1] = t2_AR.size(1); + loop_ub = t2_AR.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = t2_AR.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + r->AR.data[i1 + r->AR.size[0] * i] = t2_AR[i1 + t2_AR.size(0) * i]; + } + } + + r->R_stat.set_size(t2_R_stat.size(0), t2_R_stat.size(1)); + loop_ub = t2_R_stat.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = t2_R_stat.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + r->R_stat[i1 + r->R_stat.size(0) * i] = t2_R_stat[i1 + t2_R_stat.size(0) + * i]; + } + } + + r->CR.set_size(t2_CR.size(0), t2_CR.size(1)); + loop_ub = t2_CR.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = t2_CR.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + r->CR[i1 + r->CR.size(0) * i] = t2_CR[i1 + t2_CR.size(0) * i]; + } + } + } + + static void cast(const real_T t0_par95_data[], const int32_T t0_par95_size[2], + const real_T t0_par65_data[], const int32_T t0_par65_size[2], + const real_T t0_mean_data[], const int32_T t0_mean_size[2], :: + coder::array &t1_par95, ::coder::array + &t1_par65, ::coder::array &t1_mean) + { + int32_T loop_ub; + t1_par95.set_size(2, t0_par95_size[1]); + loop_ub = t0_par95_size[1]; + for (int32_T i{0}; i < loop_ub; i++) { + t1_par95[2 * i] = t0_par95_data[2 * i]; + t1_par95[2 * i + 1] = t0_par95_data[2 * i + 1]; + } + + t1_par65.set_size(2, t0_par65_size[1]); + loop_ub = t0_par65_size[1]; + for (int32_T i{0}; i < loop_ub; i++) { + t1_par65[2 * i] = t0_par65_data[2 * i]; + t1_par65[2 * i + 1] = t0_par65_data[2 * i + 1]; + } + + t1_mean.set_size(1, t0_mean_size[1]); + loop_ub = t0_mean_size[1]; + for (int32_T i{0}; i < loop_ub; i++) { + t1_mean[i] = t0_mean_data[i]; + } + } + + void b_makeEmptyBayesResultsStruct(real_T nContrasts, boolean_T isDomains, :: + coder::array &bayesResults_bestFitsMean_ref, ::coder::array< + cell_wrap_8, 2U> &bayesResults_bestFitsMean_sld, real_T + *bayesResults_bestFitsMean_chi, ::coder::array + &bayesResults_bestFitsMean_data, ::coder::array + &bayesResults_predlims_refPredInts, ::coder::array + &bayesResults_predlims_sldPredInts, ::coder::array + &bayesResults_predlims_refXdata, ::coder::array + &bayesResults_predlims_sldXdata, real_T + bayesResults_predlims_sampleChi_data[], int32_T + *bayesResults_predlims_sampleChi_size, ::coder::array + &bayesResults_parConfInts_par95, ::coder::array + &bayesResults_parConfInts_par65, ::coder::array + &bayesResults_parConfInts_mean, ::coder::array + &bayesResults_bestPars, b_struct_T *bayesResults_bayesRes, ::coder::array< + real_T, 2U> &bayesResults_chain) + { + ::coder::array b_f1; + ::coder::array e_f1; + ::coder::array g_f1; + ::coder::array c_f1; + ::coder::array d_f1; + ::coder::array f1; + ::coder::array f_f1; + ::coder::array t5_AR; + ::coder::array t5_CR; + ::coder::array t5_R_stat; + ::coder::array t5_outlier; + ::coder::array h_f1; + cell_wrap_12 r; + cell_wrap_12 r2; + cell_wrap_14 r4; + cell_wrap_9 r1; + cell_wrap_9 r3; + struct13_T expl_temp; + struct14_T b_expl_temp; + real_T t6_par65_data[2000]; + real_T t6_par95_data[2000]; + real_T t6_mean_data[1000]; + int32_T t6_mean_size[2]; + int32_T t6_par65_size[2]; + int32_T t6_par95_size[2]; + int32_T i; + + // A function to make an empty container to hold the results of bayes + // calculations. The struct has the following format: + // + // nPar = number of fitted parameters + // nContrasts = number of contrasts + // + // bayesResults = + // + // struct with fields: + // + // bestFitsMean: [1×1 struct] + // predlims: [1×1 struct] + // parConfInts: [1×1 struct] + // bestPars: [1xnPars double] + // bayesRes: [1×1 struct] + // chain: [1000000xnPars double] + // ----------------------------------------------------------- + // Make the individual structs.... + // (1) bayesResults.bestFitsMean + i = static_cast(nContrasts); + f1.set_size(i); + for (int32_T b_i{0}; b_i < i; b_i++) { + f1[b_i].f1.set_size(1, 3); + f1[b_i].f1[0] = 1.0; + f1[b_i].f1[f1[b_i].f1.size(0)] = 1.0; + f1[b_i].f1[f1[b_i].f1.size(0) * 2] = 1.0; + } + + if (isDomains) { + b_f1.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + b_f1[b_i].f1.set_size(2, 2); + b_f1[b_i + b_f1.size(0)].f1.set_size(2, 2); + b_f1[b_i].f1[0] = 1.0; + b_f1[b_i + b_f1.size(0)].f1[0] = 1.0; + b_f1[b_i].f1[1] = 1.0; + b_f1[b_i + b_f1.size(0)].f1[1] = 1.0; + b_f1[b_i].f1[b_f1[b_i].f1.size(0)] = 1.0; + b_f1[b_i + b_f1.size(0)].f1[b_f1[b_i + b_f1.size(0)].f1.size(0)] = 1.0; + b_f1[b_i].f1[b_f1[b_i].f1.size(0) + 1] = 1.0; + b_f1[b_i + b_f1.size(0)].f1[b_f1[b_i + b_f1.size(0)].f1.size(0) + 1] = + 1.0; + } + } else { + b_f1.set_size(i, 1); + for (int32_T b_i{0}; b_i < i; b_i++) { + b_f1[b_i].f1.set_size(1, 2); + b_f1[b_i].f1[0] = 1.0; + b_f1[b_i].f1[b_f1[b_i].f1.size(0)] = 1.0; + } + } + + c_f1.set_size(i); + + // -------------------------------------------------------------------- + // (2) bayesResults.predlims + d_f1.set_size(i); + for (int32_T b_i{0}; b_i < i; b_i++) { + c_f1[b_i].f1.set_size(1, 3); + c_f1[b_i].f1[0] = 1.0; + c_f1[b_i].f1[c_f1[b_i].f1.size(0)] = 1.0; + c_f1[b_i].f1[c_f1[b_i].f1.size(0) * 2] = 1.0; + d_f1[b_i].f1.set_size(1, 3); + d_f1[b_i].f1[0] = 1.0; + d_f1[b_i].f1[d_f1[b_i].f1.size(0)] = 1.0; + d_f1[b_i].f1[d_f1[b_i].f1.size(0) * 2] = 1.0; + } + + if (isDomains) { + e_f1.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + e_f1[b_i].f1.set_size(1, 3); + e_f1[b_i + e_f1.size(0)].f1.set_size(1, 3); + e_f1[b_i].f1[0] = 1.0; + e_f1[b_i + e_f1.size(0)].f1[0] = 1.0; + e_f1[b_i].f1[e_f1[b_i].f1.size(0)] = 1.0; + e_f1[b_i + e_f1.size(0)].f1[e_f1[b_i + e_f1.size(0)].f1.size(0)] = 1.0; + e_f1[b_i].f1[e_f1[b_i].f1.size(0) * 2] = 1.0; + e_f1[b_i + e_f1.size(0)].f1[e_f1[b_i + e_f1.size(0)].f1.size(0) * 2] = + 1.0; + } + } else { + e_f1.set_size(i, 1); + for (int32_T b_i{0}; b_i < i; b_i++) { + e_f1[b_i].f1.set_size(1, 3); + e_f1[b_i].f1[0] = 1.0; + e_f1[b_i].f1[e_f1[b_i].f1.size(0)] = 1.0; + e_f1[b_i].f1[e_f1[b_i].f1.size(0) * 2] = 1.0; + } + } + + f_f1.set_size(i); + for (int32_T b_i{0}; b_i < i; b_i++) { + f_f1[b_i].f1.set_size(1, 3); + f_f1[b_i].f1[0] = 1.0; + f_f1[b_i].f1[f_f1[b_i].f1.size(0)] = 1.0; + f_f1[b_i].f1[f_f1[b_i].f1.size(0) * 2] = 1.0; + } + + if (isDomains) { + g_f1.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + g_f1[b_i].f1.set_size(2, 3); + g_f1[b_i + g_f1.size(0)].f1.set_size(2, 3); + for (int32_T i1{0}; i1 < 3; i1++) { + g_f1[b_i].f1[g_f1[b_i].f1.size(0) * i1] = 1.0; + g_f1[b_i + g_f1.size(0)].f1[g_f1[b_i + g_f1.size(0)].f1.size(0) * i1] = + 1.0; + g_f1[b_i].f1[g_f1[b_i].f1.size(0) * i1 + 1] = 1.0; + g_f1[b_i + g_f1.size(0)].f1[g_f1[b_i + g_f1.size(0)].f1.size(0) * i1 + + 1] = 1.0; + } + } + } else { + g_f1.set_size(i, 1); + for (int32_T b_i{0}; b_i < i; b_i++) { + g_f1[b_i].f1.set_size(1, 3); + g_f1[b_i].f1[0] = 1.0; + g_f1[b_i].f1[g_f1[b_i].f1.size(0)] = 1.0; + g_f1[b_i].f1[g_f1[b_i].f1.size(0) * 2] = 1.0; + } + } + + // ------------------------------------------------------------------ + // (3) bayesResults.parConfInts + t6_par95_size[0] = 2; + t6_par95_size[1] = 1; + t6_par65_size[0] = 2; + t6_par65_size[1] = 1; + t6_mean_size[0] = 1; + t6_mean_size[1] = 1; + t6_mean_data[0] = 0.0; + + // ------------------------------------------------------------------- + // (4) bayesResults.bestPars + // ------------------------------------------------------------------- + // (5) bayesResults.bayesRes + t5_outlier.set_size(1, 2); + t5_AR.set_size(1, 2); + t5_R_stat.set_size(1, 2); + t5_CR.set_size(1, 2); + + // Nested Sampler + t6_par95_data[0] = 0.0; + t6_par65_data[0] = 0.0; + t5_outlier[0] = 1.0; + t5_AR[0] = 0.0; + t5_R_stat[0] = 0.0; + t5_CR[0] = 0.0; + t6_par95_data[1] = 0.0; + t6_par65_data[1] = 0.0; + t5_outlier[t5_outlier.size(0)] = 1.0; + t5_AR[t5_AR.size(0)] = 0.0; + t5_R_stat[t5_R_stat.size(0)] = 0.0; + t5_CR[t5_CR.size(0)] = 0.0; + expl_temp.R.set_size(1, 1); + expl_temp.R[0] = 0.0; + expl_temp.save = false; + expl_temp.restart = false; + expl_temp.modout = false; + expl_temp.IO = false; + expl_temp.ABC = false; + expl_temp.epsilon = 0.025; + expl_temp.thinning = 1.0; + expl_temp.adaptPCR = false; + expl_temp.outlier[0] = 'i'; + expl_temp.outlier[1] = 'q'; + expl_temp.outlier[2] = 'r'; + expl_temp.zeta = 1.0E-12; + expl_temp.steps = 50.0; + expl_temp.delta = 3.0; + expl_temp.nCR = 3.0; + expl_temp.pUnitGamma = 0.2; + expl_temp.lambda = 0.5; + expl_temp.CPU = 1.0; + expl_temp.parallel = false; + expl_temp.T = 1000.0; + expl_temp.N = 10.0; + expl_temp.d = 17.0; + b_expl_temp.N = 0.0; + b_expl_temp.Y = 0.0; + cast(t5_outlier, &expl_temp, b_expl_temp, t5_AR, t5_R_stat, t5_CR, + &bayesResults_bayesRes->dreamOutput); + + // ------------------------------------------------------------------ + // (6) chain + // ------------------------------------------------------------------- + // Make the final structure... + r.f1 = f1; + r1.f1 = b_f1; + r2.f1 = c_f1; + coder::internal::structConstructorHelper(&r, &r1, &r2, + bayesResults_bestFitsMean_ref, bayesResults_bestFitsMean_sld, + bayesResults_bestFitsMean_chi, bayesResults_bestFitsMean_data); + h_f1.set_size(1); + h_f1[0] = 0.0; + r.f1 = d_f1; + r1.f1 = e_f1; + r2.f1 = f_f1; + r3.f1 = g_f1; + r4.f1 = h_f1; + coder::internal::structConstructorHelper(&r, &r1, &r2, &r3, &r4, + bayesResults_predlims_refPredInts, bayesResults_predlims_sldPredInts, + bayesResults_predlims_refXdata, bayesResults_predlims_sldXdata, + bayesResults_predlims_sampleChi_data, bayesResults_predlims_sampleChi_size); + cast(t6_par95_data, t6_par95_size, t6_par65_data, t6_par65_size, + t6_mean_data, t6_mean_size, bayesResults_parConfInts_par95, + bayesResults_parConfInts_par65, bayesResults_parConfInts_mean); + bayesResults_bestPars.set_size(1, 1); + bayesResults_bestPars[0] = 1.0; + bayesResults_bayesRes->allChains.set_size(1, 3, 1); + for (i = 0; i < 3; i++) { + bayesResults_bayesRes->allChains[bayesResults_bayesRes->allChains.size(0) * + i] = 1.0; + } + + bayesResults_bayesRes->nestOutput.LogZ = 0.0; + bayesResults_bayesRes->nestOutput.nestSamples.size[0] = 1; + bayesResults_bayesRes->nestOutput.nestSamples.size[1] = 2; + bayesResults_bayesRes->nestOutput.postSamples.size[0] = 1; + bayesResults_bayesRes->nestOutput.postSamples.size[1] = 2; + bayesResults_chain.set_size(1, 2); + bayesResults_bayesRes->nestOutput.nestSamples.data[0] = 0.0; + bayesResults_bayesRes->nestOutput.postSamples.data[0] = 0.0; + bayesResults_chain[0] = 0.0; + bayesResults_bayesRes->nestOutput.nestSamples.data[1] = 0.0; + bayesResults_bayesRes->nestOutput.postSamples.data[1] = 0.0; + bayesResults_chain[bayesResults_chain.size(0)] = 0.0; + } + + void makeEmptyBayesResultsStruct(real_T nContrasts, boolean_T isDomains, + real_T nChains, ::coder::array + &bayesResults_bestFitsMean_ref, ::coder::array + &bayesResults_bestFitsMean_sld, real_T *bayesResults_bestFitsMean_chi, :: + coder::array &bayesResults_bestFitsMean_data, ::coder:: + array &bayesResults_predlims_refPredInts, ::coder::array< + cell_wrap_8, 2U> &bayesResults_predlims_sldPredInts, ::coder::array< + cell_wrap_8, 1U> &bayesResults_predlims_refXdata, ::coder::array &bayesResults_predlims_sldXdata, real_T + bayesResults_predlims_sampleChi_data[], int32_T + *bayesResults_predlims_sampleChi_size, ::coder::array + &bayesResults_parConfInts_par95, ::coder::array + &bayesResults_parConfInts_par65, ::coder::array + &bayesResults_parConfInts_mean, ::coder::array + &bayesResults_bestPars, b_struct_T *bayesResults_bayesRes, ::coder::array< + real_T, 2U> &bayesResults_chain) + { + ::coder::array b_f1; + ::coder::array e_f1; + ::coder::array g_f1; + ::coder::array c_f1; + ::coder::array d_f1; + ::coder::array f1; + ::coder::array f_f1; + ::coder::array t16_AR; + ::coder::array t16_CR; + ::coder::array t16_R_stat; + ::coder::array t16_outlier; + ::coder::array h_f1; + ::coder::array t16_DREAMPar_R; + cell_wrap_12 r; + cell_wrap_12 r2; + cell_wrap_14 r4; + cell_wrap_9 r1; + cell_wrap_9 r3; + struct13_T expl_temp; + struct14_T b_expl_temp; + real_T t17_par65_data[2000]; + real_T t17_par95_data[2000]; + real_T t17_mean_data[1000]; + int32_T t17_mean_size[2]; + int32_T t17_par65_size[2]; + int32_T t17_par95_size[2]; + int32_T i; + int32_T loop_ub_tmp; + + // A function to make an empty container to hold the results of bayes + // calculations. The struct has the following format: + // + // nPar = number of fitted parameters + // nContrasts = number of contrasts + // + // bayesResults = + // + // struct with fields: + // + // bestFitsMean: [1×1 struct] + // predlims: [1×1 struct] + // parConfInts: [1×1 struct] + // bestPars: [1xnPars double] + // bayesRes: [1×1 struct] + // chain: [1000000xnPars double] + // ----------------------------------------------------------- + // Make the individual structs.... + // (1) bayesResults.bestFitsMean + i = static_cast(nContrasts); + f1.set_size(i); + for (int32_T b_i{0}; b_i < i; b_i++) { + f1[b_i].f1.set_size(1, 3); + f1[b_i].f1[0] = 1.0; + f1[b_i].f1[f1[b_i].f1.size(0)] = 1.0; + f1[b_i].f1[f1[b_i].f1.size(0) * 2] = 1.0; + } + + if (isDomains) { + b_f1.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + b_f1[b_i].f1.set_size(2, 2); + b_f1[b_i + b_f1.size(0)].f1.set_size(2, 2); + b_f1[b_i].f1[0] = 1.0; + b_f1[b_i + b_f1.size(0)].f1[0] = 1.0; + b_f1[b_i].f1[1] = 1.0; + b_f1[b_i + b_f1.size(0)].f1[1] = 1.0; + b_f1[b_i].f1[b_f1[b_i].f1.size(0)] = 1.0; + b_f1[b_i + b_f1.size(0)].f1[b_f1[b_i + b_f1.size(0)].f1.size(0)] = 1.0; + b_f1[b_i].f1[b_f1[b_i].f1.size(0) + 1] = 1.0; + b_f1[b_i + b_f1.size(0)].f1[b_f1[b_i + b_f1.size(0)].f1.size(0) + 1] = + 1.0; + } + } else { + b_f1.set_size(i, 1); + for (int32_T b_i{0}; b_i < i; b_i++) { + b_f1[b_i].f1.set_size(1, 2); + b_f1[b_i].f1[0] = 1.0; + b_f1[b_i].f1[b_f1[b_i].f1.size(0)] = 1.0; + } + } + + c_f1.set_size(i); + + // -------------------------------------------------------------------- + // (2) bayesResults.predlims + d_f1.set_size(i); + for (int32_T b_i{0}; b_i < i; b_i++) { + c_f1[b_i].f1.set_size(1, 3); + c_f1[b_i].f1[0] = 1.0; + c_f1[b_i].f1[c_f1[b_i].f1.size(0)] = 1.0; + c_f1[b_i].f1[c_f1[b_i].f1.size(0) * 2] = 1.0; + d_f1[b_i].f1.set_size(1, 3); + d_f1[b_i].f1[0] = 1.0; + d_f1[b_i].f1[d_f1[b_i].f1.size(0)] = 1.0; + d_f1[b_i].f1[d_f1[b_i].f1.size(0) * 2] = 1.0; + } + + if (isDomains) { + e_f1.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + e_f1[b_i].f1.set_size(1, 3); + e_f1[b_i + e_f1.size(0)].f1.set_size(1, 3); + e_f1[b_i].f1[0] = 1.0; + e_f1[b_i + e_f1.size(0)].f1[0] = 1.0; + e_f1[b_i].f1[e_f1[b_i].f1.size(0)] = 1.0; + e_f1[b_i + e_f1.size(0)].f1[e_f1[b_i + e_f1.size(0)].f1.size(0)] = 1.0; + e_f1[b_i].f1[e_f1[b_i].f1.size(0) * 2] = 1.0; + e_f1[b_i + e_f1.size(0)].f1[e_f1[b_i + e_f1.size(0)].f1.size(0) * 2] = + 1.0; + } + } else { + e_f1.set_size(i, 1); + for (int32_T b_i{0}; b_i < i; b_i++) { + e_f1[b_i].f1.set_size(1, 3); + e_f1[b_i].f1[0] = 1.0; + e_f1[b_i].f1[e_f1[b_i].f1.size(0)] = 1.0; + e_f1[b_i].f1[e_f1[b_i].f1.size(0) * 2] = 1.0; + } + } + + f_f1.set_size(i); + for (int32_T b_i{0}; b_i < i; b_i++) { + f_f1[b_i].f1.set_size(1, 3); + f_f1[b_i].f1[0] = 1.0; + f_f1[b_i].f1[f_f1[b_i].f1.size(0)] = 1.0; + f_f1[b_i].f1[f_f1[b_i].f1.size(0) * 2] = 1.0; + } + + if (isDomains) { + g_f1.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + g_f1[b_i].f1.set_size(2, 3); + g_f1[b_i + g_f1.size(0)].f1.set_size(2, 3); + for (int32_T i1{0}; i1 < 3; i1++) { + g_f1[b_i].f1[g_f1[b_i].f1.size(0) * i1] = 1.0; + g_f1[b_i + g_f1.size(0)].f1[g_f1[b_i + g_f1.size(0)].f1.size(0) * i1] = + 1.0; + g_f1[b_i].f1[g_f1[b_i].f1.size(0) * i1 + 1] = 1.0; + g_f1[b_i + g_f1.size(0)].f1[g_f1[b_i + g_f1.size(0)].f1.size(0) * i1 + + 1] = 1.0; + } + } + } else { + g_f1.set_size(i, 1); + for (int32_T b_i{0}; b_i < i; b_i++) { + g_f1[b_i].f1.set_size(1, 3); + g_f1[b_i].f1[0] = 1.0; + g_f1[b_i].f1[g_f1[b_i].f1.size(0)] = 1.0; + g_f1[b_i].f1[g_f1[b_i].f1.size(0) * 2] = 1.0; + } + } + + // ------------------------------------------------------------------ + // (3) bayesResults.parConfInts + t17_par95_size[0] = 2; + t17_par95_size[1] = 1; + t17_par65_size[0] = 2; + t17_par65_size[1] = 1; + t17_mean_size[0] = 1; + t17_mean_size[1] = 1; + t17_mean_data[0] = 0.0; + + // ------------------------------------------------------------------- + // (4) bayesResults.bestPars + // ------------------------------------------------------------------- + // (5) bayesResults.bayesRes + t16_outlier.set_size(1, 2); + t17_par95_data[0] = 0.0; + t17_par65_data[0] = 0.0; + t16_outlier[0] = 1.0; + t17_par95_data[1] = 0.0; + t17_par65_data[1] = 0.0; + t16_outlier[t16_outlier.size(0)] = 1.0; + loop_ub_tmp = static_cast(nChains); + t16_DREAMPar_R.set_size(loop_ub_tmp, loop_ub_tmp); + for (i = 0; i < loop_ub_tmp; i++) { + for (int32_T i1{0}; i1 < loop_ub_tmp; i1++) { + t16_DREAMPar_R[i1 + t16_DREAMPar_R.size(0) * i] = 0; + } + } + + t16_AR.set_size(1, 2); + t16_R_stat.set_size(1, 2); + t16_CR.set_size(1, 2); + + // Nested Sampler + t16_AR[0] = 0.0; + t16_R_stat[0] = 0.0; + t16_CR[0] = 0.0; + t16_AR[t16_AR.size(0)] = 0.0; + t16_R_stat[t16_R_stat.size(0)] = 0.0; + t16_CR[t16_CR.size(0)] = 0.0; + expl_temp.R.set_size(t16_DREAMPar_R.size(0), t16_DREAMPar_R.size(1)); + loop_ub_tmp = t16_DREAMPar_R.size(1); + for (i = 0; i < loop_ub_tmp; i++) { + int32_T loop_ub; + loop_ub = t16_DREAMPar_R.size(0); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + expl_temp.R[i1 + expl_temp.R.size(0) * i] = 0.0; + } + } + + expl_temp.save = false; + expl_temp.restart = false; + expl_temp.modout = false; + expl_temp.IO = false; + expl_temp.ABC = false; + expl_temp.epsilon = 0.025; + expl_temp.thinning = 1.0; + expl_temp.adaptPCR = false; + expl_temp.outlier[0] = 'i'; + expl_temp.outlier[1] = 'q'; + expl_temp.outlier[2] = 'r'; + expl_temp.zeta = 1.0E-12; + expl_temp.steps = 50.0; + expl_temp.delta = 3.0; + expl_temp.nCR = 3.0; + expl_temp.pUnitGamma = 0.2; + expl_temp.lambda = 0.5; + expl_temp.CPU = 1.0; + expl_temp.parallel = false; + expl_temp.T = 1000.0; + expl_temp.N = 10.0; + expl_temp.d = 17.0; + b_expl_temp.N = 0.0; + b_expl_temp.Y = 0.0; + cast(t16_outlier, &expl_temp, b_expl_temp, t16_AR, t16_R_stat, t16_CR, + &bayesResults_bayesRes->dreamOutput); + + // ------------------------------------------------------------------ + // (6) chain + // ------------------------------------------------------------------- + // Make the final structure... + r.f1 = f1; + r1.f1 = b_f1; + r2.f1 = c_f1; + coder::internal::structConstructorHelper(&r, &r1, &r2, + bayesResults_bestFitsMean_ref, bayesResults_bestFitsMean_sld, + bayesResults_bestFitsMean_chi, bayesResults_bestFitsMean_data); + h_f1.set_size(1); + h_f1[0] = 0.0; + r.f1 = d_f1; + r1.f1 = e_f1; + r2.f1 = f_f1; + r3.f1 = g_f1; + r4.f1 = h_f1; + coder::internal::structConstructorHelper(&r, &r1, &r2, &r3, &r4, + bayesResults_predlims_refPredInts, bayesResults_predlims_sldPredInts, + bayesResults_predlims_refXdata, bayesResults_predlims_sldXdata, + bayesResults_predlims_sampleChi_data, bayesResults_predlims_sampleChi_size); + cast(t17_par95_data, t17_par95_size, t17_par65_data, t17_par65_size, + t17_mean_data, t17_mean_size, bayesResults_parConfInts_par95, + bayesResults_parConfInts_par65, bayesResults_parConfInts_mean); + bayesResults_bestPars.set_size(1, 1); + bayesResults_bestPars[0] = 1.0; + bayesResults_bayesRes->allChains.set_size(1, 3, 1); + for (i = 0; i < 3; i++) { + bayesResults_bayesRes->allChains[bayesResults_bayesRes->allChains.size(0) * + i] = 1.0; + } + + bayesResults_bayesRes->nestOutput.LogZ = 0.0; + bayesResults_bayesRes->nestOutput.nestSamples.size[0] = 1; + bayesResults_bayesRes->nestOutput.nestSamples.size[1] = 2; + bayesResults_bayesRes->nestOutput.postSamples.size[0] = 1; + bayesResults_bayesRes->nestOutput.postSamples.size[1] = 2; + bayesResults_chain.set_size(1, 2); + bayesResults_bayesRes->nestOutput.nestSamples.data[0] = 0.0; + bayesResults_bayesRes->nestOutput.postSamples.data[0] = 0.0; + bayesResults_chain[0] = 0.0; + bayesResults_bayesRes->nestOutput.nestSamples.data[1] = 0.0; + bayesResults_bayesRes->nestOutput.postSamples.data[1] = 0.0; + bayesResults_chain[bayesResults_chain.size(0)] = 0.0; + } +} + +// End of code generation (makeEmptyBayesResultsStruct.cpp) diff --git a/cpp/RAT/makeEmptyBayesResultsStruct.h b/cpp/RAT/makeEmptyBayesResultsStruct.h new file mode 100644 index 00000000..d9e8566f --- /dev/null +++ b/cpp/RAT/makeEmptyBayesResultsStruct.h @@ -0,0 +1,65 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// makeEmptyBayesResultsStruct.h +// +// Code generation for function 'makeEmptyBayesResultsStruct' +// +#ifndef MAKEEMPTYBAYESRESULTSSTRUCT_H +#define MAKEEMPTYBAYESRESULTSSTRUCT_H + +// Include files +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct b_struct_T; +} + +// Function Declarations +namespace RAT +{ + void b_makeEmptyBayesResultsStruct(real_T nContrasts, boolean_T isDomains, :: + coder::array &bayesResults_bestFitsMean_ref, ::coder::array< + cell_wrap_8, 2U> &bayesResults_bestFitsMean_sld, real_T + *bayesResults_bestFitsMean_chi, ::coder::array + &bayesResults_bestFitsMean_data, ::coder::array + &bayesResults_predlims_refPredInts, ::coder::array + &bayesResults_predlims_sldPredInts, ::coder::array + &bayesResults_predlims_refXdata, ::coder::array + &bayesResults_predlims_sldXdata, real_T + bayesResults_predlims_sampleChi_data[], int32_T + *bayesResults_predlims_sampleChi_size, ::coder::array + &bayesResults_parConfInts_par95, ::coder::array + &bayesResults_parConfInts_par65, ::coder::array + &bayesResults_parConfInts_mean, ::coder::array + &bayesResults_bestPars, b_struct_T *bayesResults_bayesRes, ::coder::array< + real_T, 2U> &bayesResults_chain); + void makeEmptyBayesResultsStruct(real_T nContrasts, boolean_T isDomains, + real_T nChains, ::coder::array + &bayesResults_bestFitsMean_ref, ::coder::array + &bayesResults_bestFitsMean_sld, real_T *bayesResults_bestFitsMean_chi, :: + coder::array &bayesResults_bestFitsMean_data, ::coder:: + array &bayesResults_predlims_refPredInts, ::coder::array< + cell_wrap_8, 2U> &bayesResults_predlims_sldPredInts, ::coder::array< + cell_wrap_8, 1U> &bayesResults_predlims_refXdata, ::coder::array &bayesResults_predlims_sldXdata, real_T + bayesResults_predlims_sampleChi_data[], int32_T + *bayesResults_predlims_sampleChi_size, ::coder::array + &bayesResults_parConfInts_par95, ::coder::array + &bayesResults_parConfInts_par65, ::coder::array + &bayesResults_parConfInts_mean, ::coder::array + &bayesResults_bestPars, b_struct_T *bayesResults_bayesRes, ::coder::array< + real_T, 2U> &bayesResults_chain); +} + +#endif + +// End of code generation (makeEmptyBayesResultsStruct.h) diff --git a/cpp/RAT/makeSLDProfileXY.cpp b/cpp/RAT/makeSLDProfileXY.cpp new file mode 100644 index 00000000..a7b9e6a9 --- /dev/null +++ b/cpp/RAT/makeSLDProfileXY.cpp @@ -0,0 +1,327 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// makeSLDProfileXY.cpp +// +// Code generation for function 'makeSLDProfileXY' +// + +// Include files +#include "makeSLDProfileXY.h" +#include "asymconvstep.h" +#include "blockedSummation.h" +#include "minOrMax.h" +#include "rt_nonfinite.h" +#include "sum.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + void makeSLDProfileXY(real_T bulkIn, real_T bulkOut, real_T ssub, const :: + coder::array &layers, real_T numberOfLayers, + real_T nrepeats, ::coder::array &out) + { + ::coder::array Lays; + ::coder::array SLD; + ::coder::array airBox; + ::coder::array r; + ::coder::array r1; + ::coder::array r2; + ::coder::array x; + ::coder::array b_SLD; + ::coder::array b_layers; + int32_T b_loop_ub; + int32_T i; + int32_T loop_ub; + if (numberOfLayers > 0.0) { + real_T lastBoxEdge; + real_T nextLayRough; + real_T subsBoxCen_tmp; + int32_T i1; + b_layers.set_size(layers.size(0)); + loop_ub = layers.size(0); + for (i = 0; i < loop_ub; i++) { + b_layers[i] = layers[i]; + } + + subsBoxCen_tmp = coder::sum(b_layers) * nrepeats + 150.0; + if (std::isnan(subsBoxCen_tmp)) { + x.set_size(1, 1); + x[0] = rtNaN; + } else if (subsBoxCen_tmp < 0.0) { + x.set_size(1, 0); + } else { + x.set_size(1, static_cast(subsBoxCen_tmp) + 1); + loop_ub = static_cast(subsBoxCen_tmp); + for (i = 0; i <= loop_ub; i++) { + x[i] = i; + } + } + + subsBoxCen_tmp = numberOfLayers * nrepeats; + Lays.set_size(x.size(1), static_cast(subsBoxCen_tmp + 2.0)); + loop_ub = static_cast(subsBoxCen_tmp + 2.0); + for (i = 0; i < loop_ub; i++) { + b_loop_ub = x.size(1); + for (i1 = 0; i1 < b_loop_ub; i1++) { + Lays[i1 + Lays.size(0) * i] = 0.0; + } + } + + nextLayRough = layers[layers.size(0) * 2]; + asymconvstep(x, 100.0, 0.0, nextLayRough, nextLayRough, bulkIn, airBox); + lastBoxEdge = 50.0; + i = static_cast(nrepeats); + for (int32_T n{0}; n < i; n++) { + i1 = static_cast(numberOfLayers); + for (int32_T b_i{0}; b_i < i1; b_i++) { + real_T thisBoxCentre; + real_T thisLayThick; + thisLayThick = layers[b_i]; + if (static_cast(b_i) + 1.0 < numberOfLayers) { + nextLayRough = layers[(b_i + layers.size(0) * 2) + 1]; + + // elseif (i == numberOfLayers) && (n < nrepeats) + // nextLayRough = layers(1,3); + } else { + nextLayRough = ssub; + } + + thisBoxCentre = lastBoxEdge + thisLayThick / 2.0; + b_loop_ub = static_cast((static_cast(b_i) + 1.0) + + numberOfLayers * ((static_cast(n) + 1.0) - 1.0)) - 1; + asymconvstep(x, thisLayThick, thisBoxCentre, layers[b_i + layers.size + (0) * 2], nextLayRough, layers[b_i + layers.size(0)], r1); + loop_ub = Lays.size(0); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + Lays[i2 + Lays.size(0) * b_loop_ub] = r1[i2]; + } + + lastBoxEdge = thisBoxCentre + thisLayThick / 2.0; + + // plot(x,Lays(:,i)); + } + } + + // layers(end,3); + asymconvstep(x, (x[x.size(1) - 1] - lastBoxEdge) * 2.0, x[x.size(1) - 1], + nextLayRough, ssub, bulkOut, r1); + loop_ub = Lays.size(0); + for (i = 0; i < loop_ub; i++) { + Lays[i + Lays.size(0) * (static_cast(subsBoxCen_tmp + 1.0) - 1)] + = r1[i]; + } + + // plot(x,Lays(:,(numberOfLayers*nrepeats)+1)) + loop_ub = Lays.size(0); + for (i = 0; i < loop_ub; i++) { + Lays[i + Lays.size(0) * (static_cast(subsBoxCen_tmp + 2.0) - 1)] + = airBox[i]; + } + + // plot(x,Lays(:,(numberOfLayers*nrepeats)+2)) + coder::blockedSummation(Lays, Lays.size(1), b_SLD); + b_loop_ub = b_SLD.size(0); + SLD.set_size(b_SLD.size(0), 1); + for (i = 0; i < b_loop_ub; i++) { + SLD[i] = b_SLD[i]; + } + } else { + real_T subsBoxCen_tmp; + x.set_size(1, 101); + r.set_size(1, 101); + for (i = 0; i < 101; i++) { + x[i] = i; + r[i] = i; + } + + subsBoxCen_tmp = coder::internal::maximum(r); + r.set_size(1, 101); + for (i = 0; i < 101; i++) { + r[i] = i; + } + + asymconvstep(r, subsBoxCen_tmp, 0.0, ssub, ssub, bulkIn, r1); + r.set_size(1, 101); + for (i = 0; i < 101; i++) { + r[i] = i; + } + + asymconvstep(r, subsBoxCen_tmp, subsBoxCen_tmp, ssub, ssub, bulkOut, r2); + SLD.set_size(1, r1.size(1)); + loop_ub = r1.size(1); + for (i = 0; i < loop_ub; i++) { + SLD[SLD.size(0) * i] = r1[i] + r2[i]; + } + } + + // plot(x,SLD) + b_loop_ub = SLD.size(0) * SLD.size(1); + out.set_size(x.size(1), 2); + loop_ub = x.size(1); + for (i = 0; i < loop_ub; i++) { + out[i] = x[i]; + } + + for (i = 0; i < b_loop_ub; i++) { + out[i + out.size(0)] = SLD[i]; + } + } + + void makeSLDProfileXY(real_T ssub, const ::coder::array &layers, + real_T numberOfLayers, real_T nrepeats, ::coder::array< + real_T, 2U> &out) + { + ::coder::array Lays; + ::coder::array SLD; + ::coder::array airBox; + ::coder::array r; + ::coder::array r1; + ::coder::array r2; + ::coder::array x; + ::coder::array b_SLD; + ::coder::array b_layers; + int32_T b_loop_ub; + int32_T i; + int32_T loop_ub; + if (numberOfLayers > 0.0) { + real_T lastBoxEdge; + real_T nextLayRough; + real_T subsBoxCen_tmp; + int32_T i1; + b_layers.set_size(layers.size(0)); + loop_ub = layers.size(0); + for (i = 0; i < loop_ub; i++) { + b_layers[i] = layers[i]; + } + + subsBoxCen_tmp = coder::sum(b_layers) * nrepeats + 150.0; + if (std::isnan(subsBoxCen_tmp)) { + x.set_size(1, 1); + x[0] = rtNaN; + } else if (subsBoxCen_tmp < 0.0) { + x.set_size(1, 0); + } else { + x.set_size(1, static_cast(subsBoxCen_tmp) + 1); + loop_ub = static_cast(subsBoxCen_tmp); + for (i = 0; i <= loop_ub; i++) { + x[i] = i; + } + } + + subsBoxCen_tmp = numberOfLayers * nrepeats; + Lays.set_size(x.size(1), static_cast(subsBoxCen_tmp + 2.0)); + loop_ub = static_cast(subsBoxCen_tmp + 2.0); + for (i = 0; i < loop_ub; i++) { + b_loop_ub = x.size(1); + for (i1 = 0; i1 < b_loop_ub; i1++) { + Lays[i1 + Lays.size(0) * i] = 0.0; + } + } + + nextLayRough = layers[layers.size(0) * 2]; + asymconvstep(x, 100.0, 0.0, nextLayRough, nextLayRough, airBox); + lastBoxEdge = 50.0; + i = static_cast(nrepeats); + for (int32_T n{0}; n < i; n++) { + i1 = static_cast(numberOfLayers); + for (int32_T b_i{0}; b_i < i1; b_i++) { + real_T thisBoxCentre; + real_T thisLayThick; + thisLayThick = layers[b_i]; + if (static_cast(b_i) + 1.0 < numberOfLayers) { + nextLayRough = layers[(b_i + layers.size(0) * 2) + 1]; + + // elseif (i == numberOfLayers) && (n < nrepeats) + // nextLayRough = layers(1,3); + } else { + nextLayRough = ssub; + } + + thisBoxCentre = lastBoxEdge + thisLayThick / 2.0; + b_loop_ub = static_cast((static_cast(b_i) + 1.0) + + numberOfLayers * ((static_cast(n) + 1.0) - 1.0)) - 1; + asymconvstep(x, thisLayThick, thisBoxCentre, layers[b_i + layers.size + (0) * 2], nextLayRough, layers[b_i + layers.size(0)], r1); + loop_ub = Lays.size(0); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + Lays[i2 + Lays.size(0) * b_loop_ub] = r1[i2]; + } + + lastBoxEdge = thisBoxCentre + thisLayThick / 2.0; + + // plot(x,Lays(:,i)); + } + } + + // layers(end,3); + asymconvstep(x, (x[x.size(1) - 1] - lastBoxEdge) * 2.0, x[x.size(1) - 1], + nextLayRough, ssub, r1); + loop_ub = Lays.size(0); + for (i = 0; i < loop_ub; i++) { + Lays[i + Lays.size(0) * (static_cast(subsBoxCen_tmp + 1.0) - 1)] + = r1[i]; + } + + // plot(x,Lays(:,(numberOfLayers*nrepeats)+1)) + loop_ub = Lays.size(0); + for (i = 0; i < loop_ub; i++) { + Lays[i + Lays.size(0) * (static_cast(subsBoxCen_tmp + 2.0) - 1)] + = airBox[i]; + } + + // plot(x,Lays(:,(numberOfLayers*nrepeats)+2)) + coder::blockedSummation(Lays, Lays.size(1), b_SLD); + b_loop_ub = b_SLD.size(0); + SLD.set_size(b_SLD.size(0), 1); + for (i = 0; i < b_loop_ub; i++) { + SLD[i] = b_SLD[i]; + } + } else { + real_T subsBoxCen_tmp; + x.set_size(1, 101); + r.set_size(1, 101); + for (i = 0; i < 101; i++) { + x[i] = i; + r[i] = i; + } + + subsBoxCen_tmp = coder::internal::maximum(r); + r.set_size(1, 101); + for (i = 0; i < 101; i++) { + r[i] = i; + } + + asymconvstep(r, subsBoxCen_tmp, 0.0, ssub, ssub, r1); + r.set_size(1, 101); + for (i = 0; i < 101; i++) { + r[i] = i; + } + + asymconvstep(r, subsBoxCen_tmp, subsBoxCen_tmp, ssub, ssub, r2); + SLD.set_size(1, r1.size(1)); + loop_ub = r1.size(1); + for (i = 0; i < loop_ub; i++) { + SLD[SLD.size(0) * i] = r1[i] + r2[i]; + } + } + + // plot(x,SLD) + b_loop_ub = SLD.size(0) * SLD.size(1); + out.set_size(x.size(1), 2); + loop_ub = x.size(1); + for (i = 0; i < loop_ub; i++) { + out[i] = x[i]; + } + + for (i = 0; i < b_loop_ub; i++) { + out[i + out.size(0)] = SLD[i]; + } + } +} + +// End of code generation (makeSLDProfileXY.cpp) diff --git a/cpp/RAT/makeSLDProfileXY.h b/cpp/RAT/makeSLDProfileXY.h new file mode 100644 index 00000000..981e5289 --- /dev/null +++ b/cpp/RAT/makeSLDProfileXY.h @@ -0,0 +1,32 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// makeSLDProfileXY.h +// +// Code generation for function 'makeSLDProfileXY' +// +#ifndef MAKESLDPROFILEXY_H +#define MAKESLDPROFILEXY_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void makeSLDProfileXY(real_T bulkIn, real_T bulkOut, real_T ssub, const :: + coder::array &layers, real_T numberOfLayers, + real_T nrepeats, ::coder::array &out); + void makeSLDProfileXY(real_T ssub, const ::coder::array &layers, + real_T numberOfLayers, real_T nrepeats, ::coder::array< + real_T, 2U> &out); +} + +#endif + +// End of code generation (makeSLDProfileXY.h) diff --git a/cpp/RAT/makeSLDProfiles.cpp b/cpp/RAT/makeSLDProfiles.cpp new file mode 100644 index 00000000..b6f5b78c --- /dev/null +++ b/cpp/RAT/makeSLDProfiles.cpp @@ -0,0 +1,49 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// makeSLDProfiles.cpp +// +// Code generation for function 'makeSLDProfiles' +// + +// Include files +#include "makeSLDProfiles.h" +#include "makeSLDProfileXY.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void makeSLDProfiles(real_T bulkIn, real_T bulkOut, const ::coder::array< + real_T, 2U> &sld, real_T ssub, const real_T repeats[2], :: + coder::array &sldProfile) + { + real_T d; + if (repeats[0] == 0.0) { + d = 1.0; + } else { + d = repeats[1]; + } + + makeSLDProfileXY(bulkIn, bulkOut, ssub, sld, static_cast(sld.size(0)), + d, sldProfile); + } + + void makeSLDProfiles(const ::coder::array &sld, real_T ssub, const + real_T repeats[2], ::coder::array &sldProfile) + { + real_T d; + if (repeats[0] == 0.0) { + d = 1.0; + } else { + d = repeats[1]; + } + + makeSLDProfileXY(ssub, sld, static_cast(sld.size(0)), d, sldProfile); + } +} + +// End of code generation (makeSLDProfiles.cpp) diff --git a/cpp/RAT/makeSLDProfiles.h b/cpp/RAT/makeSLDProfiles.h new file mode 100644 index 00000000..9baad4d9 --- /dev/null +++ b/cpp/RAT/makeSLDProfiles.h @@ -0,0 +1,31 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// makeSLDProfiles.h +// +// Code generation for function 'makeSLDProfiles' +// +#ifndef MAKESLDPROFILES_H +#define MAKESLDPROFILES_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void makeSLDProfiles(real_T bulkIn, real_T bulkOut, const ::coder::array< + real_T, 2U> &sld, real_T ssub, const real_T repeats[2], :: + coder::array &sldProfile); + void makeSLDProfiles(const ::coder::array &sld, real_T ssub, const + real_T repeats[2], ::coder::array &sldProfile); +} + +#endif + +// End of code generation (makeSLDProfiles.h) diff --git a/cpp/RAT/matrix_to_integer_power.cpp b/cpp/RAT/matrix_to_integer_power.cpp new file mode 100644 index 00000000..aa597826 --- /dev/null +++ b/cpp/RAT/matrix_to_integer_power.cpp @@ -0,0 +1,213 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// matrix_to_integer_power.cpp +// +// Code generation for function 'matrix_to_integer_power' +// + +// Include files +#include "matrix_to_integer_power.h" +#include "rt_nonfinite.h" +#include "vAllOrAny.h" +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + static void matrix_to_large_integer_power(real_T a_data[], real_T b, real_T + c_data[], int32_T c_size[2]); + static void matrix_to_small_integer_power(real_T a_data[], real_T b, real_T + c_data[], int32_T c_size[2]); + static void nbits(int32_T n, int32_T *log2n, int32_T *nbitson); + } +} + +// Function Definitions +namespace RAT +{ + namespace coder + { + static void matrix_to_large_integer_power(real_T a_data[], real_T b, real_T + c_data[], int32_T c_size[2]) + { + c_size[0] = 1; + c_size[1] = 1; + if ((!std::isinf(b)) && (!std::isnan(b))) { + real_T e; + boolean_T firstmult; + e = std::abs(b); + firstmult = true; + real_T ed2; + int32_T exitg1; + do { + exitg1 = 0; + ed2 = std::floor(e / 2.0); + if (2.0 * ed2 != e) { + if (firstmult) { + c_size[0] = 1; + c_size[1] = 1; + c_data[0] = a_data[0]; + firstmult = false; + } else { + e = c_data[0]; + c_size[0] = 1; + c_size[1] = 1; + c_data[0] = e * a_data[0]; + } + } + + if (ed2 == 0.0) { + exitg1 = 1; + } else { + e = ed2; + a_data[0] *= a_data[0]; + } + } while (exitg1 == 0); + } else { + c_size[0] = 1; + c_size[1] = 1; + c_data[0] = rtNaN; + } + } + + static void matrix_to_small_integer_power(real_T a_data[], real_T b, real_T + c_data[], int32_T c_size[2]) + { + real_T aBuffer_data; + int32_T n; + int32_T nb; + int32_T nbitson; + boolean_T b_first; + aBuffer_data = std::abs(b); + n = static_cast(aBuffer_data); + nbits(static_cast(aBuffer_data), &nb, &nbitson); + if (static_cast(aBuffer_data) <= 2) { + if (b == 2.0) { + c_size[0] = 1; + c_size[1] = 1; + c_data[0] = a_data[0] * a_data[0]; + } else if (b == 1.0) { + c_size[0] = 1; + c_size[1] = 1; + c_data[0] = a_data[0]; + } else { + b_first = false; + internal::c_genloops(a_data, &b_first); + if (b_first) { + c_size[0] = 1; + c_size[1] = 1; + c_data[0] = rtNaN; + } else { + c_size[0] = 1; + c_size[1] = 1; + c_data[0] = 1.0; + } + } + } else { + real_T cBuffer_data; + boolean_T aBufferInUse; + boolean_T cBufferInUse; + b_first = true; + aBufferInUse = false; + cBufferInUse = ((nbitson & 1) == 0); + for (nbitson = 0; nbitson <= nb - 2; nbitson++) { + if ((n & 1) != 0) { + if (b_first) { + b_first = false; + if (cBufferInUse) { + if (aBufferInUse) { + cBuffer_data = aBuffer_data; + } else { + cBuffer_data = a_data[0]; + } + } else if (aBufferInUse) { + c_data[0] = aBuffer_data; + } else { + c_data[0] = a_data[0]; + } + } else { + if (aBufferInUse) { + if (cBufferInUse) { + c_data[0] = cBuffer_data * aBuffer_data; + } else { + cBuffer_data = c_data[0] * aBuffer_data; + } + } else if (cBufferInUse) { + c_data[0] = cBuffer_data * a_data[0]; + } else { + cBuffer_data = c_data[0] * a_data[0]; + } + + cBufferInUse = !cBufferInUse; + } + } + + n >>= 1; + if (aBufferInUse) { + a_data[0] = aBuffer_data * aBuffer_data; + } else { + aBuffer_data = a_data[0]; + aBuffer_data *= aBuffer_data; + } + + aBufferInUse = !aBufferInUse; + } + + if (b_first) { + if (aBufferInUse) { + c_size[0] = 1; + c_size[1] = 1; + c_data[0] = aBuffer_data; + } else { + c_size[0] = 1; + c_size[1] = 1; + c_data[0] = a_data[0]; + } + } else if (aBufferInUse) { + c_size[0] = 1; + c_size[1] = 1; + c_data[0] = cBuffer_data * aBuffer_data; + } else { + c_size[0] = 1; + c_size[1] = 1; + c_data[0] = cBuffer_data * a_data[0]; + } + } + } + + static void nbits(int32_T n, int32_T *log2n, int32_T *nbitson) + { + *nbitson = 0; + *log2n = 0; + while (n > 0) { + (*log2n)++; + if ((n & 1) != 0) { + (*nbitson)++; + } + + n >>= 1; + } + } + + void matrix_to_integer_power(const real_T a_data[], real_T b, real_T c_data[], + int32_T c_size[2]) + { + if (std::abs(b) <= 2.147483647E+9) { + real_T b_a_data; + b_a_data = a_data[0]; + matrix_to_small_integer_power((real_T *)&b_a_data, b, c_data, c_size); + } else { + real_T b_a_data; + b_a_data = a_data[0]; + matrix_to_large_integer_power((real_T *)&b_a_data, b, c_data, c_size); + } + } + } +} + +// End of code generation (matrix_to_integer_power.cpp) diff --git a/cpp/RAT/matrix_to_integer_power.h b/cpp/RAT/matrix_to_integer_power.h new file mode 100644 index 00000000..7991af26 --- /dev/null +++ b/cpp/RAT/matrix_to_integer_power.h @@ -0,0 +1,30 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// matrix_to_integer_power.h +// +// Code generation for function 'matrix_to_integer_power' +// +#ifndef MATRIX_TO_INTEGER_POWER_H +#define MATRIX_TO_INTEGER_POWER_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void matrix_to_integer_power(const real_T a_data[], real_T b, real_T c_data[], + int32_T c_size[2]); + } +} + +#endif + +// End of code generation (matrix_to_integer_power.h) diff --git a/cpp/RAT/mchol.cpp b/cpp/RAT/mchol.cpp new file mode 100644 index 00000000..c2ed71eb --- /dev/null +++ b/cpp/RAT/mchol.cpp @@ -0,0 +1,476 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// mchol.cpp +// +// Code generation for function 'mchol' +// + +// Include files +#include "mchol.h" +#include "abs.h" +#include "diag.h" +#include "div.h" +#include "minOrMax.h" +#include "mtimes.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Declarations +namespace RAT +{ + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, int32_T in3, const ::coder::array &in4, + const ::coder::array &in5); + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, real_T in3, const ::coder::array &in4); +} + +// Function Definitions +namespace RAT +{ + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, int32_T in3, const ::coder::array &in4, + const ::coder::array &in5) + { + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_1_0; + stride_0_0 = (in2.size(0) != 1); + stride_1_0 = (in5.size(1) != 1); + if (in5.size(1) == 1) { + loop_ub = in2.size(0); + } else { + loop_ub = in5.size(1); + } + + for (int32_T i{0}; i < loop_ub; i++) { + in1[(static_cast(in2[i]) + in1.size(0) * in3) - 1] = in4[( + static_cast(in2[i * stride_0_0]) + in4.size(0) * in3) - 1] - + in5[i * stride_1_0]; + } + } + + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, real_T in3, const ::coder::array &in4) + { + ::coder::array b_in1; + int32_T i; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_1_0; + if (in4.size(0) == 1) { + i = in2.size(0); + } else { + i = in4.size(0); + } + + b_in1.set_size(i); + stride_0_0 = (in2.size(0) != 1); + stride_1_0 = (in4.size(0) != 1); + if (in4.size(0) == 1) { + loop_ub = in2.size(0); + } else { + loop_ub = in4.size(0); + } + + for (i = 0; i < loop_ub; i++) { + b_in1[i] = in1[static_cast(in2[i * stride_0_0]) - 1] - in3 * + in4[i * stride_1_0]; + } + + loop_ub = b_in1.size(0); + for (i = 0; i < loop_ub; i++) { + in1[static_cast(in2[i]) - 1] = b_in1[i]; + } + } + + void mchol(const ::coder::array &G, ::coder::array &L, + ::coder::array &D) + { + ::coder::array C; + ::coder::array b_G; + ::coder::array b_L; + ::coder::array ee; + ::coder::array r; + ::coder::array theta; + ::coder::array y; + ::coder::array ind; + ::coder::array r2; + ::coder::array varargin_1_tmp; + ::coder::array bb; + ::coder::array r1; + real_T b_dv1[3]; + real_T dv2[3]; + real_T b_dv[2]; + real_T b; + real_T beta2; + int32_T b_loop_ub; + int32_T i; + int32_T i1; + int32_T loop_ub; + int32_T n; + + // + // [L,D,E,pneg]=mchol(G) + // + // Given a symmetric matrix G, find a matrix E of "small" norm and c + // L, and D such that G+E is Positive Definite, and + // + // G+E = L*D*L' + // + // Also, calculate a direction pneg, such that if G is not PD, then + // + // pneg'*G*pneg < 0 + // + // Note that if G is PD, then the routine will return pneg=[]. + // + // Reference: Gill, Murray, and Wright, "Practical Optimization", p111. + // Author: Brian Borchers (borchers@nmt.edu) + // + // Copyright (c) 2009, Brian Borchers + // All rights reserved. + // + // Redistribution and use in source and binary forms, with or without + // modification, are permitted provided that the following conditions are + // met: + // + // * Redistributions of source code must retain the above copyright + // notice, this list of conditions and the following disclaimer. + // * Redistributions in binary form must reproduce the above copyright + // notice, this list of conditions and the following disclaimer in + // the documentation and/or other materials provided with the distribution + // * Neither the name of the New Mexico Inst of Mining & Tech nor the names + // of its contributors may be used to endorse or promote products derived + // from this software without specific prior written permission. + // + // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + // POSSIBILITY OF SUCH DAMAGE. + // + // n gives the size of the matrix. + // + n = G.size(0); + + // + // gamma, zi, nu, and beta2 are quantities used by the algorithm. + // + coder::diag(G, varargin_1_tmp); + coder::diag(varargin_1_tmp, r); + if ((G.size(0) == r.size(0)) && (G.size(1) == r.size(1))) { + b_G.set_size(G.size(0), G.size(1)); + loop_ub = G.size(1); + for (i = 0; i < loop_ub; i++) { + b_loop_ub = G.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + b_G[i1 + b_G.size(0) * i] = G[i1 + G.size(0) * i] - r[i1 + r.size(0) * + i]; + } + } + + coder::internal::maximum(b_G, y); + } else { + c_binary_expand_op(y, G, r); + } + + b_dv[0] = 1.0; + b_dv[1] = std::sqrt(static_cast(G.size(0)) * static_cast + (G.size(0)) - 1.0); + b_dv1[0] = coder::internal::maximum(varargin_1_tmp); + b_dv1[1] = coder::internal::maximum(y) / coder::internal::maximum(b_dv); + b_dv1[2] = 1.0E-15; + beta2 = coder::internal::b_maximum(b_dv1); + + // + // Initialize diag(C) to diag(G). + // + C.set_size(r.size(0), r.size(1)); + loop_ub = r.size(1); + for (i = 0; i < loop_ub; i++) { + b_loop_ub = r.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + C[i1 + C.size(0) * i] = r[i1 + r.size(0) * i]; + } + } + + // + // Loop through, calculating column j of L for j=1:n + // + L.set_size(G.size(0), G.size(0)); + loop_ub = G.size(0); + for (i = 0; i < loop_ub; i++) { + b_loop_ub = G.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + L[i1 + L.size(0) * i] = 0.0; + } + } + + D.set_size(G.size(0), G.size(0)); + loop_ub = G.size(0); + for (i = 0; i < loop_ub; i++) { + b_loop_ub = G.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + D[i1 + D.size(0) * i] = 0.0; + } + } + + theta.set_size(G.size(0), G.size(0)); + loop_ub = G.size(0); + for (i = 0; i < loop_ub; i++) { + b_loop_ub = G.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + theta[i1 + theta.size(0) * i] = 0.0; + } + } + + i = G.size(0); + if (G.size(0) - 1 >= 0) { + dv2[0] = 2.2204460492503131E-16; + b = static_cast(G.size(0)) * static_cast(G.size(0)); + } + + for (int32_T j{0}; j < i; j++) { + real_T a; + if (j < 1) { + bb.set_size(1, 0); + } else { + bb.set_size(1, j); + for (i1 = 0; i1 < j; i1++) { + bb[i1] = i1 + 1; + } + } + + if (static_cast(n) < static_cast(j) + 2U) { + ee.set_size(1, 0); + } else { + i1 = n - j; + ee.set_size(1, i1 - 1); + loop_ub = i1 - 2; + for (i1 = 0; i1 <= loop_ub; i1++) { + ee[i1] = (static_cast(j) + static_cast(i1)) + 2U; + } + } + + // + // Calculate the jth row of L. + // + if (j + 1 > 1) { + r2.set_size(bb.size(1)); + loop_ub = bb.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + r2[i1] = bb[i1]; + } + + b_G.set_size(r2.size(0), r2.size(0)); + loop_ub = r2.size(0); + for (i1 = 0; i1 < loop_ub; i1++) { + b_loop_ub = r2.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + b_G[i2 + b_G.size(0) * i1] = D[(static_cast(r2[i2]) + + D.size(0) * (static_cast(r2[i1]) - 1)) - 1]; + } + } + + coder::diag(b_G, varargin_1_tmp); + if (r2.size(0) == varargin_1_tmp.size(0)) { + loop_ub = r2.size(0); + for (i1 = 0; i1 < loop_ub; i1++) { + b_loop_ub = static_cast(r2[i1]) - 1; + L[j + L.size(0) * b_loop_ub] = C[j + C.size(0) * b_loop_ub] / + varargin_1_tmp[i1]; + } + } else { + binary_expand_op(L, j, r2, C, varargin_1_tmp); + } + } + + // + // Update the jth column of C. + // + if (j + 1 >= 2) { + if (j + 1 < n) { + r2.set_size(bb.size(1)); + loop_ub = bb.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + r2[i1] = bb[i1]; + } + + r.set_size(ee.size(1), r2.size(0)); + loop_ub = r2.size(0); + for (i1 = 0; i1 < loop_ub; i1++) { + b_loop_ub = ee.size(1); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + r[i2 + r.size(0) * i1] = C[(static_cast(ee[i2]) + C.size + (0) * (static_cast(r2[i1]) - 1)) - 1]; + } + } + + varargin_1_tmp.set_size(ee.size(1)); + loop_ub = ee.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + varargin_1_tmp[i1] = ee[i1]; + } + + b_L.set_size(1, r2.size(0)); + loop_ub = r2.size(0); + for (i1 = 0; i1 < loop_ub; i1++) { + b_L[i1] = L[j + L.size(0) * (static_cast(r2[i1]) - 1)]; + } + + coder::internal::blas::mtimes(b_L, r, y); + if (varargin_1_tmp.size(0) == y.size(1)) { + loop_ub = varargin_1_tmp.size(0); + for (i1 = 0; i1 < loop_ub; i1++) { + b_loop_ub = static_cast(varargin_1_tmp[i1]) - 1; + C[b_loop_ub + C.size(0) * j] = G[b_loop_ub + G.size(0) * j] - y[i1]; + } + } else { + binary_expand_op(C, varargin_1_tmp, j, G, y); + } + } + } else { + r2.set_size(ee.size(1)); + loop_ub = ee.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + r2[i1] = ee[i1]; + } + + loop_ub = r2.size(0); + for (i1 = 0; i1 < loop_ub; i1++) { + b_loop_ub = static_cast(r2[i1]) - 1; + C[b_loop_ub] = G[b_loop_ub]; + } + } + + // + // Update theta. + // + if (j + 1 == n) { + theta[j] = 0.0; + } else { + varargin_1_tmp.set_size(ee.size(1)); + loop_ub = ee.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + varargin_1_tmp[i1] = C[(static_cast(ee[i1]) + C.size(0) * j) + - 1]; + } + + coder::b_abs(varargin_1_tmp, r2); + theta[j] = coder::internal::maximum(r2); + } + + // + // Update D + // + dv2[1] = std::abs(C[j + C.size(0) * j]); + dv2[2] = theta[j] * theta[j] / beta2; + D[j + D.size(0) * j] = coder::internal::b_maximum(dv2); + + // + // Update E. + // + // Update C again... + // + // %%%%%%% M.Zibulevsky: begin of changes, old version is commented %%%%%%%%%%%%% + // for i=j+1:n, + // C(i,i)=C(i,i)-C(i,j)^2/D(j,j); + // end; + a = (static_cast(j) + 1.0) * (static_cast(n) + 1.0) + 1.0; + if (b < a) { + y.set_size(1, 0); + } else { + loop_ub = static_cast((b - a) / (static_cast(n) + 1.0)); + y.set_size(1, loop_ub + 1); + for (i1 = 0; i1 <= loop_ub; i1++) { + y[i1] = a + (static_cast(n) + 1.0) * static_cast(i1); + } + } + + ind.set_size(y.size(1)); + loop_ub = y.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + ind[i1] = y[i1]; + } + + a = 1.0 / D[j + D.size(0) * j]; + varargin_1_tmp.set_size(ee.size(1)); + loop_ub = ee.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + varargin_1_tmp[i1] = C[(static_cast(ee[i1]) + C.size(0) * j) - + 1]; + } + + r2.set_size(varargin_1_tmp.size(0)); + loop_ub = varargin_1_tmp.size(0); + for (i1 = 0; i1 < loop_ub; i1++) { + real_T varargin_1; + varargin_1 = varargin_1_tmp[i1]; + r2[i1] = varargin_1 * varargin_1; + } + + if (ind.size(0) == r2.size(0)) { + varargin_1_tmp.set_size(ind.size(0)); + loop_ub = ind.size(0); + for (i1 = 0; i1 < loop_ub; i1++) { + varargin_1_tmp[i1] = C[static_cast(ind[i1]) - 1] - a * r2[i1]; + } + + loop_ub = varargin_1_tmp.size(0); + for (i1 = 0; i1 < loop_ub; i1++) { + C[static_cast(ind[i1]) - 1] = varargin_1_tmp[i1]; + } + } else { + binary_expand_op(C, ind, a, r2); + } + } + + // + // Put 1's on the diagonal of L + // + // for j=1:n, + // L(j,j)=1; + // end; + b = static_cast(G.size(0)) * static_cast(G.size(0)); + if (b < 1.0) { + y.set_size(1, 0); + } else { + y.set_size(1, static_cast((b - 1.0) / (static_cast(G.size + (0)) + 1.0)) + 1); + loop_ub = static_cast((b - 1.0) / (static_cast(G.size(0)) + + 1.0)); + for (i = 0; i <= loop_ub; i++) { + y[i] = (static_cast(G.size(0)) + 1.0) * static_cast(i) + + 1.0; + } + } + + r1.set_size(y.size(1)); + loop_ub = y.size(1); + for (i = 0; i < loop_ub; i++) { + r1[i] = static_cast(y[i]); + } + + loop_ub = r1.size(0); + for (i = 0; i < loop_ub; i++) { + L[r1[i] - 1] = 1.0; + } + + // %%%%%%%%%%%%%%%%%%%%%%% M.Zibulevsky: end of changes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // + // if needed, find a descent direction. + // + } +} + +// End of code generation (mchol.cpp) diff --git a/cpp/RAT/mchol.h b/cpp/RAT/mchol.h new file mode 100644 index 00000000..5816e53d --- /dev/null +++ b/cpp/RAT/mchol.h @@ -0,0 +1,28 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// mchol.h +// +// Code generation for function 'mchol' +// +#ifndef MCHOL_H +#define MCHOL_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void mchol(const ::coder::array &G, ::coder::array &L, + ::coder::array &D); +} + +#endif + +// End of code generation (mchol.h) diff --git a/cpp/RAT/mean.cpp b/cpp/RAT/mean.cpp new file mode 100644 index 00000000..10af6d20 --- /dev/null +++ b/cpp/RAT/mean.cpp @@ -0,0 +1,89 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// mean.cpp +// +// Code generation for function 'mean' +// + +// Include files +#include "mean.h" +#include "blockedSummation.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + void mean(const ::coder::array &x, ::coder::array &y) + { + int32_T b_loop_ub; + int32_T loop_ub; + if ((x.size(0) == 0) || (x.size(1) == 0) || (x.size(2) == 0)) { + uint32_T sz_idx_1; + sz_idx_1 = static_cast(x.size(1)); + y.set_size(1, x.size(1), x.size(2)); + loop_ub = x.size(2); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = static_cast(sz_idx_1); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + y[i1 + y.size(1) * i] = 0.0; + } + } + } else { + nestedIter(x, x.size(0), y); + } + + y.set_size(1, y.size(1), y.size(2)); + loop_ub = y.size(2); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = y.size(1); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + y[i1 + y.size(1) * i] = y[i1 + y.size(1) * i] / static_cast + (x.size(0)); + } + } + } + + void mean(const ::coder::array &x, ::coder::array &y) + { + int32_T loop_ub; + if ((x.size(0) == 0) || (x.size(1) == 0)) { + y.set_size(1, x.size(1)); + loop_ub = x.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + y[i] = 0.0; + } + } else { + nestedIter(x, x.size(0), y); + } + + y.set_size(1, y.size(1)); + loop_ub = y.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + y[i] = y[i] / static_cast(x.size(0)); + } + } + + real_T mean(const real_T x_data[], int32_T x_size) + { + ::coder::array b_x_data; + real_T y; + if (x_size == 0) { + y = 0.0; + } else { + b_x_data.set((real_T *)&x_data[0], x_size); + y = nestedIter(b_x_data, x_size); + } + + y /= static_cast(x_size); + return y; + } + } +} + +// End of code generation (mean.cpp) diff --git a/cpp/RAT/mean.h b/cpp/RAT/mean.h new file mode 100644 index 00000000..d9008516 --- /dev/null +++ b/cpp/RAT/mean.h @@ -0,0 +1,32 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// mean.h +// +// Code generation for function 'mean' +// +#ifndef MEAN_H +#define MEAN_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void mean(const ::coder::array &x, ::coder::array &y); + void mean(const ::coder::array &x, ::coder::array &y); + real_T mean(const real_T x_data[], int32_T x_size); + } +} + +#endif + +// End of code generation (mean.h) diff --git a/cpp/RAT/mergesort.cpp b/cpp/RAT/mergesort.cpp new file mode 100644 index 00000000..cc3f8a68 --- /dev/null +++ b/cpp/RAT/mergesort.cpp @@ -0,0 +1,344 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// mergesort.cpp +// +// Code generation for function 'mergesort' +// + +// Include files +#include "mergesort.h" +#include "rt_nonfinite.h" +#include "sortLE.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + void b_mergesort(int32_T idx[4], const real_T x[4]) + { + int32_T iwork[4]; + int32_T j; + int32_T qEnd; + if (sortLE(x, 1, 2)) { + idx[0] = 1; + idx[1] = 2; + } else { + idx[0] = 2; + idx[1] = 1; + } + + if (sortLE(x, 3, 4)) { + idx[2] = 3; + idx[3] = 4; + } else { + idx[2] = 4; + idx[3] = 3; + } + + j = 1; + for (int32_T pEnd{3}; pEnd < 5; pEnd = qEnd + 2) { + int32_T k; + int32_T p; + int32_T q; + p = j; + q = pEnd; + qEnd = j + 4; + k = 0; + while (k + 1 <= 4) { + int32_T i; + int32_T i1; + i = idx[q - 1]; + i1 = idx[p - 1]; + if (sortLE(x, i1, i)) { + iwork[k] = i1; + p++; + if (p == pEnd) { + while (q < j + 4) { + k++; + iwork[k] = idx[q - 1]; + q++; + } + } + } else { + iwork[k] = i; + q++; + if (q == j + 4) { + while (p < pEnd) { + k++; + iwork[k] = idx[p - 1]; + p++; + } + } + } + + k++; + } + + for (k = 0; k < 4; k++) { + idx[(j + k) - 1] = iwork[k]; + } + + j += 4; + } + } + + void b_mergesort(::coder::array &idx, const ::coder::array< + real_T, 2U> &x, int32_T n) + { + ::coder::array iwork; + int32_T b_i; + int32_T i; + int32_T k; + int32_T qEnd; + iwork.set_size(idx.size(1)); + i = n - 1; + for (k = 1; k <= i; k += 2) { + if (sortLE(x, k, k + 1)) { + idx[k - 1] = k; + idx[k] = k + 1; + } else { + idx[k - 1] = k + 1; + idx[k] = k; + } + } + + if ((n & 1) != 0) { + idx[n - 1] = n; + } + + b_i = 2; + while (b_i < n) { + int32_T i2; + int32_T j; + i2 = b_i << 1; + j = 1; + for (int32_T pEnd{b_i + 1}; pEnd < n + 1; pEnd = qEnd + b_i) { + int32_T kEnd; + int32_T p; + int32_T q; + p = j; + q = pEnd; + qEnd = j + i2; + if (qEnd > n + 1) { + qEnd = n + 1; + } + + k = 0; + kEnd = qEnd - j; + while (k + 1 <= kEnd) { + int32_T i1; + i = idx[q - 1]; + i1 = idx[p - 1]; + if (sortLE(x, i1, i)) { + iwork[k] = i1; + p++; + if (p == pEnd) { + while (q < qEnd) { + k++; + iwork[k] = idx[q - 1]; + q++; + } + } + } else { + iwork[k] = i; + q++; + if (q == qEnd) { + while (p < pEnd) { + k++; + iwork[k] = idx[p - 1]; + p++; + } + } + } + + k++; + } + + for (k = 0; k < kEnd; k++) { + idx[(j + k) - 1] = iwork[k]; + } + + j = qEnd; + } + + b_i = i2; + } + } + + void b_mergesort(::coder::array &idx, const ::coder::array< + real_T, 1U> &x, int32_T n) + { + ::coder::array iwork; + int32_T b_i; + int32_T i; + int32_T k; + int32_T qEnd; + iwork.set_size(idx.size(0)); + i = n - 1; + for (k = 1; k <= i; k += 2) { + if (sortLE(x, k, k + 1)) { + idx[k - 1] = k; + idx[k] = k + 1; + } else { + idx[k - 1] = k + 1; + idx[k] = k; + } + } + + if ((n & 1) != 0) { + idx[n - 1] = n; + } + + b_i = 2; + while (b_i < n) { + int32_T i2; + int32_T j; + i2 = b_i << 1; + j = 1; + for (int32_T pEnd{b_i + 1}; pEnd < n + 1; pEnd = qEnd + b_i) { + int32_T kEnd; + int32_T p; + int32_T q; + p = j; + q = pEnd; + qEnd = j + i2; + if (qEnd > n + 1) { + qEnd = n + 1; + } + + k = 0; + kEnd = qEnd - j; + while (k + 1 <= kEnd) { + int32_T i1; + i = idx[q - 1]; + i1 = idx[p - 1]; + if (sortLE(x, i1, i)) { + iwork[k] = i1; + p++; + if (p == pEnd) { + while (q < qEnd) { + k++; + iwork[k] = idx[q - 1]; + q++; + } + } + } else { + iwork[k] = i; + q++; + if (q == qEnd) { + while (p < pEnd) { + k++; + iwork[k] = idx[p - 1]; + p++; + } + } + } + + k++; + } + + for (k = 0; k < kEnd; k++) { + idx[(j + k) - 1] = iwork[k]; + } + + j = qEnd; + } + + b_i = i2; + } + } + + void b_mergesort(::coder::array &idx, const ::coder::array< + real_T, 2U> &x, const int32_T dir_data[], int32_T n) + { + ::coder::array iwork; + int32_T b_i; + int32_T i; + int32_T k; + int32_T qEnd; + iwork.set_size(idx.size(0)); + i = n - 1; + for (k = 1; k <= i; k += 2) { + if (sortLE(x, dir_data, k, k + 1)) { + idx[k - 1] = k; + idx[k] = k + 1; + } else { + idx[k - 1] = k + 1; + idx[k] = k; + } + } + + if ((n & 1) != 0) { + idx[n - 1] = n; + } + + b_i = 2; + while (b_i < n) { + int32_T i2; + int32_T j; + i2 = b_i << 1; + j = 1; + for (int32_T pEnd{b_i + 1}; pEnd < n + 1; pEnd = qEnd + b_i) { + int32_T kEnd; + int32_T p; + int32_T q; + p = j; + q = pEnd; + qEnd = j + i2; + if (qEnd > n + 1) { + qEnd = n + 1; + } + + k = 0; + kEnd = qEnd - j; + while (k + 1 <= kEnd) { + int32_T i1; + i = idx[q - 1]; + i1 = idx[p - 1]; + if (sortLE(x, dir_data, i1, i)) { + iwork[k] = i1; + p++; + if (p == pEnd) { + while (q < qEnd) { + k++; + iwork[k] = idx[q - 1]; + q++; + } + } + } else { + iwork[k] = i; + q++; + if (q == qEnd) { + while (p < pEnd) { + k++; + iwork[k] = idx[p - 1]; + p++; + } + } + } + + k++; + } + + for (k = 0; k < kEnd; k++) { + idx[(j + k) - 1] = iwork[k]; + } + + j = qEnd; + } + + b_i = i2; + } + } + } + } +} + +// End of code generation (mergesort.cpp) diff --git a/cpp/RAT/mergesort.h b/cpp/RAT/mergesort.h new file mode 100644 index 00000000..34034cf9 --- /dev/null +++ b/cpp/RAT/mergesort.h @@ -0,0 +1,39 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// mergesort.h +// +// Code generation for function 'mergesort' +// +#ifndef MERGESORT_H +#define MERGESORT_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + void b_mergesort(int32_T idx[4], const real_T x[4]); + void b_mergesort(::coder::array &idx, const ::coder::array< + real_T, 2U> &x, int32_T n); + void b_mergesort(::coder::array &idx, const ::coder::array< + real_T, 1U> &x, int32_T n); + void b_mergesort(::coder::array &idx, const ::coder::array< + real_T, 2U> &x, const int32_T dir_data[], int32_T n); + } + } +} + +#endif + +// End of code generation (mergesort.h) diff --git a/cpp/RAT/metropolisRule.cpp b/cpp/RAT/metropolisRule.cpp new file mode 100644 index 00000000..d98517fd --- /dev/null +++ b/cpp/RAT/metropolisRule.cpp @@ -0,0 +1,185 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// metropolisRule.cpp +// +// Code generation for function 'metropolisRule' +// + +// Include files +#include "metropolisRule.h" +#include "RATMain_types.h" +#include "find.h" +#include "rand.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Declarations +namespace RAT +{ + static void e_binary_expand_op(::coder::array &in1, const :: + coder::array &in2, const ::coder::array &in3, const :: + coder::array &in4); + static void minus(::coder::array &in1, const ::coder::array &in2, const ::coder::array &in3); +} + +// Function Definitions +namespace RAT +{ + static void e_binary_expand_op(::coder::array &in1, const :: + coder::array &in2, const ::coder::array &in3, const :: + coder::array &in4) + { + int32_T i; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_1_0; + int32_T stride_2_0; + if (in4.size(0) == 1) { + if (in3.size(0) == 1) { + i = in2.size(0); + } else { + i = in3.size(0); + } + } else { + i = in4.size(0); + } + + in1.set_size(i); + stride_0_0 = (in2.size(0) != 1); + stride_1_0 = (in3.size(0) != 1); + stride_2_0 = (in4.size(0) != 1); + if (in4.size(0) == 1) { + if (in3.size(0) == 1) { + loop_ub = in2.size(0); + } else { + loop_ub = in3.size(0); + } + } else { + loop_ub = in4.size(0); + } + + for (i = 0; i < loop_ub; i++) { + in1[i] = (in2[i * stride_0_0] * in3[i * stride_1_0] > in4[i * stride_2_0]); + } + } + + static void minus(::coder::array &in1, const ::coder::array &in2, const ::coder::array &in3) + { + int32_T i; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_1_0; + if (in3.size(0) == 1) { + i = in2.size(0); + } else { + i = in3.size(0); + } + + in1.set_size(i); + stride_0_0 = (in2.size(0) != 1); + stride_1_0 = (in3.size(0) != 1); + if (in3.size(0) == 1) { + loop_ub = in2.size(0); + } else { + loop_ub = in3.size(0); + } + + for (i = 0; i < loop_ub; i++) { + in1[i] = in2[i * stride_0_0] - in3[i * stride_1_0]; + } + } + + void metropolisRule(const struct13_T *DREAMPar, const ::coder::array &log_L_xnew, const ::coder::array + &log_PR_xnew, const ::coder::array &log_L_xold, + const ::coder::array &log_PR_xold, ::coder:: + array &accept, ::coder::array + &idx_accept) + { + ::coder::array Z; + ::coder::array r; + ::coder::array r1; + ::coder::array r2; + ::coder::array b_accept; + int32_T i; + int32_T k; + + // Metropolis rule for acceptance or rejection + // No ABC --> regular MCMC with prior and likelihood + // Calculate the likelihood ratio + // Calculate the prior ration + // Calculate product of two probabily ratios + // Generate random numbers + coder::b_rand(DREAMPar->N, Z); + + // Find which alfa's are greater than Z + if (log_L_xnew.size(0) == log_L_xold.size(0)) { + r.set_size(log_L_xnew.size(0)); + k = log_L_xnew.size(0); + for (i = 0; i < k; i++) { + r[i] = log_L_xnew[i] - log_L_xold[i]; + } + } else { + minus(r, log_L_xnew, log_L_xold); + } + + i = r.size(0); + for (k = 0; k < i; k++) { + r[k] = std::exp(r[k]); + } + + if (log_PR_xnew.size(0) == log_PR_xold.size(0)) { + r1.set_size(log_PR_xnew.size(0)); + k = log_PR_xnew.size(0); + for (i = 0; i < k; i++) { + r1[i] = log_PR_xnew[i] - log_PR_xold[i]; + } + } else { + minus(r1, log_PR_xnew, log_PR_xold); + } + + i = r1.size(0); + for (k = 0; k < i; k++) { + r1[k] = std::exp(r1[k]); + } + + if (r.size(0) == 1) { + i = r1.size(0); + } else { + i = r.size(0); + } + + if ((r.size(0) == r1.size(0)) && (i == Z.size(0))) { + accept.set_size(r.size(0)); + k = r.size(0); + for (i = 0; i < k; i++) { + accept[i] = (r[i] * r1[i] > Z[i]); + } + } else { + e_binary_expand_op(accept, r, r1, Z); + } + + // ABC --> check if summary metrics as prior (diagnostic Bayes) or likelihood (regular ABC) + // Now derive which proposals to accept (row numbers of X) + b_accept.set_size(accept.size(0)); + k = accept.size(0); + for (i = 0; i < k; i++) { + b_accept[i] = accept[i]; + } + + coder::eml_find(b_accept, r2); + idx_accept.set_size(r2.size(0)); + k = r2.size(0); + for (i = 0; i < k; i++) { + idx_accept[i] = r2[i]; + } + } +} + +// End of code generation (metropolisRule.cpp) diff --git a/cpp/RAT/metropolisRule.h b/cpp/RAT/metropolisRule.h new file mode 100644 index 00000000..845cc8cd --- /dev/null +++ b/cpp/RAT/metropolisRule.h @@ -0,0 +1,38 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// metropolisRule.h +// +// Code generation for function 'metropolisRule' +// +#ifndef METROPOLISRULE_H +#define METROPOLISRULE_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct struct13_T; +} + +// Function Declarations +namespace RAT +{ + void metropolisRule(const struct13_T *DREAMPar, const ::coder::array &log_L_xnew, const ::coder::array + &log_PR_xnew, const ::coder::array &log_L_xold, + const ::coder::array &log_PR_xold, ::coder:: + array &accept, ::coder::array + &idx_accept); +} + +#endif + +// End of code generation (metropolisRule.h) diff --git a/cpp/RAT/minOrMax.cpp b/cpp/RAT/minOrMax.cpp new file mode 100644 index 00000000..fdcc444c --- /dev/null +++ b/cpp/RAT/minOrMax.cpp @@ -0,0 +1,420 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// minOrMax.cpp +// +// Code generation for function 'minOrMax' +// + +// Include files +#include "minOrMax.h" +#include "ixfun.h" +#include "relop.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + void c_binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in2, const ::coder::array &in3) + { + ::coder::array b_in2; + int32_T aux_0_1; + int32_T aux_1_1; + int32_T i; + int32_T i1; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_0_1; + int32_T stride_1_0; + int32_T stride_1_1; + if (in3.size(0) == 1) { + i = in2.size(0); + } else { + i = in3.size(0); + } + + if (in3.size(1) == 1) { + i1 = in2.size(1); + } else { + i1 = in3.size(1); + } + + b_in2.set_size(i, i1); + stride_0_0 = (in2.size(0) != 1); + stride_0_1 = (in2.size(1) != 1); + stride_1_0 = (in3.size(0) != 1); + stride_1_1 = (in3.size(1) != 1); + aux_0_1 = 0; + aux_1_1 = 0; + if (in3.size(1) == 1) { + loop_ub = in2.size(1); + } else { + loop_ub = in3.size(1); + } + + for (i = 0; i < loop_ub; i++) { + int32_T b_loop_ub; + i1 = in3.size(0); + if (i1 == 1) { + b_loop_ub = in2.size(0); + } else { + b_loop_ub = i1; + } + + for (i1 = 0; i1 < b_loop_ub; i1++) { + b_in2[i1 + b_in2.size(0) * i] = in2[i1 * stride_0_0 + in2.size(0) * + aux_0_1] - in3[i1 * stride_1_0 + in3.size(0) * aux_1_1]; + } + + aux_1_1 += stride_1_1; + aux_0_1 += stride_0_1; + } + + coder::internal::maximum(b_in2, in1); + } + + namespace coder + { + namespace internal + { + real_T b_maximum(const real_T x[3]) + { + real_T ex; + int32_T idx; + int32_T k; + if (!std::isnan(x[0])) { + idx = 1; + } else { + boolean_T exitg1; + idx = 0; + k = 2; + exitg1 = false; + while ((!exitg1) && (k <= 3)) { + if (!std::isnan(x[k - 1])) { + idx = k; + exitg1 = true; + } else { + k++; + } + } + } + + if (idx == 0) { + ex = x[0]; + } else { + ex = x[idx - 1]; + idx++; + for (k = idx; k < 4; k++) { + real_T d; + d = x[k - 1]; + if (ex < d) { + ex = d; + } + } + } + + return ex; + } + + void maximum(const ::coder::array &x, ::coder::array &ex) + { + int32_T m; + int32_T n; + m = x.size(0); + n = x.size(1); + ex.set_size(1, x.size(1)); + if (x.size(1) >= 1) { + for (int32_T j{0}; j < n; j++) { + ex[j] = x[x.size(0) * j]; + for (int32_T i{2}; i <= m; i++) { + real_T d; + d = x[(i + x.size(0) * j) - 1]; + if (relop(ex[j], d)) { + ex[j] = d; + } + } + } + } + } + + real_T maximum(const ::coder::array &x) + { + real_T ex; + int32_T last; + last = x.size(0); + if (x.size(0) <= 2) { + if (x.size(0) == 1) { + ex = x[0]; + } else if ((x[0] < x[x.size(0) - 1]) || (std::isnan(x[0]) && (!std:: + isnan(x[x.size(0) - 1])))) { + ex = x[x.size(0) - 1]; + } else { + ex = x[0]; + } + } else { + int32_T idx; + int32_T k; + if (!std::isnan(x[0])) { + idx = 1; + } else { + boolean_T exitg1; + idx = 0; + k = 2; + exitg1 = false; + while ((!exitg1) && (k <= last)) { + if (!std::isnan(x[k - 1])) { + idx = k; + exitg1 = true; + } else { + k++; + } + } + } + + if (idx == 0) { + ex = x[0]; + } else { + ex = x[idx - 1]; + idx++; + for (k = idx; k <= last; k++) { + real_T d; + d = x[k - 1]; + if (ex < d) { + ex = d; + } + } + } + } + + return ex; + } + + real_T maximum(const ::coder::array &x) + { + real_T ex; + int32_T last; + last = x.size(1); + if (x.size(1) <= 2) { + if (x.size(1) == 1) { + ex = x[0]; + } else if ((x[0] < x[x.size(1) - 1]) || (std::isnan(x[0]) && (!std:: + isnan(x[x.size(1) - 1])))) { + ex = x[x.size(1) - 1]; + } else { + ex = x[0]; + } + } else { + int32_T idx; + int32_T k; + if (!std::isnan(x[0])) { + idx = 1; + } else { + boolean_T exitg1; + idx = 0; + k = 2; + exitg1 = false; + while ((!exitg1) && (k <= last)) { + if (!std::isnan(x[k - 1])) { + idx = k; + exitg1 = true; + } else { + k++; + } + } + } + + if (idx == 0) { + ex = x[0]; + } else { + ex = x[idx - 1]; + idx++; + for (k = idx; k <= last; k++) { + real_T d; + d = x[k - 1]; + if (ex < d) { + ex = d; + } + } + } + } + + return ex; + } + + void maximum(const ::coder::array &x, real_T ex[2]) + { + int32_T m; + m = x.size(0); + for (int32_T j{0}; j < 2; j++) { + ex[j] = x[x.size(0) * j]; + for (int32_T i{2}; i <= m; i++) { + real_T d; + d = x[(i + x.size(0) * j) - 1]; + if (relop(ex[j], d)) { + ex[j] = d; + } + } + } + } + + real_T maximum(const real_T x[2]) + { + real_T ex; + if ((x[0] < x[1]) || (std::isnan(x[0]) && (!std::isnan(x[1])))) { + ex = x[1]; + } else { + ex = x[0]; + } + + return ex; + } + + void maximum2(const ::coder::array &x, const ::coder::array< + real_T, 1U> &y, ::coder::array &ex) + { + if (x.size(0) == y.size(0)) { + int32_T loop_ub; + ex.set_size(x.size(0)); + loop_ub = x.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + real_T varargin_1; + real_T varargin_2; + varargin_1 = x[i]; + varargin_2 = y[i]; + ex[i] = std::fmax(varargin_1, varargin_2); + } + } else { + expand_max(x, y, ex); + } + } + + void minimum(const ::coder::array &x, real_T *ex, int32_T *idx) + { + int32_T last; + last = x.size(0); + if (x.size(0) <= 2) { + if (x.size(0) == 1) { + *ex = x[0]; + *idx = 1; + } else if ((x[0] > x[x.size(0) - 1]) || (std::isnan(x[0]) && (!std:: + isnan(x[x.size(0) - 1])))) { + *ex = x[x.size(0) - 1]; + *idx = x.size(0); + } else { + *ex = x[0]; + *idx = 1; + } + } else { + int32_T k; + if (!std::isnan(x[0])) { + *idx = 1; + } else { + boolean_T exitg1; + *idx = 0; + k = 2; + exitg1 = false; + while ((!exitg1) && (k <= last)) { + if (!std::isnan(x[k - 1])) { + *idx = k; + exitg1 = true; + } else { + k++; + } + } + } + + if (*idx == 0) { + *ex = x[0]; + *idx = 1; + } else { + int32_T i; + *ex = x[*idx - 1]; + i = *idx + 1; + for (k = i; k <= last; k++) { + real_T d; + d = x[k - 1]; + if (*ex > d) { + *ex = d; + *idx = k; + } + } + } + } + } + + real_T minimum(const real_T x[2]) + { + real_T ex; + if ((x[0] > x[1]) || (std::isnan(x[0]) && (!std::isnan(x[1])))) { + ex = x[1]; + } else { + ex = x[0]; + } + + return ex; + } + + void minimum(const real_T x[50], real_T *ex, int32_T *idx) + { + int32_T k; + if (!std::isnan(x[0])) { + *idx = 1; + } else { + boolean_T exitg1; + *idx = 0; + k = 2; + exitg1 = false; + while ((!exitg1) && (k < 51)) { + if (!std::isnan(x[k - 1])) { + *idx = k; + exitg1 = true; + } else { + k++; + } + } + } + + if (*idx == 0) { + *ex = x[0]; + *idx = 1; + } else { + int32_T i; + *ex = x[*idx - 1]; + i = *idx + 1; + for (k = i; k < 51; k++) { + real_T d; + d = x[k - 1]; + if (*ex > d) { + *ex = d; + *idx = k; + } + } + } + } + + void minimum(const ::coder::array &x, real_T ex[2]) + { + int32_T m; + m = x.size(0); + for (int32_T j{0}; j < 2; j++) { + ex[j] = x[x.size(0) * j]; + for (int32_T i{2}; i <= m; i++) { + real_T d; + d = x[(i + x.size(0) * j) - 1]; + if (b_relop(ex[j], d)) { + ex[j] = d; + } + } + } + } + } + } +} + +// End of code generation (minOrMax.cpp) diff --git a/cpp/RAT/minOrMax.h b/cpp/RAT/minOrMax.h new file mode 100644 index 00000000..149b9b65 --- /dev/null +++ b/cpp/RAT/minOrMax.h @@ -0,0 +1,47 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// minOrMax.h +// +// Code generation for function 'minOrMax' +// +#ifndef MINORMAX_H +#define MINORMAX_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void c_binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in2, const ::coder::array &in3); + namespace coder + { + namespace internal + { + real_T b_maximum(const real_T x[3]); + void maximum(const ::coder::array &x, ::coder::array &ex); + real_T maximum(const ::coder::array &x); + real_T maximum(const ::coder::array &x); + void maximum(const ::coder::array &x, real_T ex[2]); + real_T maximum(const real_T x[2]); + void maximum2(const ::coder::array &x, const ::coder::array< + real_T, 1U> &y, ::coder::array &ex); + void minimum(const ::coder::array &x, real_T *ex, int32_T *idx); + real_T minimum(const real_T x[2]); + void minimum(const real_T x[50], real_T *ex, int32_T *idx); + void minimum(const ::coder::array &x, real_T ex[2]); + } + } +} + +#endif + +// End of code generation (minOrMax.h) diff --git a/cpp/RAT/mod.cpp b/cpp/RAT/mod.cpp new file mode 100644 index 00000000..31595d58 --- /dev/null +++ b/cpp/RAT/mod.cpp @@ -0,0 +1,56 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// mod.cpp +// +// Code generation for function 'mod' +// + +// Include files +#include "mod.h" +#include "rt_nonfinite.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + real_T b_mod(real_T x) + { + real_T r; + if (std::isnan(x) || std::isinf(x)) { + r = rtNaN; + } else if (x == 0.0) { + r = 0.0; + } else { + r = std::fmod(x, 100.0); + if (r == 0.0) { + r = 0.0; + } + } + + return r; + } + + real_T b_mod(real_T x, real_T y) + { + real_T r; + r = x; + if (std::isnan(x) || std::isnan(y) || std::isinf(x)) { + r = rtNaN; + } else if (!std::isinf(y)) { + r = std::fmod(x, y); + if (r == 0.0) { + r = y * 0.0; + } + } + + return r; + } + } +} + +// End of code generation (mod.cpp) diff --git a/cpp/RAT/mod.h b/cpp/RAT/mod.h new file mode 100644 index 00000000..016dae9b --- /dev/null +++ b/cpp/RAT/mod.h @@ -0,0 +1,30 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// mod.h +// +// Code generation for function 'mod' +// +#ifndef MOD_H +#define MOD_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + real_T b_mod(real_T x); + real_T b_mod(real_T x, real_T y); + } +} + +#endif + +// End of code generation (mod.h) diff --git a/cpp/RAT/mrdivide_helper.cpp b/cpp/RAT/mrdivide_helper.cpp new file mode 100644 index 00000000..31a3ae86 --- /dev/null +++ b/cpp/RAT/mrdivide_helper.cpp @@ -0,0 +1,204 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// mrdivide_helper.cpp +// +// Code generation for function 'mrdivide_helper' +// + +// Include files +#include "mrdivide_helper.h" +#include "lusolve.h" +#include "qrsolve.h" +#include "rt_nonfinite.h" +#include "xgeqp3.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in2, int32_T in3, const ::coder::array< + real_T, 2U> &in4, const ::coder::array &in5) + { + ::coder::array b_in2; + int32_T i; + int32_T loop_ub; + int32_T stride_0_1; + int32_T stride_1_1; + if (in4.size(1) == 1) { + i = in2.size(1); + } else { + i = in4.size(1); + } + + b_in2.set_size(1, i); + stride_0_1 = (in2.size(1) != 1); + stride_1_1 = (in4.size(1) != 1); + if (in4.size(1) == 1) { + loop_ub = in2.size(1); + } else { + loop_ub = in4.size(1); + } + + for (i = 0; i < loop_ub; i++) { + b_in2[b_in2.size(0) * i] = in2[in3 + in2.size(0) * (i * stride_0_1)] - + in4[in4.size(0) * (i * stride_1_1)]; + } + + coder::internal::mrdiv(b_in2, in5, in1); + } + + void c_binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in2, int32_T in3, const ::coder::array &in4, const :: + coder::array &in5) + { + ::coder::array b_in2; + int32_T aux_0_1; + int32_T aux_1_1; + int32_T i; + int32_T loop_ub; + int32_T stride_0_1; + int32_T stride_1_1; + if (in4.size(1) == 1) { + i = in2.size(1); + } else { + i = in4.size(1); + } + + b_in2.set_size(in4.size(0), i); + stride_0_1 = (in2.size(1) != 1); + stride_1_1 = (in4.size(1) != 1); + aux_0_1 = 0; + aux_1_1 = 0; + if (in4.size(1) == 1) { + loop_ub = in2.size(1); + } else { + loop_ub = in4.size(1); + } + + for (i = 0; i < loop_ub; i++) { + int32_T b_loop_ub; + b_loop_ub = in4.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + b_in2[b_in2.size(0) * i] = in2[in3 + in2.size(0) * aux_0_1] - + in4[in4.size(0) * aux_1_1]; + } + + aux_1_1 += stride_1_1; + aux_0_1 += stride_0_1; + } + + coder::internal::mrdiv(b_in2, in5, in1); + } + + namespace coder + { + namespace internal + { + void mrdiv(const ::coder::array &A, const ::coder::array< + real_T, 2U> &B, ::coder::array &Y) + { + ::coder::array b_A; + ::coder::array c_A; + ::coder::array r; + ::coder::array tau; + ::coder::array jpvt; + if ((A.size(0) == 0) || (A.size(1) == 0) || ((B.size(0) == 0) || (B.size + (1) == 0))) { + int32_T loop_ub; + Y.set_size(A.size(0), B.size(0)); + loop_ub = B.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + int32_T b_loop_ub; + b_loop_ub = A.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + Y[Y.size(0) * i] = 0.0; + } + } + } else if (B.size(0) == B.size(1)) { + lusolve(B, A, Y); + } else { + int32_T b_loop_ub; + int32_T loop_ub; + b_A.set_size(B.size(1), B.size(0)); + loop_ub = B.size(0); + b_loop_ub = B.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + b_A[i1 + b_A.size(0) * i] = B[i + B.size(0) * i1]; + } + } + + lapack::xgeqp3(b_A, tau, jpvt); + c_A.set_size(A.size(1), 1); + loop_ub = A.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + c_A[i] = A[A.size(0) * i]; + } + + LSQFromQR(b_A, tau, jpvt, c_A, rankFromQR(b_A), r); + Y.set_size(r.size(1), r.size(0)); + loop_ub = r.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = r.size(1); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + Y[Y.size(0) * i] = r[i]; + } + } + } + } + + void mrdiv(const ::coder::array &A, const ::coder::array< + real_T, 2U> &B, ::coder::array &Y) + { + ::coder::array b_A; + ::coder::array r; + ::coder::array b_B; + if ((A.size(0) == 0) || (A.size(1) == 0) || (B.size(1) == 0)) { + int32_T loop_ub; + Y.set_size(A.size(0)); + loop_ub = A.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + Y[i] = 0.0; + } + } else if (B.size(1) == 1) { + int32_T loop_ub; + Y.set_size(A.size(0)); + loop_ub = A.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + Y[i] = A[i] / B[0]; + } + } else { + int32_T b_loop_ub; + int32_T loop_ub; + b_B.set_size(B.size(1)); + loop_ub = B.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_B[i] = B[i]; + } + + b_A.set_size(A.size(1), A.size(0)); + loop_ub = A.size(0); + b_loop_ub = A.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + b_A[i1 + b_A.size(0) * i] = A[i + A.size(0) * i1]; + } + } + + qrsolve(b_B, b_A, r); + Y.set_size(r.size(1)); + loop_ub = r.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + Y[i] = r[i]; + } + } + } + } + } +} + +// End of code generation (mrdivide_helper.cpp) diff --git a/cpp/RAT/mrdivide_helper.h b/cpp/RAT/mrdivide_helper.h new file mode 100644 index 00000000..bf66ce47 --- /dev/null +++ b/cpp/RAT/mrdivide_helper.h @@ -0,0 +1,42 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// mrdivide_helper.h +// +// Code generation for function 'mrdivide_helper' +// +#ifndef MRDIVIDE_HELPER_H +#define MRDIVIDE_HELPER_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in2, int32_T in3, const ::coder::array< + real_T, 2U> &in4, const ::coder::array &in5); + void c_binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in2, int32_T in3, const ::coder::array &in4, const :: + coder::array &in5); + namespace coder + { + namespace internal + { + void mrdiv(const ::coder::array &A, const ::coder::array< + real_T, 2U> &B, ::coder::array &Y); + void mrdiv(const ::coder::array &A, const ::coder::array< + real_T, 2U> &B, ::coder::array &Y); + } + } +} + +#endif + +// End of code generation (mrdivide_helper.h) diff --git a/cpp/RAT/mtimes.cpp b/cpp/RAT/mtimes.cpp new file mode 100644 index 00000000..7be121b4 --- /dev/null +++ b/cpp/RAT/mtimes.cpp @@ -0,0 +1,174 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// mtimes.cpp +// +// Code generation for function 'mtimes' +// + +// Include files +#include "mtimes.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace blas + { + void b_mtimes(const ::coder::array &A, const ::coder::array< + real_T, 2U> &B, ::coder::array &C) + { + int32_T inner; + int32_T mc; + int32_T nc; + mc = A.size(1) - 1; + inner = A.size(0); + nc = B.size(1); + C.set_size(A.size(1), B.size(1)); + for (int32_T j{0}; j < nc; j++) { + for (int32_T i{0}; i <= mc; i++) { + C[i + C.size(0) * j] = 0.0; + } + + for (int32_T k{0}; k < inner; k++) { + real_T bkj; + bkj = B[k + B.size(0) * j]; + for (int32_T i{0}; i <= mc; i++) { + C[i + C.size(0) * j] = C[i + C.size(0) * j] + A[k + A.size(0) * + i] * bkj; + } + } + } + } + + void mtimes(const ::coder::array &A, const ::coder::array< + real_T, 2U> &B, real_T C_data[], int32_T C_size[2]) + { + int32_T inner; + int32_T mc; + int32_T nc; + mc = A.size(0) - 1; + inner = A.size(1); + nc = B.size(0); + C_size[0] = A.size(0); + C_size[1] = B.size(0); + for (int32_T j{0}; j < nc; j++) { + if (mc >= 0) { + C_data[0] = 0.0; + } + + for (int32_T k{0}; k < inner; k++) { + real_T bkj; + bkj = B[B.size(0) * k]; + for (int32_T i{0}; i <= mc; i++) { + C_data[0] += A[A.size(0) * k] * bkj; + } + } + } + } + + void mtimes(const real_T A_data[], const int32_T A_size[2], const real_T + B_data[], const int32_T B_size[2], real_T C_data[], int32_T + C_size[2]) + { + int32_T inner; + int32_T mc; + int32_T nc; + mc = A_size[0] - 1; + inner = A_size[1]; + nc = B_size[1]; + C_size[0] = A_size[0]; + C_size[1] = B_size[1]; + for (int32_T j{0}; j < nc; j++) { + if (mc >= 0) { + C_data[0] = 0.0; + } + + for (int32_T k{0}; k < inner; k++) { + real_T bkj; + bkj = B_data[0]; + for (int32_T i{0}; i <= mc; i++) { + C_data[0] += A_data[0] * bkj; + } + } + } + } + + void mtimes(const ::coder::array &A, const ::coder::array< + creal_T, 2U> &B, ::coder::array &C) + { + int32_T inner; + int32_T n; + inner = A.size(1); + n = B.size(0); + C.set_size(1, B.size(0)); + for (int32_T j{0}; j < n; j++) { + real_T s_im; + real_T s_re; + s_re = 0.0; + s_im = 0.0; + for (int32_T k{0}; k < inner; k++) { + real_T A_re_tmp; + real_T B_im; + real_T B_re; + real_T b_A_re_tmp; + B_re = B[j + B.size(0) * k].re; + B_im = -B[j + B.size(0) * k].im; + A_re_tmp = A[k].re; + b_A_re_tmp = A[k].im; + s_re += A_re_tmp * B_re - b_A_re_tmp * B_im; + s_im += A_re_tmp * B_im + b_A_re_tmp * B_re; + } + + C[j].re = s_re; + C[j].im = s_im; + } + } + + void mtimes(const ::coder::array &A, const ::coder::array< + real_T, 2U> &B, ::coder::array &C) + { + int32_T inner; + int32_T nc; + inner = A.size(1); + nc = B.size(0); + C.set_size(1, B.size(0)); + for (int32_T j{0}; j < nc; j++) { + C[j] = 0.0; + for (int32_T k{0}; k < inner; k++) { + C[j] = C[j] + A[k] * B[j + B.size(0) * k]; + } + } + } + + void mtimes(const ::coder::array &A, const ::coder::array< + real_T, 1U> &B, ::coder::array &C) + { + int32_T inner; + int32_T mc; + mc = A.size(0) - 1; + inner = A.size(1); + C.set_size(A.size(0)); + for (int32_T i{0}; i <= mc; i++) { + C[i] = 0.0; + } + + for (int32_T k{0}; k < inner; k++) { + for (int32_T i{0}; i <= mc; i++) { + C[i] = C[i] + A[i + A.size(0) * k] * B[k]; + } + } + } + } + } + } +} + +// End of code generation (mtimes.cpp) diff --git a/cpp/RAT/mtimes.h b/cpp/RAT/mtimes.h new file mode 100644 index 00000000..d856edb1 --- /dev/null +++ b/cpp/RAT/mtimes.h @@ -0,0 +1,48 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// mtimes.h +// +// Code generation for function 'mtimes' +// +#ifndef MTIMES_H +#define MTIMES_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace blas + { + void b_mtimes(const ::coder::array &A, const ::coder::array< + real_T, 2U> &B, ::coder::array &C); + void mtimes(const ::coder::array &A, const ::coder::array< + real_T, 2U> &B, real_T C_data[], int32_T C_size[2]); + void mtimes(const real_T A_data[], const int32_T A_size[2], const real_T + B_data[], const int32_T B_size[2], real_T C_data[], int32_T + C_size[2]); + void mtimes(const ::coder::array &A, const ::coder::array< + creal_T, 2U> &B, ::coder::array &C); + void mtimes(const ::coder::array &A, const ::coder::array< + real_T, 2U> &B, ::coder::array &C); + void mtimes(const ::coder::array &A, const ::coder::array< + real_T, 1U> &B, ::coder::array &C); + } + } + } +} + +#endif + +// End of code generation (mtimes.h) diff --git a/cpp/RAT/multrnd.cpp b/cpp/RAT/multrnd.cpp new file mode 100644 index 00000000..bb42fb11 --- /dev/null +++ b/cpp/RAT/multrnd.cpp @@ -0,0 +1,200 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// multrnd.cpp +// +// Code generation for function 'multrnd' +// + +// Include files +#include "multrnd.h" +#include "combineVectorElements.h" +#include "rand.h" +#include "rt_nonfinite.h" +#include "sum.h" +#include "coder_array.h" + +// Function Declarations +namespace RAT +{ + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const real_T in3_data[], int32_T in4); +} + +// Function Definitions +namespace RAT +{ + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const real_T in3_data[], int32_T in4) + { + ::coder::array b_in1; + real_T in3; + int32_T i; + int32_T loop_ub; + int32_T stride_0_1; + int32_T stride_1_1; + in3 = in3_data[in4]; + if (in2.size(1) == 1) { + i = in1.size(1); + } else { + i = in2.size(1); + } + + b_in1.set_size(1, i); + stride_0_1 = (in1.size(1) != 1); + stride_1_1 = (in2.size(1) != 1); + if (in2.size(1) == 1) { + loop_ub = in1.size(1); + } else { + loop_ub = in2.size(1); + } + + for (i = 0; i < loop_ub; i++) { + b_in1[i] = in1[i * stride_0_1] + static_cast(in2[i * stride_1_1] > + in3); + } + + in1.set_size(1, b_in1.size(1)); + loop_ub = b_in1.size(1); + for (i = 0; i < loop_ub; i++) { + in1[i] = b_in1[i]; + } + } + + void multrnd(real_T n, const real_T p_data[], const int32_T p_size[2], real_T + X_data[], int32_T X_size[2]) + { + ::coder::array b_p_data; + ::coder::array o; + ::coder::array r; + ::coder::array b_o; + real_T s_data[3]; + real_T P; + int32_T loop_ub_tmp; + + // MULTRND Multinomial random sequence of m simulations of k outcomes with p probabiltites + // in n trials. + // Y = MULTRND(N,P,M) generates a random sequence of m simulations of k integers from a + // multinomial distribution with n trials and k outcomes, where the probability for each + // simulation is, + // n! + // ---------------------- × p1^n1 × p2^n2 × . . . × pk^nk . + // n1! × n2! × . . . × nk! + // + // Then, a single sample {n1, n2, . . . , nk} have a multinomial joint distribution with + // parameters n and p1, p2, . . . , pk. The parameter n is called the number of trials; + // the parameters p1, p2, . . . , pk are called the category probabilities; k is called + // the number of categories. + // + // Syntax: function [X,Y] = multrnd(n,p,m) + // + // Inputs: + // n - number of trials. + // p - vector of associated probabilities. + // m - number of simulations (default = 1). + // Outputs: + // X - multinomial random deviates (default). + // Y - multinomial probabilities of the generated random deviates (optional). + // + // Example. We are interested to get a multinomial random values of 4 outcomes with + // associated probabilities p=[0.1 0.06 .7 .14] with 2678 trials in 10 simulations. + // + // Calling on Matlab the function: + // [X Y] = multrnd(n,p,m) + // + // where n = 2678, p = [0.1 0.06 .7 .14] and m = 10 + // + // Answer is: + // + // X = + // 271 152 1873 382 + // 249 154 1890 385 + // 266 172 1862 378 + // 290 147 1882 359 + // 247 153 1873 405 + // 291 155 1842 390 + // 268 141 1900 369 + // 248 158 1899 373 + // 267 181 1855 375 + // 259 175 1884 360 + // + // Y = + // 0.1012 0.0568 0.6994 0.1426 + // 0.0930 0.0575 0.7058 0.1438 + // 0.0993 0.0642 0.6953 0.1412 + // 0.1083 0.0549 0.7028 0.1341 + // 0.0922 0.0571 0.6994 0.1512 + // 0.1087 0.0579 0.6878 0.1456 + // 0.1001 0.0527 0.7095 0.1378 + // 0.0926 0.0590 0.7091 0.1393 + // 0.0997 0.0676 0.6927 0.1400 + // 0.0967 0.0653 0.7035 0.1344 + // + // Created by A. Trujillo-Ortiz, R. Hernandez-Walls and A. Castro-Perez + // Facultad de Ciencias Marinas + // Universidad Autonoma de Baja California + // Apdo. Postal 453 + // Ensenada, Baja California + // Mexico. + // atrujo@uabc.mx + // Copyright (C) January 12, 2005. + // + // To cite this file, this would be an appropriate format: + // Trujillo-Ortiz, A., R. Hernandez-Walls and A. Castro-Perez. (2005). multrnd: + // Multinomial random sequence. A MATLAB file. [WWW document]. URL http:// + // www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=6788 + // + // References: + // + // Abramowitz, M. and Stegun,I. A. (1964), Handbook of Mathematical + // Functions, Government Printing Office, 26.1.20. Available on + // Internet at the URL address http://hcohl.shell42.com/as/frameindex.htm + // + b_p_data.set((real_T *)&p_data[0], p_size[0], p_size[1]); + P = coder::sum(b_p_data); + + // if P ~= 1, + // error('The sum of the input probabilities must be equal 1.') + // return, + // end; + loop_ub_tmp = static_cast(n); + o.set_size(1, loop_ub_tmp); + for (int32_T i{0}; i < loop_ub_tmp; i++) { + o[i] = 1.0; + } + + s_data[0] = p_data[0] / P; + s_data[1] = p_data[1] / P; + s_data[2] = p_data[2] / P; + s_data[1] += s_data[0]; + s_data[2] += s_data[1]; + coder::b_rand(n, r); + for (int32_T j{0}; j < 3; j++) { + loop_ub_tmp = o.size(1); + if (o.size(1) == r.size(1)) { + o.set_size(1, o.size(1)); + for (int32_T i{0}; i < loop_ub_tmp; i++) { + o[i] = o[i] + static_cast(r[i] > s_data[j]); + } + } else { + binary_expand_op(o, r, s_data, j); + } + } + + X_size[0] = 1; + X_size[1] = 3; + loop_ub_tmp = o.size(1); + for (int32_T j{0}; j < 3; j++) { + b_o.set_size(1, o.size(1)); + for (int32_T i{0}; i < loop_ub_tmp; i++) { + b_o[i] = (o[i] == static_cast(j) + 1.0); + } + + X_data[j] = coder::combineVectorElements(b_o); + } + } +} + +// End of code generation (multrnd.cpp) diff --git a/cpp/RAT/multrnd.h b/cpp/RAT/multrnd.h new file mode 100644 index 00000000..43dc78a2 --- /dev/null +++ b/cpp/RAT/multrnd.h @@ -0,0 +1,27 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// multrnd.h +// +// Code generation for function 'multrnd' +// +#ifndef MULTRND_H +#define MULTRND_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void multrnd(real_T n, const real_T p_data[], const int32_T p_size[2], real_T + X_data[], int32_T X_size[2]); +} + +#endif + +// End of code generation (multrnd.h) diff --git a/cpp/RAT/nest2pos.cpp b/cpp/RAT/nest2pos.cpp new file mode 100644 index 00000000..3713cf8a --- /dev/null +++ b/cpp/RAT/nest2pos.cpp @@ -0,0 +1,246 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// nest2pos.cpp +// +// Code generation for function 'nest2pos' +// + +// Include files +#include "nest2pos.h" +#include "find.h" +#include "minOrMax.h" +#include "rand.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Declarations +namespace RAT +{ + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3, const int32_T + in4[2], real_T in5, real_T in6); +} + +// Function Definitions +namespace RAT +{ + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3, const int32_T + in4[2], real_T in5, real_T in6) + { + ::coder::array c_in2; + int32_T b_in2; + int32_T i; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_1_0; + b_in2 = in2.size(1); + in1.set_size(static_cast(in5) + in4[1]); + loop_ub = in4[1]; + for (i = 0; i < loop_ub; i++) { + in1[i] = -in3[i] / in5; + } + + loop_ub = static_cast(in5); + for (i = 0; i < loop_ub; i++) { + in1[i + in4[1]] = -in6 / in5; + } + + if (in1.size(0) == 1) { + i = in2.size(0); + } else { + i = in1.size(0); + } + + c_in2.set_size(i); + stride_0_0 = (in2.size(0) != 1); + stride_1_0 = (in1.size(0) != 1); + if (in1.size(0) == 1) { + loop_ub = in2.size(0); + } else { + loop_ub = in1.size(0); + } + + for (i = 0; i < loop_ub; i++) { + c_in2[i] = in2[i * stride_0_0 + in2.size(0) * (b_in2 - 1)] + in1[i * + stride_1_0]; + } + + in1.set_size(c_in2.size(0)); + loop_ub = c_in2.size(0); + for (i = 0; i < loop_ub; i++) { + in1[i] = c_in2[i]; + } + } + + void nest2pos(const ::coder::array &nest_samples, real_T Nlive, :: + coder::array &post_samples) + { + ::coder::array b_nest_samples; + ::coder::array y; + ::coder::array b_y; + ::coder::array logWt; + ::coder::array idx; + ::coder::array b_logWt; + real_T b; + real_T logWtmax; + int32_T sizes[2]; + int32_T i; + int32_T k; + int32_T result; + int8_T input_sizes_idx_1; + boolean_T empty_non_axis_sizes; + + // + // post_samples = nest2pos(nest_samples, Nlive) + // + // Convert nested samples with Nlive livepoints + // to samples from the posterior distribution + // (logL values in last column of nest_samples) + // + // John Veitch 2009 (modified by J. Romano 2012) + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // calculate logWt = log(L*w) = logL + logw = logL - i/Nlive + b = static_cast(nest_samples.size(0)) - Nlive; + if (std::isnan(b)) { + sizes[0] = 1; + sizes[1] = 1; + } else if (b < 1.0) { + sizes[0] = 1; + sizes[1] = 0; + } else { + sizes[0] = 1; + sizes[1] = static_cast(b - 1.0) + 1; + } + + b = static_cast(nest_samples.size(0)) - Nlive; + if (std::isnan(b)) { + y.set_size(1, 1); + y[0] = rtNaN; + } else if (b < 1.0) { + y.set_size(1, 0); + } else { + y.set_size(1, static_cast(b - 1.0) + 1); + k = static_cast(b - 1.0); + for (i = 0; i <= k; i++) { + y[i] = static_cast(i) + 1.0; + } + } + + b = static_cast(nest_samples.size(0)) - Nlive; + i = static_cast(Nlive) + sizes[1]; + if (nest_samples.size(0) == i) { + b_y.set_size(i); + k = sizes[1]; + for (i = 0; i < k; i++) { + b_y[i] = -y[i] / Nlive; + } + + k = static_cast(Nlive); + for (i = 0; i < k; i++) { + b_y[i + sizes[1]] = -b / Nlive; + } + + logWt.set_size(nest_samples.size(0)); + k = nest_samples.size(0); + for (i = 0; i < k; i++) { + logWt[i] = nest_samples[i + nest_samples.size(0) * (nest_samples.size(1) + - 1)] + b_y[i]; + } + } else { + binary_expand_op(logWt, nest_samples, y, sizes, Nlive, b); + } + + // posterior samples are given by the normalized weight + logWtmax = coder::internal::maximum(logWt); + k = logWt.size(0); + for (i = 0; i < k; i++) { + logWt[i] = logWt[i] - logWtmax; + } + + // Wt -> Wt/Wtmax + // accept a nested sample as a posterior sample only if its + // value is > than a random number drawn from a unif distribution + coder::b_rand(static_cast(nest_samples.size(0)), b_y); + i = b_y.size(0); + for (k = 0; k < i; k++) { + b_y[k] = std::log(b_y[k]); + } + + if (logWt.size(0) == b_y.size(0)) { + b_logWt.set_size(logWt.size(0)); + k = logWt.size(0); + for (i = 0; i < k; i++) { + b_logWt[i] = (logWt[i] > b_y[i]); + } + + coder::eml_find(b_logWt, idx); + } else { + binary_expand_op(idx, logWt, b_y); + } + + // attach log of posterior probabilities as final column of + // the posterior samples + // post_samples(:,Ncol+1) = logWt(idx); + if ((idx.size(0) != 0) && (nest_samples.size(1) != 0)) { + result = idx.size(0); + } else if (idx.size(0) != 0) { + result = idx.size(0); + } else { + result = 0; + } + + empty_non_axis_sizes = (result == 0); + if (empty_non_axis_sizes || ((idx.size(0) != 0) && (nest_samples.size(1) != + 0))) { + input_sizes_idx_1 = static_cast(nest_samples.size(1)); + } else { + input_sizes_idx_1 = 0; + } + + if (empty_non_axis_sizes || (idx.size(0) != 0)) { + sizes[1] = 1; + } else { + sizes[1] = 0; + } + + b_nest_samples.set_size(idx.size(0), nest_samples.size(1)); + k = nest_samples.size(1); + for (i = 0; i < k; i++) { + int32_T loop_ub; + loop_ub = idx.size(0); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_nest_samples[i1 + b_nest_samples.size(0) * i] = nest_samples[(idx[i1] + + nest_samples.size(0) * i) - 1]; + } + } + + b_y.set_size(idx.size(0)); + k = idx.size(0); + for (i = 0; i < k; i++) { + b_y[i] = logWt[idx[i] - 1]; + } + + post_samples.set_size(result, input_sizes_idx_1 + sizes[1]); + k = input_sizes_idx_1; + for (i = 0; i < k; i++) { + for (int32_T i1{0}; i1 < result; i1++) { + post_samples[i1 + post_samples.size(0) * i] = b_nest_samples[i1 + result + * i]; + } + } + + k = sizes[1]; + for (i = 0; i < k; i++) { + for (int32_T i1{0}; i1 < result; i1++) { + post_samples[i1 + post_samples.size(0) * input_sizes_idx_1] = b_y[i1]; + } + } + } +} + +// End of code generation (nest2pos.cpp) diff --git a/cpp/RAT/nest2pos.h b/cpp/RAT/nest2pos.h new file mode 100644 index 00000000..20b37c1a --- /dev/null +++ b/cpp/RAT/nest2pos.h @@ -0,0 +1,28 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// nest2pos.h +// +// Code generation for function 'nest2pos' +// +#ifndef NEST2POS_H +#define NEST2POS_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void nest2pos(const ::coder::array &nest_samples, real_T Nlive, :: + coder::array &post_samples); +} + +#endif + +// End of code generation (nest2pos.h) diff --git a/cpp/RAT/nestedSampler.cpp b/cpp/RAT/nestedSampler.cpp new file mode 100644 index 00000000..8c16065e --- /dev/null +++ b/cpp/RAT/nestedSampler.cpp @@ -0,0 +1,687 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// nestedSampler.cpp +// +// Code generation for function 'nestedSampler' +// + +// Include files +#include "nestedSampler.h" +#include "RATMain_data.h" +#include "RATMain_internal_types.h" +#include "RATMain_rtwutil.h" +#include "RATMain_types.h" +#include "cov.h" +#include "drawMCMC.h" +#include "drawMultiNest.h" +#include "ifWhileCond.h" +#include "length.h" +#include "logPlus.h" +#include "mchol.h" +#include "minOrMax.h" +#include "mod.h" +#include "mrdivide_helper.h" +#include "mtimes.h" +#include "nest2pos.h" +#include "nonSingletonDim.h" +#include "nsIntraFun.h" +#include "optimalEllipsoids.h" +#include "rand.h" +#include "randn.h" +#include "rescaleParameters.h" +#include "rt_nonfinite.h" +#include "scaleParameters.h" +#include "sort.h" +#include "sqrt1.h" +#include "sum.h" +#include "useConstantDim.h" +#include "coder_array.h" +#include +#include + +// Function Definitions +namespace RAT +{ + void nestedSampler(const c_struct_T *data_f1, const struct2_T *data_f2, const + cell_11 *data_f4, real_T Nlive, real_T Nmcmc, real_T + tolerance, const ::coder::array &prior, real_T * + logZ, ::coder::array &nest_samples, ::coder:: + array &post_samples, real_T *H) + { + ::coder::array Bs; + ::coder::array FS; + ::coder::array VEs; + ::coder::array Vtot; + ::coder::array b_Bs; + ::coder::array b_livepoints; + ::coder::array b_nest_samples; + ::coder::array b_nest_samples_data; + ::coder::array cholmat; + ::coder::array l; + ::coder::array livepoints; + ::coder::array livepoints_sorted; + ::coder::array mus; + ::coder::array ns; + ::coder::array r; + ::coder::array result; + ::coder::array toAdd; + ::coder::array b; + ::coder::array logL; + ::coder::array iidx; + ::coder::array b_FS; + real_T nest_samples_data[49]; + real_T b_dv[2]; + real_T a; + real_T a_tmp; + real_T d; + real_T j; + real_T logLmax; + real_T logLmin; + real_T logw; + real_T tol; + real_T varargin_2; + int32_T D; + int32_T K; + int32_T i; + int32_T i1; + int32_T i2; + int32_T iindx; + int32_T input_sizes_idx_1; + int32_T loop_ub_tmp; + int32_T sizes_idx_1; + boolean_T empty_non_axis_sizes; + + // function [logZ, nest_samples, post_samples] = nestedSampler(data, ... + // Nlive, Nmcmc, tolerance, likelihood, model, prior, extraparams) + // + // This function performs nested sampling of the likelihood function from + // the given prior (given a set of data, a model, and a set of extra model + // parameters). + // + // If Nmcmc > 0, new samples will be drawn from a proposal using an MCMC + // and differential evolution. The sampling will stop once the + // tolerance critereon has been reached. This method is that of Veitch & + // Vecchio. + // + // If Nmcmc = 0, new samples will be drawn from a set of bounding ellipsoids + // constructed using the MultiNest algorithm for partitioning live points. + // + // The likelihood should be the function handle of a likelihood function to + // use. This should return the log likelihood of the model parameters given + // the data. + // + // The model should be the function handle of the model function to be + // passed to the likelihood function. + // + // ------------------- STRUCTURE OF PRIOR CHANGED FOR RAT ---------------- + // The prior should be a cell array with each cell containing five values: + // parameter name (string) + // prior type (string) e.g. 'uniform', 'gaussian' of 'jeffreys' + // minimum value (for uniform prior), or mean value (for Gaussian prior) + // maximum value (for uniform prior), or width (for Gaussian prior) + // parameter behaviour (string): + // 'reflect' - if the parameters reflect off the boundaries + // 'cyclic' - if the parameter space is cyclic + // 'fixed' - if the parameters have fixe boundaries + // '' - for gaussian priors + // e.g., prior = {'h0', 'uniform', 0, 1, 'reflect'; + // 'r', 'gaussian', 0, 5, ''; + // 'phi', 'uniform', 0, 2*pi, 'cyclic'}; + // + // ----------------------------------------------------------------------- + // + // extraparams is a cell array of fixed extra parameters (in addition + // to those specified by prior) used by the model + // e.g. extraparams = {'phi', 2; + // 'x', 4}; + // + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + verbose = 1.0; + DEBUG = 0.0; + + // get the number of parameters from the prior array + ns.set_size(1, 1); + ns[0] = 1.0; + + // coder.varsize('ns'); + mus.set_size(1, 1); + mus[0] = 1.0; + + // coder.varsize('mus'); + cholmat.set_size(1, 1); + cholmat[0] = 1.0; + + // get the number of parameters from the prior array + D = prior.size(0); + + // initialize array of samples for posterior + nest_samples.set_size(1, prior.size(0) + 1); + sizes_idx_1 = prior.size(0) + 1; + for (i = 0; i < sizes_idx_1; i++) { + nest_samples[nest_samples.size(0) * i] = 0.0; + } + + // draw the set of initial live points from the prior + loop_ub_tmp = static_cast(Nlive); + livepoints.set_size(loop_ub_tmp, prior.size(0)); + sizes_idx_1 = prior.size(0); + for (i = 0; i < sizes_idx_1; i++) { + for (i1 = 0; i1 < loop_ub_tmp; i1++) { + livepoints[i1 + livepoints.size(0) * i] = 0.0; + } + } + + i = prior.size(0); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T priortype; + priortype = prior[b_i]; + if (priortype == 1.0) { + real_T p3; + + // uniform + p3 = prior[b_i + prior.size(0) * 3]; + a = prior[b_i + prior.size(0) * 4] - p3; + coder::b_rand(Nlive, b); + sizes_idx_1 = b.size(0); + for (i1 = 0; i1 < sizes_idx_1; i1++) { + livepoints[i1 + livepoints.size(0) * b_i] = p3 + a * b[i1]; + } + } else if (priortype == 2.0) { + real_T p3; + + // gaussian + p3 = prior[b_i + prior.size(0)]; + a = prior[b_i + prior.size(0) * 2]; + coder::randn(Nlive, b); + sizes_idx_1 = b.size(0); + for (i1 = 0; i1 < sizes_idx_1; i1++) { + livepoints[i1 + livepoints.size(0) * b_i] = p3 + a * b[i1]; + } + } else if (priortype == 3.0) { + // jeffreys + a_tmp = std::log10(prior[b_i + prior.size(0)]); + a = std::log10(prior[b_i + prior.size(0) * 2]) - a_tmp; + coder::b_rand(Nlive, b); + sizes_idx_1 = b.size(0); + for (i1 = 0; i1 < sizes_idx_1; i1++) { + varargin_2 = a_tmp + a * b[i1]; + livepoints[i1 + livepoints.size(0) * b_i] = rt_powd_snf(10.0, + varargin_2); + } + } + } + + // calculate the log likelihood of all the live points + logL.set_size(loop_ub_tmp); + for (int32_T b_i{0}; b_i < loop_ub_tmp; b_i++) { + // parvals = loopCell(livepoints(i,:)); + sizes_idx_1 = livepoints.size(1); + b_livepoints.set_size(1, livepoints.size(1)); + for (i = 0; i < sizes_idx_1; i++) { + b_livepoints[i] = livepoints[b_i + livepoints.size(0) * i]; + } + + logL[b_i] = nsIntraFun(data_f1, data_f2, data_f4, b_livepoints); + } + + // now scale the parameters, so that uniform parameters range from 0->1, + // and Gaussian parameters have a mean of zero and unit standard deviation + for (int32_T b_i{0}; b_i < loop_ub_tmp; b_i++) { + sizes_idx_1 = livepoints.size(1); + b_livepoints.set_size(1, livepoints.size(1)); + for (i = 0; i < sizes_idx_1; i++) { + b_livepoints[i] = livepoints[b_i + livepoints.size(0) * i]; + } + + scaleParameters(prior, b_livepoints, b); + sizes_idx_1 = livepoints.size(1); + for (i = 0; i < sizes_idx_1; i++) { + livepoints[b_i + livepoints.size(0) * i] = b[i]; + } + } + + // initial tolerance + tol = rtInf; + + // initial width of prior volume (from X_0=1 to X_1=exp(-1/N)) + logw = std::log(1.0 - std::exp(-1.0 / Nlive)); + + // initial log evidence (Z=0) + *logZ = rtMinusInf; + + // initial information + *H = 0.0; + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // some initial values if MCMC nested sampling is used + // value to scale down the covariance matrix - CAN CHANGE THIS IF REQUIRED + // %%%%%%%%%%%%%% + // some initial values if MultiNest sampling is used + // h values from bottom of p. 1605 of Feroz and Hobson + FS.set_size(1, 1); + FS[0] = 1.1; + + // start FS at h, so ellipsoidal partitioning is done first time + K = 1; + + // start with one cluster of live points + // get maximum likelihood + logLmax = coder::internal::maximum(logL); + Bs.set_size(prior.size(0), prior.size(0)); + sizes_idx_1 = prior.size(0); + for (i = 0; i < sizes_idx_1; i++) { + input_sizes_idx_1 = prior.size(0); + for (i1 = 0; i1 < input_sizes_idx_1; i1++) { + Bs[i1 + Bs.size(0) * i] = 0.0; + } + } + + VEs.set_size(prior.size(0), 1); + sizes_idx_1 = prior.size(0); + for (i = 0; i < sizes_idx_1; i++) { + VEs[i] = 0.0; + } + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // initialize iteration counter + j = 1.0; + + // MAIN LOOP + while ((tol > tolerance) || (j <= Nlive)) { + real_T VS; + real_T logWt; + real_T logZold; + + // expected value of true remaining prior volume X + VS = std::exp(-j / Nlive); + + // find minimum of likelihoods + coder::internal::minimum(logL, &logLmin, &iindx); + + // set the sample to the minimum value + // (Need to do some work brcause we are growing nest_samples in a loop) + if (j == 1.0) { + sizes_idx_1 = livepoints.size(1); + for (i = 0; i < sizes_idx_1; i++) { + nest_samples[nest_samples.size(0) * i] = livepoints[(iindx + + livepoints.size(0) * i) - 1]; + } + + nest_samples[nest_samples.size(0) * livepoints.size(1)] = logLmin; + } else { + toAdd.set_size(1, livepoints.size(1) + 1); + sizes_idx_1 = livepoints.size(1); + for (i = 0; i < sizes_idx_1; i++) { + toAdd[i] = livepoints[(iindx + livepoints.size(0) * i) - 1]; + } + + toAdd[livepoints.size(1)] = logLmin; + if (nest_samples.size(1) != 0) { + input_sizes_idx_1 = nest_samples.size(1); + } else { + input_sizes_idx_1 = toAdd.size(1); + } + + if (nest_samples.size(1) != 0) { + sizes_idx_1 = nest_samples.size(0); + } else { + sizes_idx_1 = 0; + } + + if (nest_samples.size(1) != 0) { + i = nest_samples.size(0); + } else { + i = 0; + } + + b_nest_samples.set_size(i + 1, input_sizes_idx_1); + for (i = 0; i < input_sizes_idx_1; i++) { + for (i1 = 0; i1 < sizes_idx_1; i1++) { + b_nest_samples[i1 + b_nest_samples.size(0) * i] = nest_samples[i1 + + sizes_idx_1 * i]; + } + } + + for (i = 0; i < input_sizes_idx_1; i++) { + b_nest_samples[sizes_idx_1 + b_nest_samples.size(0) * i] = toAdd[i]; + } + + nest_samples.set_size(b_nest_samples.size(0), b_nest_samples.size(1)); + sizes_idx_1 = b_nest_samples.size(1); + for (i = 0; i < sizes_idx_1; i++) { + input_sizes_idx_1 = b_nest_samples.size(0); + for (i1 = 0; i1 < input_sizes_idx_1; i1++) { + nest_samples[i1 + nest_samples.size(0) * i] = b_nest_samples[i1 + + b_nest_samples.size(0) * i]; + } + } + } + + // get the log weight (Wt = L*w) + logWt = logLmin + logw; + + // save old evidence and information + logZold = *logZ; + + // update evidence, information, and width + *logZ = logPlus(*logZ, logWt); + if (std::isnan(*H)) { + a = 0.0; + } else { + a = *H; + } + + *H = (std::exp(logWt - *logZ) * logLmin + std::exp(logZold - *logZ) * (a + + logZold)) - *logZ; + + // logw = logw - logt(Nlive); + logw -= 1.0 / Nlive; + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + if (Nmcmc > 0.0) { + // do MCMC nested sampling + // get the Cholesky decomposed covariance of the live points + // (do every 100th iteration - CAN CHANGE THIS IF REQUIRED) + if (coder::b_mod(j - 1.0) == 0.0) { + // NOTE that for numbers of parameters >~10 covariances are often + // not positive definite and cholcov will have "problems". + // cholmat = cholcov(propscale*cov(livepoints)); + // use modified Cholesky decomposition, which works even for + // matrices that are not quite positive definite + // from http://infohost.nmt.edu/~borchers/ldlt.html + // (via http://stats.stackexchange.com/questions/6364 + // /making-square-root-of-covariance-matrix-positive-definite-matlab + coder::cov(livepoints, result); + b_Bs.set_size(result.size(0), result.size(1)); + sizes_idx_1 = result.size(1); + for (i = 0; i < sizes_idx_1; i++) { + input_sizes_idx_1 = result.size(0); + for (i1 = 0; i1 < input_sizes_idx_1; i1++) { + b_Bs[i1 + b_Bs.size(0) * i] = 0.1 * result[i1 + result.size(0) * i]; + } + } + + mchol(b_Bs, l, result); + coder::b_sqrt(result); + coder::internal::blas::b_mtimes(l, result, cholmat); + + // plot3(livepoints(:,1), livepoints(:,2), livepoints(:,3), 'r.'); + // drawnow(); + } + + // draw a new sample using mcmc algorithm + drawMCMC(livepoints, cholmat, logLmin, prior, data_f1, data_f2, data_f4, + Nmcmc, b_livepoints, &logL[iindx - 1]); + sizes_idx_1 = b_livepoints.size(1); + for (i = 0; i < sizes_idx_1; i++) { + livepoints[(iindx + livepoints.size(0) * i) - 1] = b_livepoints[i]; + } + } else { + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // do MultiNest nested sampling + // separate out ellipsoids + b_FS.set_size(1, FS.size(1)); + sizes_idx_1 = FS.size(1); + for (i = 0; i < sizes_idx_1; i++) { + b_FS[b_FS.size(0) * i] = (FS[i] >= 1.1); + } + + if (coder::internal::ifWhileCond(b_FS)) { + // NOTE: THIS CODE IS GUARANTEED TO RUN THE 1ST TIME THROUGH + // calculate optimal ellipsoids + optimalEllipsoids(livepoints, VS, Bs, mus, VEs, ns); + K = coder::internal::intlength(VEs.size(0), VEs.size(1)); + + // number of ellipsoids (subclusters) + } else { + // simply rescale the bounding ellipsoids + if (K - 1 >= 0) { + d = std::exp(-(j + 1.0) / Nlive); + b_dv[0] = 1.0; + } + + for (int32_T k{0}; k < K; k++) { + real_T scalefac; + b_dv[1] = d * ns[k] / Nlive / VEs[k]; + scalefac = coder::internal::maximum(b_dv); + + // scale bounding matrix and volume + if (scalefac != 1.0) { + a_tmp = ((static_cast(k) + 1.0) - 1.0) * + static_cast(D) + 1.0; + varargin_2 = (static_cast(k) + 1.0) * static_cast + (D); + if (a_tmp > varargin_2) { + i = 0; + i1 = 0; + i2 = 1; + } else { + i = static_cast(a_tmp) - 1; + i1 = static_cast(varargin_2); + i2 = static_cast(a_tmp); + } + + a_tmp = rt_powd_snf(scalefac, 2.0 / static_cast(D)); + sizes_idx_1 = i1 - i; + input_sizes_idx_1 = Bs.size(1); + b_Bs.set_size(sizes_idx_1, Bs.size(1)); + for (i1 = 0; i1 < input_sizes_idx_1; i1++) { + for (int32_T i3{0}; i3 < sizes_idx_1; i3++) { + b_Bs[i3 + b_Bs.size(0) * i1] = Bs[(i + i3) + Bs.size(0) * i1] * + a_tmp; + } + } + + sizes_idx_1 = b_Bs.size(1); + for (i = 0; i < sizes_idx_1; i++) { + input_sizes_idx_1 = b_Bs.size(0); + for (i1 = 0; i1 < input_sizes_idx_1; i1++) { + Bs[((i2 + i1) + Bs.size(0) * i) - 1] = b_Bs[i1 + b_Bs.size(0) * + i]; + } + } + + VEs[k] = scalefac * VEs[k]; + } + } + } + + // calculate ratio of volumes (FS>=1) and cumulative fractional volume + coder::sum(VEs, Vtot); + FS.set_size(1, Vtot.size(1)); + sizes_idx_1 = Vtot.size(1); + for (i = 0; i < sizes_idx_1; i++) { + FS[i] = Vtot[i] / VS; + } + + // draw a new sample using multinest algorithm + result.set_size(VEs.size(0), VEs.size(1)); + sizes_idx_1 = VEs.size(1); + for (i = 0; i < sizes_idx_1; i++) { + input_sizes_idx_1 = VEs.size(0); + for (i1 = 0; i1 < input_sizes_idx_1; i1++) { + result[i1 + result.size(0) * i] = VEs[i1 + VEs.size(0) * i]; + } + } + + coder::internal::useConstantDim(result, coder::internal::nonSingletonDim + (VEs)); + coder::internal::mrdiv(result, Vtot, b); + drawMultiNest(b, Bs, mus, logLmin, prior, data_f1, data_f2, data_f4, r, + &logL[iindx - 1]); + sizes_idx_1 = r.size(1); + for (i = 0; i < sizes_idx_1; i++) { + input_sizes_idx_1 = r.size(0); + for (i1 = 0; i1 < input_sizes_idx_1; i1++) { + livepoints[(iindx + livepoints.size(0) * i) - 1] = r[r.size(0) * i]; + } + } + } + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // update maximum likelihood if appropriate + a_tmp = logL[iindx - 1]; + if (a_tmp > logLmax) { + logLmax = a_tmp; + } + + // work out tolerance for stopping criterion + tol = logPlus(*logZ, logLmax - j / Nlive) - *logZ; + + // display progress (optional) + if (verbose != 0.0) { + if (j < 2.147483648E+9) { + i = static_cast(j); + } else { + i = MAX_int32_T; + } + + printf("log(Z): %.5e, tol = %.5e, K = %d, iteration = %d, H = %.5e\n", + *logZ, tol, K, i, *H); + fflush(stdout); + } + + // update counter + j++; + } + + // sort the remaining points (in order of likelihood) and add them on to + // the evidence + coder::internal::sort(logL, iidx); + livepoints_sorted.set_size(iidx.size(0), livepoints.size(1)); + sizes_idx_1 = livepoints.size(1); + for (i = 0; i < sizes_idx_1; i++) { + input_sizes_idx_1 = iidx.size(0); + for (i1 = 0; i1 < input_sizes_idx_1; i1++) { + livepoints_sorted[i1 + livepoints_sorted.size(0) * i] = livepoints + [(iidx[i1] + livepoints.size(0) * i) - 1]; + } + } + + for (int32_T b_i{0}; b_i < loop_ub_tmp; b_i++) { + *logZ = logPlus(*logZ, logL[b_i] + logw); + } + + // append the additional livepoints to the nested samples + if ((iidx.size(0) != 0) && (livepoints.size(1) != 0)) { + iindx = iidx.size(0); + } else if (logL.size(0) != 0) { + iindx = logL.size(0); + } else { + iindx = iidx.size(0); + } + + empty_non_axis_sizes = (iindx == 0); + if (empty_non_axis_sizes || ((iidx.size(0) != 0) && (livepoints.size(1) != 0))) + { + input_sizes_idx_1 = livepoints.size(1); + } else { + input_sizes_idx_1 = 0; + } + + if (empty_non_axis_sizes || (logL.size(0) != 0)) { + sizes_idx_1 = 1; + } else { + sizes_idx_1 = 0; + } + + result.set_size(iindx, input_sizes_idx_1 + sizes_idx_1); + for (i = 0; i < input_sizes_idx_1; i++) { + for (i1 = 0; i1 < iindx; i1++) { + result[i1 + result.size(0) * i] = livepoints_sorted[i1 + iindx * i]; + } + } + + for (i = 0; i < sizes_idx_1; i++) { + for (i1 = 0; i1 < iindx; i1++) { + result[i1 + result.size(0) * input_sizes_idx_1] = logL[i1]; + } + } + + if (nest_samples.size(1) != 0) { + iindx = nest_samples.size(1); + } else if ((result.size(0) != 0) && (result.size(1) != 0)) { + iindx = result.size(1); + } else { + iindx = 0; + if (result.size(1) > 0) { + iindx = result.size(1); + } + } + + empty_non_axis_sizes = (iindx == 0); + if (empty_non_axis_sizes || (nest_samples.size(1) != 0)) { + sizes_idx_1 = nest_samples.size(0); + } else { + sizes_idx_1 = 0; + } + + if (empty_non_axis_sizes || ((result.size(0) != 0) && (result.size(1) != 0))) + { + input_sizes_idx_1 = result.size(0); + } else { + input_sizes_idx_1 = 0; + } + + i = sizes_idx_1 + input_sizes_idx_1; + b_nest_samples.set_size(i, iindx); + for (i1 = 0; i1 < iindx; i1++) { + for (i2 = 0; i2 < sizes_idx_1; i2++) { + b_nest_samples[i2 + b_nest_samples.size(0) * i1] = nest_samples[i2 + + sizes_idx_1 * i1]; + } + } + + for (i1 = 0; i1 < iindx; i1++) { + for (i2 = 0; i2 < input_sizes_idx_1; i2++) { + b_nest_samples[(i2 + sizes_idx_1) + b_nest_samples.size(0) * i1] = + result[i2 + input_sizes_idx_1 * i1]; + } + } + + nest_samples.set_size(b_nest_samples.size(0), b_nest_samples.size(1)); + sizes_idx_1 = b_nest_samples.size(1); + for (i1 = 0; i1 < sizes_idx_1; i1++) { + input_sizes_idx_1 = b_nest_samples.size(0); + for (i2 = 0; i2 < input_sizes_idx_1; i2++) { + nest_samples[i2 + nest_samples.size(0) * i1] = b_nest_samples[i2 + + b_nest_samples.size(0) * i1]; + } + } + + // rescale the samples back to their true ranges + i = coder::internal::intlength(i, iindx); + for (int32_T b_i{0}; b_i < i; b_i++) { + if (nest_samples.size(1) - 1 < 1) { + sizes_idx_1 = 0; + } else { + sizes_idx_1 = nest_samples.size(1) - 1; + } + + for (i1 = 0; i1 < sizes_idx_1; i1++) { + nest_samples_data[i1] = nest_samples[b_i + nest_samples.size(0) * i1]; + } + + b_nest_samples_data.set(&nest_samples_data[0], 1, sizes_idx_1); + rescaleParameters(prior, b_nest_samples_data, b); + if (nest_samples.size(1) - 1 < 1) { + sizes_idx_1 = 0; + } else { + sizes_idx_1 = nest_samples.size(1) - 1; + } + + for (i1 = 0; i1 < sizes_idx_1; i1++) { + nest_samples[b_i + nest_samples.size(0) * i1] = b[i1]; + } + } + + // convert nested samples into posterior samples - nest2pos assumes that the + // final column in the sample chain is the log likelihood + nest2pos(nest_samples, Nlive, post_samples); + } +} + +// End of code generation (nestedSampler.cpp) diff --git a/cpp/RAT/nestedSampler.h b/cpp/RAT/nestedSampler.h new file mode 100644 index 00000000..b0d629d4 --- /dev/null +++ b/cpp/RAT/nestedSampler.h @@ -0,0 +1,39 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// nestedSampler.h +// +// Code generation for function 'nestedSampler' +// +#ifndef NESTEDSAMPLER_H +#define NESTEDSAMPLER_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct c_struct_T; + struct struct2_T; + struct cell_11; +} + +// Function Declarations +namespace RAT +{ + void nestedSampler(const c_struct_T *data_f1, const struct2_T *data_f2, const + cell_11 *data_f4, real_T Nlive, real_T Nmcmc, real_T + tolerance, const ::coder::array &prior, real_T * + logZ, ::coder::array &nest_samples, ::coder:: + array &post_samples, real_T *H); +} + +#endif + +// End of code generation (nestedSampler.h) diff --git a/cpp/RAT/nonSingletonDim.cpp b/cpp/RAT/nonSingletonDim.cpp new file mode 100644 index 00000000..d8b4b533 --- /dev/null +++ b/cpp/RAT/nonSingletonDim.cpp @@ -0,0 +1,48 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// nonSingletonDim.cpp +// +// Code generation for function 'nonSingletonDim' +// + +// Include files +#include "nonSingletonDim.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + int32_T nonSingletonDim(const ::coder::array &x) + { + int32_T dim; + dim = 2; + if (x.size(0) != 1) { + dim = 1; + } + + return dim; + } + + int32_T nonSingletonDim(const ::coder::array &x) + { + int32_T dim; + dim = 2; + if (x.size(0) != 1) { + dim = 1; + } + + return dim; + } + } + } +} + +// End of code generation (nonSingletonDim.cpp) diff --git a/cpp/RAT/nonSingletonDim.h b/cpp/RAT/nonSingletonDim.h new file mode 100644 index 00000000..58601492 --- /dev/null +++ b/cpp/RAT/nonSingletonDim.h @@ -0,0 +1,34 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// nonSingletonDim.h +// +// Code generation for function 'nonSingletonDim' +// +#ifndef NONSINGLETONDIM_H +#define NONSINGLETONDIM_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + int32_T nonSingletonDim(const ::coder::array &x); + int32_T nonSingletonDim(const ::coder::array &x); + } + } +} + +#endif + +// End of code generation (nonSingletonDim.h) diff --git a/cpp/RAT/norm.cpp b/cpp/RAT/norm.cpp new file mode 100644 index 00000000..bb7d8371 --- /dev/null +++ b/cpp/RAT/norm.cpp @@ -0,0 +1,131 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// norm.cpp +// +// Code generation for function 'norm' +// + +// Include files +#include "norm.h" +#include "rt_nonfinite.h" +#include "xnrm2.h" +#include "coder_array.h" +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + static real_T mat1norm(const ::coder::array &x); + static real_T vecpnorm(const ::coder::array &x); + } +} + +// Function Definitions +namespace RAT +{ + namespace coder + { + static real_T mat1norm(const ::coder::array &x) + { + real_T y; + int32_T j; + boolean_T exitg1; + y = 0.0; + j = 0; + exitg1 = false; + while ((!exitg1) && (j <= x.size(1) - 1)) { + real_T s; + int32_T i; + s = 0.0; + i = x.size(0); + for (int32_T b_i{0}; b_i < i; b_i++) { + s += std::abs(x[b_i + x.size(0) * j]); + } + + if (std::isnan(s)) { + y = rtNaN; + exitg1 = true; + } else { + if (s > y) { + y = s; + } + + j++; + } + } + + return y; + } + + static real_T vecpnorm(const ::coder::array &x) + { + real_T y; + int32_T i; + y = 0.0; + i = x.size(0) * x.size(1); + for (int32_T k{0}; k < i; k++) { + y += std::abs(x[k]); + } + + return y; + } + + real_T b_norm(const ::coder::array &x) + { + real_T y; + boolean_T MATRIX_INPUT_AND_P_IS_ONE; + boolean_T VECTOR_INPUT_AND_P_IS_NUMERIC; + VECTOR_INPUT_AND_P_IS_NUMERIC = false; + MATRIX_INPUT_AND_P_IS_ONE = false; + if ((x.size(0) == 1) || (x.size(1) == 1)) { + VECTOR_INPUT_AND_P_IS_NUMERIC = true; + } else { + MATRIX_INPUT_AND_P_IS_ONE = true; + } + + if ((x.size(0) == 0) || (x.size(1) == 0)) { + y = 0.0; + } else if (MATRIX_INPUT_AND_P_IS_ONE) { + y = mat1norm(x); + } else if (VECTOR_INPUT_AND_P_IS_NUMERIC) { + y = vecpnorm(x); + } else { + y = rtNaN; + } + + return y; + } + + real_T b_norm(const ::coder::array &x) + { + real_T y; + int32_T i; + y = 0.0; + i = x.size(0); + for (int32_T k{0}; k < i; k++) { + y += std::abs(x[k]); + } + + return y; + } + + real_T c_norm(const ::coder::array &x) + { + real_T y; + if (x.size(1) == 0) { + y = 0.0; + } else { + y = internal::blas::xnrm2(x.size(1), x); + } + + return y; + } + } +} + +// End of code generation (norm.cpp) diff --git a/cpp/RAT/norm.h b/cpp/RAT/norm.h new file mode 100644 index 00000000..9a6d8303 --- /dev/null +++ b/cpp/RAT/norm.h @@ -0,0 +1,32 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// norm.h +// +// Code generation for function 'norm' +// +#ifndef NORM_H +#define NORM_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + real_T b_norm(const ::coder::array &x); + real_T b_norm(const ::coder::array &x); + real_T c_norm(const ::coder::array &x); + } +} + +#endif + +// End of code generation (norm.h) diff --git a/cpp/RAT/nsIntraFun.cpp b/cpp/RAT/nsIntraFun.cpp new file mode 100644 index 00000000..007efcec --- /dev/null +++ b/cpp/RAT/nsIntraFun.cpp @@ -0,0 +1,76 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// nsIntraFun.cpp +// +// Code generation for function 'nsIntraFun' +// + +// Include files +#include "nsIntraFun.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "reflectivityCalculation.h" +#include "rt_nonfinite.h" +#include "unpackParams.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + real_T nsIntraFun(const c_struct_T *data_f1, const struct2_T *data_f2, const + cell_11 *data_f4, const ::coder::array &p) + { + c_struct_T problemStruct; + cell_wrap_9 a__1[6]; + d_struct_T b_problemStruct; + int32_T loop_ub; + problemStruct = *data_f1; + + // Removed use of cells.... + problemStruct.fitParams.set_size(1, p.size(1)); + loop_ub = p.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + problemStruct.fitParams[problemStruct.fitParams.size(0) * i] = p[i]; + } + + unpackParams(&problemStruct, data_f2->checks.fitParam, + data_f2->checks.fitBackgroundParam, data_f2->checks.fitQzshift, + data_f2->checks.fitScalefactor, data_f2->checks.fitBulkIn, + data_f2->checks.fitBulkOut, data_f2->checks.fitResolutionParam, + data_f2->checks.fitDomainRatio); + reflectivityCalculation(&problemStruct, data_f4, data_f2, &b_problemStruct, + a__1); + return -b_problemStruct.calculations.sumChi / 2.0; + } + + real_T nsIntraFun(const c_struct_T *data_f1, const struct2_T *data_f2, const + cell_11 *data_f4, const ::coder::array &p) + { + c_struct_T problemStruct; + cell_wrap_9 a__1[6]; + d_struct_T b_problemStruct; + int32_T p_idx_0; + problemStruct = *data_f1; + + // Removed use of cells.... + p_idx_0 = p.size(0); + problemStruct.fitParams.set_size(p.size(0), 1); + for (int32_T i{0}; i < p_idx_0; i++) { + problemStruct.fitParams[i] = p[i]; + } + + unpackParams(&problemStruct, data_f2->checks.fitParam, + data_f2->checks.fitBackgroundParam, data_f2->checks.fitQzshift, + data_f2->checks.fitScalefactor, data_f2->checks.fitBulkIn, + data_f2->checks.fitBulkOut, data_f2->checks.fitResolutionParam, + data_f2->checks.fitDomainRatio); + reflectivityCalculation(&problemStruct, data_f4, data_f2, &b_problemStruct, + a__1); + return -b_problemStruct.calculations.sumChi / 2.0; + } +} + +// End of code generation (nsIntraFun.cpp) diff --git a/cpp/RAT/nsIntraFun.h b/cpp/RAT/nsIntraFun.h new file mode 100644 index 00000000..f26f8ebf --- /dev/null +++ b/cpp/RAT/nsIntraFun.h @@ -0,0 +1,38 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// nsIntraFun.h +// +// Code generation for function 'nsIntraFun' +// +#ifndef NSINTRAFUN_H +#define NSINTRAFUN_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct c_struct_T; + struct struct2_T; + struct cell_11; +} + +// Function Declarations +namespace RAT +{ + real_T nsIntraFun(const c_struct_T *data_f1, const struct2_T *data_f2, const + cell_11 *data_f4, const ::coder::array &p); + real_T nsIntraFun(const c_struct_T *data_f1, const struct2_T *data_f2, const + cell_11 *data_f4, const ::coder::array &p); +} + +#endif + +// End of code generation (nsIntraFun.h) diff --git a/cpp/RAT/nullAssignment.cpp b/cpp/RAT/nullAssignment.cpp new file mode 100644 index 00000000..4c1138ac --- /dev/null +++ b/cpp/RAT/nullAssignment.cpp @@ -0,0 +1,125 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// nullAssignment.cpp +// +// Code generation for function 'nullAssignment' +// + +// Include files +#include "nullAssignment.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + static void make_bitarray(int32_T n, const ::coder::array + &idx, ::coder::array &b); + static int32_T num_true(const ::coder::array &b); + } + } +} + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + static void make_bitarray(int32_T n, const ::coder::array + &idx, ::coder::array &b) + { + int32_T i; + b.set_size(1, n); + for (i = 0; i < n; i++) { + b[i] = false; + } + + i = idx.size(1); + for (int32_T k{0}; k < i; k++) { + b[idx[k] - 1] = true; + } + } + + static int32_T num_true(const ::coder::array &b) + { + int32_T i; + int32_T n; + n = 0; + i = b.size(1); + for (int32_T k{0}; k < i; k++) { + n += b[k]; + } + + return n; + } + + void nullAssignment(::coder::array &x, const ::coder::array< + int32_T, 2U> &idx) + { + ::coder::array b; + int32_T k0; + int32_T nxin; + int32_T nxout; + nxin = x.size(1); + make_bitarray(x.size(1), idx, b); + nxout = x.size(1) - num_true(b); + k0 = -1; + for (int32_T k{0}; k < nxin; k++) { + if ((k + 1 > b.size(1)) || (!b[k])) { + k0++; + x[k0] = x[k]; + } + } + + if (nxout < 1) { + nxout = 0; + } + + x.set_size(x.size(0), nxout); + } + + void nullAssignment(real_T x_data[], int32_T x_size[2]) + { + int32_T i; + int32_T i1; + int32_T j; + int32_T nrows; + i = x_size[1]; + nrows = x_size[0]; + for (j = 0; j < i; j++) { + for (int32_T b_i{0}; b_i <= nrows - 2; b_i++) { + i1 = b_i + x_size[0] * j; + x_data[i1] = x_data[i1 + 1]; + } + } + + if (x_size[0] - 1 < 1) { + nrows = 0; + } else { + nrows = x_size[0] - 1; + } + + j = x_size[1]; + for (i = 0; i < j; i++) { + for (i1 = 0; i1 < nrows; i1++) { + x_data[i1 + nrows * i] = x_data[i1 + x_size[0] * i]; + } + } + + x_size[0] = nrows; + x_size[1] = j; + } + } + } +} + +// End of code generation (nullAssignment.cpp) diff --git a/cpp/RAT/nullAssignment.h b/cpp/RAT/nullAssignment.h new file mode 100644 index 00000000..9456f2fe --- /dev/null +++ b/cpp/RAT/nullAssignment.h @@ -0,0 +1,35 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// nullAssignment.h +// +// Code generation for function 'nullAssignment' +// +#ifndef NULLASSIGNMENT_H +#define NULLASSIGNMENT_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + void nullAssignment(::coder::array &x, const ::coder::array< + int32_T, 2U> &idx); + void nullAssignment(real_T x_data[], int32_T x_size[2]); + } + } +} + +#endif + +// End of code generation (nullAssignment.h) diff --git a/cpp/RAT/optimalEllipsoids.cpp b/cpp/RAT/optimalEllipsoids.cpp new file mode 100644 index 00000000..283b2298 --- /dev/null +++ b/cpp/RAT/optimalEllipsoids.cpp @@ -0,0 +1,449 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// optimalEllipsoids.cpp +// +// Code generation for function 'optimalEllipsoids' +// + +// Include files +#include "optimalEllipsoids.h" +#include "RATMain_data.h" +#include "all.h" +#include "calcEllipsoid.h" +#include "rt_nonfinite.h" +#include "splitEllipsoid.h" +#include "validate_print_arguments.h" +#include "coder_array.h" +#include + +// Function Declarations +namespace RAT +{ + static void d_binary_expand_op(boolean_T in1_data[], int32_T in1_size[2], + const real_T in2_data[], const int32_T in2_size[2], const real_T in3_data[], + const int32_T in3_size[2], const ::coder::array &in4); +} + +// Function Definitions +namespace RAT +{ + static void d_binary_expand_op(boolean_T in1_data[], int32_T in1_size[2], + const real_T in2_data[], const int32_T in2_size[2], const real_T in3_data[], + const int32_T in3_size[2], const ::coder::array &in4) + { + int32_T b_in2_size[2]; + int32_T aux_0_1; + int32_T aux_1_1; + int32_T aux_2_1; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_0_1; + int32_T stride_1_0; + int32_T stride_1_1; + int32_T stride_2_0; + int32_T stride_2_1; + boolean_T b_in2_data; + if (in4.size(0) == 1) { + if (in3_size[0] == 1) { + b_in2_size[0] = in2_size[0]; + } else { + b_in2_size[0] = in3_size[0]; + } + } else { + b_in2_size[0] = in4.size(0); + } + + if (in4.size(1) == 1) { + if (in3_size[1] == 1) { + b_in2_size[1] = in2_size[1]; + } else { + b_in2_size[1] = in3_size[1]; + } + } else { + b_in2_size[1] = in4.size(1); + } + + stride_0_0 = (in2_size[0] != 1); + stride_0_1 = (in2_size[1] != 1); + stride_1_0 = (in3_size[0] != 1); + stride_1_1 = (in3_size[1] != 1); + stride_2_0 = (in4.size(0) != 1); + stride_2_1 = (in4.size(1) != 1); + aux_0_1 = 0; + aux_1_1 = 0; + aux_2_1 = 0; + if (in4.size(1) == 1) { + if (in3_size[1] == 1) { + loop_ub = in2_size[1]; + } else { + loop_ub = in3_size[1]; + } + } else { + loop_ub = in4.size(1); + } + + for (int32_T i{0}; i < loop_ub; i++) { + int32_T b_loop_ub; + int32_T i1; + i1 = in4.size(0); + b_loop_ub = in3_size[0]; + if (i1 == 1) { + if (b_loop_ub == 1) { + b_loop_ub = in2_size[0]; + } + } else { + b_loop_ub = i1; + } + + for (i1 = 0; i1 < b_loop_ub; i1++) { + b_in2_data = (in2_data[i1 * stride_0_0 + in2_size[0] * aux_0_1] + + in3_data[i1 * stride_1_0 + in3_size[0] * aux_1_1] < in4[i1 + * stride_2_0 + in4.size(0) * aux_2_1]); + } + + aux_2_1 += stride_2_1; + aux_1_1 += stride_1_1; + aux_0_1 += stride_0_1; + } + + coder::all((const boolean_T *)&b_in2_data, b_in2_size, in1_data, in1_size); + } + + void optimalEllipsoids(const ::coder::array &u, real_T VS, ::coder:: + array &Bs, ::coder::array &mus, ::coder::array< + real_T, 2U> &VEs, ::coder::array &ns) + { + ::coder::array B1; + ::coder::array B2; + ::coder::array VE1; + ::coder::array VE2; + ::coder::array mu; + ::coder::array mu1; + ::coder::array mu2; + ::coder::array n1; + ::coder::array n2; + ::coder::array u1; + ::coder::array u2; + real_T VE1_data; + real_T VE2_data; + real_T flag; + real_T nosplit; + int32_T VE1_size[2]; + int32_T VE2_size[2]; + int32_T b_VE1_size[2]; + int32_T tmp_size[2]; + boolean_T empty_non_axis_sizes; + + // function [Bs, mus, VEs, ns] = optimalEllipsoids(u, VS) + // + // This function attempts to optimally partition the multi-dimensional + // samples u (uniformly distributed within the sample volume VS), into + // a set of subclusters enclosed by bounding ellipsoids. The algorithm + // is based on Algorithm 1 of the MULTINEST paper by Feroz, Hobson, + // and Bridges, MNRAS, 398, 1601-1614 (2009). + // + // Output: + // Bs: an array of bounding matrices for the ellipsoids enclosing + // the subclusters, scaled to have at least the minimum volume + // required by the subclusters. ( (K x ndims) x ndims ) + // mus: an array of centroids for the bounding ellipsoids (K x ndims) + // VEs: an array of volumes for the bounding ellipsoids (K x 1) + // ns: an array containing the number of points for each subcluster (K x 1) + // + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // number of samples in multi-dimensional space + // number of dimensions + // calculate bounding matrix, etc. for bounding ellipsoid associated + // with the original set of points u + VEs.reserve(1); + calcEllipsoid(u, VS, Bs, mu, (real_T *)VEs.data(), VEs.size(), &flag); + + // attempt to split u into two subclusters + splitEllipsoid(u, VS, u1, u2, (real_T *)&VE1_data, VE1_size, (real_T *) + &VE2_data, VE2_size, &nosplit); + if ((nosplit != 0.0) || (static_cast(u1.size(0)) < + static_cast(u.size(1)) + 1U) || (static_cast + (u2.size(0)) < static_cast(u.size(1)) + 1U)) { + int32_T input_sizes_idx_0; + + // couldn't split the cluster + mus.set_size(mu.size(0), mu.size(1)); + input_sizes_idx_0 = mu.size(1); + for (int32_T i{0}; i < input_sizes_idx_0; i++) { + int32_T loop_ub; + loop_ub = mu.size(0); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + mus[mus.size(0) * i] = mu[mu.size(0) * i]; + } + } + + ns.set_size(1, 1); + ns[0] = u.size(0); + } else { + int32_T validatedHoleFilling[3]; + int32_T i; + int32_T i1; + int32_T input_sizes_idx_0; + int32_T loop_ub; + boolean_T b_VE1_data; + boolean_T guard1; + + // check if we should keep the partitioning of S + // if (all(VE1 + VE2 < VE) || all(VE > 2*VS)) + if (VE1_size[0] == 1) { + i = VE2_size[0]; + } else { + i = VE1_size[0]; + } + + if (VE1_size[1] == 1) { + i1 = VE2_size[1]; + } else { + i1 = VE1_size[1]; + } + + if ((VE1_size[0] == VE2_size[0]) && (VE1_size[1] == VE2_size[1]) && (i == + VEs.size(0)) && (i1 == VEs.size(1))) { + b_VE1_size[0] = VE1_size[0]; + b_VE1_size[1] = VE1_size[1]; + input_sizes_idx_0 = VE1_size[1]; + for (i = 0; i < input_sizes_idx_0; i++) { + loop_ub = VE1_size[0]; + for (i1 = 0; i1 < loop_ub; i1++) { + b_VE1_data = (VE1_data + VE2_data < VEs[0]); + } + } + + coder::all((const boolean_T *)&b_VE1_data, b_VE1_size, (boolean_T *) + &empty_non_axis_sizes, tmp_size); + } else { + d_binary_expand_op((boolean_T *)&empty_non_axis_sizes, tmp_size, (const + real_T *)&VE1_data, VE1_size, (const real_T *)&VE2_data, VE2_size, VEs); + } + + guard1 = false; + if (coder::b_all((const boolean_T *)&empty_non_axis_sizes, tmp_size)) { + guard1 = true; + } else { + flag = 2.0 * VS; + b_VE1_size[0] = VEs.size(0); + b_VE1_size[1] = VEs.size(1); + input_sizes_idx_0 = VEs.size(1); + for (i = 0; i < input_sizes_idx_0; i++) { + loop_ub = VEs.size(0); + for (i1 = 0; i1 < loop_ub; i1++) { + b_VE1_data = (VEs[i1 + VEs.size(0) * i] > flag); + } + } + + coder::all((const boolean_T *)&b_VE1_data, b_VE1_size, (boolean_T *) + &empty_non_axis_sizes, tmp_size); + if (coder::b_all((const boolean_T *)&empty_non_axis_sizes, tmp_size)) { + guard1 = true; + } else { + if (DEBUG != 0.0) { + coder::internal::validate_print_arguments(u.size(0), u1.size(0), + u2.size(0), validatedHoleFilling); + printf("PARTITION REJECTED: N=%d doesnt split into n1=%d and n2=%d\n", + validatedHoleFilling[0], validatedHoleFilling[1], + validatedHoleFilling[2]); + fflush(stdout); + } + + mus.set_size(mu.size(0), mu.size(1)); + input_sizes_idx_0 = mu.size(1); + for (i = 0; i < input_sizes_idx_0; i++) { + loop_ub = mu.size(0); + for (i1 = 0; i1 < loop_ub; i1++) { + mus[mus.size(0) * i] = mu[mu.size(0) * i]; + } + } + + ns.set_size(1, 1); + ns[0] = u.size(0); + } + } + + if (guard1) { + int32_T result; + int32_T sizes_idx_0; + int16_T b_input_sizes_idx_0; + if (DEBUG != 0.0) { + coder::internal::validate_print_arguments(u.size(0), u1.size(0), + u2.size(0), validatedHoleFilling); + printf("PARTITION ACCEPTED: N=%d splits to n1=%d, n2=%d\n", + validatedHoleFilling[0], validatedHoleFilling[1], + validatedHoleFilling[2]); + fflush(stdout); + } + + optimalEllipsoids(u1, static_cast(u1.size(0)) * VS / + static_cast(u.size(0)), B1, mu1, VE1, n1); + optimalEllipsoids(u2, static_cast(u2.size(0)) * VS / + static_cast(u.size(0)), B2, mu2, VE2, n2); + if ((B1.size(0) != 0) && (B1.size(1) != 0)) { + result = B1.size(1); + } else if ((B2.size(0) != 0) && (B2.size(1) != 0)) { + result = B2.size(1); + } else { + result = B1.size(1); + if (B2.size(1) > B1.size(1)) { + result = B2.size(1); + } + } + + empty_non_axis_sizes = (result == 0); + if (empty_non_axis_sizes || ((B1.size(0) != 0) && (B1.size(1) != 0))) { + input_sizes_idx_0 = B1.size(0); + } else { + input_sizes_idx_0 = 0; + } + + if (empty_non_axis_sizes || ((B2.size(0) != 0) && (B2.size(1) != 0))) { + sizes_idx_0 = B2.size(0); + } else { + sizes_idx_0 = 0; + } + + Bs.set_size(input_sizes_idx_0 + sizes_idx_0, result); + for (i = 0; i < result; i++) { + for (i1 = 0; i1 < input_sizes_idx_0; i1++) { + Bs[i1 + Bs.size(0) * i] = B1[i1 + input_sizes_idx_0 * i]; + } + } + + for (i = 0; i < result; i++) { + for (i1 = 0; i1 < sizes_idx_0; i1++) { + Bs[(i1 + input_sizes_idx_0) + Bs.size(0) * i] = B2[i1 + sizes_idx_0 * + i]; + } + } + + if ((mu1.size(0) != 0) && (mu1.size(1) != 0)) { + result = mu1.size(1); + } else if ((mu2.size(0) != 0) && (mu2.size(1) != 0)) { + result = mu2.size(1); + } else { + result = mu1.size(1); + if (mu2.size(1) > mu1.size(1)) { + result = mu2.size(1); + } + } + + empty_non_axis_sizes = (result == 0); + if (empty_non_axis_sizes || ((mu1.size(0) != 0) && (mu1.size(1) != 0))) + { + b_input_sizes_idx_0 = static_cast(mu1.size(0)); + } else { + b_input_sizes_idx_0 = 0; + } + + if (empty_non_axis_sizes || ((mu2.size(0) != 0) && (mu2.size(1) != 0))) + { + sizes_idx_0 = mu2.size(0); + } else { + sizes_idx_0 = 0; + } + + loop_ub = b_input_sizes_idx_0; + mus.set_size(b_input_sizes_idx_0 + sizes_idx_0, result); + for (i = 0; i < result; i++) { + for (i1 = 0; i1 < loop_ub; i1++) { + mus[i1 + mus.size(0) * i] = mu1[i1 + b_input_sizes_idx_0 * i]; + } + } + + for (i = 0; i < result; i++) { + for (i1 = 0; i1 < sizes_idx_0; i1++) { + mus[(i1 + b_input_sizes_idx_0) + mus.size(0) * i] = mu2[i1 + + sizes_idx_0 * i]; + } + } + + if ((VE1.size(0) != 0) && (VE1.size(1) != 0)) { + result = VE1.size(1); + } else if ((VE2.size(0) != 0) && (VE2.size(1) != 0)) { + result = VE2.size(1); + } else { + result = VE1.size(1); + if (VE2.size(1) > VE1.size(1)) { + result = VE2.size(1); + } + } + + empty_non_axis_sizes = (result == 0); + if (empty_non_axis_sizes || ((VE1.size(0) != 0) && (VE1.size(1) != 0))) + { + input_sizes_idx_0 = VE1.size(0); + } else { + input_sizes_idx_0 = 0; + } + + if (empty_non_axis_sizes || ((VE2.size(0) != 0) && (VE2.size(1) != 0))) + { + sizes_idx_0 = VE2.size(0); + } else { + sizes_idx_0 = 0; + } + + VEs.set_size(input_sizes_idx_0 + sizes_idx_0, result); + for (i = 0; i < result; i++) { + for (i1 = 0; i1 < input_sizes_idx_0; i1++) { + VEs[i1 + VEs.size(0) * i] = VE1[i1 + input_sizes_idx_0 * i]; + } + } + + for (i = 0; i < result; i++) { + for (i1 = 0; i1 < sizes_idx_0; i1++) { + VEs[(i1 + input_sizes_idx_0) + VEs.size(0) * i] = VE2[i1 + + sizes_idx_0 * i]; + } + } + + if ((n1.size(0) != 0) && (n1.size(1) != 0)) { + result = n1.size(1); + } else if ((n2.size(0) != 0) && (n2.size(1) != 0)) { + result = n2.size(1); + } else { + result = (n1.size(1) > 0); + if (n2.size(1) > result) { + result = 1; + } + } + + empty_non_axis_sizes = (result == 0); + if (empty_non_axis_sizes || ((n1.size(0) != 0) && (n1.size(1) != 0))) { + b_input_sizes_idx_0 = static_cast(n1.size(0)); + } else { + b_input_sizes_idx_0 = 0; + } + + if (empty_non_axis_sizes || ((n2.size(0) != 0) && (n2.size(1) != 0))) { + sizes_idx_0 = n2.size(0); + } else { + sizes_idx_0 = 0; + } + + loop_ub = b_input_sizes_idx_0; + ns.set_size(b_input_sizes_idx_0 + sizes_idx_0, result); + for (i = 0; i < result; i++) { + for (i1 = 0; i1 < loop_ub; i1++) { + ns[i1 + ns.size(0) * i] = n1[i1 + b_input_sizes_idx_0 * i]; + } + } + + for (i = 0; i < result; i++) { + for (i1 = 0; i1 < sizes_idx_0; i1++) { + ns[(i1 + b_input_sizes_idx_0) + ns.size(0) * i] = n2[i1 + + sizes_idx_0 * i]; + } + } + } + } + } +} + +// End of code generation (optimalEllipsoids.cpp) diff --git a/cpp/RAT/optimalEllipsoids.h b/cpp/RAT/optimalEllipsoids.h new file mode 100644 index 00000000..292f1944 --- /dev/null +++ b/cpp/RAT/optimalEllipsoids.h @@ -0,0 +1,29 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// optimalEllipsoids.h +// +// Code generation for function 'optimalEllipsoids' +// +#ifndef OPTIMALELLIPSOIDS_H +#define OPTIMALELLIPSOIDS_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void optimalEllipsoids(const ::coder::array &u, real_T VS, ::coder:: + array &Bs, ::coder::array &mus, ::coder::array< + real_T, 2U> &VEs, ::coder::array &ns); +} + +#endif + +// End of code generation (optimalEllipsoids.h) diff --git a/cpp/RAT/packParams.cpp b/cpp/RAT/packParams.cpp new file mode 100644 index 00000000..2d12d0a4 --- /dev/null +++ b/cpp/RAT/packParams.cpp @@ -0,0 +1,335 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// packParams.cpp +// +// Code generation for function 'packParams' +// + +// Include files +#include "packParams.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rt_nonfinite.h" +#include "sum.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void packParams(c_struct_T *problemStruct, const ::coder::array &problemCells_f7, const ::coder::array + &problemCells_f8, const ::coder::array + &problemCells_f9, const ::coder::array + &problemCells_f10, const ::coder::array + &problemCells_f11, const ::coder::array + &problemCells_f12, const ::coder::array + &problemCells_f13, const ::coder::array + &problemCells_f20, const struct1_T *limits, const struct3_T + *checks, ::coder::array &fitNames) + { + ::coder::array fitLimits; + ::coder::array fitParams; + ::coder::array otherLimits; + ::coder::array otherParams; + real_T numberOfFitted; + int32_T b_loop_ub; + int32_T fitCounter; + int32_T i; + int32_T loop_ub; + int32_T numberOfTotal; + int32_T otherCounter; + + // We need to pack the parameters into separate vectors + // of those that are being fitted, and those that are + // held constant. + numberOfFitted = ((((((coder::sum(checks->fitParam) + coder::sum + (checks->fitBackgroundParam)) + coder::sum(checks->fitScalefactor)) + + coder::sum(checks->fitQzshift)) + coder::sum + (checks->fitBulkIn)) + coder::sum(checks->fitBulkOut)) + + coder::sum(checks->fitResolutionParam)) + coder::sum + (checks->fitDomainRatio); + numberOfTotal = ((((((problemStruct->params.size(1) + + problemStruct->backgroundParams.size(1)) + + problemStruct->scalefactors.size(1)) + + problemStruct->qzshifts.size(1)) + + problemStruct->bulkIn.size(1)) + + problemStruct->bulkOut.size(1)) + + problemStruct->resolutionParams.size(1)) + + problemStruct->domainRatio.size(1); + fitParams.set_size(problemStruct->fitParams.size(0), + problemStruct->fitParams.size(1)); + loop_ub = problemStruct->fitParams.size(1); + for (i = 0; i < loop_ub; i++) { + b_loop_ub = problemStruct->fitParams.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + fitParams[i1 + fitParams.size(0) * i] = problemStruct->fitParams[i1 + + problemStruct->fitParams.size(0) * i]; + } + } + + // zeros(numberOfFitted,1); + b_loop_ub = static_cast(static_cast(numberOfTotal) - + numberOfFitted); + otherParams.set_size(b_loop_ub); + for (i = 0; i < b_loop_ub; i++) { + otherParams[i] = 0.0; + } + + loop_ub = static_cast(numberOfFitted); + fitLimits.set_size(loop_ub, 2); + otherLimits.set_size(b_loop_ub, 2); + for (i = 0; i < 2; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + fitLimits[i1 + fitLimits.size(0) * i] = 0.0; + } + + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + otherLimits[i1 + otherLimits.size(0) * i] = 0.0; + } + } + + // limits = problemStruct.limits; + fitNames.set_size(loop_ub); + for (int32_T b_i{0}; b_i < loop_ub; b_i++) { + fitNames[b_i].f1.set_size(1, 0); + } + + fitCounter = 0; + otherCounter = 0; + i = checks->fitParam.size(1); + for (int32_T n{0}; n < i; n++) { + if (checks->fitParam[n] == 1.0) { + fitParams[fitCounter] = problemStruct->params[n]; + fitLimits[fitCounter] = limits->param[n]; + fitLimits[fitCounter + fitLimits.size(0)] = limits->param[n + + limits->param.size(0)]; + loop_ub = problemCells_f7[n].f1.size(1); + fitNames[fitCounter].f1.set_size(1, problemCells_f7[problemCells_f7.size + (0) * n].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + fitNames[fitCounter].f1[i1] = problemCells_f7[n].f1[i1]; + } + + fitCounter++; + } else { + otherParams[otherCounter] = problemStruct->params[n]; + otherLimits[otherCounter] = limits->param[n]; + otherLimits[otherCounter + otherLimits.size(0)] = limits->param[n + + limits->param.size(0)]; + otherCounter++; + } + } + + // Also do the same for backgrounds... + i = checks->fitBackgroundParam.size(1); + for (int32_T n{0}; n < i; n++) { + if (checks->fitBackgroundParam[n] == 1.0) { + fitParams[fitCounter] = problemStruct->backgroundParams[n]; + fitLimits[fitCounter] = limits->backgroundParam[n]; + fitLimits[fitCounter + fitLimits.size(0)] = limits->backgroundParam[n + + limits->backgroundParam.size(0)]; + loop_ub = problemCells_f8[n].f1.size(1); + fitNames[fitCounter].f1.set_size(1, problemCells_f8[problemCells_f8.size + (0) * n].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + fitNames[fitCounter].f1[i1] = problemCells_f8[n].f1[i1]; + } + + fitCounter++; + } else { + otherParams[otherCounter] = problemStruct->backgroundParams[n]; + otherLimits[otherCounter] = limits->backgroundParam[n]; + otherLimits[otherCounter + otherLimits.size(0)] = + limits->backgroundParam[n + limits->backgroundParam.size(0)]; + otherCounter++; + } + } + + // ..also for the scale factors + i = checks->fitScalefactor.size(1); + for (int32_T n{0}; n < i; n++) { + if (checks->fitScalefactor[n] == 1.0) { + fitParams[fitCounter] = problemStruct->scalefactors[n]; + fitLimits[fitCounter] = limits->scalefactor[n]; + fitLimits[fitCounter + fitLimits.size(0)] = limits->scalefactor[n + + limits->scalefactor.size(0)]; + loop_ub = problemCells_f9[n].f1.size(1); + fitNames[fitCounter].f1.set_size(1, problemCells_f9[problemCells_f9.size + (0) * n].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + fitNames[fitCounter].f1[i1] = problemCells_f9[n].f1[i1]; + } + + fitCounter++; + } else { + otherParams[otherCounter] = problemStruct->scalefactors[n]; + otherLimits[otherCounter] = limits->scalefactor[n]; + otherLimits[otherCounter + otherLimits.size(0)] = limits->scalefactor[n + + limits->scalefactor.size(0)]; + otherCounter++; + } + } + + // Need qzshifts + i = checks->fitQzshift.size(1); + for (int32_T n{0}; n < i; n++) { + if (checks->fitQzshift[n] == 1.0) { + fitParams[fitCounter] = problemStruct->qzshifts[n]; + fitLimits[fitCounter] = limits->qzshift[n]; + fitLimits[fitCounter + fitLimits.size(0)] = limits->qzshift[n + + limits->qzshift.size(0)]; + loop_ub = problemCells_f10[n].f1.size(1); + fitNames[fitCounter].f1.set_size(1, + problemCells_f10[problemCells_f10.size(0) * n].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + fitNames[fitCounter].f1[i1] = problemCells_f10[n].f1[i1]; + } + + fitCounter++; + } else { + otherParams[otherCounter] = problemStruct->qzshifts[n]; + otherLimits[otherCounter] = limits->qzshift[n]; + otherLimits[otherCounter + otherLimits.size(0)] = limits->qzshift[n + + limits->qzshift.size(0)]; + otherCounter++; + } + } + + // Bulk In + i = checks->fitBulkIn.size(1); + for (int32_T n{0}; n < i; n++) { + if (checks->fitBulkIn[n] == 1.0) { + fitParams[fitCounter] = problemStruct->bulkIn[n]; + fitLimits[fitCounter] = limits->bulkIn[n]; + fitLimits[fitCounter + fitLimits.size(0)] = limits->bulkIn[n + + limits->bulkIn.size(0)]; + loop_ub = problemCells_f11[n].f1.size(1); + fitNames[fitCounter].f1.set_size(1, + problemCells_f11[problemCells_f11.size(0) * n].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + fitNames[fitCounter].f1[i1] = problemCells_f11[n].f1[i1]; + } + + fitCounter++; + } else { + otherParams[otherCounter] = problemStruct->bulkIn[n]; + otherLimits[otherCounter] = limits->bulkIn[n]; + otherLimits[otherCounter + otherLimits.size(0)] = limits->bulkIn[n + + limits->bulkIn.size(0)]; + otherCounter++; + } + } + + // Bulk Out + i = checks->fitBulkOut.size(1); + for (int32_T n{0}; n < i; n++) { + if (checks->fitBulkOut[n] == 1.0) { + fitParams[fitCounter] = problemStruct->bulkOut[n]; + fitLimits[fitCounter] = limits->bulkOut[n]; + fitLimits[fitCounter + fitLimits.size(0)] = limits->bulkOut[n + + limits->bulkOut.size(0)]; + loop_ub = problemCells_f12[n].f1.size(1); + fitNames[fitCounter].f1.set_size(1, + problemCells_f12[problemCells_f12.size(0) * n].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + fitNames[fitCounter].f1[i1] = problemCells_f12[n].f1[i1]; + } + + fitCounter++; + } else { + otherParams[otherCounter] = problemStruct->bulkOut[n]; + otherLimits[otherCounter] = limits->bulkOut[n]; + otherLimits[otherCounter + otherLimits.size(0)] = limits->bulkOut[n + + limits->bulkOut.size(0)]; + otherCounter++; + } + } + + // Resolution..... + i = checks->fitResolutionParam.size(1); + for (int32_T n{0}; n < i; n++) { + if (checks->fitResolutionParam[n] == 1.0) { + fitParams[fitCounter] = problemStruct->resolutionParams[n]; + fitLimits[fitCounter] = limits->resolutionParam[n]; + fitLimits[fitCounter + fitLimits.size(0)] = limits->resolutionParam[n + + limits->resolutionParam.size(0)]; + loop_ub = problemCells_f13[n].f1.size(1); + fitNames[fitCounter].f1.set_size(1, + problemCells_f13[problemCells_f13.size(0) * n].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + fitNames[fitCounter].f1[i1] = problemCells_f13[n].f1[i1]; + } + + fitCounter++; + } else { + otherParams[otherCounter] = problemStruct->resolutionParams[n]; + otherLimits[otherCounter] = limits->resolutionParam[n]; + otherLimits[otherCounter + otherLimits.size(0)] = + limits->resolutionParam[n + limits->resolutionParam.size(0)]; + otherCounter++; + } + } + + // Domain Ratio + i = checks->fitDomainRatio.size(1); + for (int32_T n{0}; n < i; n++) { + if (checks->fitDomainRatio[n] == 1.0) { + fitParams[fitCounter] = problemStruct->domainRatio[n]; + fitLimits[fitCounter] = limits->domainRatio[n]; + fitLimits[fitCounter + fitLimits.size(0)] = limits->domainRatio[n + + limits->domainRatio.size(0)]; + loop_ub = problemCells_f20[n].f1.size(1); + fitNames[fitCounter].f1.set_size(1, + problemCells_f20[problemCells_f20.size(0) * n].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + fitNames[fitCounter].f1[i1] = problemCells_f20[n].f1[i1]; + } + + fitCounter++; + } else { + otherParams[otherCounter] = problemStruct->domainRatio[n]; + otherLimits[otherCounter] = limits->domainRatio[n]; + otherLimits[otherCounter + otherLimits.size(0)] = limits->domainRatio[n + + limits->domainRatio.size(0)]; + otherCounter++; + } + } + + problemStruct->fitParams.set_size(fitParams.size(0), fitParams.size(1)); + loop_ub = fitParams.size(1); + for (i = 0; i < loop_ub; i++) { + b_loop_ub = fitParams.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + problemStruct->fitParams[i1 + problemStruct->fitParams.size(0) * i] = + fitParams[i1 + fitParams.size(0) * i]; + } + } + + b_loop_ub = otherParams.size(0); + problemStruct->otherParams.set_size(otherParams.size(0), 1); + for (i = 0; i < b_loop_ub; i++) { + problemStruct->otherParams[i] = otherParams[i]; + } + + problemStruct->fitLimits.set_size(fitLimits.size(0), 2); + problemStruct->otherLimits.set_size(otherLimits.size(0), 2); + loop_ub = fitLimits.size(0); + b_loop_ub = otherLimits.size(0); + for (i = 0; i < 2; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + problemStruct->fitLimits[i1 + problemStruct->fitLimits.size(0) * i] = + fitLimits[i1 + fitLimits.size(0) * i]; + } + + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + problemStruct->otherLimits[i1 + problemStruct->otherLimits.size(0) * i] = + otherLimits[i1 + otherLimits.size(0) * i]; + } + } + } +} + +// End of code generation (packParams.cpp) diff --git a/cpp/RAT/packParams.h b/cpp/RAT/packParams.h new file mode 100644 index 00000000..7798f997 --- /dev/null +++ b/cpp/RAT/packParams.h @@ -0,0 +1,43 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// packParams.h +// +// Code generation for function 'packParams' +// +#ifndef PACKPARAMS_H +#define PACKPARAMS_H + +// Include files +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct c_struct_T; +} + +// Function Declarations +namespace RAT +{ + void packParams(c_struct_T *problemStruct, const ::coder::array &problemCells_f7, const ::coder::array + &problemCells_f8, const ::coder::array + &problemCells_f9, const ::coder::array + &problemCells_f10, const ::coder::array + &problemCells_f11, const ::coder::array + &problemCells_f12, const ::coder::array + &problemCells_f13, const ::coder::array + &problemCells_f20, const struct1_T *limits, const struct3_T + *checks, ::coder::array &fitNames); +} + +#endif + +// End of code generation (packParams.h) diff --git a/cpp/RAT/parallelContrasts.cpp b/cpp/RAT/parallelContrasts.cpp new file mode 100644 index 00000000..15007351 --- /dev/null +++ b/cpp/RAT/parallelContrasts.cpp @@ -0,0 +1,267 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parallelContrasts.cpp +// +// Code generation for function 'parallelContrasts' +// + +// Include files +#include "parallelContrasts.h" +#include "RATMain_internal_types.h" +#include "RATMain_rtwutil.h" +#include "RATMain_types.h" +#include "allocateLayersForContrast.h" +#include "allocateParamsToLayers.h" +#include "backSort.h" +#include "coreLayersCalculation.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include "coder_bounded_array.h" +#include "omp.h" + +// Function Definitions +namespace RAT +{ + namespace nonPolarisedTF + { + namespace standardLayers + { + void c_parallelContrasts(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, ::coder::array + &outSsubs, ::coder::array &backgroundParams, ::coder::array< + real_T, 1U> &qzshifts, ::coder::array &scalefactors, ::coder:: + array &bulkIns, ::coder::array &bulkOuts, :: + coder::array &resolutionParams, ::coder::array + &chis, ::coder::array &reflectivity, ::coder::array< + cell_wrap_20, 1U> &simulation, ::coder::array + &shiftedData, ::coder::array &layerSlds, ::coder::array< + cell_wrap_8, 1U> &sldProfiles, ::coder::array + &allLayers, ::coder::array &allRoughs) + { + ::coder::array outParameterisedLayers; + ::coder::array reflect; + ::coder::array resampledLayers; + ::coder::array shiftedDat; + ::coder::array simul; + ::coder::array sldProfile; + ::coder::array thisContrastLayers_data; + RATMainTLS *RATMainTLSThread; + real_T b_dv[2]; + real_T b_dv1[2]; + real_T dv2[2]; + real_T thisBackground; + real_T thisBulkIn; + real_T thisBulkOut; + real_T thisChiSquared; + real_T thisQzshift; + real_T thisResol; + real_T thisScalefactor; + real_T thisSsubs; + int32_T thisContrastLayers_size[2]; + int32_T b_i; + int32_T b_loop_ub; + int32_T i; + int32_T i1; + int32_T loop_ub; + int32_T nParams; + int32_T ub_loop; + boolean_T calcSld; + boolean_T useImaginary; + RATMainTLSThread = emlrtGetThreadStackData(); + + // Standard Layers calculation paralelised over the outer loop + // This is the main reflectivity calculation of the standard layers + // calculation type. It extracts the required parameters for the contrasts + // from the input arrays, then passes the main calculation to + // 'standardLayersCore', which carries out the calculation iteself. + // The core calculation is common for both standard and custom layers. + // Extract individual cell arrays + // Splits up the master input list of all arrays into separate arrays + // + // INPUTS: + // * problemCells: cell array where all the project data is grouped together. + // + // OUTPUTS: + // * repeatLayers: controls repeating of the layers stack. + // * allData: Array of all the data arrays. + // * dataLimits: Min max limits in q for the data arrays. + // * simLimits: Limits in Q for the reflectivity simulations. + // * layersDetails: Master array of all available layers. + // * contrastLayers: Which specific combination of arrays are needed for each contrast. + // * customFiles:Filenames and path for any custom files used. + // Extract individual parameters from problemStruct + // Extract individual parameters from problem + nParams = problemStruct->params.size(1); + calcSld = controls->calcSldDuringFit; + useImaginary = problemStruct->useImaginary; + + // Allocate the memory for the output arrays before the main loop + backgroundParams.set_size(static_cast + (problemStruct->numberOfContrasts)); + + // end memory allocation. + // First we need to allocate the absolute values of the input + // parameters to all the layers in the layers list. This only needs + // to be done once, and so is done outside the contrasts loop + allocateParamsToLayers(problemStruct->params, problemCells->f6, + outParameterisedLayers); + + // Resample parameters if required + // Loop over all the contrasts + outSsubs.set_size(static_cast(problemStruct->numberOfContrasts)); + sldProfiles.set_size(static_cast + (problemStruct->numberOfContrasts)); + reflectivity.set_size(static_cast + (problemStruct->numberOfContrasts)); + simulation.set_size(static_cast + (problemStruct->numberOfContrasts)); + shiftedData.set_size(static_cast + (problemStruct->numberOfContrasts)); + layerSlds.set_size(static_cast(problemStruct->numberOfContrasts)); + chis.set_size(static_cast(problemStruct->numberOfContrasts)); + qzshifts.set_size(static_cast(problemStruct->numberOfContrasts)); + scalefactors.set_size(static_cast + (problemStruct->numberOfContrasts)); + bulkIns.set_size(static_cast(problemStruct->numberOfContrasts)); + bulkOuts.set_size(static_cast(problemStruct->numberOfContrasts)); + resolutionParams.set_size(static_cast + (problemStruct->numberOfContrasts)); + allRoughs.set_size(static_cast(problemStruct->numberOfContrasts)); + allLayers.set_size(static_cast(problemStruct->numberOfContrasts)); + ub_loop = static_cast(problemStruct->numberOfContrasts) - 1; + +#pragma omp parallel \ + num_threads(omp_get_max_threads()) \ + private(RATMainTLSThread,sldProfile,reflect,simul,shiftedDat,resampledLayers,thisSsubs,thisChiSquared,thisContrastLayers_size,thisResol,thisBulkOut,thisBulkIn,thisScalefactor,thisQzshift,thisBackground,b_dv,b_dv1,dv2,loop_ub,b_i,b_loop_ub,i1) \ + firstprivate(thisContrastLayers_data) + + { + RATMainTLSThread = emlrtGetThreadStackData(); + +#pragma omp for nowait + + for (i = 0; i <= ub_loop; i++) { + // Extract the relevant parameter values for this contrast + // from the input arrays. + // First need to decide which values of the backgrounds, scalefactors + // data shifts and bulk contrasts are associated with this contrast + backSort(problemStruct->contrastBackgrounds[i], + problemStruct->contrastQzshifts[i], + problemStruct->contrastScalefactors[i], + problemStruct->contrastBulkIns[i], + problemStruct->contrastBulkOuts[i], + problemStruct->contrastResolutions[i], + problemStruct->backgroundParams, problemStruct->qzshifts, + problemStruct->scalefactors, problemStruct->bulkIn, + problemStruct->bulkOut, problemStruct->resolutionParams, + &thisBackground, &thisQzshift, &thisScalefactor, + &thisBulkIn, &thisBulkOut, &thisResol); + + // Also need to determine which layers from the overall layers list + // are required for this contrast, and put them in the correct order + // according to geometry + allocateLayersForContrast(problemCells->f5[i].f1, + outParameterisedLayers, useImaginary, + RATMainTLSThread->f2.thisContrastLayers_data, + thisContrastLayers_size); + + // For the other parameters, we extract the correct ones from the input + // arrays + // Substrate roughness is always first parameter for standard layers + // Now call the core layers reflectivity calculation + // In this case we are single cored, so we do not parallelise over + // points + // Call the core layers calculation + thisContrastLayers_data.set + (&RATMainTLSThread->f2.thisContrastLayers_data[0], + thisContrastLayers_size[0], thisContrastLayers_size[1]); + b_dv[0] = problemCells->f3[i].f1[0]; + b_dv[1] = problemCells->f3[i].f1[1]; + b_dv1[0] = problemCells->f4[i].f1[0]; + b_dv1[1] = problemCells->f4[i].f1[1]; + dv2[0] = problemCells->f1[i].f1[0]; + dv2[1] = problemCells->f1[i].f1[1]; + coreLayersCalculation(thisContrastLayers_data, problemStruct-> + params[0], problemStruct->geometry.data, + problemStruct->geometry.size, thisBulkIn, + thisBulkOut, problemStruct->resample[i], + calcSld, thisScalefactor, thisQzshift, + problemStruct->dataPresent[i], + problemCells->f2[i].f1, b_dv, b_dv1, dv2, + thisBackground, thisResol, + problemStruct->contrastBackgroundsType[i], + static_cast(nParams), + controls->resamPars, useImaginary, sldProfile, + reflect, simul, shiftedDat, layerSlds[i].f1, + resampledLayers, &thisChiSquared, &thisSsubs); + + // Store returned values for this contrast in the output arrays. + // As well as the calculated profiles, we also store a record of + // the other values (background, scalefactors etc) for each contrast + // for future use. + outSsubs[i] = thisSsubs; + loop_ub = sldProfile.size(1); + sldProfiles[i].f1.set_size(sldProfile.size(0), sldProfile.size(1)); + for (b_i = 0; b_i < loop_ub; b_i++) { + b_loop_ub = sldProfile.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + sldProfiles[i].f1[i1 + sldProfiles[i].f1.size(0) * b_i] = + sldProfile[i1 + sldProfile.size(0) * b_i]; + } + } + + loop_ub = reflect.size(0); + reflectivity[i].f1.set_size(reflect.size(0), 2); + b_loop_ub = simul.size(0); + simulation[i].f1.set_size(simul.size(0), 2); + for (b_i = 0; b_i < 2; b_i++) { + for (i1 = 0; i1 < loop_ub; i1++) { + reflectivity[i].f1[i1 + reflectivity[i].f1.size(0) * b_i] = + reflect[i1 + reflect.size(0) * b_i]; + } + + for (i1 = 0; i1 < b_loop_ub; i1++) { + simulation[i].f1[i1 + simulation[i].f1.size(0) * b_i] = simul[i1 + + simul.size(0) * b_i]; + } + } + + loop_ub = shiftedDat.size(1); + shiftedData[i].f1.set_size(shiftedDat.size(0), shiftedDat.size(1)); + for (b_i = 0; b_i < loop_ub; b_i++) { + b_loop_ub = shiftedDat.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + shiftedData[i].f1[i1 + shiftedData[i].f1.size(0) * b_i] = + shiftedDat[i1 + shiftedDat.size(0) * b_i]; + } + } + + chis[i] = thisChiSquared; + backgroundParams[i] = thisBackground; + qzshifts[i] = thisQzshift; + scalefactors[i] = thisScalefactor; + bulkIns[i] = thisBulkIn; + bulkOuts[i] = thisBulkOut; + resolutionParams[i] = thisResol; + allRoughs[i] = problemStruct->params[0]; + loop_ub = resampledLayers.size(1); + allLayers[i].f1.set_size(resampledLayers.size(0), + resampledLayers.size(1)); + for (b_i = 0; b_i < loop_ub; b_i++) { + b_loop_ub = resampledLayers.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + allLayers[i].f1[i1 + allLayers[i].f1.size(0) * b_i] = + resampledLayers[i1 + resampledLayers.size(0) * b_i]; + } + } + } + } + } + } + } +} + +// End of code generation (parallelContrasts.cpp) diff --git a/cpp/RAT/parallelContrasts.h b/cpp/RAT/parallelContrasts.h new file mode 100644 index 00000000..c1433049 --- /dev/null +++ b/cpp/RAT/parallelContrasts.h @@ -0,0 +1,45 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parallelContrasts.h +// +// Code generation for function 'parallelContrasts' +// +#ifndef PARALLELCONTRASTS_H +#define PARALLELCONTRASTS_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace nonPolarisedTF + { + namespace standardLayers + { + void c_parallelContrasts(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, ::coder::array + &outSsubs, ::coder::array &backgroundParams, ::coder::array< + real_T, 1U> &qzshifts, ::coder::array &scalefactors, ::coder:: + array &bulkIns, ::coder::array &bulkOuts, :: + coder::array &resolutionParams, ::coder::array + &chis, ::coder::array &reflectivity, ::coder::array< + cell_wrap_20, 1U> &simulation, ::coder::array + &shiftedData, ::coder::array &layerSlds, ::coder::array< + cell_wrap_8, 1U> &sldProfiles, ::coder::array + &allLayers, ::coder::array &allRoughs); + } + } +} + +#endif + +// End of code generation (parallelContrasts.h) diff --git a/cpp/RAT/parallelContrasts1.cpp b/cpp/RAT/parallelContrasts1.cpp new file mode 100644 index 00000000..1dc300ca --- /dev/null +++ b/cpp/RAT/parallelContrasts1.cpp @@ -0,0 +1,251 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parallelContrasts1.cpp +// +// Code generation for function 'parallelContrasts1' +// + +// Include files +#include "parallelContrasts1.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "backSort.h" +#include "coreLayersCalculation.h" +#include "processCustomFunction.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include "coder_bounded_array.h" +#include "omp.h" + +// Function Definitions +namespace RAT +{ + namespace nonPolarisedTF + { + namespace customLayers + { + void c_parallelContrasts(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, ::coder::array + &outSsubs, ::coder::array &backgroundParams, ::coder::array< + real_T, 1U> &qzshifts, ::coder::array &scalefactors, ::coder:: + array &bulkIns, ::coder::array &bulkOuts, :: + coder::array &resolutionParams, ::coder::array + &chis, ::coder::array &reflectivity, ::coder::array< + cell_wrap_20, 1U> &simulation, ::coder::array + &shiftedData, ::coder::array &layerSlds, ::coder::array< + cell_wrap_8, 1U> &sldProfiles, ::coder::array + &allLayers, ::coder::array &allRoughs) + { + ::coder::array layerSld; + ::coder::array reflect; + ::coder::array resamLayers; + ::coder::array shiftedDat; + ::coder::array simul; + ::coder::array sldProfile; + real_T b_dv[2]; + real_T b_dv1[2]; + real_T dv2[2]; + real_T thisBackground; + real_T thisBulkIn; + real_T thisBulkOut; + real_T thisChiSquared; + real_T thisQzshift; + real_T thisResol; + real_T thisScalefactor; + real_T thisSsubs; + int32_T b_i; + int32_T b_loop_ub; + int32_T i1; + int32_T loop_ub; + int32_T nParams; + int32_T ub_loop; + boolean_T calcSld; + boolean_T useImaginary; + + // Multi threaded version of the custom layers, nonPolarisedTF reflectivity + // calculation. The function extracts the relevant parameters from the input + // arrays, allocates these on a pre-contrast basis, then calls the 'core' + // calculation (the core layers nonPolarisedTF calc is shared between + // multiple calculation types). + // Extract individual cell arrays + // Splits up the master input list of all arrays into separate arrays + // + // INPUTS: + // * problemCells: cell array where all the project data is grouped together. + // + // OUTPUTS: + // * repeatLayers: controls repeating of the layers stack. + // * allData: Array of all the data arrays. + // * dataLimits: Min max limits in q for the data arrays. + // * simLimits: Limits in Q for the reflectivity simulations. + // * layersDetails: Master array of all available layers. + // * contrastLayers: Which specific combination of arrays are needed for each contrast. + // * customFiles:Filenames and path for any custom files used. + // Extract individual parameters from problemStruct + // Extract individual parameters from problem + nParams = problemStruct->params.size(1); + calcSld = controls->calcSldDuringFit; + useImaginary = problemStruct->useImaginary; + + // Pre-Allocation of output arrays... + backgroundParams.set_size(static_cast + (problemStruct->numberOfContrasts)); + + // --- End Memory Allocation --- + // Resampling parameters + // Process the custom models.... + processCustomFunction(problemStruct->contrastBulkIns, + problemStruct->contrastBulkOuts, + problemStruct->bulkIn, problemStruct->bulkOut, + problemStruct->contrastCustomFiles, + problemStruct->numberOfContrasts, + problemCells->f14, problemStruct->params, + problemStruct->useImaginary, allLayers, allRoughs); + + // Multi cored over all contrasts + outSsubs.set_size(static_cast(problemStruct->numberOfContrasts)); + sldProfiles.set_size(static_cast + (problemStruct->numberOfContrasts)); + reflectivity.set_size(static_cast + (problemStruct->numberOfContrasts)); + simulation.set_size(static_cast + (problemStruct->numberOfContrasts)); + shiftedData.set_size(static_cast + (problemStruct->numberOfContrasts)); + layerSlds.set_size(static_cast(problemStruct->numberOfContrasts)); + chis.set_size(static_cast(problemStruct->numberOfContrasts)); + qzshifts.set_size(static_cast(problemStruct->numberOfContrasts)); + scalefactors.set_size(static_cast + (problemStruct->numberOfContrasts)); + bulkIns.set_size(static_cast(problemStruct->numberOfContrasts)); + bulkOuts.set_size(static_cast(problemStruct->numberOfContrasts)); + resolutionParams.set_size(static_cast + (problemStruct->numberOfContrasts)); + ub_loop = static_cast(problemStruct->numberOfContrasts) - 1; + +#pragma omp parallel for \ + num_threads(omp_get_max_threads()) \ + private(sldProfile,reflect,simul,shiftedDat,layerSld,resamLayers,thisSsubs,thisChiSquared,thisResol,thisBulkOut,thisBulkIn,thisScalefactor,thisQzshift,thisBackground,b_dv,b_dv1,dv2,loop_ub,b_i,b_loop_ub,i1) + + for (int32_T i = 0; i <= ub_loop; i++) { + // Extract the relevant parameter values for this contrast + // from the input arrays. + // First need to decide which values of the backgrounds, scalefactors + // data shifts and bulk contrasts are associated with this contrast + backSort(problemStruct->contrastBackgrounds[i], + problemStruct->contrastQzshifts[i], + problemStruct->contrastScalefactors[i], + problemStruct->contrastBulkIns[i], + problemStruct->contrastBulkOuts[i], + problemStruct->contrastResolutions[i], + problemStruct->backgroundParams, problemStruct->qzshifts, + problemStruct->scalefactors, problemStruct->bulkIn, + problemStruct->bulkOut, problemStruct->resolutionParams, + &thisBackground, &thisQzshift, &thisScalefactor, &thisBulkIn, + &thisBulkOut, &thisResol); + + // Get the custom layers output for this contrast + // For the other parameters, we extract the correct ones from the input + // arrays + // Now call the core layers reflectivity calculation + // In this case we are single cored, so we do not parallelise over + // points + // Call the reflectivity calculation + b_dv[0] = problemCells->f3[i].f1[0]; + b_dv[1] = problemCells->f3[i].f1[1]; + b_dv1[0] = problemCells->f4[i].f1[0]; + b_dv1[1] = problemCells->f4[i].f1[1]; + dv2[0] = problemCells->f1[i].f1[0]; + dv2[1] = problemCells->f1[i].f1[1]; + coreLayersCalculation(allLayers[i].f1, allRoughs[i], + problemStruct->geometry.data, + problemStruct->geometry.size, thisBulkIn, + thisBulkOut, problemStruct->resample[i], calcSld, + thisScalefactor, thisQzshift, + problemStruct->dataPresent[i], problemCells-> + f2[i].f1, b_dv, b_dv1, dv2, thisBackground, + thisResol, + problemStruct->contrastBackgroundsType[i], + static_cast(nParams), + controls->resamPars, useImaginary, sldProfile, + reflect, simul, shiftedDat, layerSld, + resamLayers, &thisChiSquared, &thisSsubs); + + // Store returned values for this contrast in the output arrays. + // As well as the calculated profiles, we also store a record of + // the other values (background, scalefactors etc) for each contrast + // for future use. + outSsubs[i] = thisSsubs; + loop_ub = sldProfile.size(1); + sldProfiles[i].f1.set_size(sldProfile.size(0), sldProfile.size(1)); + for (b_i = 0; b_i < loop_ub; b_i++) { + b_loop_ub = sldProfile.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + sldProfiles[i].f1[i1 + sldProfiles[i].f1.size(0) * b_i] = + sldProfile[i1 + sldProfile.size(0) * b_i]; + } + } + + loop_ub = reflect.size(0); + reflectivity[i].f1.set_size(reflect.size(0), 2); + b_loop_ub = simul.size(0); + simulation[i].f1.set_size(simul.size(0), 2); + for (b_i = 0; b_i < 2; b_i++) { + for (i1 = 0; i1 < loop_ub; i1++) { + reflectivity[i].f1[i1 + reflectivity[i].f1.size(0) * b_i] = + reflect[i1 + reflect.size(0) * b_i]; + } + + for (i1 = 0; i1 < b_loop_ub; i1++) { + simulation[i].f1[i1 + simulation[i].f1.size(0) * b_i] = simul[i1 + + simul.size(0) * b_i]; + } + } + + loop_ub = shiftedDat.size(1); + shiftedData[i].f1.set_size(shiftedDat.size(0), shiftedDat.size(1)); + for (b_i = 0; b_i < loop_ub; b_i++) { + b_loop_ub = shiftedDat.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + shiftedData[i].f1[i1 + shiftedData[i].f1.size(0) * b_i] = + shiftedDat[i1 + shiftedDat.size(0) * b_i]; + } + } + + loop_ub = layerSld.size(1); + layerSlds[i].f1.set_size(layerSld.size(0), layerSld.size(1)); + for (b_i = 0; b_i < loop_ub; b_i++) { + b_loop_ub = layerSld.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + layerSlds[i].f1[i1 + layerSlds[i].f1.size(0) * b_i] = layerSld[i1 + + layerSld.size(0) * b_i]; + } + } + + loop_ub = resamLayers.size(1); + allLayers[i].f1.set_size(resamLayers.size(0), resamLayers.size(1)); + for (b_i = 0; b_i < loop_ub; b_i++) { + b_loop_ub = resamLayers.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + allLayers[i].f1[i1 + allLayers[i].f1.size(0) * b_i] = + resamLayers[i1 + resamLayers.size(0) * b_i]; + } + } + + chis[i] = thisChiSquared; + backgroundParams[i] = thisBackground; + qzshifts[i] = thisQzshift; + scalefactors[i] = thisScalefactor; + bulkIns[i] = thisBulkIn; + bulkOuts[i] = thisBulkOut; + resolutionParams[i] = thisResol; + } + } + } + } +} + +// End of code generation (parallelContrasts1.cpp) diff --git a/cpp/RAT/parallelContrasts1.h b/cpp/RAT/parallelContrasts1.h new file mode 100644 index 00000000..93313e6b --- /dev/null +++ b/cpp/RAT/parallelContrasts1.h @@ -0,0 +1,45 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parallelContrasts1.h +// +// Code generation for function 'parallelContrasts1' +// +#ifndef PARALLELCONTRASTS1_H +#define PARALLELCONTRASTS1_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace nonPolarisedTF + { + namespace customLayers + { + void c_parallelContrasts(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, ::coder::array + &outSsubs, ::coder::array &backgroundParams, ::coder::array< + real_T, 1U> &qzshifts, ::coder::array &scalefactors, ::coder:: + array &bulkIns, ::coder::array &bulkOuts, :: + coder::array &resolutionParams, ::coder::array + &chis, ::coder::array &reflectivity, ::coder::array< + cell_wrap_20, 1U> &simulation, ::coder::array + &shiftedData, ::coder::array &layerSlds, ::coder::array< + cell_wrap_8, 1U> &sldProfiles, ::coder::array + &allLayers, ::coder::array &allRoughs); + } + } +} + +#endif + +// End of code generation (parallelContrasts1.h) diff --git a/cpp/RAT/parallelContrasts2.cpp b/cpp/RAT/parallelContrasts2.cpp new file mode 100644 index 00000000..17f26748 --- /dev/null +++ b/cpp/RAT/parallelContrasts2.cpp @@ -0,0 +1,244 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parallelContrasts2.cpp +// +// Code generation for function 'parallelContrasts2' +// + +// Include files +#include "parallelContrasts2.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "applyBackgroundCorrection.h" +#include "backSort.h" +#include "callReflectivity.h" +#include "chiSquared.h" +#include "processCustomFunction1.h" +#include "resampleLayers.h" +#include "resampleLayersReIm.h" +#include "rt_nonfinite.h" +#include "shiftData.h" +#include "coder_array.h" +#include "omp.h" + +// Function Definitions +namespace RAT +{ + namespace nonPolarisedTF + { + namespace customXY + { + void c_parallelContrasts(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, ::coder::array + &outSsubs, ::coder::array &backgroundParams, ::coder::array< + real_T, 1U> &qzshifts, ::coder::array &scalefactors, ::coder:: + array &bulkIns, ::coder::array &bulkOuts, :: + coder::array &resolutionParams, ::coder::array + &chis, ::coder::array &reflectivity, ::coder::array< + cell_wrap_20, 1U> &simulation, ::coder::array + &shiftedData, ::coder::array &layerSlds, ::coder::array< + cell_wrap_8, 1U> &sldProfiles, ::coder::array + &allLayers, ::coder::array &allRoughs) + { + ::coder::array b_problemCells; + ::coder::array b_sldProfiles; + ::coder::array layerSld; + ::coder::array reSLD; + ::coder::array reflect; + ::coder::array shiftedDat; + ::coder::array simul; + real_T b_dv[2]; + real_T b_dv1[2]; + real_T d; + real_T d1; + real_T d2; + real_T d3; + real_T d4; + real_T d5; + int32_T b_loop_ub; + int32_T i1; + int32_T i2; + int32_T loop_ub; + int32_T loop_ub_tmp; + int32_T nParams; + boolean_T useImaginary; + + // Extract individual cell arrays + // Splits up the master input list of all arrays into separate arrays + // + // INPUTS: + // * problemCells: cell array where all the project data is grouped together. + // + // OUTPUTS: + // * repeatLayers: controls repeating of the layers stack. + // * allData: Array of all the data arrays. + // * dataLimits: Min max limits in q for the data arrays. + // * simLimits: Limits in Q for the reflectivity simulations. + // * layersDetails: Master array of all available layers. + // * contrastLayers: Which specific combination of arrays are needed for each contrast. + // * customFiles:Filenames and path for any custom files used. + // % Layers details N/A + // Extract individual parameters from problemStruct + // Extract individual parameters from problem + nParams = problemStruct->params.size(1); + + // Pre-Allocation... + loop_ub_tmp = static_cast(problemStruct->numberOfContrasts); + backgroundParams.set_size(loop_ub_tmp); + outSsubs.set_size(loop_ub_tmp); + for (int32_T i{0}; i < loop_ub_tmp; i++) { + outSsubs[i] = 0.0; + } + + // Resampling parameters + useImaginary = problemStruct->useImaginary; + processCustomFunction(problemStruct->contrastBulkIns, + problemStruct->contrastBulkOuts, + problemStruct->bulkIn, problemStruct->bulkOut, + problemStruct->contrastCustomFiles, + problemStruct->numberOfContrasts, + problemCells->f14, problemStruct->params, + sldProfiles, allRoughs); + qzshifts.set_size(loop_ub_tmp); + scalefactors.set_size(loop_ub_tmp); + bulkIns.set_size(loop_ub_tmp); + bulkOuts.set_size(loop_ub_tmp); + resolutionParams.set_size(loop_ub_tmp); + layerSlds.set_size(loop_ub_tmp); + allLayers.set_size(loop_ub_tmp); + shiftedData.set_size(loop_ub_tmp); + chis.set_size(loop_ub_tmp); + simulation.set_size(loop_ub_tmp); + reflectivity.set_size(loop_ub_tmp); + loop_ub_tmp--; + +#pragma omp parallel for \ + num_threads(omp_get_max_threads()) \ + private(b_sldProfiles,b_problemCells,reSLD,layerSld,reflect,simul,shiftedDat,d,d1,d2,d3,d4,d5,loop_ub,b_loop_ub,i1,i2,b_dv,b_dv1) + + for (int32_T b_i = 0; b_i <= loop_ub_tmp; b_i++) { + backSort(problemStruct->contrastBackgrounds[b_i], + problemStruct->contrastQzshifts[b_i], + problemStruct->contrastScalefactors[b_i], + problemStruct->contrastBulkIns[b_i], + problemStruct->contrastBulkOuts[b_i], + problemStruct->contrastResolutions[b_i], + problemStruct->backgroundParams, problemStruct->qzshifts, + problemStruct->scalefactors, problemStruct->bulkIn, + problemStruct->bulkOut, problemStruct->resolutionParams, &d5, + &d4, &d3, &d2, &d1, &d); + backgroundParams[b_i] = d5; + qzshifts[b_i] = d4; + scalefactors[b_i] = d3; + bulkIns[b_i] = d2; + bulkOuts[b_i] = d1; + resolutionParams[b_i] = d; + + // Resample the layers + if (!useImaginary) { + resampleLayers(sldProfiles[b_i].f1, controls->resamPars, layerSld); + } else { + loop_ub = sldProfiles[b_i].f1.size(0); + reSLD.set_size(sldProfiles[b_i].f1.size(0), 2); + for (i1 = 0; i1 < 2; i1++) { + for (i2 = 0; i2 < loop_ub; i2++) { + reSLD[i2 + reSLD.size(0) * i1] = sldProfiles[b_i].f1[i2 + + sldProfiles[b_i].f1.size(0) * i1]; + } + } + + loop_ub = sldProfiles[b_i].f1.size(0); + b_sldProfiles.set_size(sldProfiles[b_i].f1.size(0), 2); + for (i1 = 0; i1 < loop_ub; i1++) { + b_sldProfiles[i1] = sldProfiles[b_i].f1[i1]; + b_sldProfiles[i1 + b_sldProfiles.size(0)] = sldProfiles[b_i].f1[i1 + + sldProfiles[b_i].f1.size(0) * 2]; + } + + b_resampleLayersReIm(reSLD, b_sldProfiles, controls->resamPars, + layerSld); + } + + layerSlds[b_i].f1.set_size(layerSld.size(0), layerSld.size(1)); + loop_ub = layerSld.size(1); + allLayers[b_i].f1.set_size(layerSld.size(0), layerSld.size(1)); + b_loop_ub = layerSld.size(0); + for (i1 = 0; i1 < loop_ub; i1++) { + for (i2 = 0; i2 < b_loop_ub; i2++) { + layerSlds[b_i].f1[i2 + layerSlds[b_i].f1.size(0) * i1] = + layerSld[i2 + layerSld.size(0) * i1]; + allLayers[b_i].f1[i2 + allLayers[b_i].f1.size(0) * i1] = + layerSld[i2 + layerSld.size(0) * i1]; + } + } + + b_problemCells.set_size(problemCells->f2[problemCells->f2.size(0) * + b_i].f1.size(0), problemCells->f2[problemCells->f2.size(0) * b_i]. + f1.size(1)); + loop_ub = problemCells->f2[b_i].f1.size(1) - 1; + for (i1 = 0; i1 <= loop_ub; i1++) { + b_loop_ub = problemCells->f2[b_i].f1.size(0) - 1; + for (i2 = 0; i2 <= b_loop_ub; i2++) { + b_problemCells[i2 + b_problemCells.size(0) * i1] = + problemCells->f2[b_i].f1[i2 + problemCells->f2[b_i].f1.size(0) * + i1]; + } + } + + b_dv[0] = problemCells->f3[b_i].f1[0]; + b_dv[1] = problemCells->f3[b_i].f1[1]; + b_dv1[0] = problemCells->f4[b_i].f1[0]; + b_dv1[1] = problemCells->f4[b_i].f1[1]; + shiftData(scalefactors[b_i], qzshifts[b_i], problemStruct-> + dataPresent[b_i], b_problemCells, b_dv, b_dv1, shiftedDat); + shiftedData[b_i].f1.set_size(shiftedDat.size(0), shiftedDat.size(1)); + loop_ub = shiftedDat.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + b_loop_ub = shiftedDat.size(0); + for (i2 = 0; i2 < b_loop_ub; i2++) { + shiftedData[b_i].f1[i2 + shiftedData[b_i].f1.size(0) * i1] = + shiftedDat[i2 + shiftedDat.size(0) * i1]; + } + } + + b_dv[0] = problemCells->f4[b_i].f1[0]; + b_dv[1] = problemCells->f4[b_i].f1[1]; + b_dv1[0] = problemCells->f1[b_i].f1[0]; + b_dv1[1] = problemCells->f1[b_i].f1[1]; + callReflectivity(bulkIns[b_i], bulkOuts[b_i], b_dv, b_dv1, shiftedDat, + layerSld, 0.0, resolutionParams[b_i], useImaginary, + reflect, simul); + applyBackgroundCorrection(reflect, simul, shiftedDat, + backgroundParams[b_i], problemStruct->contrastBackgroundsType[b_i]); + loop_ub = reflect.size(0); + reflectivity[b_i].f1.set_size(reflect.size(0), 2); + b_loop_ub = simul.size(0); + simulation[b_i].f1.set_size(simul.size(0), 2); + for (i1 = 0; i1 < 2; i1++) { + for (i2 = 0; i2 < loop_ub; i2++) { + reflectivity[b_i].f1[i2 + reflectivity[b_i].f1.size(0) * i1] = + reflect[i2 + reflect.size(0) * i1]; + } + + for (i2 = 0; i2 < b_loop_ub; i2++) { + simulation[b_i].f1[i2 + simulation[b_i].f1.size(0) * i1] = + simul[i2 + simul.size(0) * i1]; + } + } + + if (problemStruct->dataPresent[b_i] != 0.0) { + chis[b_i] = chiSquared(shiftedDat, reflect, static_cast + (nParams)); + } else { + chis[b_i] = 0.0; + } + } + } + } + } +} + +// End of code generation (parallelContrasts2.cpp) diff --git a/cpp/RAT/parallelContrasts2.h b/cpp/RAT/parallelContrasts2.h new file mode 100644 index 00000000..09d8febb --- /dev/null +++ b/cpp/RAT/parallelContrasts2.h @@ -0,0 +1,45 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parallelContrasts2.h +// +// Code generation for function 'parallelContrasts2' +// +#ifndef PARALLELCONTRASTS2_H +#define PARALLELCONTRASTS2_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace nonPolarisedTF + { + namespace customXY + { + void c_parallelContrasts(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, ::coder::array + &outSsubs, ::coder::array &backgroundParams, ::coder::array< + real_T, 1U> &qzshifts, ::coder::array &scalefactors, ::coder:: + array &bulkIns, ::coder::array &bulkOuts, :: + coder::array &resolutionParams, ::coder::array + &chis, ::coder::array &reflectivity, ::coder::array< + cell_wrap_20, 1U> &simulation, ::coder::array + &shiftedData, ::coder::array &layerSlds, ::coder::array< + cell_wrap_8, 1U> &sldProfiles, ::coder::array + &allLayers, ::coder::array &allRoughs); + } + } +} + +#endif + +// End of code generation (parallelContrasts2.h) diff --git a/cpp/RAT/parallelContrasts3.cpp b/cpp/RAT/parallelContrasts3.cpp new file mode 100644 index 00000000..cefdb72b --- /dev/null +++ b/cpp/RAT/parallelContrasts3.cpp @@ -0,0 +1,396 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parallelContrasts3.cpp +// +// Code generation for function 'parallelContrasts3' +// + +// Include files +#include "parallelContrasts3.h" +#include "RATMain_internal_types.h" +#include "RATMain_rtwutil.h" +#include "RATMain_types.h" +#include "allocateLayersForContrast.h" +#include "allocateParamsToLayers.h" +#include "averageReflectivity.h" +#include "backSort.h" +#include "chiSquared.h" +#include "coreLayersCalculation.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include "coder_bounded_array.h" +#include "omp.h" + +// Function Definitions +namespace RAT +{ + namespace domainsTF + { + namespace standardLayers + { + void c_parallelContrasts(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, ::coder::array + &outSsubs, ::coder::array &backgroundParams, ::coder::array< + real_T, 1U> &qzshifts, ::coder::array &scalefactors, ::coder:: + array &bulkIns, ::coder::array &bulkOuts, :: + coder::array &resolutionParams, ::coder::array + &chis, ::coder::array &reflectivity, ::coder::array< + cell_wrap_20, 1U> &simulation, ::coder::array + &shiftedData, ::coder::array &layerSlds, ::coder::array< + cell_wrap_8, 2U> &domainSldProfiles, ::coder::array + &allLayers, ::coder::array &allRoughs) + { + ::coder::array outParameterisedLayers; + ::coder::array tempAllLayers; + ::coder::array tempLayerSlds; + ::coder::array tempSldProfiles; + ::coder::array a__6; + ::coder::array reflect1; + ::coder::array reflect2; + ::coder::array shiftedDat; + ::coder::array simul1; + ::coder::array simul2; + ::coder::array thisContrastLayers1_data; + ::coder::array thisContrastLayers2_data; + ::coder::array totReflect; + ::coder::array totSimul; + RATMainTLS *RATMainTLSThread; + cell_wrap_8 r; + cell_wrap_8 r1; + cell_wrap_8 r2; + cell_wrap_8 r3; + cell_wrap_8 r4; + cell_wrap_8 r5; + real_T b_dv[2]; + real_T b_dv1[2]; + real_T dv2[2]; + real_T a__5; + real_T a__7; + real_T a__8; + real_T numberOfContrasts; + real_T thisBackground; + real_T thisBulkIn; + real_T thisBulkOut; + real_T thisChiSquared; + real_T thisQzshift; + real_T thisResol; + real_T thisScalefactor; + real_T thisSsubs; + int32_T thisContrastLayers1_size[2]; + int32_T thisContrastLayers2_size[2]; + int32_T b_i; + int32_T b_loop_ub; + int32_T c_i; + int32_T c_loop_ub; + int32_T d_loop_ub; + int32_T i; + int32_T i1; + int32_T i2; + int32_T i3; + int32_T loop_ub; + int32_T nParams; + int32_T ub_loop; + boolean_T calcSld; + boolean_T useImaginary; + RATMainTLSThread = emlrtGetThreadStackData(); + + // Single threaded version of the Standard Layers calculation + // This is the main reflectivity calculation of the standard layers + // calculation type. It extracts the required parameters for the contrasts + // from the input arrays, then passes the main calculation to + // 'standardLayersCore', which carries out the calculation itself. + // The core calculation is common for both standard and custom layers. + // Extract individual cell arrays + // Splits up the master input list of all arrays into separate arrays + // + // INPUTS: + // * problemCells: cell array where all the project data is grouped together. + // + // OUTPUTS: + // * repeatLayers: controls repeating of the layers stack. + // * allData: Array of all the data arrays. + // * dataLimits: Min max limits in q for the data arrays. + // * simLimits: Limits in Q for the reflectivity simulations. + // * layersDetails: Master array of all available layers. + // * contrastLayers: Which specific combination of arrays are needed for each contrast. + // * customFiles:Filenames and path for any custom files used. + // Additionally extract the additional domain layers details + // Extract individual parameters from problemStruct + // Extract individual parameters from problem + nParams = problemStruct->params.size(1); + numberOfContrasts = problemStruct->numberOfContrasts; + calcSld = controls->calcSldDuringFit; + useImaginary = problemStruct->useImaginary; + + // Default for compile. + // Allocate the memory for the output arrays before the main loop + backgroundParams.set_size(static_cast + (problemStruct->numberOfContrasts)); + + // end memory allocation. + // First we need to allocate the absolute values of the input + // parameters to all the layers in the layers list. This only needs + // to be done once, and so is done outside the contrasts loop + allocateParamsToLayers(problemStruct->params, problemCells->f6, + outParameterisedLayers); + + // Resample params if requiired + // Loop over all the contrasts + outSsubs.set_size(static_cast(problemStruct->numberOfContrasts)); + tempSldProfiles.set_size(static_cast + (problemStruct->numberOfContrasts)); + reflectivity.set_size(static_cast + (problemStruct->numberOfContrasts)); + simulation.set_size(static_cast + (problemStruct->numberOfContrasts)); + shiftedData.set_size(static_cast + (problemStruct->numberOfContrasts)); + tempLayerSlds.set_size(static_cast + (problemStruct->numberOfContrasts)); + tempAllLayers.set_size(static_cast + (problemStruct->numberOfContrasts)); + chis.set_size(static_cast(problemStruct->numberOfContrasts)); + qzshifts.set_size(static_cast(problemStruct->numberOfContrasts)); + scalefactors.set_size(static_cast + (problemStruct->numberOfContrasts)); + bulkIns.set_size(static_cast(problemStruct->numberOfContrasts)); + bulkOuts.set_size(static_cast(problemStruct->numberOfContrasts)); + resolutionParams.set_size(static_cast + (problemStruct->numberOfContrasts)); + allRoughs.set_size(static_cast(problemStruct->numberOfContrasts)); + layerSlds.set_size(static_cast(problemStruct->numberOfContrasts), + 2); + allLayers.set_size(static_cast(problemStruct->numberOfContrasts), + 2); + domainSldProfiles.set_size(static_cast + (problemStruct->numberOfContrasts), 2); + ub_loop = static_cast(problemStruct->numberOfContrasts) - 1; + +#pragma omp parallel \ + num_threads(omp_get_max_threads()) \ + private(RATMainTLSThread,r,r1,r2,r3,reflect1,simul1,shiftedDat,r4,reflect2,simul2,a__6,r5,totReflect,totSimul,thisChiSquared,a__8,a__7,thisSsubs,a__5,thisContrastLayers2_size,thisContrastLayers1_size,thisResol,thisBulkOut,thisBulkIn,thisScalefactor,thisQzshift,thisBackground,b_dv,b_dv1,dv2,c_loop_ub,d_loop_ub,i2,i3) \ + firstprivate(thisContrastLayers1_data,thisContrastLayers2_data) + + { + RATMainTLSThread = emlrtGetThreadStackData(); + +#pragma omp for nowait + + for (i = 0; i <= ub_loop; i++) { + // Get the domain ratio for this contrast + // Extract the relevant parameter values for this contrast + // from the input arrays. + // First need to decide which values of the backgrounds, scalefactors + // data shifts and bulk contrasts are associated with this contrast + backSort(problemStruct->contrastBackgrounds[i], + problemStruct->contrastQzshifts[i], + problemStruct->contrastScalefactors[i], + problemStruct->contrastBulkIns[i], + problemStruct->contrastBulkOuts[i], + problemStruct->contrastResolutions[i], + problemStruct->backgroundParams, problemStruct->qzshifts, + problemStruct->scalefactors, problemStruct->bulkIn, + problemStruct->bulkOut, problemStruct->resolutionParams, + &thisBackground, &thisQzshift, &thisScalefactor, + &thisBulkIn, &thisBulkOut, &thisResol); + + // Also need to determine which layers from the overall layers list + // are required for this contrast, and put them in the correct order + // according to geometry. We run it twice, once for each domain... + allocateLayersForContrast(problemCells->f19[0].f1, + outParameterisedLayers, useImaginary, + RATMainTLSThread->f1.thisContrastLayers1_data, + thisContrastLayers1_size); + allocateLayersForContrast(problemCells->f19[1].f1, + outParameterisedLayers, useImaginary, + RATMainTLSThread->f1.thisContrastLayers2_data, + thisContrastLayers2_size); + + // For the other parameters, we extract the correct ones from the input + // arrays + // Substrate roughness is always first parameter for standard layers + // Now call the core layers reflectivity calculation + // In this case we are single cored, so we do not parallelise over + // points + // Call the core layers calculation - need to do this once for each + // domain + thisContrastLayers1_data.set + (&RATMainTLSThread->f1.thisContrastLayers1_data[0], + thisContrastLayers1_size[0], thisContrastLayers1_size[1]); + b_dv[0] = problemCells->f3[i].f1[0]; + b_dv[1] = problemCells->f3[i].f1[1]; + b_dv1[0] = problemCells->f4[i].f1[0]; + b_dv1[1] = problemCells->f4[i].f1[1]; + dv2[0] = problemCells->f1[i].f1[0]; + dv2[1] = problemCells->f1[i].f1[1]; + nonPolarisedTF::coreLayersCalculation(thisContrastLayers1_data, + problemStruct->params[0], problemStruct->geometry.data, + problemStruct->geometry.size, thisBulkIn, thisBulkOut, + problemStruct->resample[i], calcSld, thisScalefactor, thisQzshift, + problemStruct->dataPresent[i], problemCells->f2[i].f1, b_dv, b_dv1, + dv2, thisBackground, thisResol, + problemStruct->contrastBackgroundsType[i], static_cast + (nParams), controls->resamPars, useImaginary, r3.f1, reflect1, + simul1, shiftedDat, r2.f1, r4.f1, &a__5, &thisSsubs); + thisContrastLayers2_data.set + (&RATMainTLSThread->f1.thisContrastLayers2_data[0], + thisContrastLayers2_size[0], thisContrastLayers2_size[1]); + b_dv[0] = problemCells->f3[i].f1[0]; + b_dv[1] = problemCells->f3[i].f1[1]; + b_dv1[0] = problemCells->f4[i].f1[0]; + b_dv1[1] = problemCells->f4[i].f1[1]; + dv2[0] = problemCells->f1[i].f1[0]; + dv2[1] = problemCells->f1[i].f1[1]; + nonPolarisedTF::coreLayersCalculation(thisContrastLayers2_data, + problemStruct->params[0], problemStruct->geometry.data, + problemStruct->geometry.size, thisBulkIn, thisBulkOut, + problemStruct->resample[i], calcSld, thisScalefactor, thisQzshift, + problemStruct->dataPresent[i], problemCells->f2[i].f1, b_dv, b_dv1, + dv2, thisBackground, thisResol, + problemStruct->contrastBackgroundsType[i], static_cast + (nParams), controls->resamPars, useImaginary, r1.f1, reflect2, + simul2, a__6, r.f1, r5.f1, &a__7, &a__8); + + // Calculate the average reflectivities.... + averageReflectivity(reflect1, reflect2, simul1, simul2, + problemStruct->domainRatio[static_cast + (problemStruct->contrastDomainRatios[i]) - 1], + totReflect, totSimul); + + // Get an overall chi-squared for the new averaged curve.. + thisChiSquared = chiSquared(shiftedDat, totReflect, + static_cast(problemStruct->params.size(1))); + + // Store returned values for this contrast in the output arrays. + // As well as the calculated profiles, we also store a record of + // the other values (background, scalefactors etc) for each contrast + // for future use. + outSsubs[i] = thisSsubs; + tempSldProfiles[i].f1[0] = r3; + tempSldProfiles[i].f1[1] = r1; + reflectivity[i].f1.set_size(totReflect.size(0), 2); + c_loop_ub = totSimul.size(0); + simulation[i].f1.set_size(totSimul.size(0), 2); + d_loop_ub = totReflect.size(0); + for (i2 = 0; i2 < 2; i2++) { + for (i3 = 0; i3 < d_loop_ub; i3++) { + reflectivity[i].f1[i3 + reflectivity[i].f1.size(0) * i2] = + totReflect[i3 + totReflect.size(0) * i2]; + } + + for (i3 = 0; i3 < c_loop_ub; i3++) { + simulation[i].f1[i3 + simulation[i].f1.size(0) * i2] = + totSimul[i3 + totSimul.size(0) * i2]; + } + } + + shiftedData[i].f1.set_size(shiftedDat.size(0), shiftedDat.size(1)); + c_loop_ub = shiftedDat.size(1); + for (i2 = 0; i2 < c_loop_ub; i2++) { + d_loop_ub = shiftedDat.size(0); + for (i3 = 0; i3 < d_loop_ub; i3++) { + shiftedData[i].f1[i3 + shiftedData[i].f1.size(0) * i2] = + shiftedDat[i3 + shiftedDat.size(0) * i2]; + } + } + + tempLayerSlds[i].f1[0] = r2; + tempLayerSlds[i].f1[1] = r; + tempAllLayers[i].f1[0] = r4; + tempAllLayers[i].f1[1] = r5; + chis[i] = thisChiSquared; + backgroundParams[i] = thisBackground; + qzshifts[i] = thisQzshift; + scalefactors[i] = thisScalefactor; + bulkIns[i] = thisBulkIn; + bulkOuts[i] = thisBulkOut; + resolutionParams[i] = thisResol; + allRoughs[i] = problemStruct->params[0]; + } + } + + ub_loop = static_cast(numberOfContrasts); + for (b_i = 0; b_i < ub_loop; b_i++) { + loop_ub = tempSldProfiles[b_i].f1[0].f1.size(1); + domainSldProfiles[b_i].f1.set_size(tempSldProfiles[b_i].f1[0].f1.size + (0), tempSldProfiles[b_i].f1[0].f1.size(1)); + for (c_i = 0; c_i < loop_ub; c_i++) { + b_loop_ub = tempSldProfiles[b_i].f1[0].f1.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + domainSldProfiles[b_i].f1[i1 + domainSldProfiles[b_i].f1.size(0) * + c_i] = tempSldProfiles[b_i].f1[0].f1[i1 + tempSldProfiles[b_i]. + f1[0].f1.size(0) * c_i]; + } + } + + loop_ub = tempSldProfiles[b_i].f1[1].f1.size(1); + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.set_size + (tempSldProfiles[b_i].f1[1].f1.size(0), tempSldProfiles[b_i].f1[1]. + f1.size(1)); + for (c_i = 0; c_i < loop_ub; c_i++) { + b_loop_ub = tempSldProfiles[b_i].f1[1].f1.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1[i1 + + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size(0) * + c_i] = tempSldProfiles[b_i].f1[1].f1[i1 + tempSldProfiles[b_i]. + f1[1].f1.size(0) * c_i]; + } + } + + loop_ub = tempAllLayers[b_i].f1[0].f1.size(1); + allLayers[b_i].f1.set_size(tempAllLayers[b_i].f1[0].f1.size(0), + tempAllLayers[b_i].f1[0].f1.size(1)); + for (c_i = 0; c_i < loop_ub; c_i++) { + b_loop_ub = tempAllLayers[b_i].f1[0].f1.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + allLayers[b_i].f1[i1 + allLayers[b_i].f1.size(0) * c_i] = + tempAllLayers[b_i].f1[0].f1[i1 + tempAllLayers[b_i].f1[0]. + f1.size(0) * c_i]; + } + } + + loop_ub = tempAllLayers[b_i].f1[1].f1.size(1); + allLayers[b_i + allLayers.size(0)].f1.set_size(tempAllLayers[b_i].f1[1] + .f1.size(0), tempAllLayers[b_i].f1[1].f1.size(1)); + for (c_i = 0; c_i < loop_ub; c_i++) { + b_loop_ub = tempAllLayers[b_i].f1[1].f1.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + allLayers[b_i + allLayers.size(0)].f1[i1 + allLayers[b_i + + allLayers.size(0)].f1.size(0) * c_i] = tempAllLayers[b_i].f1[1]. + f1[i1 + tempAllLayers[b_i].f1[1].f1.size(0) * c_i]; + } + } + + loop_ub = tempLayerSlds[b_i].f1[0].f1.size(1); + layerSlds[b_i].f1.set_size(tempLayerSlds[b_i].f1[0].f1.size(0), + tempLayerSlds[b_i].f1[0].f1.size(1)); + for (c_i = 0; c_i < loop_ub; c_i++) { + b_loop_ub = tempLayerSlds[b_i].f1[0].f1.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + layerSlds[b_i].f1[i1 + layerSlds[b_i].f1.size(0) * c_i] = + tempLayerSlds[b_i].f1[0].f1[i1 + tempLayerSlds[b_i].f1[0]. + f1.size(0) * c_i]; + } + } + + loop_ub = tempLayerSlds[b_i].f1[1].f1.size(1); + layerSlds[b_i + layerSlds.size(0)].f1.set_size(tempLayerSlds[b_i].f1[1] + .f1.size(0), tempLayerSlds[b_i].f1[1].f1.size(1)); + for (c_i = 0; c_i < loop_ub; c_i++) { + b_loop_ub = tempLayerSlds[b_i].f1[1].f1.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + layerSlds[b_i + layerSlds.size(0)].f1[i1 + layerSlds[b_i + + layerSlds.size(0)].f1.size(0) * c_i] = tempLayerSlds[b_i].f1[1]. + f1[i1 + tempLayerSlds[b_i].f1[1].f1.size(0) * c_i]; + } + } + } + } + } + } +} + +// End of code generation (parallelContrasts3.cpp) diff --git a/cpp/RAT/parallelContrasts3.h b/cpp/RAT/parallelContrasts3.h new file mode 100644 index 00000000..8c2d981f --- /dev/null +++ b/cpp/RAT/parallelContrasts3.h @@ -0,0 +1,45 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parallelContrasts3.h +// +// Code generation for function 'parallelContrasts3' +// +#ifndef PARALLELCONTRASTS3_H +#define PARALLELCONTRASTS3_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace domainsTF + { + namespace standardLayers + { + void c_parallelContrasts(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, ::coder::array + &outSsubs, ::coder::array &backgroundParams, ::coder::array< + real_T, 1U> &qzshifts, ::coder::array &scalefactors, ::coder:: + array &bulkIns, ::coder::array &bulkOuts, :: + coder::array &resolutionParams, ::coder::array + &chis, ::coder::array &reflectivity, ::coder::array< + cell_wrap_20, 1U> &simulation, ::coder::array + &shiftedData, ::coder::array &layerSlds, ::coder::array< + cell_wrap_8, 2U> &domainSldProfiles, ::coder::array + &allLayers, ::coder::array &allRoughs); + } + } +} + +#endif + +// End of code generation (parallelContrasts3.h) diff --git a/cpp/RAT/parallelContrasts4.cpp b/cpp/RAT/parallelContrasts4.cpp new file mode 100644 index 00000000..1b6cd166 --- /dev/null +++ b/cpp/RAT/parallelContrasts4.cpp @@ -0,0 +1,366 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parallelContrasts4.cpp +// +// Code generation for function 'parallelContrasts4' +// + +// Include files +#include "parallelContrasts4.h" +#include "RATMain_internal_types.h" +#include "RATMain_rtwutil.h" +#include "RATMain_types.h" +#include "averageReflectivity.h" +#include "backSort.h" +#include "chiSquared.h" +#include "coreLayersCalculation.h" +#include "processCustomFunction2.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include "coder_bounded_array.h" +#include "omp.h" + +// Function Definitions +namespace RAT +{ + namespace domainsTF + { + namespace customLayers + { + void c_parallelContrasts(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, ::coder::array + &outSsubs, ::coder::array &backgroundParams, ::coder::array< + real_T, 1U> &qzshifts, ::coder::array &scalefactors, ::coder:: + array &bulkIns, ::coder::array &bulkOuts, :: + coder::array &resolutionParams, ::coder::array + &chis, ::coder::array &reflectivity, ::coder::array< + cell_wrap_20, 1U> &simulation, ::coder::array + &shiftedData, ::coder::array &layerSlds, ::coder::array< + cell_wrap_8, 2U> &domainSldProfiles, ::coder::array + &allLayers, ::coder::array &allRoughs) + { + ::coder::array r; + ::coder::array tempAllLayers; + ::coder::array tempLayerSlds; + ::coder::array tempSldProfiles; + ::coder::array calcAllLayers; + ::coder::array a__5; + ::coder::array reflect1; + ::coder::array reflect2; + ::coder::array shiftedDat; + ::coder::array simul1; + ::coder::array simul2; + ::coder::array totReflect; + ::coder::array totSimul; + cell_wrap_8 r1; + cell_wrap_8 r2; + cell_wrap_8 r3; + cell_wrap_8 r4; + cell_wrap_8 r5; + cell_wrap_8 r6; + real_T b_dv[2]; + real_T b_dv1[2]; + real_T dv2[2]; + real_T a__4; + real_T a__6; + real_T a__7; + real_T numberOfContrasts; + real_T thisBackground; + real_T thisBulkIn; + real_T thisBulkOut; + real_T thisChiSquared; + real_T thisQzshift; + real_T thisResol; + real_T thisScalefactor; + real_T thisSsubs; + int32_T c_loop_ub; + int32_T d_loop_ub; + int32_T i2; + int32_T i3; + int32_T nParams; + int32_T ub_loop; + boolean_T calcSld; + boolean_T useImaginary; + + // Single threaded version of the custom layers, domainsTF reflectivity + // calculation. The function extracts the relevant parameters from the input + // arrays, allocates these on a pre-contrast basis, then calls the 'core' + // calculation (the core layers domainsTF calc is shared between multiple + // calculation types). + // Extract individual cell arrays + // Splits up the master input list of all arrays into separate arrays + // + // INPUTS: + // * problemCells: cell array where all the project data is grouped together. + // + // OUTPUTS: + // * repeatLayers: controls repeating of the layers stack. + // * allData: Array of all the data arrays. + // * dataLimits: Min max limits in q for the data arrays. + // * simLimits: Limits in Q for the reflectivity simulations. + // * layersDetails: Master array of all available layers. + // * contrastLayers: Which specific combination of arrays are needed for each contrast. + // * customFiles:Filenames and path for any custom files used. + // Extract individual parameters from problemStruct + // Extract individual parameters from problem + nParams = problemStruct->params.size(1); + numberOfContrasts = problemStruct->numberOfContrasts; + calcSld = controls->calcSldDuringFit; + useImaginary = problemStruct->useImaginary; + + // Default for compile. + // Pre-Allocation of output arrays... + backgroundParams.set_size(static_cast + (problemStruct->numberOfContrasts)); + + // Resampling parameters + // Process the custom models.... + processCustomFunction(problemStruct->contrastBulkIns, + problemStruct->contrastBulkOuts, + problemStruct->bulkIn, problemStruct->bulkOut, + problemStruct->contrastCustomFiles, + problemStruct->numberOfContrasts, + problemCells->f14, problemStruct->params, + problemStruct->useImaginary, r, allRoughs); + cast(r, calcAllLayers); + + // Parallel over all contrasts + // layersCounter = 1; + outSsubs.set_size(static_cast(problemStruct->numberOfContrasts)); + tempSldProfiles.set_size(static_cast + (problemStruct->numberOfContrasts)); + reflectivity.set_size(static_cast + (problemStruct->numberOfContrasts)); + simulation.set_size(static_cast + (problemStruct->numberOfContrasts)); + shiftedData.set_size(static_cast + (problemStruct->numberOfContrasts)); + tempLayerSlds.set_size(static_cast + (problemStruct->numberOfContrasts)); + tempAllLayers.set_size(static_cast + (problemStruct->numberOfContrasts)); + chis.set_size(static_cast(problemStruct->numberOfContrasts)); + qzshifts.set_size(static_cast(problemStruct->numberOfContrasts)); + scalefactors.set_size(static_cast + (problemStruct->numberOfContrasts)); + bulkIns.set_size(static_cast(problemStruct->numberOfContrasts)); + bulkOuts.set_size(static_cast(problemStruct->numberOfContrasts)); + resolutionParams.set_size(static_cast + (problemStruct->numberOfContrasts)); + layerSlds.set_size(static_cast(problemStruct->numberOfContrasts), + 2); + allLayers.set_size(static_cast(problemStruct->numberOfContrasts), + 2); + domainSldProfiles.set_size(static_cast + (problemStruct->numberOfContrasts), 2); + ub_loop = static_cast(problemStruct->numberOfContrasts) - 1; + +#pragma omp parallel for \ + num_threads(omp_get_max_threads()) \ + private(r1,r2,reflect1,simul1,shiftedDat,r3,r4,reflect2,simul2,a__5,r5,r6,totReflect,totSimul,thisChiSquared,a__7,a__6,thisSsubs,a__4,thisResol,thisBulkOut,thisBulkIn,thisScalefactor,thisQzshift,thisBackground,b_dv,b_dv1,dv2,c_loop_ub,d_loop_ub,i2,i3) + + for (int32_T i = 0; i <= ub_loop; i++) { + // Get the domain ratio for this contrast + // Extract the relevant parameter values for this contrast + // from the input arrays. + // First need to decide which values of the backgrounds, scalefactors + // data shifts and bulk contrasts are associated with this contrast + backSort(problemStruct->contrastBackgrounds[i], + problemStruct->contrastQzshifts[i], + problemStruct->contrastScalefactors[i], + problemStruct->contrastBulkIns[i], + problemStruct->contrastBulkOuts[i], + problemStruct->contrastResolutions[i], + problemStruct->backgroundParams, problemStruct->qzshifts, + problemStruct->scalefactors, problemStruct->bulkIn, + problemStruct->bulkOut, problemStruct->resolutionParams, + &thisBackground, &thisQzshift, &thisScalefactor, &thisBulkIn, + &thisBulkOut, &thisResol); + + // Get the custom layers output for this contrast + // We have two for each contrast - one for each domain + // For the other parameters, we extract the correct ones from the input + // arrays + // Now call the core layers reflectivity calculation + // In this case we are single cored, so we do not parallelise over + // points + // Call the reflectivity calculation for each domain + // Domain 1 + b_dv[0] = problemCells->f3[i].f1[0]; + b_dv[1] = problemCells->f3[i].f1[1]; + b_dv1[0] = problemCells->f4[i].f1[0]; + b_dv1[1] = problemCells->f4[i].f1[1]; + dv2[0] = problemCells->f1[i].f1[0]; + dv2[1] = problemCells->f1[i].f1[1]; + nonPolarisedTF::coreLayersCalculation(calcAllLayers[i].f1, allRoughs[i], + problemStruct->geometry.data, problemStruct->geometry.size, + thisBulkIn, thisBulkOut, problemStruct->resample[i], calcSld, + thisScalefactor, thisQzshift, problemStruct->dataPresent[i], + problemCells->f2[i].f1, b_dv, b_dv1, dv2, thisBackground, thisResol, + problemStruct->contrastBackgroundsType[i], static_cast + (nParams), controls->resamPars, useImaginary, r2.f1, reflect1, + simul1, shiftedDat, r3.f1, r4.f1, &a__4, &thisSsubs); + + // Domain 2 + b_dv[0] = problemCells->f3[i].f1[0]; + b_dv[1] = problemCells->f3[i].f1[1]; + b_dv1[0] = problemCells->f4[i].f1[0]; + b_dv1[1] = problemCells->f4[i].f1[1]; + dv2[0] = problemCells->f1[i].f1[0]; + dv2[1] = problemCells->f1[i].f1[1]; + nonPolarisedTF::coreLayersCalculation(calcAllLayers[i + + calcAllLayers.size(0)].f1, allRoughs[i], + problemStruct->geometry.data, problemStruct->geometry.size, + thisBulkIn, thisBulkOut, problemStruct->resample[i], calcSld, + thisScalefactor, thisQzshift, problemStruct->dataPresent[i], + problemCells->f2[i].f1, b_dv, b_dv1, dv2, thisBackground, thisResol, + problemStruct->contrastBackgroundsType[i], static_cast + (nParams), controls->resamPars, useImaginary, r1.f1, reflect2, + simul2, a__5, r5.f1, r6.f1, &a__6, &a__7); + + // Calculate the average reflectivities.... + averageReflectivity(reflect1, reflect2, simul1, simul2, + problemStruct->domainRatio[static_cast + (problemStruct->contrastDomainRatios[i]) - 1], + totReflect, totSimul); + + // Get an overall chi-squared for the new averaged curve.. + thisChiSquared = chiSquared(shiftedDat, totReflect, static_cast + (problemStruct->params.size(1))); + + // Store returned values for this contrast in the output arrays. + // As well as the calculated profiles, we also store a record of + // the other values (background, scalefactors etc) for each contrast + // for future use. + outSsubs[i] = thisSsubs; + + // domainSldProfiles{i,1} = sldProfile1; + // domainSldProfiles{i,2} = sldProfile2; + tempSldProfiles[i].f1[0] = r2; + tempSldProfiles[i].f1[1] = r1; + reflectivity[i].f1.set_size(totReflect.size(0), 2); + c_loop_ub = totSimul.size(0); + simulation[i].f1.set_size(totSimul.size(0), 2); + d_loop_ub = totReflect.size(0); + for (i2 = 0; i2 < 2; i2++) { + for (i3 = 0; i3 < d_loop_ub; i3++) { + reflectivity[i].f1[i3 + reflectivity[i].f1.size(0) * i2] = + totReflect[i3 + totReflect.size(0) * i2]; + } + + for (i3 = 0; i3 < c_loop_ub; i3++) { + simulation[i].f1[i3 + simulation[i].f1.size(0) * i2] = totSimul[i3 + + totSimul.size(0) * i2]; + } + } + + shiftedData[i].f1.set_size(shiftedDat.size(0), shiftedDat.size(1)); + c_loop_ub = shiftedDat.size(1); + for (i2 = 0; i2 < c_loop_ub; i2++) { + d_loop_ub = shiftedDat.size(0); + for (i3 = 0; i3 < d_loop_ub; i3++) { + shiftedData[i].f1[i3 + shiftedData[i].f1.size(0) * i2] = + shiftedDat[i3 + shiftedDat.size(0) * i2]; + } + } + + tempLayerSlds[i].f1[0] = r3; + tempLayerSlds[i].f1[1] = r5; + tempAllLayers[i].f1[0] = r4; + tempAllLayers[i].f1[1] = r6; + chis[i] = thisChiSquared; + backgroundParams[i] = thisBackground; + qzshifts[i] = thisQzshift; + scalefactors[i] = thisScalefactor; + bulkIns[i] = thisBulkIn; + bulkOuts[i] = thisBulkOut; + resolutionParams[i] = thisResol; + } + + ub_loop = static_cast(numberOfContrasts); + for (int32_T b_i{0}; b_i < ub_loop; b_i++) { + int32_T b_loop_ub; + int32_T loop_ub; + loop_ub = tempSldProfiles[b_i].f1[0].f1.size(1); + domainSldProfiles[b_i].f1.set_size(tempSldProfiles[b_i].f1[0].f1.size + (0), tempSldProfiles[b_i].f1[0].f1.size(1)); + for (int32_T c_i{0}; c_i < loop_ub; c_i++) { + b_loop_ub = tempSldProfiles[b_i].f1[0].f1.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + domainSldProfiles[b_i].f1[i1 + domainSldProfiles[b_i].f1.size(0) * + c_i] = tempSldProfiles[b_i].f1[0].f1[i1 + tempSldProfiles[b_i]. + f1[0].f1.size(0) * c_i]; + } + } + + loop_ub = tempSldProfiles[b_i].f1[1].f1.size(1); + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.set_size + (tempSldProfiles[b_i].f1[1].f1.size(0), tempSldProfiles[b_i].f1[1]. + f1.size(1)); + for (int32_T c_i{0}; c_i < loop_ub; c_i++) { + b_loop_ub = tempSldProfiles[b_i].f1[1].f1.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1[i1 + + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size(0) * + c_i] = tempSldProfiles[b_i].f1[1].f1[i1 + tempSldProfiles[b_i]. + f1[1].f1.size(0) * c_i]; + } + } + + loop_ub = tempAllLayers[b_i].f1[0].f1.size(1); + allLayers[b_i].f1.set_size(tempAllLayers[b_i].f1[0].f1.size(0), + tempAllLayers[b_i].f1[0].f1.size(1)); + for (int32_T c_i{0}; c_i < loop_ub; c_i++) { + b_loop_ub = tempAllLayers[b_i].f1[0].f1.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + allLayers[b_i].f1[i1 + allLayers[b_i].f1.size(0) * c_i] = + tempAllLayers[b_i].f1[0].f1[i1 + tempAllLayers[b_i].f1[0]. + f1.size(0) * c_i]; + } + } + + loop_ub = tempAllLayers[b_i].f1[1].f1.size(1); + allLayers[b_i + allLayers.size(0)].f1.set_size(tempAllLayers[b_i].f1[1] + .f1.size(0), tempAllLayers[b_i].f1[1].f1.size(1)); + for (int32_T c_i{0}; c_i < loop_ub; c_i++) { + b_loop_ub = tempAllLayers[b_i].f1[1].f1.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + allLayers[b_i + allLayers.size(0)].f1[i1 + allLayers[b_i + + allLayers.size(0)].f1.size(0) * c_i] = tempAllLayers[b_i].f1[1]. + f1[i1 + tempAllLayers[b_i].f1[1].f1.size(0) * c_i]; + } + } + + loop_ub = tempLayerSlds[b_i].f1[0].f1.size(1); + layerSlds[b_i].f1.set_size(tempLayerSlds[b_i].f1[0].f1.size(0), + tempLayerSlds[b_i].f1[0].f1.size(1)); + for (int32_T c_i{0}; c_i < loop_ub; c_i++) { + b_loop_ub = tempLayerSlds[b_i].f1[0].f1.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + layerSlds[b_i].f1[i1 + layerSlds[b_i].f1.size(0) * c_i] = + tempLayerSlds[b_i].f1[0].f1[i1 + tempLayerSlds[b_i].f1[0]. + f1.size(0) * c_i]; + } + } + + loop_ub = tempLayerSlds[b_i].f1[1].f1.size(1); + layerSlds[b_i + layerSlds.size(0)].f1.set_size(tempLayerSlds[b_i].f1[1] + .f1.size(0), tempLayerSlds[b_i].f1[1].f1.size(1)); + for (int32_T c_i{0}; c_i < loop_ub; c_i++) { + b_loop_ub = tempLayerSlds[b_i].f1[1].f1.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + layerSlds[b_i + layerSlds.size(0)].f1[i1 + layerSlds[b_i + + layerSlds.size(0)].f1.size(0) * c_i] = tempLayerSlds[b_i].f1[1]. + f1[i1 + tempLayerSlds[b_i].f1[1].f1.size(0) * c_i]; + } + } + } + } + } + } +} + +// End of code generation (parallelContrasts4.cpp) diff --git a/cpp/RAT/parallelContrasts4.h b/cpp/RAT/parallelContrasts4.h new file mode 100644 index 00000000..54b907e7 --- /dev/null +++ b/cpp/RAT/parallelContrasts4.h @@ -0,0 +1,45 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parallelContrasts4.h +// +// Code generation for function 'parallelContrasts4' +// +#ifndef PARALLELCONTRASTS4_H +#define PARALLELCONTRASTS4_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace domainsTF + { + namespace customLayers + { + void c_parallelContrasts(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, ::coder::array + &outSsubs, ::coder::array &backgroundParams, ::coder::array< + real_T, 1U> &qzshifts, ::coder::array &scalefactors, ::coder:: + array &bulkIns, ::coder::array &bulkOuts, :: + coder::array &resolutionParams, ::coder::array + &chis, ::coder::array &reflectivity, ::coder::array< + cell_wrap_20, 1U> &simulation, ::coder::array + &shiftedData, ::coder::array &layerSlds, ::coder::array< + cell_wrap_8, 2U> &domainSldProfiles, ::coder::array + &allLayers, ::coder::array &allRoughs); + } + } +} + +#endif + +// End of code generation (parallelContrasts4.h) diff --git a/cpp/RAT/parallelContrasts5.cpp b/cpp/RAT/parallelContrasts5.cpp new file mode 100644 index 00000000..f0e1c9db --- /dev/null +++ b/cpp/RAT/parallelContrasts5.cpp @@ -0,0 +1,404 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parallelContrasts5.cpp +// +// Code generation for function 'parallelContrasts5' +// + +// Include files +#include "parallelContrasts5.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "applyBackgroundCorrection.h" +#include "averageReflectivity.h" +#include "backSort.h" +#include "callReflectivity.h" +#include "chiSquared.h" +#include "processCustomFunction3.h" +#include "resampleLayers.h" +#include "resampleLayersReIm.h" +#include "rt_nonfinite.h" +#include "shiftData.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace domainsTF + { + namespace customXY + { + void c_parallelContrasts(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, ::coder::array + &outSsubs, ::coder::array &backgroundParams, ::coder::array< + real_T, 1U> &qzshifts, ::coder::array &scalefactors, ::coder:: + array &bulkIns, ::coder::array &bulkOuts, :: + coder::array &resolutionParams, ::coder::array + &chis, ::coder::array &reflectivity, ::coder::array< + cell_wrap_20, 1U> &simulation, ::coder::array + &shiftedData, ::coder::array &layerSlds, ::coder::array< + cell_wrap_8, 2U> &domainSldProfiles, ::coder::array + &allLayers, ::coder::array &allRoughs) + { + ::coder::array tempAllLayers; + ::coder::array tempLayerSlds; + ::coder::array tempSldProfiles; + ::coder::array b_domainSldProfiles; + ::coder::array b_problemCells; + ::coder::array c_domainSldProfiles; + ::coder::array r4; + ::coder::array reflect1; + ::coder::array reflect2; + ::coder::array shiftedDat; + ::coder::array simul1; + ::coder::array simul2; + ::coder::array totReflect; + cell_wrap_8 r; + cell_wrap_8 r1; + cell_wrap_8 r2; + cell_wrap_8 r3; + int32_T b_loop_ub; + int32_T i; + int32_T loop_ub; + boolean_T useImaginary; + + // Extract individual cell arrays + // Splits up the master input list of all arrays into separate arrays + // + // INPUTS: + // * problemCells: cell array where all the project data is grouped together. + // + // OUTPUTS: + // * repeatLayers: controls repeating of the layers stack. + // * allData: Array of all the data arrays. + // * dataLimits: Min max limits in q for the data arrays. + // * simLimits: Limits in Q for the reflectivity simulations. + // * layersDetails: Master array of all available layers. + // * contrastLayers: Which specific combination of arrays are needed for each contrast. + // * customFiles:Filenames and path for any custom files used. + // % Layers details N/A + // Extract individual parameters from problemStruct + // Extract individual parameters from problem + // Pre-Allocation... + i = static_cast(problemStruct->numberOfContrasts); + backgroundParams.set_size(i); + + // Resampling parameters + useImaginary = problemStruct->useImaginary; + + // Default for compile. + processCustomFunction(problemStruct->contrastBulkIns, + problemStruct->contrastBulkOuts, + problemStruct->bulkIn, problemStruct->bulkOut, + problemStruct->contrastCustomFiles, + problemStruct->numberOfContrasts, + problemCells->f14, problemStruct->params, + domainSldProfiles, allRoughs); + outSsubs.set_size(i); + qzshifts.set_size(i); + scalefactors.set_size(i); + bulkIns.set_size(i); + bulkOuts.set_size(i); + resolutionParams.set_size(i); + tempLayerSlds.set_size(i); + tempAllLayers.set_size(i); + tempSldProfiles.set_size(i); + shiftedData.set_size(i); + reflectivity.set_size(i); + simulation.set_size(i); + chis.set_size(i); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T b_dv[2]; + real_T b_dv1[2]; + outSsubs[b_i] = allRoughs[b_i]; + backSort(problemStruct->contrastBackgrounds[b_i], + problemStruct->contrastQzshifts[b_i], + problemStruct->contrastScalefactors[b_i], + problemStruct->contrastBulkIns[b_i], + problemStruct->contrastBulkOuts[b_i], + problemStruct->contrastResolutions[b_i], + problemStruct->backgroundParams, problemStruct->qzshifts, + problemStruct->scalefactors, problemStruct->bulkIn, + problemStruct->bulkOut, problemStruct->resolutionParams, + &backgroundParams[b_i], &qzshifts[b_i], &scalefactors[b_i], + &bulkIns[b_i], &bulkOuts[b_i], &resolutionParams[b_i]); + + // Get the domain ratio for this contrast + // Resample the sld profiles + if (!useImaginary) { + resampleLayers(domainSldProfiles[b_i].f1, controls->resamPars, r.f1); + r1.f1.set_size(r.f1.size(0), 3); + for (int32_T i1{0}; i1 < 3; i1++) { + loop_ub = r.f1.size(0); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + r1.f1[i2 + r1.f1.size(0) * i1] = r.f1[i2 + r.f1.size(0) * i1]; + } + } + + resampleLayers(domainSldProfiles[b_i + domainSldProfiles.size(0)].f1, + controls->resamPars, r.f1); + } else { + loop_ub = domainSldProfiles[b_i].f1.size(0); + b_domainSldProfiles.set_size(domainSldProfiles[b_i].f1.size(0), 2); + for (int32_T i1{0}; i1 < 2; i1++) { + for (int32_T i2{0}; i2 < loop_ub; i2++) { + b_domainSldProfiles[i2 + b_domainSldProfiles.size(0) * i1] = + domainSldProfiles[b_i].f1[i2 + domainSldProfiles[b_i].f1.size + (0) * i1]; + } + } + + loop_ub = domainSldProfiles[b_i].f1.size(0); + c_domainSldProfiles.set_size(domainSldProfiles[b_i].f1.size(0), 2); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + c_domainSldProfiles[i1] = domainSldProfiles[b_i].f1[i1]; + c_domainSldProfiles[i1 + c_domainSldProfiles.size(0)] = + domainSldProfiles[b_i].f1[i1 + domainSldProfiles[b_i].f1.size(0) + * 2]; + } + + b_resampleLayersReIm(b_domainSldProfiles, c_domainSldProfiles, + controls->resamPars, r.f1); + r1.f1.set_size(r.f1.size(0), 4); + for (int32_T i1{0}; i1 < 4; i1++) { + loop_ub = r.f1.size(0); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + r1.f1[i2 + r1.f1.size(0) * i1] = r.f1[i2 + r.f1.size(0) * i1]; + } + } + + loop_ub = domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size + (0); + b_domainSldProfiles.set_size(domainSldProfiles[b_i + + domainSldProfiles.size(0)].f1.size(0), 2); + for (int32_T i1{0}; i1 < 2; i1++) { + for (int32_T i2{0}; i2 < loop_ub; i2++) { + b_domainSldProfiles[i2 + b_domainSldProfiles.size(0) * i1] = + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1[i2 + + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size(0) * + i1]; + } + } + + loop_ub = domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size + (0); + c_domainSldProfiles.set_size(domainSldProfiles[b_i + + domainSldProfiles.size(0)].f1.size(0), 2); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + c_domainSldProfiles[i1] = domainSldProfiles[b_i + + domainSldProfiles.size(0)].f1[i1]; + c_domainSldProfiles[i1 + c_domainSldProfiles.size(0)] = + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1[i1 + + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size(0) * + 2]; + } + + b_resampleLayersReIm(b_domainSldProfiles, c_domainSldProfiles, + controls->resamPars, r.f1); + } + + tempLayerSlds[b_i].f1[0] = r1; + tempLayerSlds[b_i].f1[1] = r; + tempAllLayers[b_i].f1[0] = r1; + tempAllLayers[b_i].f1[1] = r; + r2.f1.set_size(domainSldProfiles[b_i].f1.size(0), + domainSldProfiles[b_i].f1.size(1)); + loop_ub = domainSldProfiles[b_i].f1.size(1); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = domainSldProfiles[b_i].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + r2.f1[i2 + r2.f1.size(0) * i1] = domainSldProfiles[b_i].f1[i2 + + domainSldProfiles[b_i].f1.size(0) * i1]; + } + } + + r3.f1.set_size(domainSldProfiles[b_i + domainSldProfiles.size(0)]. + f1.size(0), domainSldProfiles[b_i + + domainSldProfiles.size(0)].f1.size(1)); + loop_ub = domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size(1); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = domainSldProfiles[b_i + domainSldProfiles.size(0)]. + f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + r3.f1[i2 + r3.f1.size(0) * i1] = domainSldProfiles[b_i + + domainSldProfiles.size(0)].f1[i2 + domainSldProfiles[b_i + + domainSldProfiles.size(0)].f1.size(0) * i1]; + } + } + + tempSldProfiles[b_i].f1[0] = r2; + tempSldProfiles[b_i].f1[1] = r3; + b_problemCells.set_size(problemCells->f2[problemCells->f2.size(0) * + b_i].f1.size(0), problemCells->f2[problemCells->f2.size(0) * b_i]. + f1.size(1)); + loop_ub = problemCells->f2[b_i].f1.size(1) - 1; + for (int32_T i1{0}; i1 <= loop_ub; i1++) { + b_loop_ub = problemCells->f2[b_i].f1.size(0) - 1; + for (int32_T i2{0}; i2 <= b_loop_ub; i2++) { + b_problemCells[i2 + b_problemCells.size(0) * i1] = + problemCells->f2[b_i].f1[i2 + problemCells->f2[b_i].f1.size(0) * + i1]; + } + } + + b_dv[0] = problemCells->f3[b_i].f1[0]; + b_dv[1] = problemCells->f3[b_i].f1[1]; + b_dv1[0] = problemCells->f4[b_i].f1[0]; + b_dv1[1] = problemCells->f4[b_i].f1[1]; + shiftData(scalefactors[b_i], qzshifts[b_i], problemStruct-> + dataPresent[b_i], b_problemCells, b_dv, b_dv1, shiftedDat); + shiftedData[b_i].f1.set_size(shiftedDat.size(0), shiftedDat.size(1)); + loop_ub = shiftedDat.size(1); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = shiftedDat.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + shiftedData[b_i].f1[i2 + shiftedData[b_i].f1.size(0) * i1] = + shiftedDat[i2 + shiftedDat.size(0) * i1]; + } + } + + r4.set_size(r1.f1.size(0), r1.f1.size(1)); + loop_ub = r1.f1.size(1) - 1; + for (int32_T i1{0}; i1 <= loop_ub; i1++) { + b_loop_ub = r1.f1.size(0) - 1; + for (int32_T i2{0}; i2 <= b_loop_ub; i2++) { + r4[i2 + r4.size(0) * i1] = r1.f1[i2 + r1.f1.size(0) * i1]; + } + } + + b_dv[0] = problemCells->f4[b_i].f1[0]; + b_dv[1] = problemCells->f4[b_i].f1[1]; + b_dv1[0] = problemCells->f1[b_i].f1[0]; + b_dv1[1] = problemCells->f1[b_i].f1[1]; + callReflectivity(bulkIns[b_i], bulkOuts[b_i], b_dv, b_dv1, shiftedDat, + r4, allRoughs[b_i], resolutionParams[b_i], + useImaginary, reflect1, simul1); + r4.set_size(r.f1.size(0), r.f1.size(1)); + loop_ub = r.f1.size(1) - 1; + for (int32_T i1{0}; i1 <= loop_ub; i1++) { + b_loop_ub = r.f1.size(0) - 1; + for (int32_T i2{0}; i2 <= b_loop_ub; i2++) { + r4[i2 + r4.size(0) * i1] = r.f1[i2 + r.f1.size(0) * i1]; + } + } + + b_dv[0] = problemCells->f4[b_i].f1[0]; + b_dv[1] = problemCells->f4[b_i].f1[1]; + b_dv1[0] = problemCells->f1[b_i].f1[0]; + b_dv1[1] = problemCells->f1[b_i].f1[1]; + callReflectivity(bulkIns[b_i], bulkOuts[b_i], b_dv, b_dv1, shiftedDat, + r4, allRoughs[b_i], resolutionParams[b_i], + useImaginary, reflect2, simul2); + applyBackgroundCorrection(reflect1, simul1, shiftedDat, + backgroundParams[b_i], problemStruct->contrastBackgroundsType[b_i]); + applyBackgroundCorrection(reflect2, simul2, shiftedDat, + backgroundParams[b_i], problemStruct->contrastBackgroundsType[b_i]); + + // Calculate the average reflectivities.... + averageReflectivity(reflect1, reflect2, simul1, simul2, + problemStruct->domainRatio[static_cast + (problemStruct->contrastDomainRatios[b_i]) - 1], + totReflect, simulation[b_i].f1); + loop_ub = totReflect.size(0); + reflectivity[b_i].f1.set_size(totReflect.size(0), 2); + for (int32_T i1{0}; i1 < 2; i1++) { + for (int32_T i2{0}; i2 < loop_ub; i2++) { + reflectivity[b_i].f1[i2 + reflectivity[b_i].f1.size(0) * i1] = + totReflect[i2 + totReflect.size(0) * i1]; + } + } + + if (problemStruct->dataPresent[b_i] != 0.0) { + chis[b_i] = chiSquared(shiftedDat, totReflect, static_cast + (problemStruct->params.size(1))); + } else { + chis[b_i] = 0.0; + } + } + + allLayers.set_size(i, 2); + layerSlds.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + loop_ub = tempSldProfiles[b_i].f1[0].f1.size(1); + domainSldProfiles[b_i].f1.set_size(tempSldProfiles[b_i].f1[0].f1.size + (0), tempSldProfiles[b_i].f1[0].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempSldProfiles[b_i].f1[0].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + domainSldProfiles[b_i].f1[i2 + domainSldProfiles[b_i].f1.size(0) * + i1] = tempSldProfiles[b_i].f1[0].f1[i2 + tempSldProfiles[b_i] + .f1[0].f1.size(0) * i1]; + } + } + + loop_ub = tempSldProfiles[b_i].f1[1].f1.size(1); + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.set_size + (tempSldProfiles[b_i].f1[1].f1.size(0), tempSldProfiles[b_i].f1[1]. + f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempSldProfiles[b_i].f1[1].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1[i2 + + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size(0) * + i1] = tempSldProfiles[b_i].f1[1].f1[i2 + tempSldProfiles[b_i] + .f1[1].f1.size(0) * i1]; + } + } + + loop_ub = tempAllLayers[b_i].f1[0].f1.size(1); + allLayers[b_i].f1.set_size(tempAllLayers[b_i].f1[0].f1.size(0), + tempAllLayers[b_i].f1[0].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempAllLayers[b_i].f1[0].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + allLayers[b_i].f1[i2 + allLayers[b_i].f1.size(0) * i1] = + tempAllLayers[b_i].f1[0].f1[i2 + tempAllLayers[b_i].f1[0]. + f1.size(0) * i1]; + } + } + + loop_ub = tempAllLayers[b_i].f1[1].f1.size(1); + allLayers[b_i + allLayers.size(0)].f1.set_size(tempAllLayers[b_i].f1[1] + .f1.size(0), tempAllLayers[b_i].f1[1].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempAllLayers[b_i].f1[1].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + allLayers[b_i + allLayers.size(0)].f1[i2 + allLayers[b_i + + allLayers.size(0)].f1.size(0) * i1] = tempAllLayers[b_i].f1[1]. + f1[i2 + tempAllLayers[b_i].f1[1].f1.size(0) * i1]; + } + } + + loop_ub = tempLayerSlds[b_i].f1[0].f1.size(1); + layerSlds[b_i].f1.set_size(tempLayerSlds[b_i].f1[0].f1.size(0), + tempLayerSlds[b_i].f1[0].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempLayerSlds[b_i].f1[0].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + layerSlds[b_i].f1[i2 + layerSlds[b_i].f1.size(0) * i1] = + tempLayerSlds[b_i].f1[0].f1[i2 + tempLayerSlds[b_i].f1[0]. + f1.size(0) * i1]; + } + } + + loop_ub = tempLayerSlds[b_i].f1[1].f1.size(1); + layerSlds[b_i + layerSlds.size(0)].f1.set_size(tempLayerSlds[b_i].f1[1] + .f1.size(0), tempLayerSlds[b_i].f1[1].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempLayerSlds[b_i].f1[1].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + layerSlds[b_i + layerSlds.size(0)].f1[i2 + layerSlds[b_i + + layerSlds.size(0)].f1.size(0) * i1] = tempLayerSlds[b_i].f1[1]. + f1[i2 + tempLayerSlds[b_i].f1[1].f1.size(0) * i1]; + } + } + } + } + } + } +} + +// End of code generation (parallelContrasts5.cpp) diff --git a/cpp/RAT/parallelContrasts5.h b/cpp/RAT/parallelContrasts5.h new file mode 100644 index 00000000..cbe763fb --- /dev/null +++ b/cpp/RAT/parallelContrasts5.h @@ -0,0 +1,45 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parallelContrasts5.h +// +// Code generation for function 'parallelContrasts5' +// +#ifndef PARALLELCONTRASTS5_H +#define PARALLELCONTRASTS5_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace domainsTF + { + namespace customXY + { + void c_parallelContrasts(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, ::coder::array + &outSsubs, ::coder::array &backgroundParams, ::coder::array< + real_T, 1U> &qzshifts, ::coder::array &scalefactors, ::coder:: + array &bulkIns, ::coder::array &bulkOuts, :: + coder::array &resolutionParams, ::coder::array + &chis, ::coder::array &reflectivity, ::coder::array< + cell_wrap_20, 1U> &simulation, ::coder::array + &shiftedData, ::coder::array &layerSlds, ::coder::array< + cell_wrap_8, 2U> &domainSldProfiles, ::coder::array + &allLayers, ::coder::array &allRoughs); + } + } +} + +#endif + +// End of code generation (parallelContrasts5.h) diff --git a/cpp/RAT/parallelPoints.cpp b/cpp/RAT/parallelPoints.cpp new file mode 100644 index 00000000..c88bba59 --- /dev/null +++ b/cpp/RAT/parallelPoints.cpp @@ -0,0 +1,206 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parallelPoints.cpp +// +// Code generation for function 'parallelPoints' +// + +// Include files +#include "parallelPoints.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "allocateLayersForContrast.h" +#include "allocateParamsToLayers.h" +#include "backSort.h" +#include "coreLayersCalculation.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include "coder_bounded_array.h" + +// Function Definitions +namespace RAT +{ + namespace nonPolarisedTF + { + namespace standardLayers + { + void parallelPoints(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, ::coder:: + array &outSsubs, ::coder::array + &backgroundParams, ::coder::array + &qzshifts, ::coder::array &scalefactors, :: + coder::array &bulkIns, ::coder::array< + real_T, 1U> &bulkOuts, ::coder::array + &resolutionParams, ::coder::array &chis, :: + coder::array &reflectivity, ::coder:: + array &simulation, ::coder::array< + cell_wrap_8, 1U> &shiftedData, ::coder::array< + cell_wrap_8, 1U> &layerSlds, ::coder::array< + cell_wrap_8, 1U> &sldProfiles, ::coder::array< + cell_wrap_8, 1U> &allLayers, ::coder::array + &allRoughs) + { + static real_T thisContrastLayers_data[6000]; + ::coder::array outParameterisedLayers; + ::coder::array b_thisContrastLayers_data; + ::coder::array shiftedDat; + ::coder::array sldProfile; + real_T thisBackground; + real_T thisBulkIn; + real_T thisBulkOut; + real_T thisQzshift; + real_T thisResol; + real_T thisScalefactor; + int32_T i; + boolean_T useImaginary; + + // Standard Layers calculation paralelised over the inner loop + // This is the main reflectivity calculation of the standard layers + // calculation type. It extracts the required parameters for the contrasts + // from the input arrays, then passes the main calculation to + // 'standardLayersCore', which carries out the calculation iteself. + // The core calculation is common for both standard and custom layers. + // Extract individual cell arrays + // Splits up the master input list of all arrays into separate arrays + // + // INPUTS: + // * problemCells: cell array where all the project data is grouped together. + // + // OUTPUTS: + // * repeatLayers: controls repeating of the layers stack. + // * allData: Array of all the data arrays. + // * dataLimits: Min max limits in q for the data arrays. + // * simLimits: Limits in Q for the reflectivity simulations. + // * layersDetails: Master array of all available layers. + // * contrastLayers: Which specific combination of arrays are needed for each contrast. + // * customFiles:Filenames and path for any custom files used. + // Extract individual parameters from problemStruct + // Extract individual parameters from problem + useImaginary = problemStruct->useImaginary; + + // Allocate the memory for the output arrays before the main loop + i = static_cast(problemStruct->numberOfContrasts); + backgroundParams.set_size(i); + + // end memory allocation. + // First we need to allocate the absolute values of the input + // parameters to all the layers in the layers list. This only needs + // to be done once, and so is done outside the contrasts loop + allocateParamsToLayers(problemStruct->params, problemCells->f6, + outParameterisedLayers); + + // Resample params if requiired + // Loop over all the contrasts + outSsubs.set_size(i); + sldProfiles.set_size(i); + reflectivity.set_size(i); + simulation.set_size(i); + shiftedData.set_size(i); + layerSlds.set_size(i); + chis.set_size(i); + qzshifts.set_size(i); + scalefactors.set_size(i); + bulkIns.set_size(i); + bulkOuts.set_size(i); + resolutionParams.set_size(i); + allRoughs.set_size(i); + allLayers.set_size(i); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T b_dv[2]; + real_T b_dv1[2]; + real_T dv2[2]; + int32_T thisContrastLayers_size[2]; + int32_T b_loop_ub; + int32_T loop_ub; + + // Extract the relevant parameter values for this contrast + // from the input arrays. + // First need to decide which values of the backgrounds, scalefactors + // data shifts and bulk contrasts are associated with this contrast + backSort(problemStruct->contrastBackgrounds[b_i], + problemStruct->contrastQzshifts[b_i], + problemStruct->contrastScalefactors[b_i], + problemStruct->contrastBulkIns[b_i], + problemStruct->contrastBulkOuts[b_i], + problemStruct->contrastResolutions[b_i], + problemStruct->backgroundParams, problemStruct->qzshifts, + problemStruct->scalefactors, problemStruct->bulkIn, + problemStruct->bulkOut, problemStruct->resolutionParams, + &thisBackground, &thisQzshift, &thisScalefactor, &thisBulkIn, + &thisBulkOut, &thisResol); + + // Also need to determine which layers from the overall layers list + // are required for this contrast, and put them in the correct order + // according to geometry + allocateLayersForContrast(problemCells->f5[b_i].f1, + outParameterisedLayers, useImaginary, thisContrastLayers_data, + thisContrastLayers_size); + + // For the other parameters, we extract the correct ones from the input + // arrays + // Substrate roughness is always first parameter for standard layers + // Now call the core layers reflectivity calculation + // In this case we are single cored, so we do not parallelise over + // points + // Call the core layers calculation + b_thisContrastLayers_data.set(&thisContrastLayers_data[0], + thisContrastLayers_size[0], thisContrastLayers_size[1]); + b_dv[0] = problemCells->f3[b_i].f1[0]; + b_dv[1] = problemCells->f3[b_i].f1[1]; + b_dv1[0] = problemCells->f4[b_i].f1[0]; + b_dv1[1] = problemCells->f4[b_i].f1[1]; + dv2[0] = problemCells->f1[b_i].f1[0]; + dv2[1] = problemCells->f1[b_i].f1[1]; + b_coreLayersCalculation(b_thisContrastLayers_data, + problemStruct->params[0], problemStruct->geometry.data, + problemStruct->geometry.size, thisBulkIn, thisBulkOut, + problemStruct->resample[b_i], controls->calcSldDuringFit, + thisScalefactor, thisQzshift, problemStruct->dataPresent[b_i], + problemCells->f2[b_i].f1, b_dv, b_dv1, dv2, thisBackground, + thisResol, problemStruct->contrastBackgroundsType[b_i], static_cast< + real_T>(problemStruct->params.size(1)), controls->resamPars, + useImaginary, sldProfile, reflectivity[b_i].f1, simulation[b_i].f1, + shiftedDat, layerSlds[b_i].f1, allLayers[b_i].f1, &chis[b_i], + &outSsubs[b_i]); + + // Store returned values for this contrast in the output arrays. + // As well as the calculated profiles, we also store a record of + // the other values (background, scalefactors etc) for each contrast + // for future use. + loop_ub = sldProfile.size(1); + sldProfiles[b_i].f1.set_size(sldProfile.size(0), sldProfile.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = sldProfile.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + sldProfiles[b_i].f1[i2 + sldProfiles[b_i].f1.size(0) * i1] = + sldProfile[i2 + sldProfile.size(0) * i1]; + } + } + + loop_ub = shiftedDat.size(1); + shiftedData[b_i].f1.set_size(shiftedDat.size(0), shiftedDat.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = shiftedDat.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + shiftedData[b_i].f1[i2 + shiftedData[b_i].f1.size(0) * i1] = + shiftedDat[i2 + shiftedDat.size(0) * i1]; + } + } + + backgroundParams[b_i] = thisBackground; + qzshifts[b_i] = thisQzshift; + scalefactors[b_i] = thisScalefactor; + bulkIns[b_i] = thisBulkIn; + bulkOuts[b_i] = thisBulkOut; + resolutionParams[b_i] = thisResol; + allRoughs[b_i] = problemStruct->params[0]; + } + } + } + } +} + +// End of code generation (parallelPoints.cpp) diff --git a/cpp/RAT/parallelPoints.h b/cpp/RAT/parallelPoints.h new file mode 100644 index 00000000..f2e92571 --- /dev/null +++ b/cpp/RAT/parallelPoints.h @@ -0,0 +1,49 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parallelPoints.h +// +// Code generation for function 'parallelPoints' +// +#ifndef PARALLELPOINTS_H +#define PARALLELPOINTS_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace nonPolarisedTF + { + namespace standardLayers + { + void parallelPoints(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, ::coder:: + array &outSsubs, ::coder::array + &backgroundParams, ::coder::array + &qzshifts, ::coder::array &scalefactors, :: + coder::array &bulkIns, ::coder::array< + real_T, 1U> &bulkOuts, ::coder::array + &resolutionParams, ::coder::array &chis, :: + coder::array &reflectivity, ::coder:: + array &simulation, ::coder::array< + cell_wrap_8, 1U> &shiftedData, ::coder::array< + cell_wrap_8, 1U> &layerSlds, ::coder::array< + cell_wrap_8, 1U> &sldProfiles, ::coder::array< + cell_wrap_8, 1U> &allLayers, ::coder::array + &allRoughs); + } + } +} + +#endif + +// End of code generation (parallelPoints.h) diff --git a/cpp/RAT/parallelPoints1.cpp b/cpp/RAT/parallelPoints1.cpp new file mode 100644 index 00000000..550f431d --- /dev/null +++ b/cpp/RAT/parallelPoints1.cpp @@ -0,0 +1,201 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parallelPoints1.cpp +// +// Code generation for function 'parallelPoints1' +// + +// Include files +#include "parallelPoints1.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "backSort.h" +#include "coreLayersCalculation.h" +#include "processCustomFunction.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include "coder_bounded_array.h" + +// Function Definitions +namespace RAT +{ + namespace nonPolarisedTF + { + namespace customLayers + { + void parallelPoints(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, ::coder:: + array &outSsubs, ::coder::array + &backgroundParams, ::coder::array + &qzshifts, ::coder::array &scalefactors, :: + coder::array &bulkIns, ::coder::array< + real_T, 1U> &bulkOuts, ::coder::array + &resolutionParams, ::coder::array &chis, :: + coder::array &reflectivity, ::coder:: + array &simulation, ::coder::array< + cell_wrap_8, 1U> &shiftedData, ::coder::array< + cell_wrap_8, 1U> &layerSlds, ::coder::array< + cell_wrap_8, 1U> &sldProfiles, ::coder::array< + cell_wrap_8, 1U> &allLayers, ::coder::array + &allRoughs) + { + ::coder::array b_allLayers; + ::coder::array shiftedDat; + ::coder::array sldProfile; + real_T thisBackground; + real_T thisBulkIn; + real_T thisBulkOut; + real_T thisQzshift; + real_T thisResol; + real_T thisScalefactor; + int32_T i; + + // Multi threaded version of the custom layers over reflectivity poimnts + // for nonPolarisedTF reflectivity calculation. + // The function extracts the relevant parameters from the input + // arrays, allocates these on a pre-contrast basis, then calls the 'core' + // calculation (the core layers nonPolarisedTF calc is shared between + // multiple calculation types). + // Extract individual cell arrays + // Splits up the master input list of all arrays into separate arrays + // + // INPUTS: + // * problemCells: cell array where all the project data is grouped together. + // + // OUTPUTS: + // * repeatLayers: controls repeating of the layers stack. + // * allData: Array of all the data arrays. + // * dataLimits: Min max limits in q for the data arrays. + // * simLimits: Limits in Q for the reflectivity simulations. + // * layersDetails: Master array of all available layers. + // * contrastLayers: Which specific combination of arrays are needed for each contrast. + // * customFiles:Filenames and path for any custom files used. + // Extract individual parameters from problemStruct + // Extract individual parameters from problem + // Pre-Allocation of output arrays... + i = static_cast(problemStruct->numberOfContrasts); + backgroundParams.set_size(i); + + // --- End Memory Allocation --- + // Resampling parameters + // Process the custom models.... + processCustomFunction(problemStruct->contrastBulkIns, + problemStruct->contrastBulkOuts, + problemStruct->bulkIn, problemStruct->bulkOut, + problemStruct->contrastCustomFiles, + problemStruct->numberOfContrasts, + problemCells->f14, problemStruct->params, + problemStruct->useImaginary, allLayers, allRoughs); + + // Single cored over all contrasts + outSsubs.set_size(i); + sldProfiles.set_size(i); + reflectivity.set_size(i); + simulation.set_size(i); + shiftedData.set_size(i); + layerSlds.set_size(i); + chis.set_size(i); + qzshifts.set_size(i); + scalefactors.set_size(i); + bulkIns.set_size(i); + bulkOuts.set_size(i); + resolutionParams.set_size(i); + for (int32_T b_i{0}; b_i < i; b_i++) { + int32_T b_loop_ub; + int32_T loop_ub; + + // Extract the relevant parameter values for this contrast + // from the input arrays. + // First need to decide which values of the backgrounds, scalefactors + // data shifts and bulk contrasts are associated with this contrast + backSort(problemStruct->contrastBackgrounds[b_i], + problemStruct->contrastQzshifts[b_i], + problemStruct->contrastScalefactors[b_i], + problemStruct->contrastBulkIns[b_i], + problemStruct->contrastBulkOuts[b_i], + problemStruct->contrastResolutions[b_i], + problemStruct->backgroundParams, problemStruct->qzshifts, + problemStruct->scalefactors, problemStruct->bulkIn, + problemStruct->bulkOut, problemStruct->resolutionParams, + &thisBackground, &thisQzshift, &thisScalefactor, &thisBulkIn, + &thisBulkOut, &thisResol); + + // Get the custom layers output for this contrast + // For the other parameters, we extract the correct ones from the input + // arrays + // Now call the core layers reflectivity calculation + // In this case we are single cored, so we do not parallelise over + // points + // Call the reflectivity calculation + b_allLayers.set_size(allLayers[b_i].f1.size(0), allLayers[b_i].f1.size + (1)); + loop_ub = allLayers[b_i].f1.size(1) - 1; + for (int32_T i1{0}; i1 <= loop_ub; i1++) { + b_loop_ub = allLayers[b_i].f1.size(0) - 1; + for (int32_T i2{0}; i2 <= b_loop_ub; i2++) { + b_allLayers[i2 + b_allLayers.size(0) * i1] = allLayers[b_i].f1[i2 + + allLayers[b_i].f1.size(0) * i1]; + } + } + + real_T b_dv[2]; + real_T b_dv1[2]; + real_T dv2[2]; + b_dv[0] = problemCells->f3[b_i].f1[0]; + b_dv[1] = problemCells->f3[b_i].f1[1]; + b_dv1[0] = problemCells->f4[b_i].f1[0]; + b_dv1[1] = problemCells->f4[b_i].f1[1]; + dv2[0] = problemCells->f1[b_i].f1[0]; + dv2[1] = problemCells->f1[b_i].f1[1]; + b_coreLayersCalculation(b_allLayers, allRoughs[b_i], + problemStruct->geometry.data, problemStruct->geometry.size, + thisBulkIn, thisBulkOut, problemStruct->resample[b_i], + controls->calcSldDuringFit, thisScalefactor, thisQzshift, + problemStruct->dataPresent[b_i], problemCells->f2[b_i].f1, b_dv, + b_dv1, dv2, thisBackground, thisResol, + problemStruct->contrastBackgroundsType[b_i], static_cast + (problemStruct->params.size(1)), controls->resamPars, + problemStruct->useImaginary, sldProfile, reflectivity[b_i].f1, + simulation[b_i].f1, shiftedDat, layerSlds[b_i].f1, allLayers[b_i].f1, + &chis[b_i], &outSsubs[b_i]); + + // Store returned values for this contrast in the output arrays. + // As well as the calculated profiles, we also store a record of + // the other values (background, scalefactors etc) for each contrast + // for future use. + loop_ub = sldProfile.size(1); + sldProfiles[b_i].f1.set_size(sldProfile.size(0), sldProfile.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = sldProfile.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + sldProfiles[b_i].f1[i2 + sldProfiles[b_i].f1.size(0) * i1] = + sldProfile[i2 + sldProfile.size(0) * i1]; + } + } + + loop_ub = shiftedDat.size(1); + shiftedData[b_i].f1.set_size(shiftedDat.size(0), shiftedDat.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = shiftedDat.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + shiftedData[b_i].f1[i2 + shiftedData[b_i].f1.size(0) * i1] = + shiftedDat[i2 + shiftedDat.size(0) * i1]; + } + } + + backgroundParams[b_i] = thisBackground; + qzshifts[b_i] = thisQzshift; + scalefactors[b_i] = thisScalefactor; + bulkIns[b_i] = thisBulkIn; + bulkOuts[b_i] = thisBulkOut; + resolutionParams[b_i] = thisResol; + } + } + } + } +} + +// End of code generation (parallelPoints1.cpp) diff --git a/cpp/RAT/parallelPoints1.h b/cpp/RAT/parallelPoints1.h new file mode 100644 index 00000000..0d0e84ed --- /dev/null +++ b/cpp/RAT/parallelPoints1.h @@ -0,0 +1,49 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parallelPoints1.h +// +// Code generation for function 'parallelPoints1' +// +#ifndef PARALLELPOINTS1_H +#define PARALLELPOINTS1_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace nonPolarisedTF + { + namespace customLayers + { + void parallelPoints(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, ::coder:: + array &outSsubs, ::coder::array + &backgroundParams, ::coder::array + &qzshifts, ::coder::array &scalefactors, :: + coder::array &bulkIns, ::coder::array< + real_T, 1U> &bulkOuts, ::coder::array + &resolutionParams, ::coder::array &chis, :: + coder::array &reflectivity, ::coder:: + array &simulation, ::coder::array< + cell_wrap_8, 1U> &shiftedData, ::coder::array< + cell_wrap_8, 1U> &layerSlds, ::coder::array< + cell_wrap_8, 1U> &sldProfiles, ::coder::array< + cell_wrap_8, 1U> &allLayers, ::coder::array + &allRoughs); + } + } +} + +#endif + +// End of code generation (parallelPoints1.h) diff --git a/cpp/RAT/parallelPoints2.cpp b/cpp/RAT/parallelPoints2.cpp new file mode 100644 index 00000000..a7b88816 --- /dev/null +++ b/cpp/RAT/parallelPoints2.cpp @@ -0,0 +1,218 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parallelPoints2.cpp +// +// Code generation for function 'parallelPoints2' +// + +// Include files +#include "parallelPoints2.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "applyBackgroundCorrection.h" +#include "backSort.h" +#include "callReflectivity.h" +#include "chiSquared.h" +#include "processCustomFunction1.h" +#include "resampleLayers.h" +#include "resampleLayersReIm.h" +#include "rt_nonfinite.h" +#include "shiftData.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace nonPolarisedTF + { + namespace customXY + { + void parallelPoints(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, ::coder:: + array &outSsubs, ::coder::array + &backgroundParams, ::coder::array + &qzshifts, ::coder::array &scalefactors, :: + coder::array &bulkIns, ::coder::array< + real_T, 1U> &bulkOuts, ::coder::array + &resolutionParams, ::coder::array &chis, :: + coder::array &reflectivity, ::coder:: + array &simulation, ::coder::array< + cell_wrap_8, 1U> &shiftedData, ::coder::array< + cell_wrap_8, 1U> &layerSlds, ::coder::array< + cell_wrap_8, 1U> &sldProfiles, ::coder::array< + cell_wrap_8, 1U> &allLayers, ::coder::array + &allRoughs) + { + ::coder::array b_problemCells; + ::coder::array b_sldProfiles; + ::coder::array c_sldProfiles; + ::coder::array layerSld; + ::coder::array reflect; + ::coder::array shiftedDat; + int32_T loop_ub_tmp; + boolean_T useImaginary; + + // Multi threaded version of the custom XY profile over reflectivity points + // for nonPolarisedTF reflectivity calculation. + // Extract individual cell arrays + // Splits up the master input list of all arrays into separate arrays + // + // INPUTS: + // * problemCells: cell array where all the project data is grouped together. + // + // OUTPUTS: + // * repeatLayers: controls repeating of the layers stack. + // * allData: Array of all the data arrays. + // * dataLimits: Min max limits in q for the data arrays. + // * simLimits: Limits in Q for the reflectivity simulations. + // * layersDetails: Master array of all available layers. + // * contrastLayers: Which specific combination of arrays are needed for each contrast. + // * customFiles:Filenames and path for any custom files used. + // % Layers details N/A + // Extract individual parameters from problemStruct + // Extract individual parameters from problem + // Pre-Allocation... + loop_ub_tmp = static_cast(problemStruct->numberOfContrasts); + backgroundParams.set_size(loop_ub_tmp); + outSsubs.set_size(loop_ub_tmp); + for (int32_T i{0}; i < loop_ub_tmp; i++) { + outSsubs[i] = 0.0; + } + + // Resampling parameters + useImaginary = problemStruct->useImaginary; + processCustomFunction(problemStruct->contrastBulkIns, + problemStruct->contrastBulkOuts, + problemStruct->bulkIn, problemStruct->bulkOut, + problemStruct->contrastCustomFiles, + problemStruct->numberOfContrasts, + problemCells->f14, problemStruct->params, + sldProfiles, allRoughs); + qzshifts.set_size(loop_ub_tmp); + scalefactors.set_size(loop_ub_tmp); + bulkIns.set_size(loop_ub_tmp); + bulkOuts.set_size(loop_ub_tmp); + resolutionParams.set_size(loop_ub_tmp); + layerSlds.set_size(loop_ub_tmp); + allLayers.set_size(loop_ub_tmp); + shiftedData.set_size(loop_ub_tmp); + chis.set_size(loop_ub_tmp); + simulation.set_size(loop_ub_tmp); + reflectivity.set_size(loop_ub_tmp); + for (int32_T b_i{0}; b_i < loop_ub_tmp; b_i++) { + real_T b_dv[2]; + real_T b_dv1[2]; + int32_T b_loop_ub; + int32_T loop_ub; + backSort(problemStruct->contrastBackgrounds[b_i], + problemStruct->contrastQzshifts[b_i], + problemStruct->contrastScalefactors[b_i], + problemStruct->contrastBulkIns[b_i], + problemStruct->contrastBulkOuts[b_i], + problemStruct->contrastResolutions[b_i], + problemStruct->backgroundParams, problemStruct->qzshifts, + problemStruct->scalefactors, problemStruct->bulkIn, + problemStruct->bulkOut, problemStruct->resolutionParams, + &backgroundParams[b_i], &qzshifts[b_i], &scalefactors[b_i], + &bulkIns[b_i], &bulkOuts[b_i], &resolutionParams[b_i]); + + // Resample the layers + if (!useImaginary) { + resampleLayers(sldProfiles[b_i].f1, controls->resamPars, layerSld); + } else { + loop_ub = sldProfiles[b_i].f1.size(0); + b_sldProfiles.set_size(sldProfiles[b_i].f1.size(0), 2); + for (int32_T i{0}; i < 2; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_sldProfiles[i1 + b_sldProfiles.size(0) * i] = sldProfiles[b_i] + .f1[i1 + sldProfiles[b_i].f1.size(0) * i]; + } + } + + loop_ub = sldProfiles[b_i].f1.size(0); + c_sldProfiles.set_size(sldProfiles[b_i].f1.size(0), 2); + for (int32_T i{0}; i < loop_ub; i++) { + c_sldProfiles[i] = sldProfiles[b_i].f1[i]; + c_sldProfiles[i + c_sldProfiles.size(0)] = sldProfiles[b_i].f1[i + + sldProfiles[b_i].f1.size(0) * 2]; + } + + b_resampleLayersReIm(b_sldProfiles, c_sldProfiles, + controls->resamPars, layerSld); + } + + layerSlds[b_i].f1.set_size(layerSld.size(0), layerSld.size(1)); + loop_ub = layerSld.size(1); + allLayers[b_i].f1.set_size(layerSld.size(0), layerSld.size(1)); + b_loop_ub = layerSld.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + layerSlds[b_i].f1[i1 + layerSlds[b_i].f1.size(0) * i] = + layerSld[i1 + layerSld.size(0) * i]; + allLayers[b_i].f1[i1 + allLayers[b_i].f1.size(0) * i] = + layerSld[i1 + layerSld.size(0) * i]; + } + } + + b_problemCells.set_size(problemCells->f2[problemCells->f2.size(0) * + b_i].f1.size(0), problemCells->f2[problemCells->f2.size(0) * b_i]. + f1.size(1)); + loop_ub = problemCells->f2[b_i].f1.size(1) - 1; + for (int32_T i{0}; i <= loop_ub; i++) { + b_loop_ub = problemCells->f2[b_i].f1.size(0) - 1; + for (int32_T i1{0}; i1 <= b_loop_ub; i1++) { + b_problemCells[i1 + b_problemCells.size(0) * i] = problemCells-> + f2[b_i].f1[i1 + problemCells->f2[b_i].f1.size(0) * i]; + } + } + + b_dv[0] = problemCells->f3[b_i].f1[0]; + b_dv[1] = problemCells->f3[b_i].f1[1]; + b_dv1[0] = problemCells->f4[b_i].f1[0]; + b_dv1[1] = problemCells->f4[b_i].f1[1]; + shiftData(scalefactors[b_i], qzshifts[b_i], problemStruct-> + dataPresent[b_i], b_problemCells, b_dv, b_dv1, shiftedDat); + shiftedData[b_i].f1.set_size(shiftedDat.size(0), shiftedDat.size(1)); + loop_ub = shiftedDat.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = shiftedDat.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + shiftedData[b_i].f1[i1 + shiftedData[b_i].f1.size(0) * i] = + shiftedDat[i1 + shiftedDat.size(0) * i]; + } + } + + b_dv[0] = problemCells->f4[b_i].f1[0]; + b_dv[1] = problemCells->f4[b_i].f1[1]; + b_dv1[0] = problemCells->f1[b_i].f1[0]; + b_dv1[1] = problemCells->f1[b_i].f1[1]; + b_callReflectivity(bulkIns[b_i], bulkOuts[b_i], b_dv, b_dv1, + shiftedDat, layerSld, 0.0, resolutionParams[b_i], + useImaginary, reflect, simulation[b_i].f1); + applyBackgroundCorrection(reflect, simulation[b_i].f1, shiftedDat, + backgroundParams[b_i], problemStruct->contrastBackgroundsType[b_i]); + loop_ub = reflect.size(0); + reflectivity[b_i].f1.set_size(reflect.size(0), 2); + for (int32_T i{0}; i < 2; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + reflectivity[b_i].f1[i1 + reflectivity[b_i].f1.size(0) * i] = + reflect[i1 + reflect.size(0) * i]; + } + } + + if (problemStruct->dataPresent[b_i] != 0.0) { + chis[b_i] = chiSquared(shiftedDat, reflect, static_cast + (problemStruct->params.size(1))); + } else { + chis[b_i] = 0.0; + } + } + } + } + } +} + +// End of code generation (parallelPoints2.cpp) diff --git a/cpp/RAT/parallelPoints2.h b/cpp/RAT/parallelPoints2.h new file mode 100644 index 00000000..734a0729 --- /dev/null +++ b/cpp/RAT/parallelPoints2.h @@ -0,0 +1,49 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parallelPoints2.h +// +// Code generation for function 'parallelPoints2' +// +#ifndef PARALLELPOINTS2_H +#define PARALLELPOINTS2_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace nonPolarisedTF + { + namespace customXY + { + void parallelPoints(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, ::coder:: + array &outSsubs, ::coder::array + &backgroundParams, ::coder::array + &qzshifts, ::coder::array &scalefactors, :: + coder::array &bulkIns, ::coder::array< + real_T, 1U> &bulkOuts, ::coder::array + &resolutionParams, ::coder::array &chis, :: + coder::array &reflectivity, ::coder:: + array &simulation, ::coder::array< + cell_wrap_8, 1U> &shiftedData, ::coder::array< + cell_wrap_8, 1U> &layerSlds, ::coder::array< + cell_wrap_8, 1U> &sldProfiles, ::coder::array< + cell_wrap_8, 1U> &allLayers, ::coder::array + &allRoughs); + } + } +} + +#endif + +// End of code generation (parallelPoints2.h) diff --git a/cpp/RAT/parallelPoints3.cpp b/cpp/RAT/parallelPoints3.cpp new file mode 100644 index 00000000..d0792e2e --- /dev/null +++ b/cpp/RAT/parallelPoints3.cpp @@ -0,0 +1,348 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parallelPoints3.cpp +// +// Code generation for function 'parallelPoints3' +// + +// Include files +#include "parallelPoints3.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "allocateLayersForContrast.h" +#include "allocateParamsToLayers.h" +#include "averageReflectivity.h" +#include "backSort.h" +#include "chiSquared.h" +#include "coreLayersCalculation.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include "coder_bounded_array.h" + +// Function Definitions +namespace RAT +{ + namespace domainsTF + { + namespace standardLayers + { + void parallelPoints(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, ::coder:: + array &outSsubs, ::coder::array + &backgroundParams, ::coder::array + &qzshifts, ::coder::array &scalefactors, :: + coder::array &bulkIns, ::coder::array< + real_T, 1U> &bulkOuts, ::coder::array + &resolutionParams, ::coder::array &chis, :: + coder::array &reflectivity, ::coder:: + array &simulation, ::coder::array< + cell_wrap_8, 1U> &shiftedData, ::coder::array< + cell_wrap_8, 2U> &layerSlds, ::coder::array< + cell_wrap_8, 2U> &domainSldProfiles, ::coder::array< + cell_wrap_8, 2U> &allLayers, ::coder::array + &allRoughs) + { + static real_T thisContrastLayers1_data[6000]; + static real_T thisContrastLayers2_data[6000]; + ::coder::array outParameterisedLayers; + ::coder::array tempAllLayers; + ::coder::array tempLayerSlds; + ::coder::array tempSldProfiles; + ::coder::array a__6; + ::coder::array b_thisContrastLayers1_data; + ::coder::array b_thisContrastLayers2_data; + ::coder::array reflect1; + ::coder::array reflect2; + ::coder::array shiftedDat; + ::coder::array simul1; + ::coder::array simul2; + ::coder::array totReflect; + cell_wrap_8 r; + cell_wrap_8 r1; + cell_wrap_8 r2; + cell_wrap_8 r3; + cell_wrap_8 r4; + cell_wrap_8 r5; + real_T a__5; + real_T a__7; + real_T a__8; + real_T thisBackground; + real_T thisBulkIn; + real_T thisBulkOut; + real_T thisQzshift; + real_T thisResol; + real_T thisScalefactor; + int32_T b_loop_ub; + int32_T i; + int32_T loop_ub; + int32_T nParams; + boolean_T calcSld; + boolean_T useImaginary; + + // Single threaded version of the Standard Layers calculation + // This is the main reflectivity calculation of the standard layers + // calculation type. It extracts the required parameters for the contrasts + // from the input arrays, then passes the main calculation to + // 'standardLayersCore', which carries out the calculation itself. + // The core calculation is common for both standard and custom layers. + // Extract individual cell arrays + // Splits up the master input list of all arrays into separate arrays + // + // INPUTS: + // * problemCells: cell array where all the project data is grouped together. + // + // OUTPUTS: + // * repeatLayers: controls repeating of the layers stack. + // * allData: Array of all the data arrays. + // * dataLimits: Min max limits in q for the data arrays. + // * simLimits: Limits in Q for the reflectivity simulations. + // * layersDetails: Master array of all available layers. + // * contrastLayers: Which specific combination of arrays are needed for each contrast. + // * customFiles:Filenames and path for any custom files used. + // Additionally extract the additional domain layers details + // Extract individual parameters from problemStruct + // Extract individual parameters from problem + nParams = problemStruct->params.size(1); + calcSld = controls->calcSldDuringFit; + useImaginary = problemStruct->useImaginary; + + // Default for compile. + // Allocate the memory for the output arrays before the main loop + i = static_cast(problemStruct->numberOfContrasts); + backgroundParams.set_size(i); + + // end memory allocation. + // First we need to allocate the absolute values of the input + // parameters to all the layers in the layers list. This only needs + // to be done once, and so is done outside the contrasts loop + allocateParamsToLayers(problemStruct->params, problemCells->f6, + outParameterisedLayers); + + // Resample params if requiired + // Loop over all the contrasts + outSsubs.set_size(i); + tempSldProfiles.set_size(i); + reflectivity.set_size(i); + simulation.set_size(i); + shiftedData.set_size(i); + tempLayerSlds.set_size(i); + tempAllLayers.set_size(i); + chis.set_size(i); + qzshifts.set_size(i); + scalefactors.set_size(i); + bulkIns.set_size(i); + bulkOuts.set_size(i); + resolutionParams.set_size(i); + allRoughs.set_size(i); + layerSlds.set_size(i, 2); + domainSldProfiles.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T b_dv[2]; + real_T b_dv1[2]; + real_T dv2[2]; + int32_T thisContrastLayers1_size[2]; + int32_T thisContrastLayers2_size[2]; + + // Get the domain ratio for this contrast + // Extract the relevant parameter values for this contrast + // from the input arrays. + // First need to decide which values of the backgrounds, scalefactors + // data shifts and bulk contrasts are associated with this contrast + backSort(problemStruct->contrastBackgrounds[b_i], + problemStruct->contrastQzshifts[b_i], + problemStruct->contrastScalefactors[b_i], + problemStruct->contrastBulkIns[b_i], + problemStruct->contrastBulkOuts[b_i], + problemStruct->contrastResolutions[b_i], + problemStruct->backgroundParams, problemStruct->qzshifts, + problemStruct->scalefactors, problemStruct->bulkIn, + problemStruct->bulkOut, problemStruct->resolutionParams, + &thisBackground, &thisQzshift, &thisScalefactor, &thisBulkIn, + &thisBulkOut, &thisResol); + + // Also need to determine which layers from the overall layers list + // are required for this contrast, and put them in the correct order + // according to geometry. We run it twice, once for each domain... + allocateLayersForContrast(problemCells->f19[0].f1, + outParameterisedLayers, useImaginary, thisContrastLayers1_data, + thisContrastLayers1_size); + allocateLayersForContrast(problemCells->f19[1].f1, + outParameterisedLayers, useImaginary, thisContrastLayers2_data, + thisContrastLayers2_size); + + // For the other parameters, we extract the correct ones from the input + // arrays + // Substrate roughness is always first parameter for standard layers + // Now call the core layers reflectivity calculation + // In this case we are single cored, so we do not parallelise over + // points + // Call the core layers calculation - need to do this once for each + // domain + b_thisContrastLayers1_data.set(&thisContrastLayers1_data[0], + thisContrastLayers1_size[0], thisContrastLayers1_size[1]); + b_dv[0] = problemCells->f3[b_i].f1[0]; + b_dv[1] = problemCells->f3[b_i].f1[1]; + b_dv1[0] = problemCells->f4[b_i].f1[0]; + b_dv1[1] = problemCells->f4[b_i].f1[1]; + dv2[0] = problemCells->f1[b_i].f1[0]; + dv2[1] = problemCells->f1[b_i].f1[1]; + nonPolarisedTF::b_coreLayersCalculation(b_thisContrastLayers1_data, + problemStruct->params[0], problemStruct->geometry.data, + problemStruct->geometry.size, thisBulkIn, thisBulkOut, + problemStruct->resample[b_i], calcSld, thisScalefactor, thisQzshift, + problemStruct->dataPresent[b_i], problemCells->f2[b_i].f1, b_dv, + b_dv1, dv2, thisBackground, thisResol, + problemStruct->contrastBackgroundsType[b_i], static_cast + (nParams), controls->resamPars, useImaginary, r.f1, reflect1, simul1, + shiftedDat, r1.f1, r2.f1, &a__5, &outSsubs[b_i]); + b_thisContrastLayers2_data.set(&thisContrastLayers2_data[0], + thisContrastLayers2_size[0], thisContrastLayers2_size[1]); + b_dv[0] = problemCells->f3[b_i].f1[0]; + b_dv[1] = problemCells->f3[b_i].f1[1]; + b_dv1[0] = problemCells->f4[b_i].f1[0]; + b_dv1[1] = problemCells->f4[b_i].f1[1]; + dv2[0] = problemCells->f1[b_i].f1[0]; + dv2[1] = problemCells->f1[b_i].f1[1]; + nonPolarisedTF::b_coreLayersCalculation(b_thisContrastLayers2_data, + problemStruct->params[0], problemStruct->geometry.data, + problemStruct->geometry.size, thisBulkIn, thisBulkOut, + problemStruct->resample[b_i], calcSld, thisScalefactor, thisQzshift, + problemStruct->dataPresent[b_i], problemCells->f2[b_i].f1, b_dv, + b_dv1, dv2, thisBackground, thisResol, + problemStruct->contrastBackgroundsType[b_i], static_cast + (nParams), controls->resamPars, useImaginary, r3.f1, reflect2, + simul2, a__6, r4.f1, r5.f1, &a__7, &a__8); + + // Calculate the average reflectivities.... + averageReflectivity(reflect1, reflect2, simul1, simul2, + problemStruct->domainRatio[static_cast + (problemStruct->contrastDomainRatios[b_i]) - 1], + totReflect, simulation[b_i].f1); + + // Get an overall chi-squared for the new averaged curve.. + chis[b_i] = chiSquared(shiftedDat, totReflect, static_cast + (problemStruct->params.size(1))); + + // Store returned values for this contrast in the output arrays. + // As well as the calculated profiles, we also store a record of + // the other values (background, scalefactors etc) for each contrast + // for future use. + tempSldProfiles[b_i].f1[0] = r; + tempSldProfiles[b_i].f1[1] = r3; + reflectivity[b_i].f1.set_size(totReflect.size(0), 2); + loop_ub = totReflect.size(0); + for (int32_T i1{0}; i1 < 2; i1++) { + for (int32_T i2{0}; i2 < loop_ub; i2++) { + reflectivity[b_i].f1[i2 + reflectivity[b_i].f1.size(0) * i1] = + totReflect[i2 + totReflect.size(0) * i1]; + } + } + + shiftedData[b_i].f1.set_size(shiftedDat.size(0), shiftedDat.size(1)); + loop_ub = shiftedDat.size(1); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = shiftedDat.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + shiftedData[b_i].f1[i2 + shiftedData[b_i].f1.size(0) * i1] = + shiftedDat[i2 + shiftedDat.size(0) * i1]; + } + } + + tempLayerSlds[b_i].f1[0] = r1; + tempLayerSlds[b_i].f1[1] = r4; + tempAllLayers[b_i].f1[0] = r2; + tempAllLayers[b_i].f1[1] = r5; + backgroundParams[b_i] = thisBackground; + qzshifts[b_i] = thisQzshift; + scalefactors[b_i] = thisScalefactor; + bulkIns[b_i] = thisBulkIn; + bulkOuts[b_i] = thisBulkOut; + resolutionParams[b_i] = thisResol; + allRoughs[b_i] = problemStruct->params[0]; + } + + allLayers.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + loop_ub = tempSldProfiles[b_i].f1[0].f1.size(1); + domainSldProfiles[b_i].f1.set_size(tempSldProfiles[b_i].f1[0].f1.size + (0), tempSldProfiles[b_i].f1[0].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempSldProfiles[b_i].f1[0].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + domainSldProfiles[b_i].f1[i2 + domainSldProfiles[b_i].f1.size(0) * + i1] = tempSldProfiles[b_i].f1[0].f1[i2 + tempSldProfiles[b_i] + .f1[0].f1.size(0) * i1]; + } + } + + loop_ub = tempSldProfiles[b_i].f1[1].f1.size(1); + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.set_size + (tempSldProfiles[b_i].f1[1].f1.size(0), tempSldProfiles[b_i].f1[1]. + f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempSldProfiles[b_i].f1[1].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1[i2 + + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size(0) * + i1] = tempSldProfiles[b_i].f1[1].f1[i2 + tempSldProfiles[b_i] + .f1[1].f1.size(0) * i1]; + } + } + + loop_ub = tempAllLayers[b_i].f1[0].f1.size(1); + allLayers[b_i].f1.set_size(tempAllLayers[b_i].f1[0].f1.size(0), + tempAllLayers[b_i].f1[0].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempAllLayers[b_i].f1[0].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + allLayers[b_i].f1[i2 + allLayers[b_i].f1.size(0) * i1] = + tempAllLayers[b_i].f1[0].f1[i2 + tempAllLayers[b_i].f1[0]. + f1.size(0) * i1]; + } + } + + loop_ub = tempAllLayers[b_i].f1[1].f1.size(1); + allLayers[b_i + allLayers.size(0)].f1.set_size(tempAllLayers[b_i].f1[1] + .f1.size(0), tempAllLayers[b_i].f1[1].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempAllLayers[b_i].f1[1].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + allLayers[b_i + allLayers.size(0)].f1[i2 + allLayers[b_i + + allLayers.size(0)].f1.size(0) * i1] = tempAllLayers[b_i].f1[1]. + f1[i2 + tempAllLayers[b_i].f1[1].f1.size(0) * i1]; + } + } + + loop_ub = tempLayerSlds[b_i].f1[0].f1.size(1); + layerSlds[b_i].f1.set_size(tempLayerSlds[b_i].f1[0].f1.size(0), + tempLayerSlds[b_i].f1[0].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempLayerSlds[b_i].f1[0].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + layerSlds[b_i].f1[i2 + layerSlds[b_i].f1.size(0) * i1] = + tempLayerSlds[b_i].f1[0].f1[i2 + tempLayerSlds[b_i].f1[0]. + f1.size(0) * i1]; + } + } + + loop_ub = tempLayerSlds[b_i].f1[1].f1.size(1); + layerSlds[b_i + layerSlds.size(0)].f1.set_size(tempLayerSlds[b_i].f1[1] + .f1.size(0), tempLayerSlds[b_i].f1[1].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempLayerSlds[b_i].f1[1].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + layerSlds[b_i + layerSlds.size(0)].f1[i2 + layerSlds[b_i + + layerSlds.size(0)].f1.size(0) * i1] = tempLayerSlds[b_i].f1[1]. + f1[i2 + tempLayerSlds[b_i].f1[1].f1.size(0) * i1]; + } + } + } + } + } + } +} + +// End of code generation (parallelPoints3.cpp) diff --git a/cpp/RAT/parallelPoints3.h b/cpp/RAT/parallelPoints3.h new file mode 100644 index 00000000..dbb8cf9b --- /dev/null +++ b/cpp/RAT/parallelPoints3.h @@ -0,0 +1,49 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parallelPoints3.h +// +// Code generation for function 'parallelPoints3' +// +#ifndef PARALLELPOINTS3_H +#define PARALLELPOINTS3_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace domainsTF + { + namespace standardLayers + { + void parallelPoints(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, ::coder:: + array &outSsubs, ::coder::array + &backgroundParams, ::coder::array + &qzshifts, ::coder::array &scalefactors, :: + coder::array &bulkIns, ::coder::array< + real_T, 1U> &bulkOuts, ::coder::array + &resolutionParams, ::coder::array &chis, :: + coder::array &reflectivity, ::coder:: + array &simulation, ::coder::array< + cell_wrap_8, 1U> &shiftedData, ::coder::array< + cell_wrap_8, 2U> &layerSlds, ::coder::array< + cell_wrap_8, 2U> &domainSldProfiles, ::coder::array< + cell_wrap_8, 2U> &allLayers, ::coder::array + &allRoughs); + } + } +} + +#endif + +// End of code generation (parallelPoints3.h) diff --git a/cpp/RAT/parallelPoints4.cpp b/cpp/RAT/parallelPoints4.cpp new file mode 100644 index 00000000..ef8fce80 --- /dev/null +++ b/cpp/RAT/parallelPoints4.cpp @@ -0,0 +1,334 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parallelPoints4.cpp +// +// Code generation for function 'parallelPoints4' +// + +// Include files +#include "parallelPoints4.h" +#include "RATMain_internal_types.h" +#include "RATMain_rtwutil.h" +#include "RATMain_types.h" +#include "averageReflectivity.h" +#include "backSort.h" +#include "chiSquared.h" +#include "coreLayersCalculation.h" +#include "processCustomFunction2.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include "coder_bounded_array.h" + +// Function Definitions +namespace RAT +{ + namespace domainsTF + { + namespace customLayers + { + void parallelPoints(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, ::coder:: + array &outSsubs, ::coder::array + &backgroundParams, ::coder::array + &qzshifts, ::coder::array &scalefactors, :: + coder::array &bulkIns, ::coder::array< + real_T, 1U> &bulkOuts, ::coder::array + &resolutionParams, ::coder::array &chis, :: + coder::array &reflectivity, ::coder:: + array &simulation, ::coder::array< + cell_wrap_8, 1U> &shiftedData, ::coder::array< + cell_wrap_8, 2U> &layerSlds, ::coder::array< + cell_wrap_8, 2U> &domainSldProfiles, ::coder::array< + cell_wrap_8, 2U> &allLayers, ::coder::array + &allRoughs) + { + ::coder::array r; + ::coder::array tempAllLayers; + ::coder::array tempLayerSlds; + ::coder::array tempSldProfiles; + ::coder::array calcAllLayers; + ::coder::array a__5; + ::coder::array reflect1; + ::coder::array reflect2; + ::coder::array shiftedDat; + ::coder::array simul1; + ::coder::array simul2; + ::coder::array totReflect; + cell_wrap_8 r1; + cell_wrap_8 r2; + cell_wrap_8 r3; + cell_wrap_8 r4; + cell_wrap_8 r5; + cell_wrap_8 r6; + real_T a__4; + real_T a__6; + real_T a__7; + real_T thisBackground; + real_T thisBulkIn; + real_T thisBulkOut; + real_T thisQzshift; + real_T thisResol; + real_T thisScalefactor; + int32_T b_loop_ub; + int32_T i; + int32_T loop_ub; + int32_T nParams; + boolean_T calcSld; + boolean_T useImaginary; + + // Single threaded version of the custom layers, domainsTF reflectivity + // calculation. The function extracts the relevant parameters from the input + // arrays, allocates these on a pre-contrast basis, then calls the 'core' + // calculation (the core layers nonPolarisedTF calc is shared between + // multiple calculation types). + // Extract individual cell arrays + // Splits up the master input list of all arrays into separate arrays + // + // INPUTS: + // * problemCells: cell array where all the project data is grouped together. + // + // OUTPUTS: + // * repeatLayers: controls repeating of the layers stack. + // * allData: Array of all the data arrays. + // * dataLimits: Min max limits in q for the data arrays. + // * simLimits: Limits in Q for the reflectivity simulations. + // * layersDetails: Master array of all available layers. + // * contrastLayers: Which specific combination of arrays are needed for each contrast. + // * customFiles:Filenames and path for any custom files used. + // Extract individual parameters from problemStruct + // Extract individual parameters from problem + nParams = problemStruct->params.size(1); + calcSld = controls->calcSldDuringFit; + useImaginary = problemStruct->useImaginary; + + // Default for compile. + // Pre-Allocation of output arrays... + i = static_cast(problemStruct->numberOfContrasts); + backgroundParams.set_size(i); + + // Resampling parameters + // Process the custom models.... + processCustomFunction(problemStruct->contrastBulkIns, + problemStruct->contrastBulkOuts, + problemStruct->bulkIn, problemStruct->bulkOut, + problemStruct->contrastCustomFiles, + problemStruct->numberOfContrasts, + problemCells->f14, problemStruct->params, + problemStruct->useImaginary, r, allRoughs); + cast(r, calcAllLayers); + + // Parallel over all contrasts + // layersCounter = 1; + outSsubs.set_size(i); + tempSldProfiles.set_size(i); + reflectivity.set_size(i); + simulation.set_size(i); + shiftedData.set_size(i); + tempLayerSlds.set_size(i); + tempAllLayers.set_size(i); + chis.set_size(i); + qzshifts.set_size(i); + scalefactors.set_size(i); + bulkIns.set_size(i); + bulkOuts.set_size(i); + resolutionParams.set_size(i); + layerSlds.set_size(i, 2); + domainSldProfiles.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T b_dv[2]; + real_T b_dv1[2]; + real_T dv2[2]; + + // Get the domain ratio for this contrast + // Extract the relevant parameter values for this contrast + // from the input arrays. + // First need to decide which values of the backgrounds, scalefactors + // data shifts and bulk contrasts are associated with this contrast + backSort(problemStruct->contrastBackgrounds[b_i], + problemStruct->contrastQzshifts[b_i], + problemStruct->contrastScalefactors[b_i], + problemStruct->contrastBulkIns[b_i], + problemStruct->contrastBulkOuts[b_i], + problemStruct->contrastResolutions[b_i], + problemStruct->backgroundParams, problemStruct->qzshifts, + problemStruct->scalefactors, problemStruct->bulkIn, + problemStruct->bulkOut, problemStruct->resolutionParams, + &thisBackground, &thisQzshift, &thisScalefactor, &thisBulkIn, + &thisBulkOut, &thisResol); + + // Get the custom layers output for this contrast + // We have two for each contrast - one for each domain + // For the other parameters, we extract the correct ones from the input + // arrays + // Now call the core layers reflectivity calculation + // In this case we are single cored, so we do not parallelise over + // points + // Call the reflectivity calculation for each domain + // Domain 1 + b_dv[0] = problemCells->f3[b_i].f1[0]; + b_dv[1] = problemCells->f3[b_i].f1[1]; + b_dv1[0] = problemCells->f4[b_i].f1[0]; + b_dv1[1] = problemCells->f4[b_i].f1[1]; + dv2[0] = problemCells->f1[b_i].f1[0]; + dv2[1] = problemCells->f1[b_i].f1[1]; + nonPolarisedTF::b_coreLayersCalculation(calcAllLayers[b_i].f1, + allRoughs[b_i], problemStruct->geometry.data, + problemStruct->geometry.size, thisBulkIn, thisBulkOut, + problemStruct->resample[b_i], calcSld, thisScalefactor, thisQzshift, + problemStruct->dataPresent[b_i], problemCells->f2[b_i].f1, b_dv, + b_dv1, dv2, thisBackground, thisResol, + problemStruct->contrastBackgroundsType[b_i], static_cast + (nParams), controls->resamPars, useImaginary, r1.f1, reflect1, + simul1, shiftedDat, r2.f1, r3.f1, &a__4, &outSsubs[b_i]); + + // Domain 2 + b_dv[0] = problemCells->f3[b_i].f1[0]; + b_dv[1] = problemCells->f3[b_i].f1[1]; + b_dv1[0] = problemCells->f4[b_i].f1[0]; + b_dv1[1] = problemCells->f4[b_i].f1[1]; + dv2[0] = problemCells->f1[b_i].f1[0]; + dv2[1] = problemCells->f1[b_i].f1[1]; + nonPolarisedTF::b_coreLayersCalculation(calcAllLayers[b_i + + calcAllLayers.size(0)].f1, allRoughs[b_i], + problemStruct->geometry.data, problemStruct->geometry.size, + thisBulkIn, thisBulkOut, problemStruct->resample[b_i], calcSld, + thisScalefactor, thisQzshift, problemStruct->dataPresent[b_i], + problemCells->f2[b_i].f1, b_dv, b_dv1, dv2, thisBackground, + thisResol, problemStruct->contrastBackgroundsType[b_i], + static_cast(nParams), controls->resamPars, useImaginary, + r4.f1, reflect2, simul2, a__5, r5.f1, r6.f1, &a__6, &a__7); + + // Calculate the average reflectivities.... + averageReflectivity(reflect1, reflect2, simul1, simul2, + problemStruct->domainRatio[static_cast + (problemStruct->contrastDomainRatios[b_i]) - 1], + totReflect, simulation[b_i].f1); + + // Get an overall chi-squared for the new averaged curve.. + chis[b_i] = chiSquared(shiftedDat, totReflect, static_cast + (problemStruct->params.size(1))); + + // Store returned values for this contrast in the output arrays. + // As well as the calculated profiles, we also store a record of + // the other values (background, scalefactors etc) for each contrast + // for future use. + // domainSldProfiles{i,1} = sldProfile1; + // domainSldProfiles{i,2} = sldProfile2; + tempSldProfiles[b_i].f1[0] = r1; + tempSldProfiles[b_i].f1[1] = r4; + reflectivity[b_i].f1.set_size(totReflect.size(0), 2); + loop_ub = totReflect.size(0); + for (int32_T i1{0}; i1 < 2; i1++) { + for (int32_T i2{0}; i2 < loop_ub; i2++) { + reflectivity[b_i].f1[i2 + reflectivity[b_i].f1.size(0) * i1] = + totReflect[i2 + totReflect.size(0) * i1]; + } + } + + shiftedData[b_i].f1.set_size(shiftedDat.size(0), shiftedDat.size(1)); + loop_ub = shiftedDat.size(1); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = shiftedDat.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + shiftedData[b_i].f1[i2 + shiftedData[b_i].f1.size(0) * i1] = + shiftedDat[i2 + shiftedDat.size(0) * i1]; + } + } + + tempLayerSlds[b_i].f1[0] = r2; + tempLayerSlds[b_i].f1[1] = r5; + tempAllLayers[b_i].f1[0] = r3; + tempAllLayers[b_i].f1[1] = r6; + backgroundParams[b_i] = thisBackground; + qzshifts[b_i] = thisQzshift; + scalefactors[b_i] = thisScalefactor; + bulkIns[b_i] = thisBulkIn; + bulkOuts[b_i] = thisBulkOut; + resolutionParams[b_i] = thisResol; + } + + allLayers.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + loop_ub = tempSldProfiles[b_i].f1[0].f1.size(1); + domainSldProfiles[b_i].f1.set_size(tempSldProfiles[b_i].f1[0].f1.size + (0), tempSldProfiles[b_i].f1[0].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempSldProfiles[b_i].f1[0].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + domainSldProfiles[b_i].f1[i2 + domainSldProfiles[b_i].f1.size(0) * + i1] = tempSldProfiles[b_i].f1[0].f1[i2 + tempSldProfiles[b_i] + .f1[0].f1.size(0) * i1]; + } + } + + loop_ub = tempSldProfiles[b_i].f1[1].f1.size(1); + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.set_size + (tempSldProfiles[b_i].f1[1].f1.size(0), tempSldProfiles[b_i].f1[1]. + f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempSldProfiles[b_i].f1[1].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1[i2 + + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size(0) * + i1] = tempSldProfiles[b_i].f1[1].f1[i2 + tempSldProfiles[b_i] + .f1[1].f1.size(0) * i1]; + } + } + + loop_ub = tempAllLayers[b_i].f1[0].f1.size(1); + allLayers[b_i].f1.set_size(tempAllLayers[b_i].f1[0].f1.size(0), + tempAllLayers[b_i].f1[0].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempAllLayers[b_i].f1[0].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + allLayers[b_i].f1[i2 + allLayers[b_i].f1.size(0) * i1] = + tempAllLayers[b_i].f1[0].f1[i2 + tempAllLayers[b_i].f1[0]. + f1.size(0) * i1]; + } + } + + loop_ub = tempAllLayers[b_i].f1[1].f1.size(1); + allLayers[b_i + allLayers.size(0)].f1.set_size(tempAllLayers[b_i].f1[1] + .f1.size(0), tempAllLayers[b_i].f1[1].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempAllLayers[b_i].f1[1].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + allLayers[b_i + allLayers.size(0)].f1[i2 + allLayers[b_i + + allLayers.size(0)].f1.size(0) * i1] = tempAllLayers[b_i].f1[1]. + f1[i2 + tempAllLayers[b_i].f1[1].f1.size(0) * i1]; + } + } + + loop_ub = tempLayerSlds[b_i].f1[0].f1.size(1); + layerSlds[b_i].f1.set_size(tempLayerSlds[b_i].f1[0].f1.size(0), + tempLayerSlds[b_i].f1[0].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempLayerSlds[b_i].f1[0].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + layerSlds[b_i].f1[i2 + layerSlds[b_i].f1.size(0) * i1] = + tempLayerSlds[b_i].f1[0].f1[i2 + tempLayerSlds[b_i].f1[0]. + f1.size(0) * i1]; + } + } + + loop_ub = tempLayerSlds[b_i].f1[1].f1.size(1); + layerSlds[b_i + layerSlds.size(0)].f1.set_size(tempLayerSlds[b_i].f1[1] + .f1.size(0), tempLayerSlds[b_i].f1[1].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempLayerSlds[b_i].f1[1].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + layerSlds[b_i + layerSlds.size(0)].f1[i2 + layerSlds[b_i + + layerSlds.size(0)].f1.size(0) * i1] = tempLayerSlds[b_i].f1[1]. + f1[i2 + tempLayerSlds[b_i].f1[1].f1.size(0) * i1]; + } + } + } + } + } + } +} + +// End of code generation (parallelPoints4.cpp) diff --git a/cpp/RAT/parallelPoints4.h b/cpp/RAT/parallelPoints4.h new file mode 100644 index 00000000..f16b3105 --- /dev/null +++ b/cpp/RAT/parallelPoints4.h @@ -0,0 +1,49 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parallelPoints4.h +// +// Code generation for function 'parallelPoints4' +// +#ifndef PARALLELPOINTS4_H +#define PARALLELPOINTS4_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace domainsTF + { + namespace customLayers + { + void parallelPoints(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, ::coder:: + array &outSsubs, ::coder::array + &backgroundParams, ::coder::array + &qzshifts, ::coder::array &scalefactors, :: + coder::array &bulkIns, ::coder::array< + real_T, 1U> &bulkOuts, ::coder::array + &resolutionParams, ::coder::array &chis, :: + coder::array &reflectivity, ::coder:: + array &simulation, ::coder::array< + cell_wrap_8, 1U> &shiftedData, ::coder::array< + cell_wrap_8, 2U> &layerSlds, ::coder::array< + cell_wrap_8, 2U> &domainSldProfiles, ::coder::array< + cell_wrap_8, 2U> &allLayers, ::coder::array + &allRoughs); + } + } +} + +#endif + +// End of code generation (parallelPoints4.h) diff --git a/cpp/RAT/parallelPoints5.cpp b/cpp/RAT/parallelPoints5.cpp new file mode 100644 index 00000000..4bc34bbd --- /dev/null +++ b/cpp/RAT/parallelPoints5.cpp @@ -0,0 +1,410 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parallelPoints5.cpp +// +// Code generation for function 'parallelPoints5' +// + +// Include files +#include "parallelPoints5.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "applyBackgroundCorrection.h" +#include "averageReflectivity.h" +#include "backSort.h" +#include "callReflectivity.h" +#include "chiSquared.h" +#include "processCustomFunction3.h" +#include "resampleLayers.h" +#include "resampleLayersReIm.h" +#include "rt_nonfinite.h" +#include "shiftData.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace domainsTF + { + namespace customXY + { + void parallelPoints(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, ::coder:: + array &outSsubs, ::coder::array + &backgroundParams, ::coder::array + &qzshifts, ::coder::array &scalefactors, :: + coder::array &bulkIns, ::coder::array< + real_T, 1U> &bulkOuts, ::coder::array + &resolutionParams, ::coder::array &chis, :: + coder::array &reflectivity, ::coder:: + array &simulation, ::coder::array< + cell_wrap_8, 1U> &shiftedData, ::coder::array< + cell_wrap_8, 2U> &layerSlds, ::coder::array< + cell_wrap_8, 2U> &domainSldProfiles, ::coder::array< + cell_wrap_8, 2U> &allLayers, ::coder::array + &allRoughs) + { + ::coder::array tempAllLayers; + ::coder::array tempLayerSlds; + ::coder::array tempSldProfiles; + ::coder::array b_domainSldProfiles; + ::coder::array b_problemCells; + ::coder::array c_domainSldProfiles; + ::coder::array r4; + ::coder::array reflect1; + ::coder::array reflect2; + ::coder::array shiftedDat; + ::coder::array simul1; + ::coder::array simul2; + ::coder::array totReflect; + cell_wrap_8 r; + cell_wrap_8 r1; + cell_wrap_8 r2; + cell_wrap_8 r3; + int32_T b_loop_ub; + int32_T i; + int32_T loop_ub; + boolean_T useImaginary; + + // Extract individual cell arrays + // Splits up the master input list of all arrays into separate arrays + // + // INPUTS: + // * problemCells: cell array where all the project data is grouped together. + // + // OUTPUTS: + // * repeatLayers: controls repeating of the layers stack. + // * allData: Array of all the data arrays. + // * dataLimits: Min max limits in q for the data arrays. + // * simLimits: Limits in Q for the reflectivity simulations. + // * layersDetails: Master array of all available layers. + // * contrastLayers: Which specific combination of arrays are needed for each contrast. + // * customFiles:Filenames and path for any custom files used. + // % Layers details N/A + // Extract individual parameters from problemStruct + // Extract individual parameters from problem + // Pre-Allocation... + i = static_cast(problemStruct->numberOfContrasts); + backgroundParams.set_size(i); + + // Resampling parameters + useImaginary = problemStruct->useImaginary; + + // Default for compile. + processCustomFunction(problemStruct->contrastBulkIns, + problemStruct->contrastBulkOuts, + problemStruct->bulkIn, problemStruct->bulkOut, + problemStruct->contrastCustomFiles, + problemStruct->numberOfContrasts, + problemCells->f14, problemStruct->params, + domainSldProfiles, allRoughs); + outSsubs.set_size(i); + qzshifts.set_size(i); + scalefactors.set_size(i); + bulkIns.set_size(i); + bulkOuts.set_size(i); + resolutionParams.set_size(i); + tempLayerSlds.set_size(i); + tempAllLayers.set_size(i); + tempSldProfiles.set_size(i); + shiftedData.set_size(i); + reflectivity.set_size(i); + simulation.set_size(i); + chis.set_size(i); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T b_dv[2]; + real_T b_dv1[2]; + outSsubs[b_i] = allRoughs[b_i]; + backSort(problemStruct->contrastBackgrounds[b_i], + problemStruct->contrastQzshifts[b_i], + problemStruct->contrastScalefactors[b_i], + problemStruct->contrastBulkIns[b_i], + problemStruct->contrastBulkOuts[b_i], + problemStruct->contrastResolutions[b_i], + problemStruct->backgroundParams, problemStruct->qzshifts, + problemStruct->scalefactors, problemStruct->bulkIn, + problemStruct->bulkOut, problemStruct->resolutionParams, + &backgroundParams[b_i], &qzshifts[b_i], &scalefactors[b_i], + &bulkIns[b_i], &bulkOuts[b_i], &resolutionParams[b_i]); + + // Get the domain ratio for this contrast + // Resample the sld profiles + if (!useImaginary) { + resampleLayers(domainSldProfiles[b_i].f1, controls->resamPars, r.f1); + r1.f1.set_size(r.f1.size(0), 3); + for (int32_T i1{0}; i1 < 3; i1++) { + loop_ub = r.f1.size(0); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + r1.f1[i2 + r1.f1.size(0) * i1] = r.f1[i2 + r.f1.size(0) * i1]; + } + } + + resampleLayers(domainSldProfiles[b_i + domainSldProfiles.size(0)].f1, + controls->resamPars, r.f1); + } else { + loop_ub = domainSldProfiles[b_i].f1.size(0); + b_domainSldProfiles.set_size(domainSldProfiles[b_i].f1.size(0), 2); + for (int32_T i1{0}; i1 < 2; i1++) { + for (int32_T i2{0}; i2 < loop_ub; i2++) { + b_domainSldProfiles[i2 + b_domainSldProfiles.size(0) * i1] = + domainSldProfiles[b_i].f1[i2 + domainSldProfiles[b_i].f1.size + (0) * i1]; + } + } + + loop_ub = domainSldProfiles[b_i].f1.size(0); + c_domainSldProfiles.set_size(domainSldProfiles[b_i].f1.size(0), 2); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + c_domainSldProfiles[i1] = domainSldProfiles[b_i].f1[i1]; + c_domainSldProfiles[i1 + c_domainSldProfiles.size(0)] = + domainSldProfiles[b_i].f1[i1 + domainSldProfiles[b_i].f1.size(0) + * 2]; + } + + b_resampleLayersReIm(b_domainSldProfiles, c_domainSldProfiles, + controls->resamPars, r.f1); + r1.f1.set_size(r.f1.size(0), 4); + for (int32_T i1{0}; i1 < 4; i1++) { + loop_ub = r.f1.size(0); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + r1.f1[i2 + r1.f1.size(0) * i1] = r.f1[i2 + r.f1.size(0) * i1]; + } + } + + loop_ub = domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size + (0); + b_domainSldProfiles.set_size(domainSldProfiles[b_i + + domainSldProfiles.size(0)].f1.size(0), 2); + for (int32_T i1{0}; i1 < 2; i1++) { + for (int32_T i2{0}; i2 < loop_ub; i2++) { + b_domainSldProfiles[i2 + b_domainSldProfiles.size(0) * i1] = + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1[i2 + + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size(0) * + i1]; + } + } + + loop_ub = domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size + (0); + c_domainSldProfiles.set_size(domainSldProfiles[b_i + + domainSldProfiles.size(0)].f1.size(0), 2); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + c_domainSldProfiles[i1] = domainSldProfiles[b_i + + domainSldProfiles.size(0)].f1[i1]; + c_domainSldProfiles[i1 + c_domainSldProfiles.size(0)] = + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1[i1 + + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size(0) * + 2]; + } + + b_resampleLayersReIm(b_domainSldProfiles, c_domainSldProfiles, + controls->resamPars, r.f1); + } + + tempLayerSlds[b_i].f1[0] = r1; + tempLayerSlds[b_i].f1[1] = r; + tempAllLayers[b_i].f1[0] = r1; + tempAllLayers[b_i].f1[1] = r; + r2.f1.set_size(domainSldProfiles[b_i].f1.size(0), + domainSldProfiles[b_i].f1.size(1)); + loop_ub = domainSldProfiles[b_i].f1.size(1); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = domainSldProfiles[b_i].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + r2.f1[i2 + r2.f1.size(0) * i1] = domainSldProfiles[b_i].f1[i2 + + domainSldProfiles[b_i].f1.size(0) * i1]; + } + } + + r3.f1.set_size(domainSldProfiles[b_i + domainSldProfiles.size(0)]. + f1.size(0), domainSldProfiles[b_i + + domainSldProfiles.size(0)].f1.size(1)); + loop_ub = domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size(1); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = domainSldProfiles[b_i + domainSldProfiles.size(0)]. + f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + r3.f1[i2 + r3.f1.size(0) * i1] = domainSldProfiles[b_i + + domainSldProfiles.size(0)].f1[i2 + domainSldProfiles[b_i + + domainSldProfiles.size(0)].f1.size(0) * i1]; + } + } + + tempSldProfiles[b_i].f1[0] = r2; + tempSldProfiles[b_i].f1[1] = r3; + b_problemCells.set_size(problemCells->f2[problemCells->f2.size(0) * + b_i].f1.size(0), problemCells->f2[problemCells->f2.size(0) * b_i]. + f1.size(1)); + loop_ub = problemCells->f2[b_i].f1.size(1) - 1; + for (int32_T i1{0}; i1 <= loop_ub; i1++) { + b_loop_ub = problemCells->f2[b_i].f1.size(0) - 1; + for (int32_T i2{0}; i2 <= b_loop_ub; i2++) { + b_problemCells[i2 + b_problemCells.size(0) * i1] = + problemCells->f2[b_i].f1[i2 + problemCells->f2[b_i].f1.size(0) * + i1]; + } + } + + b_dv[0] = problemCells->f3[b_i].f1[0]; + b_dv[1] = problemCells->f3[b_i].f1[1]; + b_dv1[0] = problemCells->f4[b_i].f1[0]; + b_dv1[1] = problemCells->f4[b_i].f1[1]; + shiftData(scalefactors[b_i], qzshifts[b_i], problemStruct-> + dataPresent[b_i], b_problemCells, b_dv, b_dv1, shiftedDat); + shiftedData[b_i].f1.set_size(shiftedDat.size(0), shiftedDat.size(1)); + loop_ub = shiftedDat.size(1); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = shiftedDat.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + shiftedData[b_i].f1[i2 + shiftedData[b_i].f1.size(0) * i1] = + shiftedDat[i2 + shiftedDat.size(0) * i1]; + } + } + + r4.set_size(r1.f1.size(0), r1.f1.size(1)); + loop_ub = r1.f1.size(1) - 1; + for (int32_T i1{0}; i1 <= loop_ub; i1++) { + b_loop_ub = r1.f1.size(0) - 1; + for (int32_T i2{0}; i2 <= b_loop_ub; i2++) { + r4[i2 + r4.size(0) * i1] = r1.f1[i2 + r1.f1.size(0) * i1]; + } + } + + b_dv[0] = problemCells->f4[b_i].f1[0]; + b_dv[1] = problemCells->f4[b_i].f1[1]; + b_dv1[0] = problemCells->f1[b_i].f1[0]; + b_dv1[1] = problemCells->f1[b_i].f1[1]; + b_callReflectivity(bulkIns[b_i], bulkOuts[b_i], b_dv, b_dv1, + shiftedDat, r4, allRoughs[b_i], + resolutionParams[b_i], useImaginary, reflect1, + simul1); + r4.set_size(r.f1.size(0), r.f1.size(1)); + loop_ub = r.f1.size(1) - 1; + for (int32_T i1{0}; i1 <= loop_ub; i1++) { + b_loop_ub = r.f1.size(0) - 1; + for (int32_T i2{0}; i2 <= b_loop_ub; i2++) { + r4[i2 + r4.size(0) * i1] = r.f1[i2 + r.f1.size(0) * i1]; + } + } + + b_dv[0] = problemCells->f4[b_i].f1[0]; + b_dv[1] = problemCells->f4[b_i].f1[1]; + b_dv1[0] = problemCells->f1[b_i].f1[0]; + b_dv1[1] = problemCells->f1[b_i].f1[1]; + b_callReflectivity(bulkIns[b_i], bulkOuts[b_i], b_dv, b_dv1, + shiftedDat, r4, allRoughs[b_i], + resolutionParams[b_i], useImaginary, reflect2, + simul2); + applyBackgroundCorrection(reflect1, simul1, shiftedDat, + backgroundParams[b_i], problemStruct->contrastBackgroundsType[b_i]); + applyBackgroundCorrection(reflect2, simul2, shiftedDat, + backgroundParams[b_i], problemStruct->contrastBackgroundsType[b_i]); + + // Calculate the average reflectivities.... + averageReflectivity(reflect1, reflect2, simul1, simul2, + problemStruct->domainRatio[static_cast + (problemStruct->contrastDomainRatios[b_i]) - 1], + totReflect, simulation[b_i].f1); + loop_ub = totReflect.size(0); + reflectivity[b_i].f1.set_size(totReflect.size(0), 2); + for (int32_T i1{0}; i1 < 2; i1++) { + for (int32_T i2{0}; i2 < loop_ub; i2++) { + reflectivity[b_i].f1[i2 + reflectivity[b_i].f1.size(0) * i1] = + totReflect[i2 + totReflect.size(0) * i1]; + } + } + + if (problemStruct->dataPresent[b_i] != 0.0) { + chis[b_i] = chiSquared(shiftedDat, totReflect, static_cast + (problemStruct->params.size(1))); + } else { + chis[b_i] = 0.0; + } + } + + allLayers.set_size(i, 2); + layerSlds.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + loop_ub = tempSldProfiles[b_i].f1[0].f1.size(1); + domainSldProfiles[b_i].f1.set_size(tempSldProfiles[b_i].f1[0].f1.size + (0), tempSldProfiles[b_i].f1[0].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempSldProfiles[b_i].f1[0].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + domainSldProfiles[b_i].f1[i2 + domainSldProfiles[b_i].f1.size(0) * + i1] = tempSldProfiles[b_i].f1[0].f1[i2 + tempSldProfiles[b_i] + .f1[0].f1.size(0) * i1]; + } + } + + loop_ub = tempSldProfiles[b_i].f1[1].f1.size(1); + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.set_size + (tempSldProfiles[b_i].f1[1].f1.size(0), tempSldProfiles[b_i].f1[1]. + f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempSldProfiles[b_i].f1[1].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1[i2 + + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size(0) * + i1] = tempSldProfiles[b_i].f1[1].f1[i2 + tempSldProfiles[b_i] + .f1[1].f1.size(0) * i1]; + } + } + + loop_ub = tempAllLayers[b_i].f1[0].f1.size(1); + allLayers[b_i].f1.set_size(tempAllLayers[b_i].f1[0].f1.size(0), + tempAllLayers[b_i].f1[0].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempAllLayers[b_i].f1[0].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + allLayers[b_i].f1[i2 + allLayers[b_i].f1.size(0) * i1] = + tempAllLayers[b_i].f1[0].f1[i2 + tempAllLayers[b_i].f1[0]. + f1.size(0) * i1]; + } + } + + loop_ub = tempAllLayers[b_i].f1[1].f1.size(1); + allLayers[b_i + allLayers.size(0)].f1.set_size(tempAllLayers[b_i].f1[1] + .f1.size(0), tempAllLayers[b_i].f1[1].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempAllLayers[b_i].f1[1].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + allLayers[b_i + allLayers.size(0)].f1[i2 + allLayers[b_i + + allLayers.size(0)].f1.size(0) * i1] = tempAllLayers[b_i].f1[1]. + f1[i2 + tempAllLayers[b_i].f1[1].f1.size(0) * i1]; + } + } + + loop_ub = tempLayerSlds[b_i].f1[0].f1.size(1); + layerSlds[b_i].f1.set_size(tempLayerSlds[b_i].f1[0].f1.size(0), + tempLayerSlds[b_i].f1[0].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempLayerSlds[b_i].f1[0].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + layerSlds[b_i].f1[i2 + layerSlds[b_i].f1.size(0) * i1] = + tempLayerSlds[b_i].f1[0].f1[i2 + tempLayerSlds[b_i].f1[0]. + f1.size(0) * i1]; + } + } + + loop_ub = tempLayerSlds[b_i].f1[1].f1.size(1); + layerSlds[b_i + layerSlds.size(0)].f1.set_size(tempLayerSlds[b_i].f1[1] + .f1.size(0), tempLayerSlds[b_i].f1[1].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempLayerSlds[b_i].f1[1].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + layerSlds[b_i + layerSlds.size(0)].f1[i2 + layerSlds[b_i + + layerSlds.size(0)].f1.size(0) * i1] = tempLayerSlds[b_i].f1[1]. + f1[i2 + tempLayerSlds[b_i].f1[1].f1.size(0) * i1]; + } + } + } + } + } + } +} + +// End of code generation (parallelPoints5.cpp) diff --git a/cpp/RAT/parallelPoints5.h b/cpp/RAT/parallelPoints5.h new file mode 100644 index 00000000..740599d7 --- /dev/null +++ b/cpp/RAT/parallelPoints5.h @@ -0,0 +1,49 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parallelPoints5.h +// +// Code generation for function 'parallelPoints5' +// +#ifndef PARALLELPOINTS5_H +#define PARALLELPOINTS5_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace domainsTF + { + namespace customXY + { + void parallelPoints(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, ::coder:: + array &outSsubs, ::coder::array + &backgroundParams, ::coder::array + &qzshifts, ::coder::array &scalefactors, :: + coder::array &bulkIns, ::coder::array< + real_T, 1U> &bulkOuts, ::coder::array + &resolutionParams, ::coder::array &chis, :: + coder::array &reflectivity, ::coder:: + array &simulation, ::coder::array< + cell_wrap_8, 1U> &shiftedData, ::coder::array< + cell_wrap_8, 2U> &layerSlds, ::coder::array< + cell_wrap_8, 2U> &domainSldProfiles, ::coder::array< + cell_wrap_8, 2U> &allLayers, ::coder::array + &allRoughs); + } + } +} + +#endif + +// End of code generation (parallelPoints5.h) diff --git a/cpp/RAT/parseResultToStruct.cpp b/cpp/RAT/parseResultToStruct.cpp new file mode 100644 index 00000000..7f92d87f --- /dev/null +++ b/cpp/RAT/parseResultToStruct.cpp @@ -0,0 +1,110 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parseResultToStruct.cpp +// +// Code generation for function 'parseResultToStruct' +// + +// Include files +#include "parseResultToStruct.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void parseResultToStruct(const d_struct_T *contrastParams, const cell_wrap_9 + resultCells[6], ::coder::array &result_reflectivity, :: + coder::array &result_simulation, ::coder::array &result_shiftedData, ::coder::array &result_layerSlds, :: + coder::array &result_sldProfiles, ::coder::array< + cell_wrap_8, 2U> &result_allLayers, real_T *result_calculationResults_sumChi, + d_struct_T *result_contrastParams) + { + int32_T b_loop_ub; + int32_T loop_ub; + result_reflectivity.set_size(resultCells[0].f1.size(0), resultCells[0]. + f1.size(1)); + loop_ub = resultCells[0].f1.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = resultCells[0].f1.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + result_reflectivity[i1 + result_reflectivity.size(0) * i] = resultCells + [0].f1[i1 + resultCells[0].f1.size(0) * i]; + } + } + + // Reflectivity art points + result_simulation.set_size(resultCells[1].f1.size(0), resultCells[1].f1.size + (1)); + loop_ub = resultCells[1].f1.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = resultCells[1].f1.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + result_simulation[i1 + result_simulation.size(0) * i] = resultCells[1]. + f1[i1 + resultCells[1].f1.size(0) * i]; + } + } + + // Reflectivity between sim limits + result_shiftedData.set_size(resultCells[2].f1.size(0), resultCells[2]. + f1.size(1)); + loop_ub = resultCells[2].f1.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = resultCells[2].f1.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + result_shiftedData[i1 + result_shiftedData.size(0) * i] = resultCells[2] + .f1[i1 + resultCells[2].f1.size(0) * i]; + } + } + + // Data corrected for sfs + result_layerSlds.set_size(resultCells[3].f1.size(0), resultCells[3].f1.size + (1)); + loop_ub = resultCells[3].f1.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = resultCells[3].f1.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + result_layerSlds[i1 + result_layerSlds.size(0) * i] = resultCells[3] + .f1[i1 + resultCells[3].f1.size(0) * i]; + } + } + + // Layers if defined (i.e. not customXY) + result_sldProfiles.set_size(resultCells[4].f1.size(0), resultCells[4]. + f1.size(1)); + loop_ub = resultCells[4].f1.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = resultCells[4].f1.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + result_sldProfiles[i1 + result_sldProfiles.size(0) * i] = resultCells[4] + .f1[i1 + resultCells[4].f1.size(0) * i]; + } + } + + // Calculated SLD profiles + result_allLayers.set_size(resultCells[5].f1.size(0), resultCells[5].f1.size + (1)); + loop_ub = resultCells[5].f1.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = resultCells[5].f1.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + result_allLayers[i1 + result_allLayers.size(0) * i] = resultCells[5] + .f1[i1 + resultCells[5].f1.size(0) * i]; + } + } + + // Resampled layers + // For compile, we can't remove a field, so just clear it for now... + // contrastParams = rmfield(contrastParams,'calculations'); + *result_contrastParams = *contrastParams; + *result_calculationResults_sumChi = contrastParams->calculations.sumChi; + } +} + +// End of code generation (parseResultToStruct.cpp) diff --git a/cpp/RAT/parseResultToStruct.h b/cpp/RAT/parseResultToStruct.h new file mode 100644 index 00000000..f12dd732 --- /dev/null +++ b/cpp/RAT/parseResultToStruct.h @@ -0,0 +1,40 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// parseResultToStruct.h +// +// Code generation for function 'parseResultToStruct' +// +#ifndef PARSERESULTTOSTRUCT_H +#define PARSERESULTTOSTRUCT_H + +// Include files +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct d_struct_T; +} + +// Function Declarations +namespace RAT +{ + void parseResultToStruct(const d_struct_T *contrastParams, const cell_wrap_9 + resultCells[6], ::coder::array &result_reflectivity, :: + coder::array &result_simulation, ::coder::array &result_shiftedData, ::coder::array &result_layerSlds, :: + coder::array &result_sldProfiles, ::coder::array< + cell_wrap_8, 2U> &result_allLayers, real_T *result_calculationResults_sumChi, + d_struct_T *result_contrastParams); +} + +#endif + +// End of code generation (parseResultToStruct.h) diff --git a/cpp/RAT/pow2.cpp b/cpp/RAT/pow2.cpp new file mode 100644 index 00000000..703bf929 --- /dev/null +++ b/cpp/RAT/pow2.cpp @@ -0,0 +1,36 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// pow2.cpp +// +// Code generation for function 'pow2' +// + +// Include files +#include "pow2.h" +#include "RATMain_rtwutil.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + void pow2(const ::coder::array &a, ::coder::array &y) + { + y.set_size(a.size(0)); + if (a.size(0) != 0) { + int32_T i; + i = a.size(0); + for (int32_T k{0}; k < i; k++) { + y[k] = rt_powd_snf(2.0, a[k]); + } + } + } + } +} + +// End of code generation (pow2.cpp) diff --git a/cpp/RAT/pow2.h b/cpp/RAT/pow2.h new file mode 100644 index 00000000..0b764461 --- /dev/null +++ b/cpp/RAT/pow2.h @@ -0,0 +1,30 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// pow2.h +// +// Code generation for function 'pow2' +// +#ifndef POW2_H +#define POW2_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void pow2(const ::coder::array &a, ::coder::array &y); + } +} + +#endif + +// End of code generation (pow2.h) diff --git a/cpp/RAT/prctile.cpp b/cpp/RAT/prctile.cpp new file mode 100644 index 00000000..d7471254 --- /dev/null +++ b/cpp/RAT/prctile.cpp @@ -0,0 +1,371 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// prctile.cpp +// +// Code generation for function 'prctile' +// + +// Include files +#include "prctile.h" +#include "rt_nonfinite.h" +#include "sortIdx.h" +#include "coder_array.h" +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + static void b_percentile_vector(const ::coder::array &x, real_T + pct[2]); + static void percentile_vector(const ::coder::array &x, real_T + pct[2]); + } +} + +// Function Definitions +namespace RAT +{ + namespace coder + { + static void b_percentile_vector(const ::coder::array &x, real_T + pct[2]) + { + ::coder::array idx; + if (x.size(0) == 0) { + pct[0] = rtNaN; + pct[1] = rtNaN; + } else { + int32_T nj; + internal::sortIdx(x, idx); + nj = x.size(0); + while ((nj > 0) && std::isnan(x[idx[nj - 1] - 1])) { + nj--; + } + + if (nj < 1) { + pct[0] = rtNaN; + pct[1] = rtNaN; + } else if (nj == 1) { + real_T r; + r = x[idx[0] - 1]; + pct[0] = r; + pct[1] = r; + } else { + real_T r; + int32_T i; + r = 0.175 * static_cast(nj); + i = static_cast(std::round(r)); + if (i < 1) { + pct[0] = x[idx[0] - 1]; + } else if (i >= nj) { + pct[0] = x[idx[nj - 1] - 1]; + } else { + r -= static_cast(i); + pct[0] = (0.5 - r) * x[idx[i - 1] - 1] + (r + 0.5) * x[idx[i] - 1]; + } + + r = 0.825 * static_cast(nj); + i = static_cast(std::round(r)); + if (i >= nj) { + pct[1] = x[idx[nj - 1] - 1]; + } else { + r -= static_cast(i); + pct[1] = (0.5 - r) * x[idx[i - 1] - 1] + (r + 0.5) * x[idx[i] - 1]; + } + } + } + } + + static void percentile_vector(const ::coder::array &x, real_T + pct[2]) + { + ::coder::array idx; + if (x.size(0) == 0) { + pct[0] = rtNaN; + pct[1] = rtNaN; + } else { + int32_T nj; + internal::sortIdx(x, idx); + nj = x.size(0); + while ((nj > 0) && std::isnan(x[idx[nj - 1] - 1])) { + nj--; + } + + if (nj < 1) { + pct[0] = rtNaN; + pct[1] = rtNaN; + } else if (nj == 1) { + real_T r; + r = x[idx[0] - 1]; + pct[0] = r; + pct[1] = r; + } else { + real_T r; + int32_T i; + r = 0.025 * static_cast(nj); + i = static_cast(std::round(r)); + if (i < 1) { + pct[0] = x[idx[0] - 1]; + } else if (i >= nj) { + pct[0] = x[idx[nj - 1] - 1]; + } else { + r -= static_cast(i); + pct[0] = (0.5 - r) * x[idx[i - 1] - 1] + (r + 0.5) * x[idx[i] - 1]; + } + + r = 0.975 * static_cast(nj); + i = static_cast(std::round(r)); + if (i >= nj) { + pct[1] = x[idx[nj - 1] - 1]; + } else { + r -= static_cast(i); + pct[1] = (0.5 - r) * x[idx[i - 1] - 1] + (r + 0.5) * x[idx[i] - 1]; + } + } + } + } + + void b_prctile(const ::coder::array &x, ::coder::array &y) + { + ::coder::array wk; + y.set_size(2, x.size(1)); + if ((x.size(0) == 0) || (x.size(1) == 0)) { + int32_T vlen; + vlen = x.size(1); + y.set_size(2, x.size(1)); + for (int32_T k{0}; k < vlen; k++) { + y[2 * k] = rtNaN; + y[2 * k + 1] = rtNaN; + } + } else { + int32_T ix; + int32_T npages; + int32_T vlen; + vlen = x.size(0); + wk.set_size(x.size(0)); + npages = x.size(1); + ix = -1; + for (int32_T xi{0}; xi < npages; xi++) { + real_T pctv[2]; + int32_T k; + wk[0] = x[ix + 1]; + for (k = 2; k <= vlen; k++) { + wk[k - 1] = x[ix + k]; + } + + if (vlen < 2) { + ix++; + } else { + ix += vlen; + } + + b_percentile_vector(wk, pctv); + k = xi << 1; + y[k] = pctv[0]; + y[k + 1] = pctv[1]; + } + } + } + + void b_prctile(const real_T x_data[], int32_T x_size, real_T y[2]) + { + ::coder::array b_x_data; + ::coder::array idx; + if (x_size == 0) { + y[0] = rtNaN; + y[1] = rtNaN; + } else { + int32_T nj; + b_x_data.set((real_T *)&x_data[0], x_size); + internal::sortIdx(b_x_data, idx); + nj = x_size; + while ((nj > 0) && std::isnan(x_data[idx[nj - 1] - 1])) { + nj--; + } + + if (nj < 1) { + y[0] = rtNaN; + y[1] = rtNaN; + } else if (nj == 1) { + real_T r; + r = x_data[idx[0] - 1]; + y[0] = r; + y[1] = r; + } else { + real_T r; + int32_T i; + r = 0.175 * static_cast(nj); + i = static_cast(std::round(r)); + if (i < 1) { + y[0] = x_data[idx[0] - 1]; + } else if (i >= nj) { + y[0] = x_data[idx[nj - 1] - 1]; + } else { + r -= static_cast(i); + y[0] = (0.5 - r) * x_data[idx[i - 1] - 1] + (r + 0.5) * x_data[idx[i] + - 1]; + } + + r = 0.825 * static_cast(nj); + i = static_cast(std::round(r)); + if (i >= nj) { + y[1] = x_data[idx[nj - 1] - 1]; + } else { + r -= static_cast(i); + y[1] = (0.5 - r) * x_data[idx[i - 1] - 1] + (r + 0.5) * x_data[idx[i] + - 1]; + } + } + } + } + + void prctile(const ::coder::array &x, real_T y[2]) + { + ::coder::array idx; + if (x.size(1) == 0) { + y[0] = rtNaN; + y[1] = rtNaN; + } else { + int32_T nj; + internal::sortIdx(x, idx); + nj = x.size(1); + while ((nj > 0) && std::isnan(x[idx[nj - 1] - 1])) { + nj--; + } + + if (nj < 1) { + y[0] = rtNaN; + y[1] = rtNaN; + } else if (nj == 1) { + real_T r; + r = x[idx[0] - 1]; + y[0] = r; + y[1] = r; + } else { + real_T r; + int32_T i; + r = 0.75 * static_cast(nj); + i = static_cast(std::round(r)); + if (i >= nj) { + y[0] = x[idx[nj - 1] - 1]; + } else { + r -= static_cast(i); + y[0] = (0.5 - r) * x[idx[i - 1] - 1] + (r + 0.5) * x[idx[i] - 1]; + } + + r = 0.25 * static_cast(nj); + i = static_cast(std::round(r)); + if (i >= nj) { + y[1] = x[idx[nj - 1] - 1]; + } else { + r -= static_cast(i); + y[1] = (0.5 - r) * x[idx[i - 1] - 1] + (r + 0.5) * x[idx[i] - 1]; + } + } + } + } + + void prctile(const ::coder::array &x, ::coder::array + &y) + { + ::coder::array wk; + y.set_size(2, x.size(1)); + if ((x.size(0) == 0) || (x.size(1) == 0)) { + int32_T vlen; + vlen = x.size(1); + y.set_size(2, x.size(1)); + for (int32_T k{0}; k < vlen; k++) { + y[2 * k] = rtNaN; + y[2 * k + 1] = rtNaN; + } + } else { + int32_T ix; + int32_T npages; + int32_T vlen; + vlen = x.size(0); + wk.set_size(x.size(0)); + npages = x.size(1); + ix = -1; + for (int32_T xi{0}; xi < npages; xi++) { + real_T pctv[2]; + int32_T k; + wk[0] = x[ix + 1]; + for (k = 2; k <= vlen; k++) { + wk[k - 1] = x[ix + k]; + } + + if (vlen < 2) { + ix++; + } else { + ix += vlen; + } + + percentile_vector(wk, pctv); + k = xi << 1; + y[k] = pctv[0]; + y[k + 1] = pctv[1]; + } + } + } + + void prctile(const real_T x_data[], int32_T x_size, real_T y[2]) + { + ::coder::array b_x_data; + ::coder::array idx; + if (x_size == 0) { + y[0] = rtNaN; + y[1] = rtNaN; + } else { + int32_T nj; + b_x_data.set((real_T *)&x_data[0], x_size); + internal::sortIdx(b_x_data, idx); + nj = x_size; + while ((nj > 0) && std::isnan(x_data[idx[nj - 1] - 1])) { + nj--; + } + + if (nj < 1) { + y[0] = rtNaN; + y[1] = rtNaN; + } else if (nj == 1) { + real_T r; + r = x_data[idx[0] - 1]; + y[0] = r; + y[1] = r; + } else { + real_T r; + int32_T i; + r = 0.025 * static_cast(nj); + i = static_cast(std::round(r)); + if (i < 1) { + y[0] = x_data[idx[0] - 1]; + } else if (i >= nj) { + y[0] = x_data[idx[nj - 1] - 1]; + } else { + r -= static_cast(i); + y[0] = (0.5 - r) * x_data[idx[i - 1] - 1] + (r + 0.5) * x_data[idx[i] + - 1]; + } + + r = 0.975 * static_cast(nj); + i = static_cast(std::round(r)); + if (i >= nj) { + y[1] = x_data[idx[nj - 1] - 1]; + } else { + r -= static_cast(i); + y[1] = (0.5 - r) * x_data[idx[i - 1] - 1] + (r + 0.5) * x_data[idx[i] + - 1]; + } + } + } + } + } +} + +// End of code generation (prctile.cpp) diff --git a/cpp/RAT/prctile.h b/cpp/RAT/prctile.h new file mode 100644 index 00000000..ebbb1cd6 --- /dev/null +++ b/cpp/RAT/prctile.h @@ -0,0 +1,36 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// prctile.h +// +// Code generation for function 'prctile' +// +#ifndef PRCTILE_H +#define PRCTILE_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void b_prctile(const ::coder::array &x, ::coder::array &y); + void b_prctile(const real_T x_data[], int32_T x_size, real_T y[2]); + void prctile(const ::coder::array &x, real_T y[2]); + void prctile(const ::coder::array &x, ::coder::array + &y); + void prctile(const real_T x_data[], int32_T x_size, real_T y[2]); + } +} + +#endif + +// End of code generation (prctile.h) diff --git a/cpp/RAT/prctileConfInts.cpp b/cpp/RAT/prctileConfInts.cpp new file mode 100644 index 00000000..b692e8f5 --- /dev/null +++ b/cpp/RAT/prctileConfInts.cpp @@ -0,0 +1,32 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// prctileConfInts.cpp +// +// Code generation for function 'prctileConfInts' +// + +// Include files +#include "prctileConfInts.h" +#include "mean.h" +#include "prctile.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void prctileConfInts(const ::coder::array &chain, ::coder::array< + real_T, 2U> &parConfInts_par95, ::coder::array + &parConfInts_par65, ::coder::array + &parConfInts_mean) + { + coder::prctile(chain, parConfInts_par95); + coder::b_prctile(chain, parConfInts_par65); + coder::mean(chain, parConfInts_mean); + } +} + +// End of code generation (prctileConfInts.cpp) diff --git a/cpp/RAT/prctileConfInts.h b/cpp/RAT/prctileConfInts.h new file mode 100644 index 00000000..61596525 --- /dev/null +++ b/cpp/RAT/prctileConfInts.h @@ -0,0 +1,30 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// prctileConfInts.h +// +// Code generation for function 'prctileConfInts' +// +#ifndef PRCTILECONFINTS_H +#define PRCTILECONFINTS_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void prctileConfInts(const ::coder::array &chain, ::coder::array< + real_T, 2U> &parConfInts_par95, ::coder::array + &parConfInts_par65, ::coder::array + &parConfInts_mean); +} + +#endif + +// End of code generation (prctileConfInts.h) diff --git a/cpp/RAT/processBayes.cpp b/cpp/RAT/processBayes.cpp new file mode 100644 index 00000000..d942c8d3 --- /dev/null +++ b/cpp/RAT/processBayes.cpp @@ -0,0 +1,168 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// processBayes.cpp +// +// Code generation for function 'processBayes' +// + +// Include files +#include "processBayes.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "parseResultToStruct.h" +#include "prctileConfInts.h" +#include "refPrctileConfInts.h" +#include "reflectivityCalculation.h" +#include "rt_nonfinite.h" +#include "unpackParams.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void processBayes(const real_T bayesOutputs_bestPars_data[], const int32_T + bayesOutputs_bestPars_size[2], const ::coder::array &bayesOutputs_chain, const c_struct_T *allProblem_f1, + const struct2_T *allProblem_f2, const cell_11 *allProblem_f4, + c_struct_T *problemStruct, d_struct_T *contrastParams, + cell_wrap_9 result[6], e_struct_T *bayesResults_bestFitsMean, + f_struct_T *bayesResults_predlims, struct10_T + *bayesResults_parConfInts) + { + static struct2_T controlsStruct; + ::coder::array b_expl_temp; + ::coder::array c_expl_temp; + ::coder::array expl_temp; + c_struct_T b_problemStruct; + d_struct_T d_expl_temp; + real_T p_calculationResults_sumChi; + int32_T loop_ub; + + // problem = {problemStruct ; controls ; problemLimits ; problemCells}; + *problemStruct = *allProblem_f1; + controlsStruct = *allProblem_f2; + + // Need to impose that we calculate the SLD.. + controlsStruct.calcSldDuringFit = true; + + // ... and use the Bayes bestpars + problemStruct->fitParams.set_size(1, bayesOutputs_bestPars_size[1]); + loop_ub = bayesOutputs_bestPars_size[1]; + for (int32_T i{0}; i < loop_ub; i++) { + problemStruct->fitParams[problemStruct->fitParams.size(0) * i] = + bayesOutputs_bestPars_data[i]; + } + + unpackParams(problemStruct, allProblem_f2->checks.fitParam, + allProblem_f2->checks.fitBackgroundParam, + allProblem_f2->checks.fitQzshift, + allProblem_f2->checks.fitScalefactor, + allProblem_f2->checks.fitBulkIn, + allProblem_f2->checks.fitBulkOut, + allProblem_f2->checks.fitResolutionParam, + allProblem_f2->checks.fitDomainRatio); + prctileConfInts(bayesOutputs_chain, bayesResults_parConfInts->par95, + bayesResults_parConfInts->par65, + bayesResults_parConfInts->mean); + + // iterShortest(output.chain,length(fitNames),[],0.95); + // Calculate 'mean' best fit curves + reflectivityCalculation(problemStruct, allProblem_f4, &controlsStruct, + contrastParams, result); + parseResultToStruct(contrastParams, result, bayesResults_bestFitsMean->ref, + expl_temp, bayesResults_bestFitsMean->data, b_expl_temp, + bayesResults_bestFitsMean->sld, c_expl_temp, + &p_calculationResults_sumChi, &d_expl_temp); + bayesResults_bestFitsMean->chi = p_calculationResults_sumChi; + + // 2. Reflectivity and SLD shading + b_problemStruct = *problemStruct; + refPrctileConfInts(bayesOutputs_chain, &b_problemStruct, allProblem_f4, + &controlsStruct, bayesResults_predlims); + + // --------------------------------- + // bayesResults.chain = bayesOutputs.chain; + // bayesResults.bestPars_Max = bestPars_max; + // bayesResults.bayesData = bayesOutputs.data; + // bayesResults.bestFitsMax = {bestFitMax_Ref, bestFitMax_Sld, bestFitMax_chi}; + // bayesResults.bestFitsMean = bestFitMean; + // bayesResults.predlims = allPredInts; + // bayesResults.parConfInts = parConfInts; + // bayesResults.bestPars = bayesOutputs.bestPars; + } + + void processBayes(const ::coder::array &bayesOutputs_bestPars, + const ::coder::array &bayesOutputs_chain, const + c_struct_T *allProblem_f1, const struct2_T *allProblem_f2, + const cell_11 *allProblem_f4, c_struct_T *problemStruct, + d_struct_T *contrastParams, cell_wrap_9 result[6], + e_struct_T *bayesResults_bestFitsMean, f_struct_T + *bayesResults_predlims, struct10_T *bayesResults_parConfInts) + { + static struct2_T controlsStruct; + ::coder::array b_expl_temp; + ::coder::array c_expl_temp; + ::coder::array expl_temp; + c_struct_T b_problemStruct; + d_struct_T d_expl_temp; + real_T p_calculationResults_sumChi; + int32_T loop_ub; + + // problem = {problemStruct ; controls ; problemLimits ; problemCells}; + *problemStruct = *allProblem_f1; + controlsStruct = *allProblem_f2; + + // Need to impose that we calculate the SLD.. + controlsStruct.calcSldDuringFit = true; + + // ... and use the Bayes bestpars + problemStruct->fitParams.set_size(1, bayesOutputs_bestPars.size(1)); + loop_ub = bayesOutputs_bestPars.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + problemStruct->fitParams[problemStruct->fitParams.size(0) * i] = + bayesOutputs_bestPars[i]; + } + + unpackParams(problemStruct, allProblem_f2->checks.fitParam, + allProblem_f2->checks.fitBackgroundParam, + allProblem_f2->checks.fitQzshift, + allProblem_f2->checks.fitScalefactor, + allProblem_f2->checks.fitBulkIn, + allProblem_f2->checks.fitBulkOut, + allProblem_f2->checks.fitResolutionParam, + allProblem_f2->checks.fitDomainRatio); + prctileConfInts(bayesOutputs_chain, bayesResults_parConfInts->par95, + bayesResults_parConfInts->par65, + bayesResults_parConfInts->mean); + + // iterShortest(output.chain,length(fitNames),[],0.95); + // Calculate 'mean' best fit curves + reflectivityCalculation(problemStruct, allProblem_f4, &controlsStruct, + contrastParams, result); + parseResultToStruct(contrastParams, result, bayesResults_bestFitsMean->ref, + expl_temp, bayesResults_bestFitsMean->data, b_expl_temp, + bayesResults_bestFitsMean->sld, c_expl_temp, + &p_calculationResults_sumChi, &d_expl_temp); + bayesResults_bestFitsMean->chi = p_calculationResults_sumChi; + + // 2. Reflectivity and SLD shading + b_problemStruct = *problemStruct; + refPrctileConfInts(bayesOutputs_chain, &b_problemStruct, allProblem_f4, + &controlsStruct, bayesResults_predlims); + + // --------------------------------- + // bayesResults.chain = bayesOutputs.chain; + // bayesResults.bestPars_Max = bestPars_max; + // bayesResults.bayesData = bayesOutputs.data; + // bayesResults.bestFitsMax = {bestFitMax_Ref, bestFitMax_Sld, bestFitMax_chi}; + // bayesResults.bestFitsMean = bestFitMean; + // bayesResults.predlims = allPredInts; + // bayesResults.parConfInts = parConfInts; + // bayesResults.bestPars = bayesOutputs.bestPars; + } +} + +// End of code generation (processBayes.cpp) diff --git a/cpp/RAT/processBayes.h b/cpp/RAT/processBayes.h new file mode 100644 index 00000000..070fb069 --- /dev/null +++ b/cpp/RAT/processBayes.h @@ -0,0 +1,54 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// processBayes.h +// +// Code generation for function 'processBayes' +// +#ifndef PROCESSBAYES_H +#define PROCESSBAYES_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct c_struct_T; + struct struct2_T; + struct cell_11; + struct d_struct_T; + struct cell_wrap_9; + struct e_struct_T; + struct f_struct_T; + struct struct10_T; +} + +// Function Declarations +namespace RAT +{ + void processBayes(const real_T bayesOutputs_bestPars_data[], const int32_T + bayesOutputs_bestPars_size[2], const ::coder::array &bayesOutputs_chain, const c_struct_T *allProblem_f1, + const struct2_T *allProblem_f2, const cell_11 *allProblem_f4, + c_struct_T *problemStruct, d_struct_T *contrastParams, + cell_wrap_9 result[6], e_struct_T *bayesResults_bestFitsMean, + f_struct_T *bayesResults_predlims, struct10_T + *bayesResults_parConfInts); + void processBayes(const ::coder::array &bayesOutputs_bestPars, + const ::coder::array &bayesOutputs_chain, const + c_struct_T *allProblem_f1, const struct2_T *allProblem_f2, + const cell_11 *allProblem_f4, c_struct_T *problemStruct, + d_struct_T *contrastParams, cell_wrap_9 result[6], + e_struct_T *bayesResults_bestFitsMean, f_struct_T + *bayesResults_predlims, struct10_T *bayesResults_parConfInts); +} + +#endif + +// End of code generation (processBayes.h) diff --git a/cpp/RAT/processCustomFunction.cpp b/cpp/RAT/processCustomFunction.cpp new file mode 100644 index 00000000..30166525 --- /dev/null +++ b/cpp/RAT/processCustomFunction.cpp @@ -0,0 +1,159 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// processCustomFunction.cpp +// +// Code generation for function 'processCustomFunction' +// + +// Include files +#include "processCustomFunction.h" +#include "RATMain_types.h" +#include "applyHydrationImag.h" +#include "applyHydrationReal.h" +#include "callCppFunction.h" +#include "rt_nonfinite.h" +#include "str2double.h" +#include "coder_array.h" +#include + +// Function Declarations +namespace RAT +{ + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_8, 1U> &r1); +} + +// Function Definitions +namespace RAT +{ + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_8, 1U> &r1) + { + int32_T i; + r1.set_size(r.size(0)); + i = r.size(0); + for (int32_T i1{0}; i1 < i; i1++) { + int32_T loop_ub; + loop_ub = r[i1].f1.size(1); + r1[i1].f1.set_size(r[i1].f1.size(0), r[i1].f1.size(1)); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + int32_T b_loop_ub; + b_loop_ub = r[i1].f1.size(0); + for (int32_T i3{0}; i3 < b_loop_ub; i3++) { + r1[i1].f1[i3 + r1[i1].f1.size(0) * i2] = r[i1].f1[i3 + r[i1].f1.size(0) + * i2]; + } + } + } + } + + namespace nonPolarisedTF + { + namespace customLayers + { + void processCustomFunction(const ::coder::array + &contrastBulkIns, const ::coder::array &contrastBulkOuts, + const ::coder::array &bulkIn, const ::coder::array &bulkOut, const ::coder::array &cCustFiles, real_T + numberOfContrasts, const ::coder::array &customFiles, + const ::coder::array ¶ms, boolean_T useImaginary, :: + coder::array &allLayers, ::coder::array + &allRoughs) + { + ::coder::array tempAllLayers; + ::coder::array allBulkOuts; + ::coder::array b_allBulkOuts; + ::coder::array b_params; + ::coder::array thisContrastLayers; + int32_T i; + int32_T loop_ub; + + // Top-level function for processing custom layers for all the + // contrasts. + // Do some pre-definitions to keep the compiler happy... + i = static_cast(numberOfContrasts); + allRoughs.set_size(i); + allBulkOuts.set_size(1, contrastBulkOuts.size(1)); + loop_ub = contrastBulkOuts.size(1); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + allBulkOuts[i1] = bulkOut[static_cast(contrastBulkOuts[i1]) - + 1]; + } + + tempAllLayers.set_size(i); + for (int32_T b_i{0}; b_i < i; b_i++) { + creal_T x; + real_T d; + int32_T iv[2]; + + // TODO - the ambition is for parfor here, but would fail for Matlab and Python CM's.. + // Choose which custom file is associated with this contrast + // Find values of 'bulkIn' and 'bulkOut' for this + // contrast... + // typeDef + d = cCustFiles[b_i]; + iv[0] = (*(int32_T (*)[2])((::coder::array *)&customFiles[ + static_cast(d) - 1].f1)->size())[0]; + iv[1] = (*(int32_T (*)[2])((::coder::array *)&customFiles[ + static_cast(d) - 1].f1)->size())[1]; + x = coder::str2double((const char_T *)((::coder::array *) + &customFiles[static_cast(d) - 1].f1)->data(), iv); + if ((!std::isnan(x.re)) && (!std::isnan(x.im))) { + b_params.set_size(1, params.size(1)); + loop_ub = params.size(1) - 1; + for (int32_T i1{0}; i1 <= loop_ub; i1++) { + b_params[i1] = params[i1]; + } + + b_allBulkOuts.set_size(1, allBulkOuts.size(1)); + loop_ub = allBulkOuts.size(1) - 1; + for (int32_T i1{0}; i1 <= loop_ub; i1++) { + b_allBulkOuts[i1] = allBulkOuts[i1]; + } + + iv[0] = (*(int32_T (*)[2])((::coder::array *) + &customFiles[static_cast(d) - 1].f1)->size())[0]; + iv[1] = (*(int32_T (*)[2])((::coder::array *) + &customFiles[static_cast(d) - 1].f1)->size())[1]; + callCppFunction((const char_T *)((::coder::array *) + &customFiles[static_cast(d) - 1].f1)->data(), iv, + b_params, bulkIn[static_cast + (contrastBulkIns[b_i]) - 1], b_allBulkOuts, ( + static_cast(b_i) + 1.0) - 1.0, thisContrastLayers, + &allRoughs[b_i]); + } + + // If the output layers has 5 columns, then we need to do + // the hydration correction (the user has not done it in the + // custom function). Do that here.... + if (!useImaginary) { + applyHydrationReal(thisContrastLayers, bulkIn[static_cast + (contrastBulkIns[b_i]) - 1], allBulkOuts[b_i]); + } else { + applyHydrationImag(thisContrastLayers, bulkIn[static_cast + (contrastBulkIns[b_i]) - 1], allBulkOuts[b_i]); + } + + loop_ub = thisContrastLayers.size(1); + tempAllLayers[b_i].f1.set_size(thisContrastLayers.size(0), + thisContrastLayers.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + int32_T b_loop_ub; + b_loop_ub = thisContrastLayers.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + tempAllLayers[b_i].f1[i2 + tempAllLayers[b_i].f1.size(0) * i1] = + thisContrastLayers[i2 + thisContrastLayers.size(0) * i1]; + } + } + } + + cast(tempAllLayers, allLayers); + } + } + } +} + +// End of code generation (processCustomFunction.cpp) diff --git a/cpp/RAT/processCustomFunction.h b/cpp/RAT/processCustomFunction.h new file mode 100644 index 00000000..630d6f28 --- /dev/null +++ b/cpp/RAT/processCustomFunction.h @@ -0,0 +1,41 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// processCustomFunction.h +// +// Code generation for function 'processCustomFunction' +// +#ifndef PROCESSCUSTOMFUNCTION_H +#define PROCESSCUSTOMFUNCTION_H + +// Include files +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace nonPolarisedTF + { + namespace customLayers + { + void processCustomFunction(const ::coder::array + &contrastBulkIns, const ::coder::array &contrastBulkOuts, + const ::coder::array &bulkIn, const ::coder::array &bulkOut, const ::coder::array &cCustFiles, real_T + numberOfContrasts, const ::coder::array &customFiles, + const ::coder::array ¶ms, boolean_T useImaginary, :: + coder::array &allLayers, ::coder::array + &allRoughs); + } + } +} + +#endif + +// End of code generation (processCustomFunction.h) diff --git a/cpp/RAT/processCustomFunction1.cpp b/cpp/RAT/processCustomFunction1.cpp new file mode 100644 index 00000000..2bf9c06b --- /dev/null +++ b/cpp/RAT/processCustomFunction1.cpp @@ -0,0 +1,144 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// processCustomFunction1.cpp +// +// Code generation for function 'processCustomFunction1' +// + +// Include files +#include "processCustomFunction1.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "callCppFunction.h" +#include "rt_nonfinite.h" +#include "str2double.h" +#include "coder_array.h" +#include + +// Function Declarations +namespace RAT +{ + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_8, 1U> &r1); +} + +// Function Definitions +namespace RAT +{ + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_8, 1U> &r1) + { + int32_T i; + r1.set_size(r.size(0)); + i = r.size(0); + for (int32_T i1{0}; i1 < i; i1++) { + int32_T loop_ub; + loop_ub = r[i1].f1.size(1); + r1[i1].f1.set_size(r[i1].f1.size(0), r[i1].f1.size(1)); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + int32_T b_loop_ub; + b_loop_ub = r[i1].f1.size(0); + for (int32_T i3{0}; i3 < b_loop_ub; i3++) { + r1[i1].f1[i3 + r1[i1].f1.size(0) * i2] = r[i1].f1[i3 + r[i1].f1.size(0) + * i2]; + } + } + } + } + + namespace nonPolarisedTF + { + namespace customXY + { + void processCustomFunction(const ::coder::array + &contrastBulkIns, const ::coder::array &contrastBulkOuts, + const ::coder::array &bulkIn, const ::coder::array &bulkOut, const ::coder::array &cCustFiles, real_T + numberOfContrasts, const ::coder::array &customFiles, + const ::coder::array ¶ms, ::coder::array + &allSLDs, ::coder::array &allRoughs) + { + ::coder::array tempAllSLDs; + ::coder::array allBulkOuts; + ::coder::array b_allBulkOuts; + ::coder::array b_params; + ::coder::array r; + int32_T i; + int32_T loop_ub; + + // Top-level function for processing custom XY profiles for all the + // contrasts. + // Do some pre-definitions to keep the compiler happy... + i = static_cast(numberOfContrasts); + allRoughs.set_size(i); + + // 3 columns to allow for potential imaginary curve + allBulkOuts.set_size(1, contrastBulkOuts.size(1)); + loop_ub = contrastBulkOuts.size(1); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + allBulkOuts[i1] = bulkOut[static_cast(contrastBulkOuts[i1]) - + 1]; + } + + tempAllSLDs.set_size(i); + for (int32_T b_i{0}; b_i < i; b_i++) { + creal_T x; + real_T d; + int32_T iv[2]; + + // TODO - the ambition is for parfor here, but would fail for Matlab and Python CM's.. + // Choose which custom file is associated with this contrast + // Find values of 'bulkIn' and 'bulkOut' for this + // contrast... + d = cCustFiles[b_i]; + iv[0] = (*(int32_T (*)[2])((::coder::array *)&customFiles[ + static_cast(d) - 1].f1)->size())[0]; + iv[1] = (*(int32_T (*)[2])((::coder::array *)&customFiles[ + static_cast(d) - 1].f1)->size())[1]; + x = coder::str2double((const char_T *)((::coder::array *) + &customFiles[static_cast(d) - 1].f1)->data(), iv); + if ((!std::isnan(x.re)) && (!std::isnan(x.im))) { + b_params.set_size(1, params.size(1)); + loop_ub = params.size(1) - 1; + for (int32_T i1{0}; i1 <= loop_ub; i1++) { + b_params[i1] = params[i1]; + } + + b_allBulkOuts.set_size(1, allBulkOuts.size(1)); + loop_ub = allBulkOuts.size(1) - 1; + for (int32_T i1{0}; i1 <= loop_ub; i1++) { + b_allBulkOuts[i1] = allBulkOuts[i1]; + } + + iv[0] = (*(int32_T (*)[2])((::coder::array *) + &customFiles[static_cast(d) - 1].f1)->size())[0]; + iv[1] = (*(int32_T (*)[2])((::coder::array *) + &customFiles[static_cast(d) - 1].f1)->size())[1]; + callCppFunction((const char_T *)((::coder::array *) + &customFiles[static_cast(d) - 1].f1)->data(), iv, + b_params, bulkIn[static_cast + (contrastBulkIns[b_i]) - 1], b_allBulkOuts, ( + static_cast(b_i) + 1.0) - 1.0, r, &allRoughs[b_i]); + loop_ub = r.size(1); + tempAllSLDs[b_i].f1.set_size(r.size(0), r.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + int32_T b_loop_ub; + b_loop_ub = r.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + tempAllSLDs[b_i].f1[i2 + tempAllSLDs[b_i].f1.size(0) * i1] = + r[i2 + r.size(0) * i1]; + } + } + } + } + + cast(tempAllSLDs, allSLDs); + } + } + } +} + +// End of code generation (processCustomFunction1.cpp) diff --git a/cpp/RAT/processCustomFunction1.h b/cpp/RAT/processCustomFunction1.h new file mode 100644 index 00000000..be19a812 --- /dev/null +++ b/cpp/RAT/processCustomFunction1.h @@ -0,0 +1,40 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// processCustomFunction1.h +// +// Code generation for function 'processCustomFunction1' +// +#ifndef PROCESSCUSTOMFUNCTION1_H +#define PROCESSCUSTOMFUNCTION1_H + +// Include files +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace nonPolarisedTF + { + namespace customXY + { + void processCustomFunction(const ::coder::array + &contrastBulkIns, const ::coder::array &contrastBulkOuts, + const ::coder::array &bulkIn, const ::coder::array &bulkOut, const ::coder::array &cCustFiles, real_T + numberOfContrasts, const ::coder::array &customFiles, + const ::coder::array ¶ms, ::coder::array + &allSLDs, ::coder::array &allRoughs); + } + } +} + +#endif + +// End of code generation (processCustomFunction1.h) diff --git a/cpp/RAT/processCustomFunction2.cpp b/cpp/RAT/processCustomFunction2.cpp new file mode 100644 index 00000000..f3fbc9cd --- /dev/null +++ b/cpp/RAT/processCustomFunction2.cpp @@ -0,0 +1,183 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// processCustomFunction2.cpp +// +// Code generation for function 'processCustomFunction2' +// + +// Include files +#include "processCustomFunction2.h" +#include "RATMain_types.h" +#include "applyHydrationImag.h" +#include "applyHydrationReal.h" +#include "callCppFunction.h" +#include "rt_nonfinite.h" +#include "str2double.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace domainsTF + { + namespace customLayers + { + void processCustomFunction(const ::coder::array + &contrastBulkIns, const ::coder::array &contrastBulkOuts, + const ::coder::array &bulkIn, const ::coder::array &bulkOut, const ::coder::array &cCustFiles, real_T + numberOfContrasts, const ::coder::array &customFiles, + const ::coder::array ¶ms, boolean_T useImaginary, :: + coder::array &allLayers, ::coder::array + &allRoughs) + { + ::coder::array allBulkOuts; + ::coder::array b_allBulkOuts; + ::coder::array b_params; + ::coder::array b_thisContrastLayers1; + ::coder::array thisContrastLayers1; + real_T a__2; + int32_T i; + int32_T loop_ub; + + // Top-level function for processing custom layers for all the + // contrasts. + // Do some pre-definitions to keep the compiler happy... + // totNumCalcs = numberOfContrasts * 2; + i = static_cast(numberOfContrasts); + allRoughs.set_size(i); + allBulkOuts.set_size(1, contrastBulkOuts.size(1)); + loop_ub = contrastBulkOuts.size(1); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + allBulkOuts[i1] = bulkOut[static_cast(contrastBulkOuts[i1]) - + 1]; + } + + allLayers.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + creal_T x; + real_T d; + int32_T iv[2]; + int32_T b_loop_ub; + + // Choose which custom file is associated with this contrast + // Find values of 'bulkIn' and 'bulkOut' for this + // contrast... + // typeDef + d = cCustFiles[b_i]; + iv[0] = (*(int32_T (*)[2])((::coder::array *)&customFiles[ + static_cast(d) - 1].f1)->size())[0]; + iv[1] = (*(int32_T (*)[2])((::coder::array *)&customFiles[ + static_cast(d) - 1].f1)->size())[1]; + x = coder::str2double((const char_T *)((::coder::array *) + &customFiles[static_cast(d) - 1].f1)->data(), iv); + if ((!std::isnan(x.re)) && (!std::isnan(x.im))) { + b_params.set_size(1, params.size(1)); + loop_ub = params.size(1) - 1; + for (int32_T i1{0}; i1 <= loop_ub; i1++) { + b_params[i1] = params[i1]; + } + + b_allBulkOuts.set_size(1, allBulkOuts.size(1)); + loop_ub = allBulkOuts.size(1) - 1; + for (int32_T i1{0}; i1 <= loop_ub; i1++) { + b_allBulkOuts[i1] = allBulkOuts[i1]; + } + + iv[0] = (*(int32_T (*)[2])((::coder::array *) + &customFiles[static_cast(d) - 1].f1)->size())[0]; + iv[1] = (*(int32_T (*)[2])((::coder::array *) + &customFiles[static_cast(d) - 1].f1)->size())[1]; + b_callCppFunction((const char_T *)((::coder::array *) + &customFiles[static_cast(d) - 1].f1)->data(), iv, + b_params, bulkIn[static_cast + (contrastBulkIns[b_i]) - 1], b_allBulkOuts, ( + static_cast(b_i) + 1.0) - 1.0, b_thisContrastLayers1, + &allRoughs[b_i]); + loop_ub = b_thisContrastLayers1.size(1); + thisContrastLayers1.set_size(b_thisContrastLayers1.size(0), + b_thisContrastLayers1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = b_thisContrastLayers1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + thisContrastLayers1[i2 + thisContrastLayers1.size(0) * i1] = + b_thisContrastLayers1[i2 + b_thisContrastLayers1.size(0) * i1]; + } + } + + b_params.set_size(1, params.size(1)); + loop_ub = params.size(1) - 1; + for (int32_T i1{0}; i1 <= loop_ub; i1++) { + b_params[i1] = params[i1]; + } + + b_allBulkOuts.set_size(1, allBulkOuts.size(1)); + loop_ub = allBulkOuts.size(1) - 1; + for (int32_T i1{0}; i1 <= loop_ub; i1++) { + b_allBulkOuts[i1] = allBulkOuts[i1]; + } + + iv[0] = (*(int32_T (*)[2])((::coder::array *) + &customFiles[static_cast(cCustFiles[b_i]) - 1].f1) + ->size())[0]; + iv[1] = (*(int32_T (*)[2])((::coder::array *) + &customFiles[static_cast(cCustFiles[b_i]) - 1].f1) + ->size())[1]; + c_callCppFunction((const char_T *)((::coder::array *) + &customFiles[static_cast(cCustFiles[b_i]) - 1].f1)->data(), + iv, b_params, bulkIn[static_cast + (contrastBulkIns[b_i]) - 1], b_allBulkOuts, ( + static_cast(b_i) + 1.0) - 1.0, b_thisContrastLayers1, + &a__2); + } + + // If the output layers has 5 columns, then we need to do + // the hydration correction (the user has not done it in the + // custom function). Do that here.... + if (!useImaginary) { + d = contrastBulkIns[b_i]; + applyHydrationReal(thisContrastLayers1, bulkIn[static_cast + (d) - 1], allBulkOuts[b_i]); + applyHydrationReal(b_thisContrastLayers1, bulkIn[static_cast + (d) - 1], allBulkOuts[b_i]); + } else { + d = contrastBulkIns[b_i]; + applyHydrationImag(thisContrastLayers1, bulkIn[static_cast + (d) - 1], allBulkOuts[b_i]); + applyHydrationImag(b_thisContrastLayers1, bulkIn[static_cast + (d) - 1], allBulkOuts[b_i]); + } + + allLayers[b_i].f1.set_size(thisContrastLayers1.size(0), + thisContrastLayers1.size(1)); + loop_ub = thisContrastLayers1.size(1); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = thisContrastLayers1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + allLayers[b_i].f1[i2 + allLayers[b_i].f1.size(0) * i1] = + thisContrastLayers1[i2 + thisContrastLayers1.size(0) * i1]; + } + } + + loop_ub = b_thisContrastLayers1.size(1); + allLayers[b_i + allLayers.size(0)].f1.set_size + (b_thisContrastLayers1.size(0), b_thisContrastLayers1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = b_thisContrastLayers1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + allLayers[b_i + allLayers.size(0)].f1[i2 + allLayers[b_i + + allLayers.size(0)].f1.size(0) * i1] = b_thisContrastLayers1[i2 + + b_thisContrastLayers1.size(0) * i1]; + } + } + } + } + } + } +} + +// End of code generation (processCustomFunction2.cpp) diff --git a/cpp/RAT/processCustomFunction2.h b/cpp/RAT/processCustomFunction2.h new file mode 100644 index 00000000..1e5d765a --- /dev/null +++ b/cpp/RAT/processCustomFunction2.h @@ -0,0 +1,41 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// processCustomFunction2.h +// +// Code generation for function 'processCustomFunction2' +// +#ifndef PROCESSCUSTOMFUNCTION2_H +#define PROCESSCUSTOMFUNCTION2_H + +// Include files +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace domainsTF + { + namespace customLayers + { + void processCustomFunction(const ::coder::array + &contrastBulkIns, const ::coder::array &contrastBulkOuts, + const ::coder::array &bulkIn, const ::coder::array &bulkOut, const ::coder::array &cCustFiles, real_T + numberOfContrasts, const ::coder::array &customFiles, + const ::coder::array ¶ms, boolean_T useImaginary, :: + coder::array &allLayers, ::coder::array + &allRoughs); + } + } +} + +#endif + +// End of code generation (processCustomFunction2.h) diff --git a/cpp/RAT/processCustomFunction3.cpp b/cpp/RAT/processCustomFunction3.cpp new file mode 100644 index 00000000..92d2838b --- /dev/null +++ b/cpp/RAT/processCustomFunction3.cpp @@ -0,0 +1,178 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// processCustomFunction3.cpp +// +// Code generation for function 'processCustomFunction3' +// + +// Include files +#include "processCustomFunction3.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "callCppFunction.h" +#include "rt_nonfinite.h" +#include "str2double.h" +#include "coder_array.h" +#include + +// Function Declarations +namespace RAT +{ + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_8, 2U> &r1); +} + +// Function Definitions +namespace RAT +{ + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_8, 2U> &r1) + { + int32_T i; + r1.set_size(r.size(0), 2); + i = r.size(0) << 1; + for (int32_T i1{0}; i1 < i; i1++) { + int32_T loop_ub; + loop_ub = r[i1].f1.size(1); + r1[i1].f1.set_size(r[i1].f1.size(0), r[i1].f1.size(1)); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + int32_T b_loop_ub; + b_loop_ub = r[i1].f1.size(0); + for (int32_T i3{0}; i3 < b_loop_ub; i3++) { + r1[i1].f1[i3 + r1[i1].f1.size(0) * i2] = r[i1].f1[i3 + r[i1].f1.size(0) + * i2]; + } + } + } + } + + namespace domainsTF + { + namespace customXY + { + void processCustomFunction(const ::coder::array + &contrastBulkIns, const ::coder::array &contrastBulkOuts, + const ::coder::array &bulkIn, const ::coder::array &bulkOut, const ::coder::array &cCustFiles, real_T + numberOfContrasts, const ::coder::array &customFiles, + const ::coder::array ¶ms, ::coder::array + &allSLDs, ::coder::array &allRoughs) + { + ::coder::array tempAllSLDs; + ::coder::array allBulkOuts; + ::coder::array b_allBulkOuts; + ::coder::array b_params; + ::coder::array r; + real_T a__2; + int32_T i; + int32_T loop_ub; + + // Top-level function for processing custom XY profiles for all the + // contrasts. + // Do some pre-definitions to keep the compiler happy... + i = static_cast(numberOfContrasts); + allRoughs.set_size(i); + + // 3 columns to allow for potential imaginary curve + allBulkOuts.set_size(1, contrastBulkOuts.size(1)); + loop_ub = contrastBulkOuts.size(1); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + allBulkOuts[i1] = bulkOut[static_cast(contrastBulkOuts[i1]) - + 1]; + } + + tempAllSLDs.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + creal_T x; + real_T d; + int32_T iv[2]; + + // TODO - the ambition is for parfor here, but would fail for Matlab and Python CM's.. + // Choose which custom file is associated with this contrast + // Find values of 'bulkIn' and 'bulkOut' for this contrast... + d = cCustFiles[b_i]; + iv[0] = (*(int32_T (*)[2])((::coder::array *)&customFiles[ + static_cast(d) - 1].f1)->size())[0]; + iv[1] = (*(int32_T (*)[2])((::coder::array *)&customFiles[ + static_cast(d) - 1].f1)->size())[1]; + x = coder::str2double((const char_T *)((::coder::array *) + &customFiles[static_cast(d) - 1].f1)->data(), iv); + if ((!std::isnan(x.re)) && (!std::isnan(x.im))) { + int32_T b_loop_ub; + b_params.set_size(1, params.size(1)); + loop_ub = params.size(1) - 1; + for (int32_T i1{0}; i1 <= loop_ub; i1++) { + b_params[i1] = params[i1]; + } + + b_allBulkOuts.set_size(1, allBulkOuts.size(1)); + loop_ub = allBulkOuts.size(1) - 1; + for (int32_T i1{0}; i1 <= loop_ub; i1++) { + b_allBulkOuts[i1] = allBulkOuts[i1]; + } + + iv[0] = (*(int32_T (*)[2])((::coder::array *) + &customFiles[static_cast(d) - 1].f1)->size())[0]; + iv[1] = (*(int32_T (*)[2])((::coder::array *) + &customFiles[static_cast(d) - 1].f1)->size())[1]; + b_callCppFunction((const char_T *)((::coder::array *) + &customFiles[static_cast(d) - 1].f1)->data(), iv, + b_params, bulkIn[static_cast + (contrastBulkIns[b_i]) - 1], b_allBulkOuts, ( + static_cast(b_i) + 1.0) - 1.0, r, &allRoughs[b_i]); + loop_ub = r.size(1); + tempAllSLDs[b_i].f1.set_size(r.size(0), r.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = r.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + tempAllSLDs[b_i].f1[i2 + tempAllSLDs[b_i].f1.size(0) * i1] = + r[i2 + r.size(0) * i1]; + } + } + + b_params.set_size(1, params.size(1)); + loop_ub = params.size(1) - 1; + for (int32_T i1{0}; i1 <= loop_ub; i1++) { + b_params[i1] = params[i1]; + } + + b_allBulkOuts.set_size(1, allBulkOuts.size(1)); + loop_ub = allBulkOuts.size(1) - 1; + for (int32_T i1{0}; i1 <= loop_ub; i1++) { + b_allBulkOuts[i1] = allBulkOuts[i1]; + } + + iv[0] = (*(int32_T (*)[2])((::coder::array *) + &customFiles[static_cast(cCustFiles[b_i]) - 1].f1) + ->size())[0]; + iv[1] = (*(int32_T (*)[2])((::coder::array *) + &customFiles[static_cast(cCustFiles[b_i]) - 1].f1) + ->size())[1]; + c_callCppFunction((const char_T *)((::coder::array *) + &customFiles[static_cast(cCustFiles[b_i]) - 1].f1)->data(), + iv, b_params, bulkIn[static_cast + (contrastBulkIns[b_i]) - 1], b_allBulkOuts, ( + static_cast(b_i) + 1.0) - 1.0, r, &a__2); + loop_ub = r.size(1); + tempAllSLDs[b_i + tempAllSLDs.size(0)].f1.set_size(r.size(0), r.size + (1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = r.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + tempAllSLDs[b_i + tempAllSLDs.size(0)].f1[i2 + tempAllSLDs[b_i + + tempAllSLDs.size(0)].f1.size(0) * i1] = r[i2 + r.size(0) * i1]; + } + } + } + } + + cast(tempAllSLDs, allSLDs); + } + } + } +} + +// End of code generation (processCustomFunction3.cpp) diff --git a/cpp/RAT/processCustomFunction3.h b/cpp/RAT/processCustomFunction3.h new file mode 100644 index 00000000..2302fcae --- /dev/null +++ b/cpp/RAT/processCustomFunction3.h @@ -0,0 +1,40 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// processCustomFunction3.h +// +// Code generation for function 'processCustomFunction3' +// +#ifndef PROCESSCUSTOMFUNCTION3_H +#define PROCESSCUSTOMFUNCTION3_H + +// Include files +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace domainsTF + { + namespace customXY + { + void processCustomFunction(const ::coder::array + &contrastBulkIns, const ::coder::array &contrastBulkOuts, + const ::coder::array &bulkIn, const ::coder::array &bulkOut, const ::coder::array &cCustFiles, real_T + numberOfContrasts, const ::coder::array &customFiles, + const ::coder::array ¶ms, ::coder::array + &allSLDs, ::coder::array &allRoughs); + } + } +} + +#endif + +// End of code generation (processCustomFunction3.h) diff --git a/cpp/RAT/qrsolve.cpp b/cpp/RAT/qrsolve.cpp new file mode 100644 index 00000000..55947edf --- /dev/null +++ b/cpp/RAT/qrsolve.cpp @@ -0,0 +1,175 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// qrsolve.cpp +// +// Code generation for function 'qrsolve' +// + +// Include files +#include "qrsolve.h" +#include "rt_nonfinite.h" +#include "xunormqr.h" +#include "xzgeqp3.h" +#include "coder_array.h" +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + static void LSQFromQR(const ::coder::array &A, const real_T + tau_data[], ::coder::array &B, int32_T + rankA, ::coder::array &Y); + static int32_T rankFromQR(const ::coder::array &A); + } + } +} + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + static void LSQFromQR(const ::coder::array &A, const real_T + tau_data[], ::coder::array &B, int32_T + rankA, ::coder::array &Y) + { + int32_T k; + int32_T nb; + nb = B.size(1); + Y.set_size(1, B.size(1)); + k = B.size(1); + for (int32_T j{0}; j < k; j++) { + Y[j] = 0.0; + } + + lapack::xunormqr(A, B, tau_data); + for (k = 0; k < nb; k++) { + if (static_cast(rankA) - 1 >= 0) { + Y[k] = B[B.size(0) * k]; + } + + for (int32_T j{rankA}; j >= 1; j--) { + Y[k] = Y[k] / A[0]; + } + } + } + + static int32_T rankFromQR(const ::coder::array &A) + { + int32_T r; + r = 0; + if (A.size(0) >= 1) { + real_T tol_tmp; + tol_tmp = std::abs(A[0]); + if (!(tol_tmp <= std::fmin(1.4901161193847656E-8, + 2.2204460492503131E-15 * static_cast(A.size(0))) * + tol_tmp)) { + r = 1; + } + } + + return r; + } + + void LSQFromQR(const ::coder::array &A, const ::coder::array< + real_T, 1U> &tau, const ::coder::array &jpvt, :: + coder::array &B, int32_T rankA, ::coder::array< + real_T, 2U> &Y) + { + int32_T b_i; + int32_T i; + int32_T k; + int32_T nb; + nb = B.size(1); + Y.set_size(A.size(1), B.size(1)); + i = B.size(1); + for (b_i = 0; b_i < i; b_i++) { + k = A.size(1); + for (int32_T j{0}; j < k; j++) { + Y[j] = 0.0; + } + } + + lapack::xunormqr(A, B, tau); + for (k = 0; k < nb; k++) { + for (i = 0; i < rankA; i++) { + Y[jpvt[i] - 1] = B[i]; + } + + for (int32_T j{rankA}; j >= 1; j--) { + b_i = jpvt[j - 1]; + Y[b_i - 1] = Y[b_i - 1] / A[(j + A.size(0) * (j - 1)) - 1]; + for (i = 0; i <= j - 2; i++) { + Y[jpvt[i] - 1] = Y[jpvt[i] - 1] - Y[jpvt[j - 1] - 1] * A[i + + A.size(0) * (j - 1)]; + } + } + } + } + + void qrsolve(const ::coder::array &A, const ::coder::array< + real_T, 2U> &B, ::coder::array &Y) + { + ::coder::array b_B; + ::coder::array b_A; + real_T tau_data; + int32_T jpvt; + int32_T loop_ub; + b_A.set_size(A.size(0)); + loop_ub = A.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + b_A[i] = A[i]; + } + + reflapack::xzgeqp3(b_A, A.size(0), (real_T *)&tau_data, &loop_ub, &jpvt); + b_B.set_size(B.size(0), B.size(1)); + loop_ub = B.size(1) - 1; + for (int32_T i{0}; i <= loop_ub; i++) { + jpvt = B.size(0) - 1; + for (int32_T i1{0}; i1 <= jpvt; i1++) { + b_B[i1 + b_B.size(0) * i] = B[i1 + B.size(0) * i]; + } + } + + LSQFromQR(b_A, (const real_T *)&tau_data, b_B, rankFromQR(b_A), Y); + } + + int32_T rankFromQR(const ::coder::array &A) + { + int32_T maxmn; + int32_T minmn; + int32_T r; + r = 0; + if (A.size(0) < A.size(1)) { + minmn = A.size(0); + maxmn = A.size(1); + } else { + minmn = A.size(1); + maxmn = A.size(0); + } + + if (minmn > 0) { + real_T tol; + tol = std::fmin(1.4901161193847656E-8, 2.2204460492503131E-15 * + static_cast(maxmn)) * std::abs(A[0]); + while ((r < minmn) && (!(std::abs(A[r + A.size(0) * r]) <= tol))) { + r++; + } + } + + return r; + } + } + } +} + +// End of code generation (qrsolve.cpp) diff --git a/cpp/RAT/qrsolve.h b/cpp/RAT/qrsolve.h new file mode 100644 index 00000000..028a3643 --- /dev/null +++ b/cpp/RAT/qrsolve.h @@ -0,0 +1,39 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// qrsolve.h +// +// Code generation for function 'qrsolve' +// +#ifndef QRSOLVE_H +#define QRSOLVE_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + void LSQFromQR(const ::coder::array &A, const ::coder::array< + real_T, 1U> &tau, const ::coder::array &jpvt, :: + coder::array &B, int32_T rankA, ::coder::array< + real_T, 2U> &Y); + void qrsolve(const ::coder::array &A, const ::coder::array< + real_T, 2U> &B, ::coder::array &Y); + int32_T rankFromQR(const ::coder::array &A); + } + } +} + +#endif + +// End of code generation (qrsolve.h) diff --git a/cpp/RAT/rand.cpp b/cpp/RAT/rand.cpp new file mode 100644 index 00000000..6c5d8df5 --- /dev/null +++ b/cpp/RAT/rand.cpp @@ -0,0 +1,383 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// rand.cpp +// +// Code generation for function 'rand' +// + +// Include files +#include "rand.h" +#include "RATMain_data.h" +#include "eml_rand_mt19937ar.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + void b_rand(real_T r[4]) + { + real_T b_r; + uint32_T u[2]; + + // ========================= COPYRIGHT NOTICE ============================ + // This is a uniform (0,1) pseudorandom number generator based on: + // + // A C-program for MT19937, with initialization improved 2002/1/26. + // Coded by Takuji Nishimura and Makoto Matsumoto. + // + // Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + // All rights reserved. + // + // Redistribution and use in source and binary forms, with or without + // modification, are permitted provided that the following conditions + // are met: + // + // 1. Redistributions of source code must retain the above copyright + // notice, this list of conditions and the following disclaimer. + // + // 2. Redistributions in binary form must reproduce the above copyright + // notice, this list of conditions and the following disclaimer + // in the documentation and/or other materials provided with the + // distribution. + // + // 3. The names of its contributors may not be used to endorse or + // promote products derived from this software without specific + // prior written permission. + // + // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + // + // ============================= END ================================= + do { + genrand_uint32_vector(state, u); + u[0] >>= 5U; + u[1] >>= 6U; + b_r = 1.1102230246251565E-16 * (static_cast(u[0]) * 6.7108864E+7 + + static_cast(u[1])); + } while (b_r == 0.0); + + r[0] = b_r; + + // ========================= COPYRIGHT NOTICE ============================ + // This is a uniform (0,1) pseudorandom number generator based on: + // + // A C-program for MT19937, with initialization improved 2002/1/26. + // Coded by Takuji Nishimura and Makoto Matsumoto. + // + // Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + // All rights reserved. + // + // Redistribution and use in source and binary forms, with or without + // modification, are permitted provided that the following conditions + // are met: + // + // 1. Redistributions of source code must retain the above copyright + // notice, this list of conditions and the following disclaimer. + // + // 2. Redistributions in binary form must reproduce the above copyright + // notice, this list of conditions and the following disclaimer + // in the documentation and/or other materials provided with the + // distribution. + // + // 3. The names of its contributors may not be used to endorse or + // promote products derived from this software without specific + // prior written permission. + // + // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + // + // ============================= END ================================= + do { + genrand_uint32_vector(state, u); + u[0] >>= 5U; + u[1] >>= 6U; + b_r = 1.1102230246251565E-16 * (static_cast(u[0]) * 6.7108864E+7 + + static_cast(u[1])); + } while (b_r == 0.0); + + r[1] = b_r; + + // ========================= COPYRIGHT NOTICE ============================ + // This is a uniform (0,1) pseudorandom number generator based on: + // + // A C-program for MT19937, with initialization improved 2002/1/26. + // Coded by Takuji Nishimura and Makoto Matsumoto. + // + // Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + // All rights reserved. + // + // Redistribution and use in source and binary forms, with or without + // modification, are permitted provided that the following conditions + // are met: + // + // 1. Redistributions of source code must retain the above copyright + // notice, this list of conditions and the following disclaimer. + // + // 2. Redistributions in binary form must reproduce the above copyright + // notice, this list of conditions and the following disclaimer + // in the documentation and/or other materials provided with the + // distribution. + // + // 3. The names of its contributors may not be used to endorse or + // promote products derived from this software without specific + // prior written permission. + // + // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + // + // ============================= END ================================= + do { + genrand_uint32_vector(state, u); + u[0] >>= 5U; + u[1] >>= 6U; + b_r = 1.1102230246251565E-16 * (static_cast(u[0]) * 6.7108864E+7 + + static_cast(u[1])); + } while (b_r == 0.0); + + r[2] = b_r; + + // ========================= COPYRIGHT NOTICE ============================ + // This is a uniform (0,1) pseudorandom number generator based on: + // + // A C-program for MT19937, with initialization improved 2002/1/26. + // Coded by Takuji Nishimura and Makoto Matsumoto. + // + // Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + // All rights reserved. + // + // Redistribution and use in source and binary forms, with or without + // modification, are permitted provided that the following conditions + // are met: + // + // 1. Redistributions of source code must retain the above copyright + // notice, this list of conditions and the following disclaimer. + // + // 2. Redistributions in binary form must reproduce the above copyright + // notice, this list of conditions and the following disclaimer + // in the documentation and/or other materials provided with the + // distribution. + // + // 3. The names of its contributors may not be used to endorse or + // promote products derived from this software without specific + // prior written permission. + // + // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + // + // ============================= END ================================= + do { + genrand_uint32_vector(state, u); + u[0] >>= 5U; + u[1] >>= 6U; + b_r = 1.1102230246251565E-16 * (static_cast(u[0]) * 6.7108864E+7 + + static_cast(u[1])); + } while (b_r == 0.0); + + r[3] = b_r; + } + + real_T b_rand() + { + real_T r; + + // ========================= COPYRIGHT NOTICE ============================ + // This is a uniform (0,1) pseudorandom number generator based on: + // + // A C-program for MT19937, with initialization improved 2002/1/26. + // Coded by Takuji Nishimura and Makoto Matsumoto. + // + // Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + // All rights reserved. + // + // Redistribution and use in source and binary forms, with or without + // modification, are permitted provided that the following conditions + // are met: + // + // 1. Redistributions of source code must retain the above copyright + // notice, this list of conditions and the following disclaimer. + // + // 2. Redistributions in binary form must reproduce the above copyright + // notice, this list of conditions and the following disclaimer + // in the documentation and/or other materials provided with the + // distribution. + // + // 3. The names of its contributors may not be used to endorse or + // promote products derived from this software without specific + // prior written permission. + // + // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + // + // ============================= END ================================= + uint32_T u[2]; + do { + genrand_uint32_vector(state, u); + u[0] >>= 5U; + u[1] >>= 6U; + r = 1.1102230246251565E-16 * (static_cast(u[0]) * 6.7108864E+7 + + static_cast(u[1])); + } while (r == 0.0); + + return r; + } + + void b_rand(real_T varargin_1, real_T varargin_2, ::coder::array + &r) + { + int32_T i; + r.set_size(static_cast(varargin_1), static_cast + (varargin_2)); + i = static_cast(varargin_1) * static_cast(varargin_2); + for (int32_T k{0}; k < i; k++) { + r[k] = eml_rand_mt19937ar(state); + } + } + + void b_rand(const real_T varargin_1[2], ::coder::array &r) + { + int32_T i; + i = static_cast(varargin_1[0]); + r.set_size(i); + for (int32_T k{0}; k < i; k++) { + r[k] = eml_rand_mt19937ar(state); + } + } + + void b_rand(real_T varargin_1, ::coder::array &r) + { + int32_T i; + i = static_cast(varargin_1); + r.set_size(i); + for (int32_T k{0}; k < i; k++) { + r[k] = eml_rand_mt19937ar(state); + } + } + + void b_rand(int32_T varargin_1, ::coder::array &r) + { + r.set_size(varargin_1); + for (int32_T k{0}; k < varargin_1; k++) { + r[k] = eml_rand_mt19937ar(state); + } + } + + void b_rand(real_T varargin_2, ::coder::array &r) + { + int32_T i; + i = static_cast(varargin_2); + r.set_size(1, i); + for (int32_T k{0}; k < i; k++) { + r[k] = eml_rand_mt19937ar(state); + } + } + + void c_rand(real_T r[1000]) + { + for (int32_T k{0}; k < 1000; k++) { + real_T b_r; + + // ========================= COPYRIGHT NOTICE ============================ + // This is a uniform (0,1) pseudorandom number generator based on: + // + // A C-program for MT19937, with initialization improved 2002/1/26. + // Coded by Takuji Nishimura and Makoto Matsumoto. + // + // Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + // All rights reserved. + // + // Redistribution and use in source and binary forms, with or without + // modification, are permitted provided that the following conditions + // are met: + // + // 1. Redistributions of source code must retain the above copyright + // notice, this list of conditions and the following disclaimer. + // + // 2. Redistributions in binary form must reproduce the above copyright + // notice, this list of conditions and the following disclaimer + // in the documentation and/or other materials provided with the + // distribution. + // + // 3. The names of its contributors may not be used to endorse or + // promote products derived from this software without specific + // prior written permission. + // + // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + // + // ============================= END ================================= + uint32_T u[2]; + do { + genrand_uint32_vector(state, u); + u[0] >>= 5U; + u[1] >>= 6U; + b_r = 1.1102230246251565E-16 * (static_cast(u[0]) * + 6.7108864E+7 + static_cast(u[1])); + } while (b_r == 0.0); + + r[k] = b_r; + } + } + } +} + +// End of code generation (rand.cpp) diff --git a/cpp/RAT/rand.h b/cpp/RAT/rand.h new file mode 100644 index 00000000..220270c1 --- /dev/null +++ b/cpp/RAT/rand.h @@ -0,0 +1,38 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// rand.h +// +// Code generation for function 'rand' +// +#ifndef RAND_H +#define RAND_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void b_rand(real_T r[4]); + real_T b_rand(); + void b_rand(real_T varargin_1, real_T varargin_2, ::coder::array + &r); + void b_rand(const real_T varargin_1[2], ::coder::array &r); + void b_rand(real_T varargin_1, ::coder::array &r); + void b_rand(int32_T varargin_1, ::coder::array &r); + void b_rand(real_T varargin_2, ::coder::array &r); + void c_rand(real_T r[1000]); + } +} + +#endif + +// End of code generation (rand.h) diff --git a/cpp/RAT/randn.cpp b/cpp/RAT/randn.cpp new file mode 100644 index 00000000..0fef26b7 --- /dev/null +++ b/cpp/RAT/randn.cpp @@ -0,0 +1,132 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// randn.cpp +// +// Code generation for function 'randn' +// + +// Include files +#include "randn.h" +#include "RATMain_data.h" +#include "eml_rand_mt19937ar.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + void randn(real_T varargin_2, ::coder::array &r) + { + int32_T i; + i = static_cast(varargin_2); + r.set_size(1, i); + for (int32_T k{0}; k < i; k++) { + r[k] = b_eml_rand_mt19937ar(state); + } + } + + void randn(real_T varargin_1, ::coder::array &r) + { + int32_T i; + i = static_cast(varargin_1); + r.set_size(i); + for (int32_T k{0}; k < i; k++) { + r[k] = b_eml_rand_mt19937ar(state); + } + } + + void randn(real_T r[2]) + { + real_T b_r; + real_T u; + real_T x; + int32_T exitg1; + int32_T i; + uint32_T u32[2]; + do { + exitg1 = 0; + genrand_uint32_vector(state, u32); + i = static_cast((u32[1] >> 24U) + 1U); + b_r = ((static_cast(u32[0] >> 3U) * 1.6777216E+7 + + static_cast(static_cast(u32[1]) & 16777215)) * + 2.2204460492503131E-16 - 1.0) * dv[i]; + if (std::abs(b_r) <= dv[i - 1]) { + exitg1 = 1; + } else if (i < 256) { + u = eml_rand_mt19937ar(state); + if (dv1[i] + u * (dv1[i - 1] - dv1[i]) < std::exp(-0.5 * b_r * b_r)) { + exitg1 = 1; + } + } else { + do { + u = eml_rand_mt19937ar(state); + x = std::log(u) * 0.273661237329758; + u = eml_rand_mt19937ar(state); + } while (!(-2.0 * std::log(u) > x * x)); + + if (b_r < 0.0) { + b_r = x - 3.65415288536101; + } else { + b_r = 3.65415288536101 - x; + } + + exitg1 = 1; + } + } while (exitg1 == 0); + + r[0] = b_r; + do { + exitg1 = 0; + genrand_uint32_vector(state, u32); + i = static_cast((u32[1] >> 24U) + 1U); + b_r = ((static_cast(u32[0] >> 3U) * 1.6777216E+7 + + static_cast(static_cast(u32[1]) & 16777215)) * + 2.2204460492503131E-16 - 1.0) * dv[i]; + if (std::abs(b_r) <= dv[i - 1]) { + exitg1 = 1; + } else if (i < 256) { + u = eml_rand_mt19937ar(state); + if (dv1[i] + u * (dv1[i - 1] - dv1[i]) < std::exp(-0.5 * b_r * b_r)) { + exitg1 = 1; + } + } else { + do { + u = eml_rand_mt19937ar(state); + x = std::log(u) * 0.273661237329758; + u = eml_rand_mt19937ar(state); + } while (!(-2.0 * std::log(u) > x * x)); + + if (b_r < 0.0) { + b_r = x - 3.65415288536101; + } else { + b_r = 3.65415288536101 - x; + } + + exitg1 = 1; + } + } while (exitg1 == 0); + + r[1] = b_r; + } + + void randn(real_T varargin_1, real_T varargin_2, ::coder::array + &r) + { + int32_T i; + r.set_size(static_cast(varargin_1), static_cast + (varargin_2)); + i = static_cast(varargin_1) * static_cast(varargin_2); + for (int32_T k{0}; k < i; k++) { + r[k] = b_eml_rand_mt19937ar(state); + } + } + } +} + +// End of code generation (randn.cpp) diff --git a/cpp/RAT/randn.h b/cpp/RAT/randn.h new file mode 100644 index 00000000..cf81a7bb --- /dev/null +++ b/cpp/RAT/randn.h @@ -0,0 +1,34 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// randn.h +// +// Code generation for function 'randn' +// +#ifndef RANDN_H +#define RANDN_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void randn(real_T varargin_2, ::coder::array &r); + void randn(real_T varargin_1, ::coder::array &r); + void randn(real_T r[2]); + void randn(real_T varargin_1, real_T varargin_2, ::coder::array + &r); + } +} + +#endif + +// End of code generation (randn.h) diff --git a/cpp/RAT/randperm.cpp b/cpp/RAT/randperm.cpp new file mode 100644 index 00000000..ca838e2a --- /dev/null +++ b/cpp/RAT/randperm.cpp @@ -0,0 +1,38 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// randperm.cpp +// +// Code generation for function 'randperm' +// + +// Include files +#include "randperm.h" +#include "rand.h" +#include "rt_nonfinite.h" +#include "sortIdx.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + void randperm(real_T n, ::coder::array &p) + { + ::coder::array idx; + int32_T p_idx_1; + b_rand(n, p); + internal::sortIdx(p, idx); + p_idx_1 = p.size(1); + p.set_size(1, p_idx_1); + for (int32_T i{0}; i < p_idx_1; i++) { + p[i] = idx[i]; + } + } + } +} + +// End of code generation (randperm.cpp) diff --git a/cpp/RAT/randperm.h b/cpp/RAT/randperm.h new file mode 100644 index 00000000..2865100d --- /dev/null +++ b/cpp/RAT/randperm.h @@ -0,0 +1,30 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// randperm.h +// +// Code generation for function 'randperm' +// +#ifndef RANDPERM_H +#define RANDPERM_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void randperm(real_T n, ::coder::array &p); + } +} + +#endif + +// End of code generation (randperm.h) diff --git a/cpp/RAT/randsample.cpp b/cpp/RAT/randsample.cpp new file mode 100644 index 00000000..b23e53a1 --- /dev/null +++ b/cpp/RAT/randsample.cpp @@ -0,0 +1,82 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// randsample.cpp +// +// Code generation for function 'randsample' +// + +// Include files +#include "randsample.h" +#include "histc.h" +#include "rand.h" +#include "rt_nonfinite.h" +#include "sum.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + void randsample(real_T varargin_2, const real_T varargin_4[2], ::coder:: + array &y) + { + ::coder::array idx; + ::coder::array r; + real_T a__1[3]; + real_T edges[3]; + real_T x; + x = std::floor(varargin_2); + edges[0] = 0.0; + edges[2] = 1.0; + edges[1] = std::fmin(varargin_4[0] / (varargin_4[0] + varargin_4[1]), 1.0); + y.set_size(1, static_cast(x)); + if (static_cast(x) > 0) { + int32_T y_idx_1; + b_rand(static_cast(x), r); + histc(r, edges, a__1, idx); + y_idx_1 = static_cast(x); + y.set_size(1, static_cast(x)); + for (int32_T i{0}; i < y_idx_1; i++) { + y[i] = static_cast(static_cast(idx[i]) - 1); + } + } + } + + void randsample(const real_T varargin_1_data[], real_T varargin_2, const + real_T varargin_4_data[], ::coder::array &y) + { + ::coder::array b_varargin_4_data; + ::coder::array idx; + ::coder::array r; + real_T a__1_data[4]; + real_T edges_data[4]; + real_T sumw; + real_T x; + int32_T a__1_size; + x = std::floor(varargin_2); + b_varargin_4_data.set((real_T *)&varargin_4_data[0], 3); + sumw = sum(b_varargin_4_data); + edges_data[0] = 0.0; + edges_data[3] = 1.0; + edges_data[1] = std::fmin(varargin_4_data[0] / sumw, 1.0); + edges_data[2] = std::fmin(edges_data[1] + varargin_4_data[1] / sumw, 1.0); + y.set_size(1, static_cast(x)); + if (static_cast(x) > 0) { + b_rand(static_cast(x), r); + histc(r, edges_data, a__1_data, &a__1_size, idx); + a__1_size = static_cast(x); + y.set_size(1, static_cast(x)); + for (int32_T i{0}; i < a__1_size; i++) { + y[i] = varargin_1_data[static_cast(idx[i]) - 1]; + } + } + } + } +} + +// End of code generation (randsample.cpp) diff --git a/cpp/RAT/randsample.h b/cpp/RAT/randsample.h new file mode 100644 index 00000000..986ed1a2 --- /dev/null +++ b/cpp/RAT/randsample.h @@ -0,0 +1,33 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// randsample.h +// +// Code generation for function 'randsample' +// +#ifndef RANDSAMPLE_H +#define RANDSAMPLE_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void randsample(real_T varargin_2, const real_T varargin_4[2], ::coder:: + array &y); + void randsample(const real_T varargin_1_data[], real_T varargin_2, const + real_T varargin_4_data[], ::coder::array &y); + } +} + +#endif + +// End of code generation (randsample.h) diff --git a/cpp/RAT/ratDREAM.cpp b/cpp/RAT/ratDREAM.cpp new file mode 100644 index 00000000..f7a9d4bb --- /dev/null +++ b/cpp/RAT/ratDREAM.cpp @@ -0,0 +1,820 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// ratDREAM.cpp +// +// Code generation for function 'ratDREAM' +// + +// Include files +#include "ratDREAM.h" +#include "RATMain_data.h" +#include "RATMain_internal_types.h" +#include "RATMain_rtwutil.h" +#include "RATMain_types.h" +#include "adaptPCR.h" +#include "blockedSummation.h" +#include "calcDensity.h" +#include "calcProposal.h" +#include "combineVectorElements.h" +#include "drawCR.h" +#include "evaluateModel.h" +#include "fileManager.h" +#include "find.h" +#include "gelman.h" +#include "initializeDREAM.h" +#include "metropolisRule.h" +#include "mod.h" +#include "removeOutlier.h" +#include "repmat.h" +#include "rt_nonfinite.h" +#include "setupDREAM.h" +#include "std.h" +#include "sum.h" +#include "textProgressBar.h" +#include "tic.h" +#include "toc.h" +#include "unsafeSxfun.h" +#include "coder_array.h" +#include "coder_bounded_array.h" +#include +#include +#include + +// Type Definitions +namespace RAT +{ + struct h_struct_T + { + char_T prior[7]; + ::coder::array min; + ::coder::array max; + ::coder::bounded_array boundhandling; + boolean_T mvnpdf; + }; +} + +// Function Definitions +namespace RAT +{ + void ratDREAM(real_T dreamVariables_d, real_T dreamVariables_N, real_T + dreamVariables_T, real_T dreamVariables_lambda, real_T + dreamVariables_pUnitGamma, boolean_T dreamVariables_adaptPCR, + const ::coder::array &Par_info_min, const ::coder:: + array &Par_info_max, const char_T + Par_info_boundhandling_data[], const int32_T + Par_info_boundhandling_size[2], const c_struct_T + *ratInputs_problemStruct, const cell_11 *ratInputs_problemCells, + const struct2_T *ratInputs_controls, const ::coder::array &ratInputs_priors, ::coder::array &chain, + struct12_T *output, ::coder::array &fx) + { + ::coder::array b_chain; + ::coder::array CR; + ::coder::array Table_gamma; + ::coder::array X; + ::coder::array b_r; + ::coder::array b_xnew; + ::coder::array fx_new; + ::coder::array log_L; + ::coder::array r; + ::coder::array r1; + ::coder::array x; + ::coder::array xnew; + ::coder::array xold; + ::coder::array b_X; + ::coder::array c_X; + ::coder::array delta_normX; + ::coder::array idx_ac; + ::coder::array log_L_xnew; + ::coder::array log_PR_xnew; + ::coder::array r2; + ::coder::array accept; + ::coder::array b_CR_data; + h_struct_T Par_info; + struct13_T DREAMPar; + struct14_T Meas_info; + real_T delta_tot_data[3]; + real_T lCR_data[3]; + real_T pCR_data[3]; + real_T totaccept; + int32_T delta_tot_size[2]; + int32_T lCR_size[2]; + int32_T pCR_size[2]; + int32_T gen; + int32_T i; + int32_T iteration; + int32_T loop_ub; + uint32_T iloc; + boolean_T CR_data[100]; + + // Modified version of Vrugt DREAm algorithm to be specific for RAT.... + // ----------------------------------------------------------------------------------------------% + // % + // DDDDDDDDDDDDDDD RRRRRRRRRRRRRR EEEEEEEEEEEEEEEE AAAAA MMM MMM % + // DDDDDDDDDDDDDDDD RRRRRRRRRRRRRRR EEEEEEEEEEEEEEEE AAAAA MMMM MMMM % + // DDD DDD RRR RRR EEE AAA AAA MMMMM MMMMM % + // DDD DDD RRR RRR EEE AAA AAA MMMMMM MMMMMM % + // DDD DDD RRR RRR EEE AAA AAA MMM MMM MMM MMM % + // DDD DDD RRR RRR EEE AAA AAA MMM MMM MMM MMM % + // DDD DDD RRRRRRRRRRRRRRR EEEEEEEEEEEEEEEE AAA AAA MMM MMM MMM MMM % + // DDD DDD RRRRRRRRRRRRRR EEEEEEEEEEEEEEEE AAAAAAAAAAA MMM MMMM MMM % + // DDD DDD RRR RR EEE AAA AAA MMM MMM % + // DDD DDD RRR RRR EEE AAA AAA MMM MMM % + // DDD DDD RRR RRR EEE AAA AAA MMM MMM % + // DDDDDDDDDDDDDDDD RRR RRR EEEEEEEEEEEEEEEE AAA AAA MMM MMM % + // DDDDDDDDDDDDDDD RRR RRR EEEEEEEEEEEEEEEE AAA AAA MMM MMM % + // % + // ----------------------------------------------------------------------------------------------% + // ----------------- DiffeRential Evolution Adaptive Metropolis algorithm -----------------------% + // % + // DREAM runs multiple different chains simultaneously for global exploration, and automatically % + // tunes the scale and orientation of the proposal distribution using differential evolution. % + // The algorithm maintains detailed balance and ergodicity and works well and efficient for a % + // large range of problems, especially in the presence of high-dimensionality and % + // multimodality. % + // % + // DREAM developed by Jasper A. Vrugt and Cajo ter Braak % + // % + // --------------------------------------------------------------------------------------------- % + // % + // SYNOPSIS: [chain,output,fx,log_L] = DREAM(Func_name,DREAMPar) % + // [chain,output,fx,log_L] = DREAM(Func_name,DREAMPar,Par_info) % + // [chain,output,fx,log_L] = DREAM(Func_name,DREAMPar,Par_info,Meas_info) % + // % + // Input: Func_name = name of the function ( = model ) that returns density of proposal % + // DREAMPar = structure with algorithmic / computatinal settings of DREAM % + // Par_info = structure with parameter ranges, prior distribution, boundary handling % + // Meas_info = optional structure with measurements to be evaluated against % + // % + // Output: chain = 3D array with chain trajectories, log-prior and log-likelihood values % + // output = structure with convergence properties, acceptance rate, CR values, etc. % + // fx = matrix with model simulations % + // log_L = matrix with log-likelihood values sampled chains % + // % + // The directory \PostProcessing contains a script "PostProcMCMC" that will compute various % + // posterior statistics (MEAN, STD, MAP, CORR) and create create various plots including, % + // marginal posterior parameter distributions, R_stat convergence diagnostic, two-dimensional % + // correlation plots of the posterior parameter samples, chain convergence plots, and parameter % + // and total posterior simulation uncertainty ranges (interval can be specified) % + // % + // --------------------------------------------------------------------------------------------- % + // % + // This algorithm has been described in: % + // % + // Vrugt, J.A., C.J.F. ter Braak, M.P. Clark, J.M. Hyman, and B.A. Robinson, Treatment of % + // input uncertainty in hydrologic modeling: Doing hydrology backward with Markov chain % + // Monte Carlo simulation, Water Resources Research, 44, W00B09, doi:10.1029/2007WR006720, % + // 2008. % + // % + // Vrugt, J.A., C.J.F. ter Braak, C.G.H. Diks, D. Higdon, B.A. Robinson, and J.M. Hyman, % + // Accelerating Markov chain Monte Carlo simulation by differential evolution with % + // self-adaptive randomized subspace sampling, International Journal of Nonlinear % + // Sciences and Numerical Simulation, 10(3), 271-288, 2009. % + // % + // Vrugt, J.A., C.J.F. ter Braak, H.V. Gupta, and B.A. Robinson, Equifinality of formal % + // (DREAM) and informal (GLUE) Bayesian approaches in hydrologic modeling?, Stochastic % + // Environmental Research and Risk Assessment, 23(7), 1011-1026, % + // doi:10.1007/s00477-008-0274-y, 2009 % + // % + // Laloy, E., and J.A. Vrugt, High-dimensional posterior exploration of hydrologic models % + // using multiple-try DREAM_(ZS) and high-performance computing, Water Resources Research, % + // 48, W01526, doi:10.1029/2011WR010608, 2012. % + // % + // Vrugt, J.A., and M. Sadegh, Toward diagnostic model calibration and evaluation: % + // Approximate Bayesian computation, Water Resources Research, 49, 4335�4345, % + // doi:10.1002/wrcr.20354, 2013. % + // % + // Sadegh, M., and J.A. Vrugt, Approximate Bayesian computation using Markov chain Monte % + // Carlo simulation: DREAM_(ABC), Water Resources Research, doi:10.1002/2014WR015386, % + // 2014. % + // % + // For more information please read: % + // % + // Ter Braak, C.J.F., A Markov Chain Monte Carlo version of the genetic algorithm Differential % + // Evolution: easy Bayesian computing for real parameter spaces, Stat. Comput., 16, % + // 239 - 249, doi:10.1007/s11222-006-8769-1, 2006. % + // % + // Vrugt, J.A., H.V. Gupta, W. Bouten and S. Sorooshian, A Shuffled Complex Evolution % + // Metropolis algorithm for optimization and uncertainty assessment of hydrologic model % + // parameters, Water Resour. Res., 39 (8), 1201, doi:10.1029/2002WR001642, 2003. % + // % + // Ter Braak, C.J.F., and J.A. Vrugt, Differential Evolution Markov Chain with snooker updater % + // and fewer chains, Statistics and Computing, 10.1007/s11222-008-9104-9, 2008. % + // % + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // % + // Copyright (C) 2011-2012 the authors % + // % + // This program is free software: you can modify it under the terms of the GNU General % + // Public License as published by the Free Software Foundation, either version 3 of the % + // License, or (at your option) any later version. % + // % + // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; % + // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. % + // See the GNU General Public License for more details. % + // % + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // % + // MATLAB code written by Jasper A. Vrugt, University of California Irvine, jasper@uci.edu % + // % + // Version 0.5: June 2008 % + // Version 1.0: October 2008 Adaption updated and generalized CR implementation % + // Version 1.1: January 2010 Restart run and new AR-1 likelihood function with model error % + // Version 1.2: August 2010 Generalized likelihood function and prior distribution % + // Version 1.3: September 2010 Explicit treatment of prior distribution % + // Version 1.4: October 2010 Limits of acceptability (GLUE) and few small changes % + // Version 1.5: April 2011 Small maintenance updates -- 2 external executables % + // Version 1.6: August 2011 whittle likelihood function (SPECTRAL ANALYSIS !!) % + // Version 1.7: April 2012 Simplified code (removed variables) + graphical interface % + // Version 1.8: May 2012 Added new option for Approximate Bayesian Computation % + // Version 1.9: June 2012 Simulations stored, new example, and updated likelihood func. % + // Version 2.0: January 2013 Simplification of metrop.m and DREAM.m % + // Version 2.1: September 2013 Added inference of measurement error as new option % + // Version 2.4: May 2014 Parallellization using parfor (done if CPU > 1) % + // % + // --------------------------------------------------------------------------------------------- % + // ------ AVH -- Always will have consistent variable numbers ------- + // Check how many input variables + // if nargin < 4, Meas_info.Y = []; end; + // if isempty(Meas_info), Meas_info.Y = []; end; + // ------------------------------------------------------------------------ + // if ~isfield(dreamVariables,'restart') || ~dreamVariables.restart + // Initialize the main variables used in DREAM + Par_info.min.set_size(1, Par_info_min.size(1)); + loop_ub = Par_info_min.size(1); + for (i = 0; i < loop_ub; i++) { + Par_info.min[i] = Par_info_min[i]; + } + + Par_info.max.set_size(1, Par_info_max.size(1)); + loop_ub = Par_info_max.size(1); + for (i = 0; i < loop_ub; i++) { + Par_info.max[i] = Par_info_max[i]; + } + + Par_info.boundhandling.size[0] = 1; + Par_info.boundhandling.size[1] = Par_info_boundhandling_size[1]; + loop_ub = Par_info_boundhandling_size[1]; + if (loop_ub - 1 >= 0) { + std::copy(&Par_info_boundhandling_data[0], + &Par_info_boundhandling_data[loop_ub], + &Par_info.boundhandling.data[0]); + } + + setupDREAM(dreamVariables_d, dreamVariables_N, dreamVariables_T, + dreamVariables_lambda, dreamVariables_pUnitGamma, + dreamVariables_adaptPCR, &DREAMPar, &Meas_info, chain, output, + log_L, Table_gamma); + iloc = 1U; + iteration = 1; + gen = 1; + + // Check for setup errors + // [stop,fid] = checkDREAM(DREAMPar,Par_info,Meas_info); + // Check for setup errors + // Assign stop to be No + // First close all files + coder::fileManager(); + + // ----------------------REMOVE warning file - AVH + // open an output file with warnings + // fid = fopen('warning_file.txt','w'); + // fprintf(fid,'-------------- DREAM warning file --------------\n'); + // ------------------------------------------------ + // Check number of chains + // Check parameter ranges + // % Check prior distribution + // if ( strcmp(lower(DREAMPar.prior),'yes') ) || ( strcmp(lower(Par_info),'prior') ), + // % Error -- if explicit prior is used --> marginals need to be defined + // if ~isfield(Par_info,'prior_marginal'); + // evalstr = char('DREAM ERROR: Prior chosen but no marginal distribution specified to sample from -> Define Par_info.prior_marginal!!\n'); + // % Now print warning to screen and to file + // fprintf(evalstr); fprintf(fid,evalstr); + // % Stop DREAM + // stop = true; + // end; + // end; + // Check whether we specified measurement sigma correctly + // if ( DREAMPar.lik == 12 || DREAMPar.lik == 13 ) && ( isfield(Meas_info,'Sigma') == 0 ) + // % Error -- Meas_info.Sigma needs to be specified!! + // error('DREAM ERROR: Meas_info.Sigma needs to be specified either as inline function or one or multiple numerical values!!\n'); + // end + // Check whether the length of the user specified sigma is correct + // Return to main program + // if stop; return; end + // Create computing environment (depending whether multi-core is used) + // Sets up sequential / parallel + // global DREAM_dir EXAMPLE_dir; + // Now create the function handle + // Currently using a function handle for RAT - AVH + // if isa(Func_name,'function_handle') + // f_handle = Func_name; + // else + // f_handle = eval(['@(x)',char(Func_name),'(x)']); + // end + // Now check if we want parallel execution of chains or not? + // We use 1 CPU (processor) + DREAMPar.CPU = 1.0; + + // Now print to screen all the settings + // Now check how the measurement sigma is arranged (estimated or defined) + // + // ----------------------------------------- + // We do not have user inputted sigma in this form for the RAT + // implementation - Measurement Error is dealt with downstream in the + // likelihood function. So, we can remove the check for sigma. + // --------------- AVH ------------------------- + // Meas_info = checkSigma(Meas_info); + // Create the initial states of each of the chains (initial population) + initializeDREAM(&DREAMPar, Par_info.min, Par_info.max, + Par_info.boundhandling.data, Par_info.boundhandling.size, + chain, output, log_L, ratInputs_problemStruct, + ratInputs_problemCells, ratInputs_controls, ratInputs_priors, + X, fx, CR, pCR_data, pCR_size, lCR_data, lCR_size, + delta_tot_data, delta_tot_size); + + // elseif DREAMPar.restart + // + // % Print to screen restart run + // disp('Restart run'); + // % If a restart run is being done: just load the output from the previous ongoing trial + // load DREAM.mat; [CR] = drawCR(DREAMPar,pCR); DREAMPar.T = 2 * DREAMPar.T; + // % And make sure we add zeros to "chain" array + // chain = [chain ; nan(size(chain,1)-1,size(chain,2),size(chain,3))]; + // % Open warning file and set T_start + // fid = fopen('warning_file.txt','a+'); T_start = t + 1; + // end + // Initialize waitbar. + // fprintf('\n'); + lastNchar = 0.0; + lastNchar_not_empty = true; + + // h = waitbar(0,'Running DREAM - Please wait...'); + totaccept = 0.0; + coder::tic(); + + // Now start iteration ... + i = static_cast(DREAMPar.T - 1.0); + for (int32_T t{0}; t < i; t++) { + real_T tmp_data[100]; + real_T varargin_1; + int32_T b_loop_ub; + int32_T i1; + int32_T i2; + int32_T input_sizes_idx_1; + int32_T result; + int32_T tmp_size; + int8_T b_input_sizes_idx_1; + int8_T sizes_idx_1; + boolean_T empty_non_axis_sizes; + + // Unoack current state of chain and associated log-likelihood and log-prior values + if (X.size(1) - 2 < 1) { + loop_ub = 0; + } else { + loop_ub = X.size(1) - 2; + } + + xold.set_size(X.size(0), loop_ub); + for (i1 = 0; i1 < loop_ub; i1++) { + b_loop_ub = X.size(0); + for (i2 = 0; i2 < b_loop_ub; i2++) { + xold[i2 + xold.size(0) * i1] = X[i2 + X.size(0) * i1]; + } + } + + // Now generate candidate in each sequence using current point and members of X + loop_ub = CR.size(0); + tmp_size = CR.size(0); + for (i1 = 0; i1 < loop_ub; i1++) { + tmp_data[i1] = CR[i1 + CR.size(0) * gen]; + } + + calcProposal(xold, tmp_data, &DREAMPar, Table_gamma, Par_info.min, + Par_info.max, Par_info.boundhandling.data, + Par_info.boundhandling.size, xnew); + for (i1 = 0; i1 < tmp_size; i1++) { + CR[i1 + CR.size(0) * gen] = tmp_data[i1]; + } + + // Now evaluate the model ( = pdf ) and return fx + evaluateModel(xnew, &DREAMPar, ratInputs_problemStruct, + ratInputs_problemCells, ratInputs_controls, fx_new); + + // Calculate the log-likelihood and log-prior of x (fx) + calcDensity(xnew, fx_new, &DREAMPar, ratInputs_problemStruct->fitLimits, + ratInputs_priors, log_L_xnew, log_PR_xnew); + + // Calculate the Metropolis ratio + tmp_size = X.size(1); + loop_ub = X.size(0); + b_X.set_size(X.size(0)); + c_X.set_size(X.size(0)); + for (i1 = 0; i1 < loop_ub; i1++) { + b_X[i1] = X[i1 + X.size(0) * (tmp_size - 1)]; + c_X[i1] = X[i1 + X.size(0) * (tmp_size - 2)]; + } + + metropolisRule(&DREAMPar, log_L_xnew, log_PR_xnew, b_X, c_X, accept, + idx_ac); + + // And update X and the model simulation + if (DREAMPar.d < 1.0) { + loop_ub = 0; + } else { + loop_ub = static_cast(DREAMPar.d); + } + + if ((idx_ac.size(0) != 0) && (loop_ub != 0)) { + result = idx_ac.size(0); + } else if (idx_ac.size(0) != 0) { + result = idx_ac.size(0); + } else { + result = 0; + } + + empty_non_axis_sizes = (result == 0); + if (empty_non_axis_sizes || ((idx_ac.size(0) != 0) && (loop_ub != 0))) { + input_sizes_idx_1 = loop_ub; + } else { + input_sizes_idx_1 = 0; + } + + if (empty_non_axis_sizes || (idx_ac.size(0) != 0)) { + b_input_sizes_idx_1 = 1; + } else { + b_input_sizes_idx_1 = 0; + } + + if (empty_non_axis_sizes || (idx_ac.size(0) != 0)) { + sizes_idx_1 = 1; + } else { + sizes_idx_1 = 0; + } + + b_xnew.set_size(idx_ac.size(0), loop_ub); + for (i1 = 0; i1 < loop_ub; i1++) { + b_loop_ub = idx_ac.size(0); + for (i2 = 0; i2 < b_loop_ub; i2++) { + b_xnew[i2 + b_xnew.size(0) * i1] = xnew[(static_cast + (idx_ac[i2]) + xnew.size(0) * i1) - 1]; + } + } + + loop_ub = idx_ac.size(0); + c_X.set_size(idx_ac.size(0)); + b_X.set_size(idx_ac.size(0)); + for (i1 = 0; i1 < loop_ub; i1++) { + tmp_size = static_cast(idx_ac[i1]) - 1; + c_X[i1] = log_PR_xnew[tmp_size]; + b_X[i1] = log_L_xnew[tmp_size]; + } + + for (i1 = 0; i1 < input_sizes_idx_1; i1++) { + for (i2 = 0; i2 < result; i2++) { + X[(static_cast(idx_ac[i2]) + X.size(0) * i1) - 1] = b_xnew[i2 + + result * i1]; + } + } + + loop_ub = b_input_sizes_idx_1; + for (i1 = 0; i1 < loop_ub; i1++) { + for (i2 = 0; i2 < result; i2++) { + X[(static_cast(idx_ac[i2]) + X.size(0) * input_sizes_idx_1) - + 1] = c_X[i2]; + } + } + + loop_ub = sizes_idx_1; + for (i1 = 0; i1 < loop_ub; i1++) { + for (i2 = 0; i2 < result; i2++) { + X[(static_cast(idx_ac[i2]) + X.size(0) * (input_sizes_idx_1 + + b_input_sizes_idx_1)) - 1] = b_X[i2]; + } + } + + loop_ub = idx_ac.size(0); + for (i1 = 0; i1 < loop_ub; i1++) { + tmp_size = static_cast(idx_ac[i1]) - 1; + fx[tmp_size] = fx_new[tmp_size]; + } + + // Check whether to add the current points to the chains or not? + if (coder::b_mod(static_cast(t) + 2.0, 1.0) == 0.0) { + // Store the current sample in chain + iloc++; + loop_ub = X.size(0); + b_xnew.set_size(X.size(1), X.size(0)); + for (i1 = 0; i1 < loop_ub; i1++) { + b_loop_ub = X.size(1); + for (i2 = 0; i2 < b_loop_ub; i2++) { + b_xnew[i2 + b_xnew.size(0) * i1] = X[i1 + X.size(0) * i2]; + } + } + + tmp_size = static_cast(DREAMPar.d + 2.0); + loop_ub = static_cast(DREAMPar.N); + for (i1 = 0; i1 < loop_ub; i1++) { + for (i2 = 0; i2 < tmp_size; i2++) { + chain[((static_cast(iloc) + chain.size(0) * i2) + + chain.size(0) * chain.size(1) * i1) - 1] = b_xnew[i2 + + tmp_size * i1]; + } + } + + // kf added 16/10/2015 + // store the distance between the simualted and observed signatures + // Store the model simulations (if appropriate) + // storeDREAMResults(DREAMPar,fx,Meas_info,'a+'); + } + + // Check whether we update the crossover values + if (DREAMPar.adaptPCR) { + // Calculate the standard deviation of each dimension of X + if (DREAMPar.N < 1.0) { + loop_ub = 0; + } else { + loop_ub = static_cast(DREAMPar.N); + } + + if (DREAMPar.d < 1.0) { + b_loop_ub = 0; + } else { + b_loop_ub = static_cast(DREAMPar.d); + } + + b_xnew.set_size(loop_ub, b_loop_ub); + for (i1 = 0; i1 < b_loop_ub; i1++) { + for (i2 = 0; i2 < loop_ub; i2++) { + b_xnew[i2 + b_xnew.size(0) * i1] = X[i2 + X.size(0) * i1]; + } + } + + coder::b_std(b_xnew, r); + coder::repmat(r, DREAMPar.N, b_r); + + // Compute the Euclidean distance between new X and old X + if (xold.size(0) < 1) { + loop_ub = 0; + } else { + loop_ub = xold.size(0); + } + + if (DREAMPar.d < 1.0) { + b_loop_ub = 0; + } else { + b_loop_ub = static_cast(DREAMPar.d); + } + + if (X.size(0) < 1) { + i1 = 0; + } else { + i1 = X.size(0); + } + + if (DREAMPar.d < 1.0) { + i2 = 0; + } else { + i2 = static_cast(DREAMPar.d); + } + + if (loop_ub == 1) { + tmp_size = i1; + } else { + tmp_size = loop_ub; + } + + if (b_loop_ub == 1) { + result = i2; + } else { + result = b_loop_ub; + } + + if ((loop_ub == i1) && (b_loop_ub == i2) && (tmp_size == b_r.size(0)) && + (result == b_r.size(1))) { + x.set_size(loop_ub, b_loop_ub); + for (i1 = 0; i1 < b_loop_ub; i1++) { + for (i2 = 0; i2 < loop_ub; i2++) { + varargin_1 = (xold[i2 + xold.size(0) * i1] - X[i2 + X.size(0) * i1]) + / b_r[i2 + b_r.size(0) * i1]; + x[i2 + x.size(0) * i1] = rt_powd_snf(varargin_1, 2.0); + } + } + } else { + binary_expand_op(x, xold, loop_ub - 1, b_loop_ub - 1, X, i1 - 1, i2 - + 1, b_r); + } + + // Use this information to update sum_p2 to update N_CR + if (DREAMPar.N < 1.0) { + loop_ub = 0; + } else { + loop_ub = static_cast(DREAMPar.N); + } + + coder::blockedSummation(x, x.size(1), b_X); + + // Calculate total normalized Euclidean distance for each crossover value + // Derive sum_p2 for each different CR value + for (int32_T j{0}; j < 3; j++) { + // Find which chains are updated with j/DREAMPar.nCR + // Add the normalized squared distance tot the current delta_tot; + varargin_1 = (static_cast(j) + 1.0) / 3.0; + for (i1 = 0; i1 < loop_ub; i1++) { + CR_data[i1] = (CR[i1 + CR.size(0) * gen] == varargin_1); + } + + b_CR_data.set(&CR_data[0], loop_ub); + coder::eml_find(b_CR_data, r2); + delta_normX.set_size(r2.size(0)); + b_loop_ub = r2.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + delta_normX[i1] = b_X[r2[i1] - 1]; + } + + delta_tot_data[j] += coder::sum(delta_normX); + } + } + + // Update gen + gen++; + + // How many candidate points have been accepted -- to calculate acceptance rate + totaccept += static_cast(coder::c_combineVectorElements(accept)); + + // Update log_L + if (DREAMPar.N < 1.0) { + loop_ub = 0; + } else { + loop_ub = static_cast(DREAMPar.N); + } + + varargin_1 = (static_cast(t) + 2.0) * DREAMPar.N; + log_L[t + 1] = varargin_1; + for (i1 = 0; i1 < loop_ub; i1++) { + log_L[(t + log_L.size(0) * (i1 + 1)) + 1] = X[i1 + X.size(0) * ( + static_cast(DREAMPar.d + 2.0) - 1)]; + } + + // Update the waitbar. TJP Edit to check for graphical enviro + // waitbar(t/DREAMPar.T,h); + textProgressBar((static_cast(t) + 2.0) / DREAMPar.T); + + // If t equal to MCMC.steps then convergence checks and updates + if (coder::b_mod(static_cast(t) + 2.0, DREAMPar.steps) == 0.0) { + int32_T start_idx; + + // Save some important output -- Acceptance Rate + output->AR.data[iteration] = varargin_1; + output->AR.data[iteration + output->AR.size[0]] = 100.0 * totaccept / + (DREAMPar.N * DREAMPar.steps); + + // Check whether to update individual pCR values + if (static_cast(t) + 2.0 <= DREAMPar.T / 10.0) { + if (DREAMPar.adaptPCR) { + real_T b_lCR_data[3]; + + // Update pCR values + for (i1 = 0; i1 < 3; i1++) { + b_lCR_data[i1] = lCR_data[i1]; + } + + adaptPCR(&DREAMPar, CR, delta_tot_data, b_lCR_data, pCR_data, + pCR_size, lCR_data, lCR_size); + } + } else { + // See whether there are any outlier chains, and remove them to current best value of X + if (DREAMPar.N + 1.0 < 2.0) { + i1 = 0; + i2 = 0; + } else { + i1 = 1; + i2 = static_cast(DREAMPar.N + 1.0); + } + + loop_ub = i2 - i1; + x.set_size(t + 2, loop_ub); + for (i2 = 0; i2 < loop_ub; i2++) { + for (result = 0; result <= t + 1; result++) { + x[result + x.size(0) * i2] = log_L[result + log_L.size(0) * (i1 + + i2)]; + } + } + + removeOutlier(X, x, output->outlier.data, output->outlier.size, + &DREAMPar, r1); + output->outlier.size[0] = r1.size(0); + output->outlier.size[1] = r1.size(1); + loop_ub = r1.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + b_loop_ub = r1.size(0); + for (i2 = 0; i2 < b_loop_ub; i2++) { + output->outlier.data[i2 + output->outlier.size[0] * i1] = r1[i2 + + r1.size(0) * i1]; + } + } + + i1 = !(DREAMPar.N + 1.0 < 2.0); + loop_ub = x.size(1); + for (i2 = 0; i2 < loop_ub; i2++) { + b_loop_ub = x.size(0); + for (result = 0; result < b_loop_ub; result++) { + log_L[result + log_L.size(0) * (i1 + i2)] = x[result + x.size(0) * + i2]; + } + } + } + + // Store diagnostic information -- Probability of individual crossover values + output->CR[iteration] = varargin_1; + output->CR[iteration + output->CR.size(0)] = pCR_data[0]; + output->CR[iteration + output->CR.size(0) * 2] = pCR_data[1]; + output->CR[iteration + output->CR.size(0) * 3] = pCR_data[2]; + + // Generate new crossover values + drawCR(&DREAMPar, pCR_data, pCR_size, CR); + + // Calculate Gelman and Rubin Convergence Diagnostic + start_idx = static_cast(std::fmax(1.0, std::floor + (static_cast(iloc) / 2.0))); + + // Compute the R-statistic using 50% burn-in from chain + if (start_idx > static_cast(iloc)) { + i1 = 0; + i2 = 0; + } else { + i1 = start_idx - 1; + i2 = static_cast(iloc); + } + + if (DREAMPar.d < 1.0) { + loop_ub = 0; + } else { + loop_ub = static_cast(DREAMPar.d); + } + + if (DREAMPar.N < 1.0) { + b_loop_ub = 0; + } else { + b_loop_ub = static_cast(DREAMPar.N); + } + + tmp_size = i2 - i1; + b_chain.set_size(tmp_size, loop_ub, b_loop_ub); + for (i2 = 0; i2 < b_loop_ub; i2++) { + for (result = 0; result < loop_ub; result++) { + for (input_sizes_idx_1 = 0; input_sizes_idx_1 < tmp_size; + input_sizes_idx_1++) { + b_chain[(input_sizes_idx_1 + b_chain.size(0) * result) + + b_chain.size(0) * b_chain.size(1) * i2] = chain[((i1 + + input_sizes_idx_1) + chain.size(0) * result) + chain.size(0) * + chain.size(1) * i2]; + } + } + } + + gelman(b_chain, &DREAMPar, r); + output->R_stat[iteration] = varargin_1; + loop_ub = r.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + output->R_stat[iteration + output->R_stat.size(0) * (i1 + 1)] = r[i1]; + } + + // Update the iteration, set gen back to 1 and totaccept to zero + iteration++; + gen = 0; + totaccept = 0.0; + + // Save the output or not? + // if DREAMPar.save + // + // % Store in memory + // save DREAM.mat + // end + } + } + + // ------------------------------------------------------------------------- + // Determine total run time + output->RunTime = coder::toc(); + + // Variables have been pre-allocated --> need to remove zeros at end + // [chain,output,fx] = DREAMEnd(DREAMPar,Meas_info,chain,output,iteration,iloc); + // Place everything in output to do diagnostics later (outside C++) + output->DREAMPar = DREAMPar; + output->Meas_info = Meas_info; + output->iteration = iteration + 1; + output->iloc = iloc; + + // Close the waitbar + printf("\n"); + fflush(stdout); + + // close(h); + } +} + +// End of code generation (ratDREAM.cpp) diff --git a/cpp/RAT/ratDREAM.h b/cpp/RAT/ratDREAM.h new file mode 100644 index 00000000..43cbc38f --- /dev/null +++ b/cpp/RAT/ratDREAM.h @@ -0,0 +1,46 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// ratDREAM.h +// +// Code generation for function 'ratDREAM' +// +#ifndef RATDREAM_H +#define RATDREAM_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct c_struct_T; + struct cell_11; + struct struct2_T; + struct struct12_T; +} + +// Function Declarations +namespace RAT +{ + void ratDREAM(real_T dreamVariables_d, real_T dreamVariables_N, real_T + dreamVariables_T, real_T dreamVariables_lambda, real_T + dreamVariables_pUnitGamma, boolean_T dreamVariables_adaptPCR, + const ::coder::array &Par_info_min, const ::coder:: + array &Par_info_max, const char_T + Par_info_boundhandling_data[], const int32_T + Par_info_boundhandling_size[2], const c_struct_T + *ratInputs_problemStruct, const cell_11 *ratInputs_problemCells, + const struct2_T *ratInputs_controls, const ::coder::array &ratInputs_priors, ::coder::array &chain, + struct12_T *output, ::coder::array &fx); +} + +#endif + +// End of code generation (ratDREAM.h) diff --git a/cpp/RAT/rcond.cpp b/cpp/RAT/rcond.cpp new file mode 100644 index 00000000..b94d2d9d --- /dev/null +++ b/cpp/RAT/rcond.cpp @@ -0,0 +1,239 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// rcond.cpp +// +// Code generation for function 'rcond' +// + +// Include files +#include "rcond.h" +#include "norm.h" +#include "rt_nonfinite.h" +#include "vAllOrAny.h" +#include "xgetrf.h" +#include "xtrsv.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + real_T rcond(const ::coder::array &A) + { + ::coder::array b_A; + ::coder::array x; + real_T result; + int32_T n; + n = A.size(0); + result = 0.0; + if (n == 0) { + result = rtInf; + } else if (n == 1) { + real_T temp; + temp = std::abs(A[0]); + if (!std::isinf(temp)) { + if (std::isnan(temp)) { + result = rtNaN; + } else if (temp != 0.0) { + result = 1.0; + } + } + } else { + real_T normA; + normA = b_norm(A); + if (!(normA == 0.0)) { + int32_T i; + int32_T jlast; + int32_T jump; + int32_T kase; + b_A.set_size(A.size(0), A.size(1)); + kase = A.size(1); + for (i = 0; i < kase; i++) { + jump = A.size(0); + for (jlast = 0; jlast < jump; jlast++) { + b_A[jlast + b_A.size(0) * i] = A[jlast + A.size(0) * i]; + } + } + + internal::lapack::xgetrf(n, n, b_A, n); + kase = n; + int32_T exitg1; + do { + exitg1 = 0; + if (kase > 0) { + if (b_A[(kase + b_A.size(0) * (kase - 1)) - 1] == 0.0) { + exitg1 = 1; + } else { + kase--; + } + } else { + real_T ainvnm; + int32_T iter; + int32_T j; + ainvnm = 0.0; + iter = 2; + kase = 1; + jump = 1; + j = 0; + x.set_size(n); + for (i = 0; i < n; i++) { + x[i] = 1.0 / static_cast(n); + } + + while (kase != 0) { + if (kase == 1) { + internal::blas::xtrsv(n, b_A, n, x); + internal::blas::b_xtrsv(n, b_A, n, x); + } else { + internal::blas::c_xtrsv(n, b_A, n, x); + internal::blas::d_xtrsv(n, b_A, n, x); + } + + if (jump == 1) { + ainvnm = b_norm(x); + if ((!std::isinf(ainvnm)) && (!std::isnan(ainvnm))) { + i = x.size(0); + for (kase = 0; kase < i; kase++) { + real_T temp; + temp = std::abs(x[kase]); + if (temp > 2.2250738585072014E-308) { + x[kase] = x[kase] / temp; + } else { + x[kase] = 1.0; + } + } + + kase = 2; + jump = 2; + } else { + kase = 0; + } + } else if (jump == 2) { + real_T temp; + j = 0; + temp = std::abs(x[0]); + i = x.size(0); + for (kase = 0; kase <= i - 2; kase++) { + real_T absrexk; + absrexk = std::abs(x[kase + 1]); + if (!(absrexk <= temp)) { + j = kase + 1; + temp = absrexk; + } + } + + iter = 2; + kase = x.size(0); + x.set_size(kase); + for (i = 0; i < kase; i++) { + x[i] = 0.0; + } + + x[j] = 1.0; + kase = 1; + jump = 3; + } else if (jump == 3) { + ainvnm = b_norm(x); + if (ainvnm <= x[0]) { + real_T temp; + temp = 1.0; + i = x.size(0); + for (kase = 0; kase < i; kase++) { + x[kase] = temp * (((static_cast(kase) + 1.0) - 1.0) + / (static_cast(x.size(0)) - 1.0) + + 1.0); + temp = -temp; + } + + kase = 1; + jump = 5; + } else { + i = x.size(0); + for (kase = 0; kase < i; kase++) { + real_T temp; + temp = std::abs(x[kase]); + if (temp > 2.2250738585072014E-308) { + x[kase] = x[kase] / temp; + } else { + x[kase] = 1.0; + } + } + + kase = 2; + jump = 4; + } + } else if (jump == 4) { + real_T temp; + jlast = j; + j = 0; + temp = std::abs(x[0]); + i = x.size(0); + for (kase = 0; kase <= i - 2; kase++) { + real_T absrexk; + absrexk = std::abs(x[kase + 1]); + if (!(absrexk <= temp)) { + j = kase + 1; + temp = absrexk; + } + } + + if ((std::abs(x[jlast]) != std::abs(x[j])) && (iter <= 5)) { + iter++; + kase = x.size(0); + x.set_size(kase); + for (i = 0; i < kase; i++) { + x[i] = 0.0; + } + + x[j] = 1.0; + kase = 1; + jump = 3; + } else { + temp = 1.0; + i = x.size(0); + for (kase = 0; kase < i; kase++) { + x[kase] = temp * (((static_cast(kase) + 1.0) - 1.0) + / (static_cast(x.size(0)) - 1.0) + + 1.0); + temp = -temp; + } + + kase = 1; + jump = 5; + } + } else if (jump == 5) { + real_T temp; + temp = 2.0 * b_norm(x) / 3.0 / static_cast(n); + if (temp > ainvnm) { + ainvnm = temp; + } + + kase = 0; + } + } + + if (ainvnm != 0.0) { + result = 1.0 / ainvnm / normA; + } + + if (std::isnan(result) && (!internal::vAllOrAny(b_A))) { + result = 0.0; + } + + exitg1 = 1; + } + } while (exitg1 == 0); + } + } + + return result; + } + } +} + +// End of code generation (rcond.cpp) diff --git a/cpp/RAT/rcond.h b/cpp/RAT/rcond.h new file mode 100644 index 00000000..a127abdf --- /dev/null +++ b/cpp/RAT/rcond.h @@ -0,0 +1,30 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// rcond.h +// +// Code generation for function 'rcond' +// +#ifndef RCOND_H +#define RCOND_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + real_T rcond(const ::coder::array &A); + } +} + +#endif + +// End of code generation (rcond.h) diff --git a/cpp/RAT/rdivide_helper.cpp b/cpp/RAT/rdivide_helper.cpp new file mode 100644 index 00000000..9777623b --- /dev/null +++ b/cpp/RAT/rdivide_helper.cpp @@ -0,0 +1,47 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// rdivide_helper.cpp +// +// Code generation for function 'rdivide_helper' +// + +// Include files +#include "rdivide_helper.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 1U> &in2, const ::coder::array &in3) + { + int32_T i; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_1_0; + if (in3.size(0) == 1) { + i = in2.size(0); + } else { + i = in3.size(0); + } + + in1.set_size(i); + stride_0_0 = (in2.size(0) != 1); + stride_1_0 = (in3.size(0) != 1); + if (in3.size(0) == 1) { + loop_ub = in2.size(0); + } else { + loop_ub = in3.size(0); + } + + for (i = 0; i < loop_ub; i++) { + in1[i] = static_cast(in2[i * stride_0_0] == in3[i * stride_1_0]); + } + } +} + +// End of code generation (rdivide_helper.cpp) diff --git a/cpp/RAT/rdivide_helper.h b/cpp/RAT/rdivide_helper.h new file mode 100644 index 00000000..ee8a45d3 --- /dev/null +++ b/cpp/RAT/rdivide_helper.h @@ -0,0 +1,28 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// rdivide_helper.h +// +// Code generation for function 'rdivide_helper' +// +#ifndef RDIVIDE_HELPER_H +#define RDIVIDE_HELPER_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 1U> &in2, const ::coder::array &in3); +} + +#endif + +// End of code generation (rdivide_helper.h) diff --git a/cpp/RAT/refPrctileConfInts.cpp b/cpp/RAT/refPrctileConfInts.cpp new file mode 100644 index 00000000..3c13cef4 --- /dev/null +++ b/cpp/RAT/refPrctileConfInts.cpp @@ -0,0 +1,528 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// refPrctileConfInts.cpp +// +// Code generation for function 'refPrctileConfInts' +// + +// Include files +#include "refPrctileConfInts.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "interp1.h" +#include "makeCell.h" +#include "mean.h" +#include "parseResultToStruct.h" +#include "prctile.h" +#include "rand.h" +#include "reflectivityCalculation.h" +#include "rt_nonfinite.h" +#include "strcmp.h" +#include "unpackParams.h" +#include "coder_array.h" +#include "coder_bounded_array.h" +#include + +// Function Definitions +namespace RAT +{ + void refPrctileConfInts(const ::coder::array &bayesOutputs_chain, + c_struct_T *problemStruct, const cell_11 *problemCells, const struct2_T + *controlsStruct, f_struct_T *allPredInts) + { + ::coder::array r; + ::coder::array b_expl_temp; + ::coder::array c_expl_temp; + ::coder::array calcResult_reflectivity; + ::coder::array calcResult_sldProfiles; + ::coder::array d_expl_temp; + ::coder::array expl_temp; + ::coder::array r1; + ::coder::array refYVals; + ::coder::array sldYVals; + ::coder::array r2; + ::coder::array refArray; + ::coder::array rowVals; + ::coder::array sldArray; + ::coder::array sldArray1; + ::coder::array sldArray2; + ::coder::array vals; + ::coder::array b_calcResult_reflectivity; + ::coder::array c_calcResult_reflectivity; + cell_wrap_9 calcResult[6]; + d_struct_T calcContrastParams; + d_struct_T e_expl_temp; + real_T a[1000]; + real_T isample[1000]; + real_T thisCol_data[1000]; + real_T ci65[2]; + real_T ci95[2]; + real_T calcResult_calculationResults_sumChi; + int32_T b_loop_ub; + int32_T b_thisCol_size; + int32_T c_loop_ub; + int32_T i; + int32_T i1; + int32_T k; + int32_T loop_ub; + int32_T thisCol_size; + boolean_T domains; + + // Need to deal slightly differently with SLDs if there are domains + domains = coder::internal::b_strcmp(problemStruct->TF.data, + problemStruct->TF.size); + + // Calc the ref and SLD for the first row of the chain. This 'sticks' the x + // values of each that we then interpolate the values from the rest of the + // cain onto.... + problemStruct->fitParams.set_size(1, bayesOutputs_chain.size(1)); + loop_ub = bayesOutputs_chain.size(1); + for (i = 0; i < loop_ub; i++) { + problemStruct->fitParams[problemStruct->fitParams.size(0) * i] = + bayesOutputs_chain[bayesOutputs_chain.size(0) * i]; + } + + unpackParams(problemStruct, controlsStruct->checks.fitParam, + controlsStruct->checks.fitBackgroundParam, + controlsStruct->checks.fitQzshift, + controlsStruct->checks.fitScalefactor, + controlsStruct->checks.fitBulkIn, + controlsStruct->checks.fitBulkOut, + controlsStruct->checks.fitResolutionParam, + controlsStruct->checks.fitDomainRatio); + + // Calc the reflectivities.... + reflectivityCalculation(problemStruct, problemCells, controlsStruct, + &calcContrastParams, calcResult); + + // 'result' is currently a cell array. Convert this to a struct because it's + // easier to work with fieldnames... + parseResultToStruct(&calcContrastParams, calcResult, calcResult_reflectivity, + expl_temp, b_expl_temp, c_expl_temp, + calcResult_sldProfiles, d_expl_temp, + &calcResult_calculationResults_sumChi, &e_expl_temp); + + // so each is a {n x 1} cell array, because of n contrasts. + // Prepare some arrays to hold the SLD's and Refs for all the chain, keeping only the Y vales. + // We'll save x values in a separate array + vals.set_size(1, 3); + rowVals.set_size(1, 3); + vals[0] = 0.0; + rowVals[0] = 0.0; + vals[vals.size(0)] = 0.0; + rowVals[1] = 0.0; + vals[vals.size(0) * 2] = 0.0; + rowVals[2] = 0.0; + makeCell(problemStruct->numberOfContrasts, (const real_T *)rowVals.data(), + allPredInts->refXdata); + + // cell(numberOfContrasts,1); + makeCell(problemStruct->numberOfContrasts, (const real_T *)vals.data(), + refYVals); + + // cell(numberOfContrasts,1); + if (!domains) { + makeCell(problemStruct->numberOfContrasts, (const real_T *)rowVals.data(), + r); + allPredInts->sldXdata.set_size(r.size(0), 1); + loop_ub = r.size(0); + for (i = 0; i < loop_ub; i++) { + allPredInts->sldXdata[i] = r[i]; + } + + makeCell(problemStruct->numberOfContrasts, (const real_T *)vals.data(), r1); + sldYVals.set_size(r1.size(0), 1); + loop_ub = r1.size(0); + for (i = 0; i < loop_ub; i++) { + sldYVals[i] = r1[i]; + } + } else { + b_makeCell(problemStruct->numberOfContrasts, (const real_T *)rowVals.data(), + r); + allPredInts->sldXdata.set_size(r.size(0), 2); + b_makeCell(problemStruct->numberOfContrasts, (const real_T *)vals.data(), + r1); + sldYVals.set_size(r1.size(0), 2); + loop_ub = r.size(0); + k = r1.size(0); + for (i = 0; i < 2; i++) { + for (i1 = 0; i1 < loop_ub; i1++) { + allPredInts->sldXdata[i1 + allPredInts->sldXdata.size(0) * i] = r[i1 + + r.size(0) * i]; + } + + for (i1 = 0; i1 < k; i1++) { + sldYVals[i1 + sldYVals.size(0) * i] = r1[i1 + r1.size(0) * i]; + } + } + } + + // We need to have the yvals interpolated onto the same xvals when we + // calculate the sample. So, take the current reflectivity value from above + // to get the 'base' x for ref and SLD, then all following + // interpelations are onto these x values.... + i = static_cast(problemStruct->numberOfContrasts); + for (int32_T b_i{0}; b_i < i; b_i++) { + loop_ub = calcResult_reflectivity[b_i].f1.size(0); + allPredInts->refXdata[b_i].f1.set_size(1, calcResult_reflectivity[b_i]. + f1.size(0)); + for (i1 = 0; i1 < loop_ub; i1++) { + allPredInts->refXdata[b_i].f1[i1] = calcResult_reflectivity[b_i].f1[i1]; + } + + // Transpose these into rows for storage + if (!domains) { + loop_ub = calcResult_sldProfiles[b_i].f1.size(0); + allPredInts->sldXdata[b_i].f1.set_size(1, calcResult_sldProfiles[b_i]. + f1.size(0)); + for (i1 = 0; i1 < loop_ub; i1++) { + allPredInts->sldXdata[b_i].f1[i1] = calcResult_sldProfiles[b_i].f1[i1]; + } + } else { + for (int32_T m{0}; m < 2; m++) { + loop_ub = calcResult_sldProfiles[b_i + calcResult_sldProfiles.size(0) * + m].f1.size(0); + allPredInts->sldXdata[b_i + allPredInts->sldXdata.size(0) * m]. + f1.set_size(1, calcResult_sldProfiles[b_i + + calcResult_sldProfiles.size(0) * m].f1.size(0)); + for (i1 = 0; i1 < loop_ub; i1++) { + allPredInts->sldXdata[b_i + allPredInts->sldXdata.size(0) * m].f1[i1] + = calcResult_sldProfiles[b_i + calcResult_sldProfiles.size(0) * m] + .f1[i1]; + } + } + } + } + + // Loop over the whole chain, collecting the Sld's and Refs together into + // one array for each contrast. + // will be = nsimu + // To speed things up, we'll take a random sample of the chain, rather than + // calculating >20000 reflectivities... + coder::c_rand(a); + for (k = 0; k < 1000; k++) { + isample[k] = std::ceil(a[k] * static_cast(bayesOutputs_chain.size + (0))); + } + + // First, we populate the yVals arrays with zero arrays of the correct size... + for (int32_T b_i{0}; b_i < i; b_i++) { + refYVals[b_i].f1.set_size(1000, calcResult_reflectivity[b_i].f1.size(0)); + loop_ub = calcResult_reflectivity[b_i].f1.size(0); + for (i1 = 0; i1 < loop_ub; i1++) { + for (int32_T i2{0}; i2 < 1000; i2++) { + refYVals[b_i].f1[i2 + refYVals[b_i].f1.size(0) * i1] = 0.0; + } + } + + if (!domains) { + sldYVals[b_i].f1.set_size(1000, calcResult_sldProfiles[b_i].f1.size(0)); + loop_ub = calcResult_sldProfiles[b_i].f1.size(0); + for (i1 = 0; i1 < loop_ub; i1++) { + for (int32_T i2{0}; i2 < 1000; i2++) { + sldYVals[b_i].f1[i2 + sldYVals[b_i].f1.size(0) * i1] = 0.0; + } + } + } else { + sldYVals[b_i].f1.set_size(1000, calcResult_sldProfiles[b_i].f1.size(0)); + loop_ub = calcResult_sldProfiles[b_i].f1.size(0); + for (i1 = 0; i1 < loop_ub; i1++) { + for (int32_T i2{0}; i2 < 1000; i2++) { + sldYVals[b_i].f1[i2 + sldYVals[b_i].f1.size(0) * i1] = 0.0; + } + } + + sldYVals[b_i + sldYVals.size(0)].f1.set_size(1000, + calcResult_sldProfiles[b_i + calcResult_sldProfiles.size(0)].f1.size(0)); + loop_ub = calcResult_sldProfiles[b_i + calcResult_sldProfiles.size(0)]. + f1.size(0); + for (i1 = 0; i1 < loop_ub; i1++) { + for (int32_T i2{0}; i2 < 1000; i2++) { + sldYVals[b_i + sldYVals.size(0)].f1[i2 + sldYVals[b_i + + sldYVals.size(0)].f1.size(0) * i1] = 0.0; + } + } + } + } + + // Calculate all the samples.... + loop_ub = bayesOutputs_chain.size(1); + for (int32_T b_i{0}; b_i < 1000; b_i++) { + problemStruct->fitParams.set_size(1, bayesOutputs_chain.size(1)); + for (i1 = 0; i1 < loop_ub; i1++) { + problemStruct->fitParams[problemStruct->fitParams.size(0) * i1] = + bayesOutputs_chain[(static_cast(isample[b_i]) + + bayesOutputs_chain.size(0) * i1) - 1]; + } + + unpackParams(problemStruct, controlsStruct->checks.fitParam, + controlsStruct->checks.fitBackgroundParam, + controlsStruct->checks.fitQzshift, + controlsStruct->checks.fitScalefactor, + controlsStruct->checks.fitBulkIn, + controlsStruct->checks.fitBulkOut, + controlsStruct->checks.fitResolutionParam, + controlsStruct->checks.fitDomainRatio); + + // Calc the reflectivities.... + reflectivityCalculation(problemStruct, problemCells, controlsStruct, + &calcContrastParams, calcResult); + + // 'result' is currently a cell array. Convert this to a struct because it's + // easier to work with fieldnames... + parseResultToStruct(&calcContrastParams, calcResult, + calcResult_reflectivity, expl_temp, b_expl_temp, + c_expl_temp, calcResult_sldProfiles, d_expl_temp, + &calcResult_calculationResults_sumChi, &e_expl_temp); + allPredInts->sampleChi[b_i] = calcResult_calculationResults_sumChi; + for (int32_T n{0}; n < i; n++) { + k = calcResult_reflectivity[n].f1.size(0); + b_calcResult_reflectivity.set_size(calcResult_reflectivity[n].f1.size(0)); + for (i1 = 0; i1 < k; i1++) { + b_calcResult_reflectivity[i1] = calcResult_reflectivity[n].f1[i1]; + } + + k = calcResult_reflectivity[n].f1.size(0); + c_calcResult_reflectivity.set_size(calcResult_reflectivity[n].f1.size(0)); + for (i1 = 0; i1 < k; i1++) { + c_calcResult_reflectivity[i1] = calcResult_reflectivity[n].f1[i1 + + calcResult_reflectivity[n].f1.size(0)]; + } + + coder::interp1(b_calcResult_reflectivity, c_calcResult_reflectivity, + allPredInts->refXdata[n].f1, r2); + k = r2.size(1); + for (i1 = 0; i1 < k; i1++) { + refYVals[n].f1[b_i + refYVals[n].f1.size(0) * i1] = r2[i1]; + } + + // Automatically comes back as a row from inpterp1 + if (!domains) { + k = calcResult_sldProfiles[n].f1.size(0); + b_calcResult_reflectivity.set_size(calcResult_sldProfiles[n].f1.size(0)); + for (i1 = 0; i1 < k; i1++) { + b_calcResult_reflectivity[i1] = calcResult_sldProfiles[n].f1[i1]; + } + + k = calcResult_sldProfiles[n].f1.size(0); + c_calcResult_reflectivity.set_size(calcResult_sldProfiles[n].f1.size(0)); + for (i1 = 0; i1 < k; i1++) { + c_calcResult_reflectivity[i1] = calcResult_sldProfiles[n].f1[i1 + + calcResult_sldProfiles[n].f1.size(0)]; + } + + coder::b_interp1(b_calcResult_reflectivity, c_calcResult_reflectivity, + allPredInts->sldXdata[n].f1, r2); + k = r2.size(1); + for (i1 = 0; i1 < k; i1++) { + sldYVals[n].f1[b_i + sldYVals[n].f1.size(0) * i1] = r2[i1]; + } + } else { + for (int32_T m{0}; m < 2; m++) { + k = calcResult_sldProfiles[n + calcResult_sldProfiles.size(0) * m]. + f1.size(0); + b_calcResult_reflectivity.set_size(calcResult_sldProfiles[n + + calcResult_sldProfiles.size(0) * m].f1.size(0)); + for (i1 = 0; i1 < k; i1++) { + b_calcResult_reflectivity[i1] = calcResult_sldProfiles[n + + calcResult_sldProfiles.size(0) * m].f1[i1]; + } + + k = calcResult_sldProfiles[n + calcResult_sldProfiles.size(0) * m]. + f1.size(0); + c_calcResult_reflectivity.set_size(calcResult_sldProfiles[n + + calcResult_sldProfiles.size(0) * m].f1.size(0)); + for (i1 = 0; i1 < k; i1++) { + c_calcResult_reflectivity[i1] = calcResult_sldProfiles[n + + calcResult_sldProfiles.size(0) * m].f1[i1 + + calcResult_sldProfiles[n + calcResult_sldProfiles.size(0) * m]. + f1.size(0)]; + } + + coder::b_interp1(b_calcResult_reflectivity, + c_calcResult_reflectivity, allPredInts->sldXdata[n + + allPredInts->sldXdata.size(0) * m].f1, r2); + k = r2.size(1); + for (i1 = 0; i1 < k; i1++) { + sldYVals[n + sldYVals.size(0) * m].f1[b_i + sldYVals[n + + sldYVals.size(0) * m].f1.size(0) * i1] = r2[i1]; + } + } + } + } + } + + // Calculate the percentiles across all the calculated samples for each + // point in x... We calculate 95% and 65% CI's for each set of curves + // Reflectivity.. + allPredInts->refPredInts.set_size(i); + for (int32_T b_i{0}; b_i < i; b_i++) { + refArray.set_size(5, refYVals[b_i].f1.size(1)); + loop_ub = refYVals[b_i].f1.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + for (int32_T i2{0}; i2 < 5; i2++) { + refArray[i2 + 5 * i1] = 0.0; + } + } + + // We could possibly use CIFn in one shot here (rather than loop over + // points....) + i1 = refYVals[b_i].f1.size(1); + if (refYVals[b_i].f1.size(1) - 1 >= 0) { + thisCol_size = refYVals[b_i].f1.size(0); + b_loop_ub = refYVals[b_i].f1.size(0); + } + + for (int32_T points{0}; points < i1; points++) { + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + thisCol_data[i2] = refYVals[b_i].f1[i2 + refYVals[b_i].f1.size(0) * + points]; + } + + coder::prctile(thisCol_data, thisCol_size, ci95); + coder::b_prctile(thisCol_data, thisCol_size, ci65); + refArray[5 * points] = ci95[0]; + refArray[5 * points + 1] = ci65[0]; + refArray[5 * points + 2] = coder::mean(thisCol_data, thisCol_size); + refArray[5 * points + 3] = ci65[1]; + refArray[5 * points + 4] = ci95[1]; + } + + allPredInts->refPredInts[b_i].f1.set_size(5, refArray.size(1)); + loop_ub = refArray.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + for (int32_T i2{0}; i2 < 5; i2++) { + allPredInts->refPredInts[b_i].f1[i2 + 5 * i1] = refArray[i2 + 5 * i1]; + } + } + } + + // Also the SLD's + if (!domains) { + allPredInts->sldPredInts.set_size(i, 1); + for (int32_T b_i{0}; b_i < i; b_i++) { + sldArray.set_size(5, sldYVals[b_i].f1.size(1)); + loop_ub = sldYVals[b_i].f1.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + for (int32_T i2{0}; i2 < 5; i2++) { + sldArray[i2 + 5 * i1] = 0.0; + } + } + + i1 = sldYVals[b_i].f1.size(1); + if (sldYVals[b_i].f1.size(1) - 1 >= 0) { + b_thisCol_size = sldYVals[b_i].f1.size(0); + c_loop_ub = sldYVals[b_i].f1.size(0); + } + + for (int32_T points{0}; points < i1; points++) { + for (int32_T i2{0}; i2 < c_loop_ub; i2++) { + thisCol_data[i2] = sldYVals[b_i].f1[i2 + sldYVals[b_i].f1.size(0) * + points]; + } + + coder::prctile(thisCol_data, b_thisCol_size, ci95); + coder::b_prctile(thisCol_data, b_thisCol_size, ci65); + sldArray[5 * points] = ci95[0]; + sldArray[5 * points + 1] = ci65[0]; + sldArray[5 * points + 2] = coder::mean(thisCol_data, b_thisCol_size); + sldArray[5 * points + 3] = ci65[1]; + sldArray[5 * points + 4] = ci95[1]; + } + + allPredInts->sldPredInts[b_i].f1.set_size(5, sldArray.size(1)); + loop_ub = sldArray.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + for (int32_T i2{0}; i2 < 5; i2++) { + allPredInts->sldPredInts[b_i].f1[i2 + 5 * i1] = sldArray[i2 + 5 * i1]; + } + } + } + } else { + allPredInts->sldPredInts.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + sldArray1.set_size(5, sldYVals[b_i].f1.size(1)); + loop_ub = sldYVals[b_i].f1.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + for (int32_T i2{0}; i2 < 5; i2++) { + sldArray1[i2 + 5 * i1] = 0.0; + } + } + + sldArray2.set_size(5, sldYVals[b_i + sldYVals.size(0)].f1.size(1)); + loop_ub = sldYVals[b_i + sldYVals.size(0)].f1.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + for (int32_T i2{0}; i2 < 5; i2++) { + sldArray2[i2 + 5 * i1] = 0.0; + } + } + + i1 = sldYVals[b_i].f1.size(1); + for (int32_T points{0}; points < i1; points++) { + real_T thisCol1_data[1000]; + loop_ub = sldYVals[b_i].f1.size(0); + k = sldYVals[b_i].f1.size(0); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + thisCol1_data[i2] = sldYVals[b_i].f1[i2 + sldYVals[b_i].f1.size(0) * + points]; + } + + real_T ci651[2]; + real_T ci951[2]; + coder::prctile(thisCol1_data, k, ci951); + coder::b_prctile(thisCol1_data, k, ci651); + sldArray1[5 * points] = ci951[0]; + sldArray1[5 * points + 1] = ci651[0]; + sldArray1[5 * points + 2] = coder::mean(thisCol1_data, k); + sldArray1[5 * points + 3] = ci651[1]; + sldArray1[5 * points + 4] = ci951[1]; + } + + i1 = sldYVals[b_i + sldYVals.size(0)].f1.size(1); + for (int32_T points{0}; points < i1; points++) { + real_T thisCol2_data[1000]; + loop_ub = sldYVals[b_i + sldYVals.size(0)].f1.size(0); + k = sldYVals[b_i + sldYVals.size(0)].f1.size(0); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + thisCol2_data[i2] = sldYVals[b_i + sldYVals.size(0)].f1[i2 + + sldYVals[b_i + sldYVals.size(0)].f1.size(0) * points]; + } + + real_T ci652[2]; + real_T ci952[2]; + coder::prctile(thisCol2_data, k, ci952); + coder::b_prctile(thisCol2_data, k, ci652); + sldArray2[5 * points] = ci952[0]; + sldArray2[5 * points + 1] = ci652[0]; + sldArray2[5 * points + 2] = coder::mean(thisCol2_data, k); + sldArray2[5 * points + 3] = ci652[1]; + sldArray2[5 * points + 4] = ci952[1]; + } + + allPredInts->sldPredInts[b_i].f1.set_size(5, sldArray1.size(1)); + loop_ub = sldArray1.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + for (int32_T i2{0}; i2 < 5; i2++) { + allPredInts->sldPredInts[b_i].f1[i2 + 5 * i1] = sldArray1[i2 + 5 * + i1]; + } + } + + allPredInts->sldPredInts[b_i + allPredInts->sldPredInts.size(0)]. + f1.set_size(5, sldArray2.size(1)); + loop_ub = sldArray2.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + for (int32_T i2{0}; i2 < 5; i2++) { + allPredInts->sldPredInts[b_i + allPredInts->sldPredInts.size(0)] + .f1[i2 + 5 * i1] = sldArray2[i2 + 5 * i1]; + } + } + } + } + } +} + +// End of code generation (refPrctileConfInts.cpp) diff --git a/cpp/RAT/refPrctileConfInts.h b/cpp/RAT/refPrctileConfInts.h new file mode 100644 index 00000000..ba8743fa --- /dev/null +++ b/cpp/RAT/refPrctileConfInts.h @@ -0,0 +1,38 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// refPrctileConfInts.h +// +// Code generation for function 'refPrctileConfInts' +// +#ifndef REFPRCTILECONFINTS_H +#define REFPRCTILECONFINTS_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct c_struct_T; + struct cell_11; + struct struct2_T; + struct f_struct_T; +} + +// Function Declarations +namespace RAT +{ + void refPrctileConfInts(const ::coder::array &bayesOutputs_chain, + c_struct_T *problemStruct, const cell_11 *problemCells, const struct2_T + *controlsStruct, f_struct_T *allPredInts); +} + +#endif + +// End of code generation (refPrctileConfInts.h) diff --git a/cpp/RAT/reflectivityCalculation.cpp b/cpp/RAT/reflectivityCalculation.cpp new file mode 100644 index 00000000..d5626cdd --- /dev/null +++ b/cpp/RAT/reflectivityCalculation.cpp @@ -0,0 +1,667 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// reflectivityCalculation.cpp +// +// Code generation for function 'reflectivityCalculation' +// + +// Include files +#include "reflectivityCalculation.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "reflectivityCalculation1.h" +#include "reflectivityCalculation2.h" +#include "rt_nonfinite.h" +#include "strcmp.h" +#include "coder_array.h" +#include "coder_bounded_array.h" + +// Type Definitions +namespace RAT +{ + struct cell_wrap_16 + { + ::coder::array f1; + }; + + struct cell_wrap_17 + { + ::coder::array f1; + }; +} + +// Function Declarations +namespace RAT +{ + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_18, 1U> &r1); + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_16, 1U> &r1); + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_16, 1U> &r1); + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_17, 1U> &r1); + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_18, 2U> &r1); + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_34, 2U> &r1); + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_17, 2U> &r1); +} + +// Function Definitions +namespace RAT +{ + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_18, 1U> &r1) + { + int32_T i; + r1.set_size(r.size(0)); + i = r.size(0); + for (int32_T i1{0}; i1 < i; i1++) { + int32_T loop_ub; + loop_ub = r[i1].f1.size(1); + r1[i1].f1.set_size(r[i1].f1.size(0), r[i1].f1.size(1)); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + int32_T b_loop_ub; + b_loop_ub = r[i1].f1.size(0); + for (int32_T i3{0}; i3 < b_loop_ub; i3++) { + r1[i1].f1[i3 + r1[i1].f1.size(0) * i2] = r[i1].f1[i3 + r[i1].f1.size(0) + * i2]; + } + } + } + } + + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_16, 1U> &r1) + { + int32_T i; + r1.set_size(r.size(0)); + i = r.size(0); + for (int32_T i1{0}; i1 < i; i1++) { + int32_T loop_ub; + loop_ub = r[i1].f1.size(1); + r1[i1].f1.set_size(r[i1].f1.size(0), r[i1].f1.size(1)); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + int32_T b_loop_ub; + b_loop_ub = r[i1].f1.size(0); + for (int32_T i3{0}; i3 < b_loop_ub; i3++) { + r1[i1].f1[i3 + r1[i1].f1.size(0) * i2] = r[i1].f1[i3 + r[i1].f1.size(0) + * i2]; + } + } + } + } + + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_16, 1U> &r1) + { + int32_T i; + r1.set_size(r.size(0)); + i = r.size(0); + for (int32_T i1{0}; i1 < i; i1++) { + int32_T loop_ub; + loop_ub = r[i1].f1.size(0); + r1[i1].f1.set_size(r[i1].f1.size(0), 2); + for (int32_T i2{0}; i2 < 2; i2++) { + for (int32_T i3{0}; i3 < loop_ub; i3++) { + r1[i1].f1[i3 + r1[i1].f1.size(0) * i2] = r[i1].f1[i3 + r[i1].f1.size(0) + * i2]; + } + } + } + } + + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_17, 1U> &r1) + { + int32_T i; + r1.set_size(r.size(0)); + i = r.size(0); + for (int32_T i1{0}; i1 < i; i1++) { + int32_T loop_ub; + loop_ub = r[i1].f1.size(1); + r1[i1].f1.set_size(r[i1].f1.size(0), r[i1].f1.size(1)); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + int32_T b_loop_ub; + b_loop_ub = r[i1].f1.size(0); + for (int32_T i3{0}; i3 < b_loop_ub; i3++) { + r1[i1].f1[i3 + r1[i1].f1.size(0) * i2] = r[i1].f1[i3 + r[i1].f1.size(0) + * i2]; + } + } + } + } + + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_18, 2U> &r1) + { + int32_T i; + r1.set_size(r.size(0), r.size(1)); + i = r.size(0) * r.size(1); + for (int32_T i1{0}; i1 < i; i1++) { + int32_T loop_ub; + loop_ub = r[i1].f1.size(1); + r1[i1].f1.set_size(r[i1].f1.size(0), r[i1].f1.size(1)); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + int32_T b_loop_ub; + b_loop_ub = r[i1].f1.size(0); + for (int32_T i3{0}; i3 < b_loop_ub; i3++) { + r1[i1].f1[i3 + r1[i1].f1.size(0) * i2] = r[i1].f1[i3 + r[i1].f1.size(0) + * i2]; + } + } + } + } + + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_34, 2U> &r1) + { + int32_T i; + r1.set_size(r.size(0), r.size(1)); + i = r.size(0) * r.size(1); + for (int32_T i1{0}; i1 < i; i1++) { + int32_T loop_ub; + loop_ub = r[i1].f1.size(1); + r1[i1].f1.set_size(r[i1].f1.size(0), r[i1].f1.size(1)); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + int32_T b_loop_ub; + b_loop_ub = r[i1].f1.size(0); + for (int32_T i3{0}; i3 < b_loop_ub; i3++) { + r1[i1].f1[i3 + r1[i1].f1.size(0) * i2] = r[i1].f1[i3 + r[i1].f1.size(0) + * i2]; + } + } + } + } + + static void cast(const ::coder::array &r, ::coder::array< + cell_wrap_17, 2U> &r1) + { + int32_T i; + r1.set_size(r.size(0), r.size(1)); + i = r.size(0) * r.size(1); + for (int32_T i1{0}; i1 < i; i1++) { + int32_T loop_ub; + loop_ub = r[i1].f1.size(1); + r1[i1].f1.set_size(r[i1].f1.size(0), r[i1].f1.size(1)); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + int32_T b_loop_ub; + b_loop_ub = r[i1].f1.size(0); + for (int32_T i3{0}; i3 < b_loop_ub; i3++) { + r1[i1].f1[i3 + r1[i1].f1.size(0) * i2] = r[i1].f1[i3 + r[i1].f1.size(0) + * i2]; + } + } + } + } + + void reflectivityCalculation(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, d_struct_T *contrastParams, + cell_wrap_9 resultCells[6]) + { + ::coder::array reflectivity; + ::coder::array simulation; + ::coder::array sldProfiles; + ::coder::array domainAllLayers; + ::coder::array r2; + ::coder::array allLayers; + ::coder::array shiftedData; + ::coder::array domainLayerSlds; + ::coder::array r; + ::coder::array layerSlds; + ::coder::array b_reflectivity; + ::coder::array b_simulation; + ::coder::array domainSldProfiles; + ::coder::array r1; + ::coder::array b_domainAllLayers; + ::coder::array b_domainLayerSlds; + ::coder::array b_domainSldProfiles; + ::coder::array cell1; + ::coder::array cell2; + ::coder::array cell3; + ::coder::array cell4; + ::coder::array cell5; + ::coder::array cell6; + ::coder::array b_allLayers; + ::coder::array b_layerSlds; + ::coder::array b_shiftedData; + ::coder::array b_sldProfiles; + int32_T b_index; + int32_T i; + int32_T i1; + int32_T loop_ub; + + // Main entry point into the reflectivity calculation for the toolbox. + // This is the main function that is called by any of the minimisers or + // analysis tools from the rest of the toolbox. + // + // *The main job of this function is to decide which type of calculation + // (i.e. 'Target function' is required, and call the relevant routines. + // The types of available target functions are:* + // + // * non polarised - The main basic target function type, for non polarised neutrons (or x-rays) with non-absorbing samples. Different model types are specified in sub functions from here. + // + // * oil water - Target function for oil-water samples + // + // * domains - Target function for samples consisting of domains which are larger than the beam lateral coherence length. + // + // * magnetic - Target function for cases for polarised neutrons with polarisation analysis. + // + // for compilation, we have to preallocate memory for the output arrays + // Setting these parameters in the struct defines them as doubles + contrastParams->ssubs.set_size(1); + contrastParams->ssubs[0] = 0.0; + contrastParams->backgroundParams.set_size(1); + contrastParams->backgroundParams[0] = 0.0; + contrastParams->qzshifts.set_size(1); + contrastParams->qzshifts[0] = 0.0; + contrastParams->scalefactors.set_size(1); + contrastParams->scalefactors[0] = 0.0; + contrastParams->bulkIn.set_size(1); + contrastParams->bulkIn[0] = 0.0; + contrastParams->bulkOut.set_size(1); + contrastParams->bulkOut[0] = 0.0; + contrastParams->resolutionParams.set_size(1); + contrastParams->resolutionParams[0] = 0.0; + contrastParams->calculations.allChis.set_size(1); + contrastParams->calculations.allChis[0] = 0.0; + contrastParams->calculations.sumChi = 0.0; + contrastParams->allSubRough.set_size(1); + contrastParams->allSubRough[0] = 0.0; + contrastParams->resample.set_size(1, 1); + contrastParams->resample[0] = 0.0; + + // We also foll the results arrays to define their + // type and size. (NOTE: at the moment we have a 'coder.varsize' + // pre-processor directives for the compiler here and at the + // end for the results block. We are unlikely to need both + // TODO: Find out which is necessary and tidy this up. + i = static_cast(problemStruct->numberOfContrasts); + reflectivity.set_size(i); + simulation.set_size(i); + shiftedData.set_size(i); + layerSlds.set_size(i); + domainLayerSlds.set_size(i, 2); + sldProfiles.set_size(i); + domainSldProfiles.set_size(i, 2); + allLayers.set_size(i); + domainAllLayers.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + reflectivity[b_i].f1.set_size(2, 2); + reflectivity[b_i].f1[0] = 1.0; + reflectivity[b_i].f1[1] = 1.0; + reflectivity[b_i].f1[reflectivity[b_i].f1.size(0)] = 1.0; + reflectivity[b_i].f1[reflectivity[b_i].f1.size(0) + 1] = 1.0; + simulation[b_i].f1.set_size(2, 2); + simulation[b_i].f1[0] = 1.0; + simulation[b_i].f1[1] = 1.0; + simulation[b_i].f1[simulation[b_i].f1.size(0)] = 1.0; + simulation[b_i].f1[simulation[b_i].f1.size(0) + 1] = 1.0; + shiftedData[b_i].f1.set_size(2, 3); + layerSlds[b_i].f1.set_size(2, 3); + domainLayerSlds[b_i].f1.set_size(2, 3); + domainLayerSlds[b_i + domainLayerSlds.size(0)].f1.set_size(2, 3); + sldProfiles[b_i].f1.set_size(2, 2); + sldProfiles[b_i].f1[0] = 1.0; + sldProfiles[b_i].f1[1] = 1.0; + sldProfiles[b_i].f1[sldProfiles[b_i].f1.size(0)] = 1.0; + sldProfiles[b_i].f1[sldProfiles[b_i].f1.size(0) + 1] = 1.0; + domainSldProfiles[b_i].f1.set_size(2, 2); + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.set_size(2, 2); + domainSldProfiles[b_i].f1[0] = 1.0; + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1[0] = 1.0; + domainSldProfiles[b_i].f1[1] = 1.0; + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1[1] = 1.0; + domainSldProfiles[b_i].f1[domainSldProfiles[b_i].f1.size(0)] = 1.0; + domainSldProfiles[b_i + domainSldProfiles.size(0)] + .f1[domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size(0)] = 1.0; + domainSldProfiles[b_i].f1[domainSldProfiles[b_i].f1.size(0) + 1] = 1.0; + domainSldProfiles[b_i + domainSldProfiles.size(0)] + .f1[domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size(0) + 1] = + 1.0; + allLayers[b_i].f1.set_size(2, 3); + domainAllLayers[b_i].f1.set_size(2, 3); + domainAllLayers[b_i + domainAllLayers.size(0)].f1.set_size(2, 3); + for (i1 = 0; i1 < 3; i1++) { + shiftedData[b_i].f1[shiftedData[b_i].f1.size(0) * i1] = 1.0; + shiftedData[b_i].f1[shiftedData[b_i].f1.size(0) * i1 + 1] = 1.0; + layerSlds[b_i].f1[layerSlds[b_i].f1.size(0) * i1] = 1.0; + layerSlds[b_i].f1[layerSlds[b_i].f1.size(0) * i1 + 1] = 1.0; + domainLayerSlds[b_i].f1[domainLayerSlds[b_i].f1.size(0) * i1] = 1.0; + domainLayerSlds[b_i + domainLayerSlds.size(0)].f1[domainLayerSlds[b_i + + domainLayerSlds.size(0)].f1.size(0) * i1] = 1.0; + domainLayerSlds[b_i].f1[domainLayerSlds[b_i].f1.size(0) * i1 + 1] = 1.0; + domainLayerSlds[b_i + domainLayerSlds.size(0)].f1[domainLayerSlds[b_i + + domainLayerSlds.size(0)].f1.size(0) * i1 + 1] = 1.0; + allLayers[b_i].f1[allLayers[b_i].f1.size(0) * i1] = 1.0; + allLayers[b_i].f1[allLayers[b_i].f1.size(0) * i1 + 1] = 1.0; + domainAllLayers[b_i].f1[domainAllLayers[b_i].f1.size(0) * i1] = 1.0; + domainAllLayers[b_i + domainAllLayers.size(0)].f1[domainAllLayers[b_i + + domainAllLayers.size(0)].f1.size(0) * i1] = 1.0; + domainAllLayers[b_i].f1[domainAllLayers[b_i].f1.size(0) * i1 + 1] = 1.0; + domainAllLayers[b_i + domainAllLayers.size(0)].f1[domainAllLayers[b_i + + domainAllLayers.size(0)].f1.size(0) * i1 + 1] = 1.0; + } + } + + // Decide which target function we are calling and call the relevant routines + if (coder::internal::i_strcmp(problemStruct->TF.data, problemStruct->TF.size)) + { + b_index = 0; + } else if (coder::internal::j_strcmp(problemStruct->TF.data, + problemStruct->TF.size)) { + b_index = 1; + } else { + b_index = -1; + } + + switch (b_index) { + case 0: + nonPolarisedTF::b_reflectivityCalculation(problemStruct, problemCells, + controls, contrastParams, b_reflectivity, b_simulation, b_shiftedData, + b_layerSlds, b_sldProfiles, b_allLayers); + cast(b_reflectivity, reflectivity); + cast(b_simulation, simulation); + cast(b_shiftedData, shiftedData); + cast(b_layerSlds, layerSlds); + cast(b_sldProfiles, sldProfiles); + cast(b_allLayers, allLayers); + + // case 'oil water' + // contrastParams = oilWaterTFReflectivityCalculation(problemStruct,problemCells,controls); + // case 'magnetic' + // contrastParams = polarisedTFReflectivityCalculation(problemStruct,problemCells,controls); + break; + + case 1: + domainsTF::b_reflectivityCalculation(problemStruct, problemCells, controls, + contrastParams, b_reflectivity, b_simulation, b_shiftedData, + b_domainLayerSlds, b_domainSldProfiles, b_domainAllLayers); + cast(b_reflectivity, reflectivity); + cast(b_simulation, simulation); + cast(b_shiftedData, shiftedData); + cast(b_domainLayerSlds, r); + domainLayerSlds.set_size(r.size(0), r.size(1)); + b_index = r.size(1); + for (i1 = 0; i1 < b_index; i1++) { + loop_ub = r.size(0); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + domainLayerSlds[i2 + domainLayerSlds.size(0) * i1] = r[i2 + r.size(0) * + i1]; + } + } + + cast(b_domainSldProfiles, r1); + domainSldProfiles.set_size(r1.size(0), r1.size(1)); + b_index = r1.size(1); + for (i1 = 0; i1 < b_index; i1++) { + loop_ub = r1.size(0); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + domainSldProfiles[i2 + domainSldProfiles.size(0) * i1] = r1[i2 + + r1.size(0) * i1]; + } + } + + cast(b_domainAllLayers, r2); + domainAllLayers.set_size(r2.size(0), r2.size(1)); + b_index = r2.size(1); + for (i1 = 0; i1 < b_index; i1++) { + loop_ub = r2.size(0); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + domainAllLayers[i2 + domainAllLayers.size(0) * i1] = r2[i2 + r2.size(0) + * i1]; + } + } + + // otherwise + // error('The calculation type "%s" is not supported', whichTF); + break; + } + + cell1.set_size(i, 1); + for (int32_T b_i{0}; b_i < i; b_i++) { + b_index = reflectivity[b_i].f1.size(0); + cell1[b_i].f1.set_size(reflectivity[b_i].f1.size(0), 2); + for (i1 = 0; i1 < 2; i1++) { + for (int32_T i2{0}; i2 < b_index; i2++) { + cell1[b_i].f1[i2 + cell1[b_i].f1.size(0) * i1] = reflectivity[b_i] + .f1[i2 + reflectivity[b_i].f1.size(0) * i1]; + } + } + } + + resultCells[0].f1.set_size(cell1.size(0), 1); + b_index = cell1.size(0); + for (i1 = 0; i1 < b_index; i1++) { + resultCells[0].f1[i1] = cell1[i1]; + } + + cell2.set_size(i, 1); + for (int32_T b_i{0}; b_i < i; b_i++) { + b_index = simulation[b_i].f1.size(0); + cell2[b_i].f1.set_size(simulation[b_i].f1.size(0), 2); + for (i1 = 0; i1 < 2; i1++) { + for (int32_T i2{0}; i2 < b_index; i2++) { + cell2[b_i].f1[i2 + cell2[b_i].f1.size(0) * i1] = simulation[b_i].f1[i2 + + simulation[b_i].f1.size(0) * i1]; + } + } + } + + resultCells[1].f1.set_size(cell2.size(0), 1); + b_index = cell2.size(0); + for (i1 = 0; i1 < b_index; i1++) { + resultCells[1].f1[i1] = cell2[i1]; + } + + cell3.set_size(i, 1); + for (int32_T b_i{0}; b_i < i; b_i++) { + b_index = shiftedData[b_i].f1.size(0); + cell3[b_i].f1.set_size(shiftedData[b_i].f1.size(0), 3); + for (i1 = 0; i1 < 3; i1++) { + for (int32_T i2{0}; i2 < b_index; i2++) { + cell3[b_i].f1[i2 + cell3[b_i].f1.size(0) * i1] = shiftedData[b_i] + .f1[i2 + shiftedData[b_i].f1.size(0) * i1]; + } + } + } + + resultCells[2].f1.set_size(cell3.size(0), 1); + b_index = cell3.size(0); + for (i1 = 0; i1 < b_index; i1++) { + resultCells[2].f1[i1] = cell3[i1]; + } + + // The size of this array now varies depending on TF + if (coder::internal::j_strcmp(problemStruct->TF.data, problemStruct->TF.size)) + { + i1 = 0; + } else { + i1 = -1; + } + + if (i1 == 0) { + cell4.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + b_index = domainLayerSlds[b_i].f1.size(1); + cell4[b_i].f1.set_size(domainLayerSlds[b_i].f1.size(0), + domainLayerSlds[b_i].f1.size(1)); + for (i1 = 0; i1 < b_index; i1++) { + loop_ub = domainLayerSlds[b_i].f1.size(0); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + cell4[b_i].f1[i2 + cell4[b_i].f1.size(0) * i1] = domainLayerSlds[b_i] + .f1[i2 + domainLayerSlds[b_i].f1.size(0) * i1]; + } + } + + b_index = domainLayerSlds[b_i + domainLayerSlds.size(0)].f1.size(1); + cell4[b_i + cell4.size(0)].f1.set_size(domainLayerSlds[b_i + + domainLayerSlds.size(0)].f1.size(0), domainLayerSlds[b_i + + domainLayerSlds.size(0)].f1.size(1)); + for (i1 = 0; i1 < b_index; i1++) { + loop_ub = domainLayerSlds[b_i + domainLayerSlds.size(0)].f1.size(0); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + cell4[b_i + cell4.size(0)].f1[i2 + cell4[b_i + cell4.size(0)]. + f1.size(0) * i1] = domainLayerSlds[b_i + domainLayerSlds.size(0)]. + f1[i2 + domainLayerSlds[b_i + domainLayerSlds.size(0)].f1.size(0) * + i1]; + } + } + } + + resultCells[3].f1.set_size(cell4.size(0), 2); + b_index = cell4.size(0); + for (i1 = 0; i1 < 2; i1++) { + for (int32_T i2{0}; i2 < b_index; i2++) { + resultCells[3].f1[i2 + resultCells[3].f1.size(0) * i1] = cell4[i2 + + cell4.size(0) * i1]; + } + } + + cell5.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + b_index = domainSldProfiles[b_i].f1.size(1); + cell5[b_i].f1.set_size(domainSldProfiles[b_i].f1.size(0), + domainSldProfiles[b_i].f1.size(1)); + for (i1 = 0; i1 < b_index; i1++) { + loop_ub = domainSldProfiles[b_i].f1.size(0); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + cell5[b_i].f1[i2 + cell5[b_i].f1.size(0) * i1] = + domainSldProfiles[b_i].f1[i2 + domainSldProfiles[b_i].f1.size(0) * + i1]; + } + } + + b_index = domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size(1); + cell5[b_i + cell5.size(0)].f1.set_size(domainSldProfiles[b_i + + domainSldProfiles.size(0)].f1.size(0), domainSldProfiles[b_i + + domainSldProfiles.size(0)].f1.size(1)); + for (i1 = 0; i1 < b_index; i1++) { + loop_ub = domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size(0); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + cell5[b_i + cell5.size(0)].f1[i2 + cell5[b_i + cell5.size(0)]. + f1.size(0) * i1] = domainSldProfiles[b_i + domainSldProfiles.size + (0)].f1[i2 + domainSldProfiles[b_i + domainSldProfiles.size(0)]. + f1.size(0) * i1]; + } + } + } + + resultCells[4].f1.set_size(cell5.size(0), 2); + b_index = cell5.size(0); + for (i1 = 0; i1 < 2; i1++) { + for (int32_T i2{0}; i2 < b_index; i2++) { + resultCells[4].f1[i2 + resultCells[4].f1.size(0) * i1] = cell5[i2 + + cell5.size(0) * i1]; + } + } + + cell6.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + b_index = domainAllLayers[b_i].f1.size(0); + cell6[b_i].f1.set_size(domainAllLayers[b_i].f1.size(0), 3); + loop_ub = domainAllLayers[b_i + domainAllLayers.size(0)].f1.size(0); + cell6[b_i + cell6.size(0)].f1.set_size(domainAllLayers[b_i + + domainAllLayers.size(0)].f1.size(0), 3); + for (i1 = 0; i1 < 3; i1++) { + for (int32_T i2{0}; i2 < b_index; i2++) { + cell6[b_i].f1[i2 + cell6[b_i].f1.size(0) * i1] = domainAllLayers[b_i] + .f1[i2 + domainAllLayers[b_i].f1.size(0) * i1]; + } + + for (int32_T i2{0}; i2 < loop_ub; i2++) { + cell6[b_i + cell6.size(0)].f1[i2 + cell6[b_i + cell6.size(0)]. + f1.size(0) * i1] = domainAllLayers[b_i + domainAllLayers.size(0)]. + f1[i2 + domainAllLayers[b_i + domainAllLayers.size(0)].f1.size(0) * + i1]; + } + } + } + + resultCells[5].f1.set_size(cell6.size(0), 2); + b_index = cell6.size(0); + for (i = 0; i < 2; i++) { + for (i1 = 0; i1 < b_index; i1++) { + resultCells[5].f1[i1 + resultCells[5].f1.size(0) * i] = cell6[i1 + + cell6.size(0) * i]; + } + } + } else { + cell4.set_size(i, 1); + for (int32_T b_i{0}; b_i < i; b_i++) { + b_index = layerSlds[b_i].f1.size(1); + cell4[b_i].f1.set_size(layerSlds[b_i].f1.size(0), layerSlds[b_i].f1.size + (1)); + for (i1 = 0; i1 < b_index; i1++) { + loop_ub = layerSlds[b_i].f1.size(0); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + cell4[b_i].f1[i2 + cell4[b_i].f1.size(0) * i1] = layerSlds[b_i] + .f1[i2 + layerSlds[b_i].f1.size(0) * i1]; + } + } + } + + resultCells[3].f1.set_size(cell4.size(0), 1); + b_index = cell4.size(0); + for (i1 = 0; i1 < b_index; i1++) { + resultCells[3].f1[i1] = cell4[i1]; + } + + cell5.set_size(i, 1); + for (int32_T b_i{0}; b_i < i; b_i++) { + b_index = sldProfiles[b_i].f1.size(0); + cell5[b_i].f1.set_size(sldProfiles[b_i].f1.size(0), 2); + for (i1 = 0; i1 < 2; i1++) { + for (int32_T i2{0}; i2 < b_index; i2++) { + cell5[b_i].f1[i2 + cell5[b_i].f1.size(0) * i1] = sldProfiles[b_i] + .f1[i2 + sldProfiles[b_i].f1.size(0) * i1]; + } + } + } + + resultCells[4].f1.set_size(cell5.size(0), 1); + b_index = cell5.size(0); + for (i1 = 0; i1 < b_index; i1++) { + resultCells[4].f1[i1] = cell5[i1]; + } + + cell6.set_size(i, 1); + for (int32_T b_i{0}; b_i < i; b_i++) { + b_index = allLayers[b_i].f1.size(0); + cell6[b_i].f1.set_size(allLayers[b_i].f1.size(0), 3); + for (i1 = 0; i1 < 3; i1++) { + for (int32_T i2{0}; i2 < b_index; i2++) { + cell6[b_i].f1[i2 + cell6[b_i].f1.size(0) * i1] = allLayers[b_i] + .f1[i2 + allLayers[b_i].f1.size(0) * i1]; + } + } + } + + resultCells[5].f1.set_size(cell6.size(0), 1); + b_index = cell6.size(0); + for (i = 0; i < b_index; i++) { + resultCells[5].f1[i] = cell6[i]; + } + } + + // Pre-processor directives for Matlab Coder + // to define the size of the output array + // Result coder definitions.... + // Reflectivity + // simulation + // Shifted data + // coder.varsize('result{4}',[Inf 2],[1 1]); %Layers slds + // coder.varsize('result{4}{:}',[Inf 6],[1 1]); + // coder.varsize('result{5}',[Inf 2],[1 1]); %Sld profiles + // coder.varsize('results{5}{:}',[Inf 2],[1 2]); + // coder.varsize('result{6}',[Inf 2],[1 1]); %All layers (resampled) + // coder.varsize('result{6}{:}',[Inf 3],[1 0]); + } +} + +// End of code generation (reflectivityCalculation.cpp) diff --git a/cpp/RAT/reflectivityCalculation.h b/cpp/RAT/reflectivityCalculation.h new file mode 100644 index 00000000..d82580bb --- /dev/null +++ b/cpp/RAT/reflectivityCalculation.h @@ -0,0 +1,38 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// reflectivityCalculation.h +// +// Code generation for function 'reflectivityCalculation' +// +#ifndef REFLECTIVITYCALCULATION_H +#define REFLECTIVITYCALCULATION_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct c_struct_T; + struct cell_11; + struct struct2_T; + struct d_struct_T; + struct cell_wrap_9; +} + +// Function Declarations +namespace RAT +{ + void reflectivityCalculation(const c_struct_T *problemStruct, const cell_11 + *problemCells, const struct2_T *controls, d_struct_T *contrastParams, + cell_wrap_9 resultCells[6]); +} + +#endif + +// End of code generation (reflectivityCalculation.h) diff --git a/cpp/RAT/reflectivityCalculation1.cpp b/cpp/RAT/reflectivityCalculation1.cpp new file mode 100644 index 00000000..a7cc5e3f --- /dev/null +++ b/cpp/RAT/reflectivityCalculation1.cpp @@ -0,0 +1,153 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// reflectivityCalculation1.cpp +// +// Code generation for function 'reflectivityCalculation1' +// + +// Include files +#include "reflectivityCalculation1.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "calculate.h" +#include "calculate1.h" +#include "calculate2.h" +#include "lower.h" +#include "rt_nonfinite.h" +#include "strcmp.h" +#include "coder_array.h" +#include "coder_bounded_array.h" + +// Function Definitions +namespace RAT +{ + namespace nonPolarisedTF + { + void b_reflectivityCalculation(const c_struct_T *problemStruct, const + cell_11 *problemCells, const struct2_T *controls, d_struct_T + *contrastParams, ::coder::array &reflectivity, ::coder:: + array &simulation, ::coder::array + &shiftedData, ::coder::array &layerSlds, ::coder::array< + cell_wrap_8, 1U> &sldProfiles, ::coder::array &allLayers) + { + int32_T switch_expression_size[2]; + int32_T loop_ub_tmp; + char_T switch_expression_data[10000]; + + // Main function for the nonPolarisedTF reflectivity calculation + // This function decides what type of model is being analysed and barnches + // to the correct one. The main options are: + // layers - This is the equivalent of Standard Layers in RasCAL + // Custom Layers - This is also a layers calculation, but the + // specification of the layers is dne using a user defined + // function. + // Custom XY - This also has a model described by a user supplied + // function, but in this case the function generates an + // SLD profile (i.e. XY function) rather than a list of + // layers. + // Find out the model type from the input structs + // Pre-allocate the output arrays.. this is necessary because otherwise + // the compiler complains with 'Output argument <....> is not assigned on + // some execution paths' error. + loop_ub_tmp = static_cast(problemStruct->numberOfContrasts); + contrastParams->ssubs.set_size(loop_ub_tmp); + contrastParams->backgroundParams.set_size(loop_ub_tmp); + contrastParams->qzshifts.set_size(loop_ub_tmp); + contrastParams->scalefactors.set_size(loop_ub_tmp); + contrastParams->bulkIn.set_size(loop_ub_tmp); + contrastParams->bulkOut.set_size(loop_ub_tmp); + contrastParams->resolutionParams.set_size(loop_ub_tmp); + contrastParams->calculations.allChis.set_size(loop_ub_tmp); + contrastParams->calculations.sumChi = 0.0; + contrastParams->allSubRough.set_size(loop_ub_tmp); + contrastParams->resample.set_size(1, loop_ub_tmp); + reflectivity.set_size(loop_ub_tmp); + simulation.set_size(loop_ub_tmp); + shiftedData.set_size(loop_ub_tmp); + layerSlds.set_size(loop_ub_tmp); + sldProfiles.set_size(loop_ub_tmp); + allLayers.set_size(loop_ub_tmp); + for (int32_T i{0}; i < loop_ub_tmp; i++) { + contrastParams->ssubs[i] = 0.0; + contrastParams->backgroundParams[i] = 0.0; + contrastParams->qzshifts[i] = 0.0; + contrastParams->scalefactors[i] = 0.0; + contrastParams->bulkIn[i] = 0.0; + contrastParams->bulkOut[i] = 0.0; + contrastParams->resolutionParams[i] = 0.0; + contrastParams->calculations.allChis[i] = 0.0; + contrastParams->allSubRough[i] = 0.0; + contrastParams->resample[i] = 0.0; + reflectivity[i].f1.set_size(2, 2); + reflectivity[i].f1[0] = 1.0; + reflectivity[i].f1[1] = 1.0; + reflectivity[i].f1[reflectivity[i].f1.size(0)] = 1.0; + reflectivity[i].f1[reflectivity[i].f1.size(0) + 1] = 1.0; + simulation[i].f1.set_size(2, 2); + simulation[i].f1[0] = 1.0; + simulation[i].f1[1] = 1.0; + simulation[i].f1[simulation[i].f1.size(0)] = 1.0; + simulation[i].f1[simulation[i].f1.size(0) + 1] = 1.0; + shiftedData[i].f1.set_size(2, 3); + layerSlds[i].f1.set_size(2, 3); + sldProfiles[i].f1.set_size(2, 2); + sldProfiles[i].f1[0] = 1.0; + sldProfiles[i].f1[1] = 1.0; + sldProfiles[i].f1[sldProfiles[i].f1.size(0)] = 1.0; + sldProfiles[i].f1[sldProfiles[i].f1.size(0) + 1] = 1.0; + allLayers[i].f1.set_size(2, 3); + for (int32_T b_i{0}; b_i < 3; b_i++) { + shiftedData[i].f1[shiftedData[i].f1.size(0) * b_i] = 1.0; + shiftedData[i].f1[shiftedData[i].f1.size(0) * b_i + 1] = 1.0; + layerSlds[i].f1[layerSlds[i].f1.size(0) * b_i] = 1.0; + layerSlds[i].f1[layerSlds[i].f1.size(0) * b_i + 1] = 1.0; + allLayers[i].f1[allLayers[i].f1.size(0) * b_i] = 1.0; + allLayers[i].f1[allLayers[i].f1.size(0) * b_i + 1] = 1.0; + } + } + + coder::lower(problemStruct->modelType.data, problemStruct->modelType.size, + switch_expression_data, switch_expression_size); + if (coder::internal::k_strcmp(switch_expression_data, + switch_expression_size)) { + loop_ub_tmp = 0; + } else if (coder::internal::l_strcmp(switch_expression_data, + switch_expression_size)) { + loop_ub_tmp = 1; + } else if (coder::internal::m_strcmp(switch_expression_data, + switch_expression_size)) { + loop_ub_tmp = 2; + } else { + loop_ub_tmp = -1; + } + + switch (loop_ub_tmp) { + case 0: + // Standard layers calculation + standardLayers::calculate(problemStruct, problemCells, controls, + contrastParams, reflectivity, simulation, shiftedData, layerSlds, + sldProfiles, allLayers); + break; + + case 1: + // Custom layers with user supplied custom model file + customLayers::calculate(problemStruct, problemCells, controls, + contrastParams, reflectivity, simulation, shiftedData, layerSlds, + sldProfiles, allLayers); + break; + + case 2: + // Custom SLD profile with user defined model file + customXY::calculate(problemStruct, problemCells, controls, + contrastParams, reflectivity, simulation, + shiftedData, layerSlds, sldProfiles, allLayers); + break; + } + } + } +} + +// End of code generation (reflectivityCalculation1.cpp) diff --git a/cpp/RAT/reflectivityCalculation1.h b/cpp/RAT/reflectivityCalculation1.h new file mode 100644 index 00000000..4d2dc677 --- /dev/null +++ b/cpp/RAT/reflectivityCalculation1.h @@ -0,0 +1,37 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// reflectivityCalculation1.h +// +// Code generation for function 'reflectivityCalculation1' +// +#ifndef REFLECTIVITYCALCULATION1_H +#define REFLECTIVITYCALCULATION1_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace nonPolarisedTF + { + void b_reflectivityCalculation(const c_struct_T *problemStruct, const + cell_11 *problemCells, const struct2_T *controls, d_struct_T + *contrastParams, ::coder::array &reflectivity, ::coder:: + array &simulation, ::coder::array + &shiftedData, ::coder::array &layerSlds, ::coder::array< + cell_wrap_8, 1U> &sldProfiles, ::coder::array &allLayers); + } +} + +#endif + +// End of code generation (reflectivityCalculation1.h) diff --git a/cpp/RAT/reflectivityCalculation2.cpp b/cpp/RAT/reflectivityCalculation2.cpp new file mode 100644 index 00000000..58048bf6 --- /dev/null +++ b/cpp/RAT/reflectivityCalculation2.cpp @@ -0,0 +1,230 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// reflectivityCalculation2.cpp +// +// Code generation for function 'reflectivityCalculation2' +// + +// Include files +#include "reflectivityCalculation2.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "calculate3.h" +#include "calculate4.h" +#include "calculate5.h" +#include "lower.h" +#include "rt_nonfinite.h" +#include "strcmp.h" +#include "coder_array.h" +#include "coder_bounded_array.h" + +// Function Definitions +namespace RAT +{ + namespace domainsTF + { + void b_reflectivityCalculation(const c_struct_T *problemStruct, const + cell_11 *problemCells, const struct2_T *controls, d_struct_T + *contrastParams, ::coder::array &reflectivity, ::coder:: + array &simulation, ::coder::array + &shiftedData, ::coder::array &layerSlds, ::coder::array< + cell_wrap_8, 2U> &domainSldProfiles, ::coder::array + &allLayers) + { + ::coder::array b_domainSldProfiles; + ::coder::array b_layerSlds; + ::coder::array r; + int32_T switch_expression_size[2]; + int32_T loop_ub_tmp; + char_T switch_expression_data[10000]; + + // Main function for the domainsTF reflectivity calculation + // This function decides what type of model is being analysed and barnches + // to the correct one. The main options are: + // layers - This is the equivalent of Standard Layers in RasCAL + // Custom Layers - This is also a layers calculation, but the + // specification of the layers is dne using a user defined + // function. + // Custom XY - This also has a model described by a user supplied + // function, but in this case the function generates an + // SLD profile (i.e. XY function) rather than a list of + // layers. + // Find out the model type from the input structs + // Pre-allocate the output arrays.. this is necessary because otherwise + // the compiler complains with 'Output argument <....> is not assigned on + // some execution paths' error. + loop_ub_tmp = static_cast(problemStruct->numberOfContrasts); + contrastParams->ssubs.set_size(loop_ub_tmp); + contrastParams->backgroundParams.set_size(loop_ub_tmp); + contrastParams->qzshifts.set_size(loop_ub_tmp); + contrastParams->scalefactors.set_size(loop_ub_tmp); + contrastParams->bulkIn.set_size(loop_ub_tmp); + contrastParams->bulkOut.set_size(loop_ub_tmp); + contrastParams->resolutionParams.set_size(loop_ub_tmp); + contrastParams->calculations.allChis.set_size(loop_ub_tmp); + contrastParams->calculations.sumChi = 0.0; + contrastParams->allSubRough.set_size(loop_ub_tmp); + contrastParams->resample.set_size(1, loop_ub_tmp); + reflectivity.set_size(loop_ub_tmp); + simulation.set_size(loop_ub_tmp); + shiftedData.set_size(loop_ub_tmp); + layerSlds.set_size(loop_ub_tmp, 2); + domainSldProfiles.set_size(loop_ub_tmp, 2); + allLayers.set_size(loop_ub_tmp, 2); + for (int32_T i{0}; i < loop_ub_tmp; i++) { + contrastParams->ssubs[i] = 0.0; + contrastParams->backgroundParams[i] = 0.0; + contrastParams->qzshifts[i] = 0.0; + contrastParams->scalefactors[i] = 0.0; + contrastParams->bulkIn[i] = 0.0; + contrastParams->bulkOut[i] = 0.0; + contrastParams->resolutionParams[i] = 0.0; + contrastParams->calculations.allChis[i] = 0.0; + contrastParams->allSubRough[i] = 0.0; + contrastParams->resample[i] = 0.0; + reflectivity[i].f1.set_size(2, 2); + reflectivity[i].f1[0] = 1.0; + reflectivity[i].f1[1] = 1.0; + reflectivity[i].f1[reflectivity[i].f1.size(0)] = 1.0; + reflectivity[i].f1[reflectivity[i].f1.size(0) + 1] = 1.0; + simulation[i].f1.set_size(2, 2); + simulation[i].f1[0] = 1.0; + simulation[i].f1[1] = 1.0; + simulation[i].f1[simulation[i].f1.size(0)] = 1.0; + simulation[i].f1[simulation[i].f1.size(0) + 1] = 1.0; + shiftedData[i].f1.set_size(2, 3); + layerSlds[i].f1.set_size(2, 3); + layerSlds[i + layerSlds.size(0)].f1.set_size(2, 3); + domainSldProfiles[i].f1.set_size(2, 2); + domainSldProfiles[i + domainSldProfiles.size(0)].f1.set_size(2, 2); + domainSldProfiles[i].f1[0] = 1.0; + domainSldProfiles[i + domainSldProfiles.size(0)].f1[0] = 1.0; + domainSldProfiles[i].f1[1] = 1.0; + domainSldProfiles[i + domainSldProfiles.size(0)].f1[1] = 1.0; + domainSldProfiles[i].f1[domainSldProfiles[i].f1.size(0)] = 1.0; + domainSldProfiles[i + domainSldProfiles.size(0)].f1[domainSldProfiles[i + + domainSldProfiles.size(0)].f1.size(0)] = 1.0; + domainSldProfiles[i].f1[domainSldProfiles[i].f1.size(0) + 1] = 1.0; + domainSldProfiles[i + domainSldProfiles.size(0)].f1[domainSldProfiles[i + + domainSldProfiles.size(0)].f1.size(0) + 1] = 1.0; + allLayers[i].f1.set_size(2, 3); + allLayers[i + allLayers.size(0)].f1.set_size(2, 3); + for (int32_T b_i{0}; b_i < 3; b_i++) { + shiftedData[i].f1[shiftedData[i].f1.size(0) * b_i] = 1.0; + shiftedData[i].f1[shiftedData[i].f1.size(0) * b_i + 1] = 1.0; + layerSlds[i].f1[layerSlds[i].f1.size(0) * b_i] = 1.0; + layerSlds[i + layerSlds.size(0)].f1[layerSlds[i + layerSlds.size(0)]. + f1.size(0) * b_i] = 1.0; + layerSlds[i].f1[layerSlds[i].f1.size(0) * b_i + 1] = 1.0; + layerSlds[i + layerSlds.size(0)].f1[layerSlds[i + layerSlds.size(0)]. + f1.size(0) * b_i + 1] = 1.0; + allLayers[i].f1[allLayers[i].f1.size(0) * b_i] = 1.0; + allLayers[i + allLayers.size(0)].f1[allLayers[i + allLayers.size(0)]. + f1.size(0) * b_i] = 1.0; + allLayers[i].f1[allLayers[i].f1.size(0) * b_i + 1] = 1.0; + allLayers[i + allLayers.size(0)].f1[allLayers[i + allLayers.size(0)]. + f1.size(0) * b_i + 1] = 1.0; + } + } + + coder::lower(problemStruct->modelType.data, problemStruct->modelType.size, + switch_expression_data, switch_expression_size); + if (coder::internal::k_strcmp(switch_expression_data, + switch_expression_size)) { + loop_ub_tmp = 0; + } else if (coder::internal::l_strcmp(switch_expression_data, + switch_expression_size)) { + loop_ub_tmp = 1; + } else if (coder::internal::m_strcmp(switch_expression_data, + switch_expression_size)) { + loop_ub_tmp = 2; + } else { + loop_ub_tmp = -1; + } + + switch (loop_ub_tmp) { + case 0: + // Standard layers calculation + standardLayers::calculate(problemStruct, problemCells, controls, + contrastParams, reflectivity, simulation, shiftedData, layerSlds, + domainSldProfiles, allLayers); + break; + + case 1: + { + int32_T loop_ub; + + // Custom layers with user supplied custom model file + customLayers::calculate(problemStruct, problemCells, controls, + contrastParams, reflectivity, simulation, shiftedData, b_layerSlds, + b_domainSldProfiles, r); + layerSlds.set_size(b_layerSlds.size(0), 2); + domainSldProfiles.set_size(b_domainSldProfiles.size(0), 2); + loop_ub_tmp = b_layerSlds.size(0); + loop_ub = b_domainSldProfiles.size(0); + for (int32_T b_i{0}; b_i < 2; b_i++) { + for (int32_T i1{0}; i1 < loop_ub_tmp; i1++) { + layerSlds[i1 + layerSlds.size(0) * b_i] = b_layerSlds[i1 + + b_layerSlds.size(0) * b_i]; + } + + for (int32_T i1{0}; i1 < loop_ub; i1++) { + domainSldProfiles[i1 + domainSldProfiles.size(0) * b_i] = + b_domainSldProfiles[i1 + b_domainSldProfiles.size(0) * b_i]; + } + } + + allLayers.set_size(r.size(0), r.size(1)); + loop_ub_tmp = r.size(1); + for (int32_T b_i{0}; b_i < loop_ub_tmp; b_i++) { + loop_ub = r.size(0); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + allLayers[i1 + allLayers.size(0) * b_i] = r[i1 + r.size(0) * b_i]; + } + } + } + break; + + case 2: + { + int32_T loop_ub; + + // Custom SLD profile with user defined model file + customXY::calculate(problemStruct, problemCells, controls, + contrastParams, reflectivity, simulation, + shiftedData, b_layerSlds, b_domainSldProfiles, r); + layerSlds.set_size(b_layerSlds.size(0), 2); + domainSldProfiles.set_size(b_domainSldProfiles.size(0), 2); + loop_ub_tmp = b_layerSlds.size(0); + loop_ub = b_domainSldProfiles.size(0); + for (int32_T b_i{0}; b_i < 2; b_i++) { + for (int32_T i1{0}; i1 < loop_ub_tmp; i1++) { + layerSlds[i1 + layerSlds.size(0) * b_i] = b_layerSlds[i1 + + b_layerSlds.size(0) * b_i]; + } + + for (int32_T i1{0}; i1 < loop_ub; i1++) { + domainSldProfiles[i1 + domainSldProfiles.size(0) * b_i] = + b_domainSldProfiles[i1 + b_domainSldProfiles.size(0) * b_i]; + } + } + + allLayers.set_size(r.size(0), r.size(1)); + loop_ub_tmp = r.size(1); + for (int32_T b_i{0}; b_i < loop_ub_tmp; b_i++) { + loop_ub = r.size(0); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + allLayers[i1 + allLayers.size(0) * b_i] = r[i1 + r.size(0) * b_i]; + } + } + } + break; + } + } + } +} + +// End of code generation (reflectivityCalculation2.cpp) diff --git a/cpp/RAT/reflectivityCalculation2.h b/cpp/RAT/reflectivityCalculation2.h new file mode 100644 index 00000000..57b89647 --- /dev/null +++ b/cpp/RAT/reflectivityCalculation2.h @@ -0,0 +1,38 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// reflectivityCalculation2.h +// +// Code generation for function 'reflectivityCalculation2' +// +#ifndef REFLECTIVITYCALCULATION2_H +#define REFLECTIVITYCALCULATION2_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace domainsTF + { + void b_reflectivityCalculation(const c_struct_T *problemStruct, const + cell_11 *problemCells, const struct2_T *controls, d_struct_T + *contrastParams, ::coder::array &reflectivity, ::coder:: + array &simulation, ::coder::array + &shiftedData, ::coder::array &layerSlds, ::coder::array< + cell_wrap_8, 2U> &domainSldProfiles, ::coder::array + &allLayers); + } +} + +#endif + +// End of code generation (reflectivityCalculation2.h) diff --git a/cpp/RAT/relop.cpp b/cpp/RAT/relop.cpp new file mode 100644 index 00000000..66b9f412 --- /dev/null +++ b/cpp/RAT/relop.cpp @@ -0,0 +1,68 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// relop.cpp +// +// Code generation for function 'relop' +// + +// Include files +#include "relop.h" +#include "rt_nonfinite.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + boolean_T b_relop(real_T a, real_T b) + { + boolean_T p; + if (std::isnan(b)) { + p = false; + } else if (std::isnan(a)) { + p = true; + } else { + p = (a > b); + } + + return p; + } + + boolean_T c_relop(real_T a, real_T b) + { + boolean_T p; + if (std::isnan(b)) { + p = !std::isnan(a); + } else if (std::isnan(a)) { + p = false; + } else { + p = (a < b); + } + + return p; + } + + boolean_T relop(real_T a, real_T b) + { + boolean_T p; + if (std::isnan(b)) { + p = false; + } else if (std::isnan(a)) { + p = true; + } else { + p = (a < b); + } + + return p; + } + } + } +} + +// End of code generation (relop.cpp) diff --git a/cpp/RAT/relop.h b/cpp/RAT/relop.h new file mode 100644 index 00000000..f0a74ef6 --- /dev/null +++ b/cpp/RAT/relop.h @@ -0,0 +1,34 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// relop.h +// +// Code generation for function 'relop' +// +#ifndef RELOP_H +#define RELOP_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + boolean_T b_relop(real_T a, real_T b); + boolean_T c_relop(real_T a, real_T b); + boolean_T relop(real_T a, real_T b); + } + } +} + +#endif + +// End of code generation (relop.h) diff --git a/cpp/RAT/removeOutlier.cpp b/cpp/RAT/removeOutlier.cpp new file mode 100644 index 00000000..67e71574 --- /dev/null +++ b/cpp/RAT/removeOutlier.cpp @@ -0,0 +1,261 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// removeOutlier.cpp +// +// Code generation for function 'removeOutlier' +// + +// Include files +#include "removeOutlier.h" +#include "RATMain_types.h" +#include "find.h" +#include "mean.h" +#include "nullAssignment.h" +#include "prctile.h" +#include "randperm.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Declarations +namespace RAT +{ + static void iqr(const ::coder::array &log_L, ::coder::array &idx_outlier); +} + +// Function Definitions +namespace RAT +{ + static void iqr(const ::coder::array &log_L, ::coder::array &idx_outlier) + { + ::coder::array r; + ::coder::array b_log_L; + real_T Q[2]; + real_T b_Q; + int32_T loop_ub; + + // Secondary functions used by this function + // ------------------------------------------------------------------------- + // ------------------- Interquartie range diagnostic ----------------------- + // ------------------------------------------------------------------------- + // Derive the upper and lower quantile of the data + coder::prctile(log_L, Q); + + // Derive the inter quartile range + // Are there any outlier chains ( 2 * IQR is liberal - normal is 1.5 * IQR) + b_Q = Q[1] - 2.0 * (Q[0] - Q[1]); + b_log_L.set_size(1, log_L.size(1)); + loop_ub = log_L.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_log_L[i] = (log_L[i] < b_Q); + } + + coder::d_eml_find(b_log_L, r); + idx_outlier.set_size(1, r.size(1)); + loop_ub = r.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + idx_outlier[i] = r[i]; + } + } + + void removeOutlier(::coder::array &X, ::coder::array + &log_L, const real_T outlier_data[], const int32_T + outlier_size[2], const struct13_T *DREAMPar, ::coder::array< + real_T, 2U> &outputOutlier) + { + ::coder::array b_chain_select; + ::coder::array b_log_L; + ::coder::array b_outputOutlier; + ::coder::array chain_id; + ::coder::array chain_select; + ::coder::array r; + ::coder::array c_log_L; + ::coder::array b_chain_id; + int32_T b_loop_ub; + int32_T chain_select_tmp; + int32_T i; + int32_T i1; + int32_T loop_ub; + int32_T t_half; + + // Finds outlier chains and removes them when needed + // Determine the number of elements of L_density + t_half = static_cast(std::floor(static_cast(log_L.size(0)) / + 2.0)); + + // Then determine the mean log density of the active chains + if (t_half > log_L.size(0)) { + i = 0; + i1 = 0; + } else { + i = t_half - 1; + i1 = log_L.size(0); + } + + if (DREAMPar->N < 1.0) { + loop_ub = 0; + } else { + loop_ub = static_cast(DREAMPar->N); + } + + // ------------------------------ + // Always use the same outlier check (to remove eval) + // ---------------------------------- AVH + b_loop_ub = i1 - i; + b_log_L.set_size(b_loop_ub, loop_ub); + for (i1 = 0; i1 < loop_ub; i1++) { + for (chain_select_tmp = 0; chain_select_tmp < b_loop_ub; chain_select_tmp + ++) { + b_log_L[chain_select_tmp + b_log_L.size(0) * i1] = log_L[(i + + chain_select_tmp) + log_L.size(0) * i1]; + } + } + + coder::mean(b_log_L, chain_select); + iqr(chain_select, chain_id); + + // % Create outlier handle + // evalstr = strcat('chain_id=',DREAMPar.outlier,'(mean_log_L);'); + // + // % Now evaluate outlier handle + // try + // eval(evalstr); + // catch + // % Warning -- not enough chains to do sampling -- increase number of chains! + // fprintf('DREAM WARNING: Unknown outlier detection test at %d generations \n',t); + // % Now print warning to screen and to file + // %fprintf(evalstr); % fprintf(fid,evalstr); + // % No outlier detected + // outlier = []; + // return + // end + outputOutlier.set_size(outlier_size[0], 2); + loop_ub = outlier_size[0]; + for (i = 0; i < 2; i++) { + for (i1 = 0; i1 < loop_ub; i1++) { + outputOutlier[i1 + outputOutlier.size(0) * i] = outlier_data[i1 + + outlier_size[0] * i]; + } + } + + // How many outliers? + // If at least one outlier chain has been found --> reset its state + if (chain_id.size(1) > 0) { + // Re-initialize ecah outlier chain to current state random other chain + if (std::isnan(DREAMPar->N)) { + b_chain_select.set_size(1, 1); + b_chain_select[0] = rtNaN; + } else if (DREAMPar->N < 1.0) { + b_chain_select.set_size(1, 0); + } else { + b_chain_select.set_size(1, static_cast(DREAMPar->N - 1.0) + 1); + loop_ub = static_cast(DREAMPar->N - 1.0); + for (i = 0; i <= loop_ub; i++) { + b_chain_select[i] = static_cast(i) + 1.0; + } + } + + b_chain_id.set_size(1, chain_id.size(1)); + loop_ub = chain_id.size(1); + for (i = 0; i < loop_ub; i++) { + b_chain_id[i] = static_cast(chain_id[i]); + } + + coder::internal::nullAssignment(b_chain_select, b_chain_id); + + // Randomly permute these available chains + coder::randperm(DREAMPar->N - static_cast(chain_id.size(1)), r); + chain_select.set_size(1, r.size(1)); + loop_ub = r.size(1); + for (i = 0; i < loop_ub; i++) { + chain_select[i] = b_chain_select[static_cast(r[i]) - 1]; + } + + b_chain_select.set_size(1, chain_select.size(1)); + loop_ub = chain_select.size(1); + for (i = 0; i < loop_ub; i++) { + b_chain_select[i] = chain_select[i]; + } + + // Loop over each outlier chain + i = chain_id.size(1); + loop_ub = static_cast(DREAMPar->d + 2.0); + for (int32_T j{0}; j < i; j++) { + int32_T chain_id_tmp; + int16_T i2; + + // Added -- update log_L -- chain will not be considered as an outlier chain then + chain_select_tmp = static_cast(b_chain_select[j]); + chain_id_tmp = static_cast(chain_id[j]); + b_loop_ub = log_L.size(0); + c_log_L.set_size(b_loop_ub); + for (i1 = 0; i1 < b_loop_ub; i1++) { + c_log_L[i1] = log_L[i1 + log_L.size(0) * (chain_select_tmp - 1)]; + } + + b_loop_ub = c_log_L.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + log_L[i1 + log_L.size(0) * (chain_id_tmp - 1)] = c_log_L[i1]; + } + + // Jump outlier chain to r_idx -- X + chain_select.set_size(1, loop_ub); + for (i1 = 0; i1 < loop_ub; i1++) { + chain_select[i1] = X[(chain_select_tmp + X.size(0) * i1) - 1]; + } + + b_loop_ub = chain_select.size(1); + for (i1 = 0; i1 < b_loop_ub; i1++) { + X[(chain_id_tmp + X.size(0) * i1) - 1] = chain_select[i1]; + } + + // Add to chain_outlier and print to screen + if (outputOutlier.size(0) != 0) { + i2 = static_cast(outputOutlier.size(0)); + } else { + i2 = 0; + } + + if (outputOutlier.size(0) != 0) { + b_loop_ub = static_cast(outputOutlier.size(0)); + } else { + b_loop_ub = 0; + } + + b_outputOutlier.set_size(i2 + 1, 2); + for (i1 = 0; i1 < 2; i1++) { + for (chain_select_tmp = 0; chain_select_tmp < b_loop_ub; + chain_select_tmp++) { + b_outputOutlier[chain_select_tmp + b_outputOutlier.size(0) * i1] = + outputOutlier[chain_select_tmp + i2 * i1]; + } + } + + b_outputOutlier[static_cast(i2)] = log_L.size(0); + b_outputOutlier[i2 + b_outputOutlier.size(0)] = chain_id[j]; + outputOutlier.set_size(b_outputOutlier.size(0), 2); + b_loop_ub = b_outputOutlier.size(0); + for (i1 = 0; i1 < 2; i1++) { + for (chain_select_tmp = 0; chain_select_tmp < b_loop_ub; + chain_select_tmp++) { + outputOutlier[chain_select_tmp + outputOutlier.size(0) * i1] = + b_outputOutlier[chain_select_tmp + b_outputOutlier.size(0) * i1]; + } + } + + // Warning -- not enough chains to do sampling -- increase number of chains! + // evalstr = char(strcat('DREAM WARNING: Irreversible jump chain',{' '},num2str(chain_id(j)),{' '},'at',{' '},num2str(t),{' '},'generations \n')); + // fprintf(' DREAM WARNING: Irreversible jump chain %0.2f at %0.2f generations \n \n \n',chain_id(j),t) + // Now print warning to screen and to file + // fprintf(evalstr); % fprintf(fid,evalstr); + } + } + } +} + +// End of code generation (removeOutlier.cpp) diff --git a/cpp/RAT/removeOutlier.h b/cpp/RAT/removeOutlier.h new file mode 100644 index 00000000..a7365419 --- /dev/null +++ b/cpp/RAT/removeOutlier.h @@ -0,0 +1,36 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// removeOutlier.h +// +// Code generation for function 'removeOutlier' +// +#ifndef REMOVEOUTLIER_H +#define REMOVEOUTLIER_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct struct13_T; +} + +// Function Declarations +namespace RAT +{ + void removeOutlier(::coder::array &X, ::coder::array + &log_L, const real_T outlier_data[], const int32_T + outlier_size[2], const struct13_T *DREAMPar, ::coder::array< + real_T, 2U> &outputOutlier); +} + +#endif + +// End of code generation (removeOutlier.h) diff --git a/cpp/RAT/repmat.cpp b/cpp/RAT/repmat.cpp new file mode 100644 index 00000000..5879c34d --- /dev/null +++ b/cpp/RAT/repmat.cpp @@ -0,0 +1,99 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// repmat.cpp +// +// Code generation for function 'repmat' +// + +// Include files +#include "repmat.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + void b_repmat(real_T varargin_2, ::coder::array &b) + { + int32_T loop_ub_tmp; + loop_ub_tmp = static_cast(varargin_2); + b.set_size(1, loop_ub_tmp); + for (int32_T i{0}; i < loop_ub_tmp; i++) { + b[i] = '.'; + } + } + + void repmat(cell_wrap_9 b[6]) + { + cell_wrap_8 r; + r.f1.set_size(1, 1); + r.f1[0] = 1.0; + for (int32_T jtilecol{0}; jtilecol < 6; jtilecol++) { + b[jtilecol].f1.set_size(1, 1); + b[jtilecol].f1[0] = r; + } + } + + void repmat(real_T varargin_1, ::coder::array &b) + { + int32_T loop_ub_tmp; + loop_ub_tmp = static_cast(varargin_1); + b.set_size(loop_ub_tmp); + for (int32_T i{0}; i < loop_ub_tmp; i++) { + b[i].I_no = 0.0; + b[i].FVr_oa = 0.0; + } + } + + void repmat(const ::coder::array &a, real_T varargin_1, ::coder:: + array &b) + { + b.set_size(static_cast(varargin_1), a.size(1)); + if ((static_cast(varargin_1) != 0) && (a.size(1) != 0)) { + int32_T i; + int32_T na; + na = a.size(1); + i = static_cast(varargin_1) - 1; + for (int32_T k{0}; k < na; k++) { + for (int32_T t{0}; t <= i; t++) { + b[t + b.size(0) * k] = a[k]; + } + } + } + } + + void repmat(real_T varargin_2, ::coder::array &b) + { + int32_T loop_ub_tmp; + loop_ub_tmp = static_cast(varargin_2); + b.set_size(1, loop_ub_tmp); + for (int32_T i{0}; i < loop_ub_tmp; i++) { + b[i] = '*'; + } + } + + void repmat(const real_T a[2], real_T varargin_1, ::coder::array + &b) + { + b.set_size(static_cast(varargin_1), 2); + if (static_cast(varargin_1) != 0) { + int32_T i; + i = static_cast(varargin_1) - 1; + for (int32_T k{0}; k < 2; k++) { + for (int32_T t{0}; t <= i; t++) { + b[t + b.size(0) * k] = a[k]; + } + } + } + } + } +} + +// End of code generation (repmat.cpp) diff --git a/cpp/RAT/repmat.h b/cpp/RAT/repmat.h new file mode 100644 index 00000000..6f35398c --- /dev/null +++ b/cpp/RAT/repmat.h @@ -0,0 +1,44 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// repmat.h +// +// Code generation for function 'repmat' +// +#ifndef REPMAT_H +#define REPMAT_H + +// Include files +#include "RATMain_internal_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct cell_wrap_9; +} + +// Function Declarations +namespace RAT +{ + namespace coder + { + void b_repmat(real_T varargin_2, ::coder::array &b); + void repmat(cell_wrap_9 b[6]); + void repmat(real_T varargin_1, ::coder::array &b); + void repmat(const ::coder::array &a, real_T varargin_1, ::coder:: + array &b); + void repmat(real_T varargin_2, ::coder::array &b); + void repmat(const real_T a[2], real_T varargin_1, ::coder::array + &b); + } +} + +#endif + +// End of code generation (repmat.h) diff --git a/cpp/RAT/resampleLayers.cpp b/cpp/RAT/resampleLayers.cpp new file mode 100644 index 00000000..0c086b40 --- /dev/null +++ b/cpp/RAT/resampleLayers.cpp @@ -0,0 +1,69 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// resampleLayers.cpp +// +// Code generation for function 'resampleLayers' +// + +// Include files +#include "resampleLayers.h" +#include "RATMain_internal_types.h" +#include "adaptive.h" +#include "length.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void resampleLayers(const ::coder::array &sldProfile, const real_T + resamPars[2], ::coder::array &newSLD) + { + cell_25 expl_temp; + real_T b_sldProfile[2]; + int32_T i; + int32_T n; + + // Function handle for adaptive resampling + // f = @(x) SLDFunction(x); + // + // Keep points and minangle as constants for now + // will fix later + b_sldProfile[0] = sldProfile[0]; + b_sldProfile[1] = sldProfile[sldProfile.size(0) - 1]; + adaptive(sldProfile, b_sldProfile, resamPars[0] * 3.1415926535897931, + resamPars[1], &expl_temp); + n = coder::internal::intlength(expl_temp.f1.size(0), 1); + newSLD.set_size(n - 1, 3); + n--; + for (i = 0; i < 3; i++) { + for (int32_T i1{0}; i1 < n; i1++) { + newSLD[i1 + newSLD.size(0) * i] = 0.0; + } + } + + // Now build a layer model from these resampled points + i = coder::internal::intlength(expl_temp.f1.size(0), 1); + for (n = 0; n <= i - 2; n++) { + real_T d; + real_T d1; + real_T thisLayRho; + d = expl_temp.f1[(n + expl_temp.f1.size(0)) + 1]; + d1 = expl_temp.f1[n + expl_temp.f1.size(0)]; + if (d > d1) { + thisLayRho = (d - d1) / 2.0 + d1; + } else { + thisLayRho = (d1 - d) / 2.0 + d; + } + + newSLD[n] = expl_temp.f1[n + 1] - expl_temp.f1[n]; + newSLD[n + newSLD.size(0)] = thisLayRho; + newSLD[n + newSLD.size(0) * 2] = 2.2204460492503131E-16; + } + } +} + +// End of code generation (resampleLayers.cpp) diff --git a/cpp/RAT/resampleLayers.h b/cpp/RAT/resampleLayers.h new file mode 100644 index 00000000..a2b0ad17 --- /dev/null +++ b/cpp/RAT/resampleLayers.h @@ -0,0 +1,28 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// resampleLayers.h +// +// Code generation for function 'resampleLayers' +// +#ifndef RESAMPLELAYERS_H +#define RESAMPLELAYERS_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void resampleLayers(const ::coder::array &sldProfile, const real_T + resamPars[2], ::coder::array &newSLD); +} + +#endif + +// End of code generation (resampleLayers.h) diff --git a/cpp/RAT/resampleLayersReIm.cpp b/cpp/RAT/resampleLayersReIm.cpp new file mode 100644 index 00000000..fe78e640 --- /dev/null +++ b/cpp/RAT/resampleLayersReIm.cpp @@ -0,0 +1,191 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// resampleLayersReIm.cpp +// +// Code generation for function 'resampleLayersReIm' +// + +// Include files +#include "resampleLayersReIm.h" +#include "RATMain_internal_types.h" +#include "adaptive.h" +#include "interp1.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void b_resampleLayersReIm(const ::coder::array &sldProfile, const :: + coder::array &sldProfileIm, const real_T resamPars[2], ::coder:: + array &newSLD) + { + ::coder::array b_expl_temp; + ::coder::array b_sldProfileIm; + ::coder::array c_sldProfileIm; + ::coder::array newYIm; + cell_25 expl_temp; + real_T b_sldProfile[2]; + int32_T i; + int32_T loop_ub; + + // Resample the SLD profile. In this case we have an imaginary SLD also, and + // so we resample that onto the same points as the real one.. + // Function handle for adaptive resampling + // f = @(x) SLDFunction(x); + // + // Keep points and minangle as constants for now + // will fix later + // newX = linspace(xstart,xend,100); + b_sldProfile[0] = sldProfile[0]; + b_sldProfile[1] = sldProfile[sldProfile.size(0) - 1]; + adaptive(sldProfile, b_sldProfile, resamPars[0] * 3.1415926535897931, + resamPars[1], &expl_temp); + + // Now interpolate the imaginary profile so that it is on the same x points + // as the resampled real one.... + b_sldProfileIm.set_size(sldProfileIm.size(0)); + loop_ub = sldProfileIm.size(0); + for (i = 0; i < loop_ub; i++) { + b_sldProfileIm[i] = sldProfileIm[i]; + } + + c_sldProfileIm.set_size(sldProfileIm.size(0)); + loop_ub = sldProfileIm.size(0); + for (i = 0; i < loop_ub; i++) { + c_sldProfileIm[i] = sldProfileIm[i + sldProfileIm.size(0)]; + } + + b_expl_temp.set_size(expl_temp.f1.size(0)); + loop_ub = expl_temp.f1.size(0); + for (i = 0; i < loop_ub; i++) { + b_expl_temp[i] = expl_temp.f1[i]; + } + + coder::interp1(b_sldProfileIm, c_sldProfileIm, b_expl_temp, newYIm); + newSLD.set_size(expl_temp.f1.size(0) - 1, 4); + loop_ub = expl_temp.f1.size(0) - 1; + for (i = 0; i < 4; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + newSLD[i1 + newSLD.size(0) * i] = 0.0; + } + } + + // Now build a layer model from these resampled points + i = expl_temp.f1.size(0); + for (int32_T n{0}; n <= i - 2; n++) { + real_T d; + real_T d1; + real_T thisLayRho; + real_T thisLayRhoIm; + d = expl_temp.f1[(n + expl_temp.f1.size(0)) + 1]; + d1 = expl_temp.f1[n + expl_temp.f1.size(0)]; + if (d > d1) { + thisLayRho = (d - d1) / 2.0 + d1; + } else { + thisLayRho = (d1 - d) / 2.0 + d; + } + + d = newYIm[n + 1]; + if (d > newYIm[n]) { + thisLayRhoIm = (d - newYIm[n]) / 2.0 + newYIm[n]; + } else { + thisLayRhoIm = (newYIm[n] - d) / 2.0 + d; + } + + newSLD[n] = expl_temp.f1[n + 1] - expl_temp.f1[n]; + newSLD[n + newSLD.size(0)] = thisLayRho; + newSLD[n + newSLD.size(0) * 2] = thisLayRhoIm; + newSLD[n + newSLD.size(0) * 3] = 2.2204460492503131E-16; + } + } + + void resampleLayersReIm(const ::coder::array &sldProfile, const :: + coder::array &sldProfileIm, const real_T resamPars[2], ::coder:: + array &newSLD) + { + ::coder::array b_expl_temp; + ::coder::array b_sldProfileIm; + ::coder::array c_sldProfileIm; + ::coder::array newYIm; + cell_25 expl_temp; + real_T b_sldProfile[2]; + int32_T i; + int32_T loop_ub; + + // Resample the SLD profile. In this case we have an imaginary SLD also, and + // so we resample that onto the same points as the real one.. + // Function handle for adaptive resampling + // f = @(x) SLDFunction(x); + // + // Keep points and minangle as constants for now + // will fix later + // newX = linspace(xstart,xend,100); + b_sldProfile[0] = sldProfile[0]; + b_sldProfile[1] = sldProfile[sldProfile.size(0) - 1]; + adaptive(sldProfile, b_sldProfile, resamPars[0] * 3.1415926535897931, + resamPars[1], &expl_temp); + + // Now interpolate the imaginary profile so that it is on the same x points + // as the resampled real one.... + b_sldProfileIm.set_size(sldProfileIm.size(0)); + loop_ub = sldProfileIm.size(0); + for (i = 0; i < loop_ub; i++) { + b_sldProfileIm[i] = sldProfileIm[i]; + } + + c_sldProfileIm.set_size(sldProfileIm.size(0)); + loop_ub = sldProfileIm.size(0); + for (i = 0; i < loop_ub; i++) { + c_sldProfileIm[i] = sldProfileIm[i + sldProfileIm.size(0)]; + } + + b_expl_temp.set_size(expl_temp.f1.size(0)); + loop_ub = expl_temp.f1.size(0); + for (i = 0; i < loop_ub; i++) { + b_expl_temp[i] = expl_temp.f1[i]; + } + + coder::interp1(b_sldProfileIm, c_sldProfileIm, b_expl_temp, newYIm); + newSLD.set_size(expl_temp.f1.size(0) - 1, 4); + loop_ub = expl_temp.f1.size(0) - 1; + for (i = 0; i < 4; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + newSLD[i1 + newSLD.size(0) * i] = 0.0; + } + } + + // Now build a layer model from these resampled points + i = expl_temp.f1.size(0); + for (int32_T n{0}; n <= i - 2; n++) { + real_T d; + real_T d1; + real_T thisLayRho; + real_T thisLayRhoIm; + d = expl_temp.f1[(n + expl_temp.f1.size(0)) + 1]; + d1 = expl_temp.f1[n + expl_temp.f1.size(0)]; + if (d > d1) { + thisLayRho = (d - d1) / 2.0 + d1; + } else { + thisLayRho = (d1 - d) / 2.0 + d; + } + + d = newYIm[n + 1]; + if (d > newYIm[n]) { + thisLayRhoIm = (d - newYIm[n]) / 2.0 + newYIm[n]; + } else { + thisLayRhoIm = (newYIm[n] - d) / 2.0 + d; + } + + newSLD[n] = expl_temp.f1[n + 1] - expl_temp.f1[n]; + newSLD[n + newSLD.size(0)] = thisLayRho; + newSLD[n + newSLD.size(0) * 2] = thisLayRhoIm; + newSLD[n + newSLD.size(0) * 3] = 2.2204460492503131E-16; + } + } +} + +// End of code generation (resampleLayersReIm.cpp) diff --git a/cpp/RAT/resampleLayersReIm.h b/cpp/RAT/resampleLayersReIm.h new file mode 100644 index 00000000..a943e3dc --- /dev/null +++ b/cpp/RAT/resampleLayersReIm.h @@ -0,0 +1,32 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// resampleLayersReIm.h +// +// Code generation for function 'resampleLayersReIm' +// +#ifndef RESAMPLELAYERSREIM_H +#define RESAMPLELAYERSREIM_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void b_resampleLayersReIm(const ::coder::array &sldProfile, const :: + coder::array &sldProfileIm, const real_T resamPars[2], ::coder:: + array &newSLD); + void resampleLayersReIm(const ::coder::array &sldProfile, const :: + coder::array &sldProfileIm, const real_T resamPars[2], ::coder:: + array &newSLD); +} + +#endif + +// End of code generation (resampleLayersReIm.h) diff --git a/cpp/RAT/rescale.cpp b/cpp/RAT/rescale.cpp new file mode 100644 index 00000000..faa00820 --- /dev/null +++ b/cpp/RAT/rescale.cpp @@ -0,0 +1,133 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// rescale.cpp +// +// Code generation for function 'rescale' +// + +// Include files +#include "rescale.h" +#include "bsxfun.h" +#include "rescaleKernel.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + void rescale(::coder::array &A, const ::coder::array + &varargin_2, const ::coder::array &varargin_4, :: + coder::array &R) + { + ::coder::array b_A; + real_T b_varargin_2; + real_T varargin_1; + int32_T loop_ub; + boolean_T p; + if (varargin_2.size(0) == 1) { + loop_ub = A.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + varargin_1 = A[i]; + b_varargin_2 = varargin_2[0]; + if (std::isnan(b_varargin_2)) { + p = !std::isnan(varargin_1); + } else if (std::isnan(varargin_1)) { + p = false; + } else { + p = (varargin_1 < b_varargin_2); + } + + if (p) { + A[i] = b_varargin_2; + } else { + A[i] = varargin_1; + } + } + } else { + b_A.set_size(A.size(0)); + loop_ub = A.size(0) - 1; + for (int32_T i{0}; i <= loop_ub; i++) { + b_A[i] = A[i]; + } + + bsxfun(b_A, varargin_2, A); + } + + if (varargin_4.size(0) == 1) { + R.set_size(A.size(0)); + loop_ub = A.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + varargin_1 = A[i]; + b_varargin_2 = varargin_4[0]; + if (std::isnan(b_varargin_2)) { + p = !std::isnan(varargin_1); + } else if (std::isnan(varargin_1)) { + p = false; + } else { + p = (varargin_1 > b_varargin_2); + } + + if (p) { + R[i] = b_varargin_2; + } else { + R[i] = varargin_1; + } + } + } else { + b_bsxfun(A, varargin_4, R); + } + + rescaleKernel(R, varargin_2, varargin_4); + } + + real_T rescale_anonFcn1(real_T x, real_T y) + { + real_T varargout_1; + boolean_T p; + if (std::isnan(y)) { + p = !std::isnan(x); + } else if (std::isnan(x)) { + p = false; + } else { + p = (x < y); + } + + if (p) { + varargout_1 = y; + } else { + varargout_1 = x; + } + + return varargout_1; + } + + real_T rescale_anonFcn2(real_T x, real_T y) + { + real_T varargout_1; + boolean_T p; + if (std::isnan(y)) { + p = !std::isnan(x); + } else if (std::isnan(x)) { + p = false; + } else { + p = (x > y); + } + + if (p) { + varargout_1 = y; + } else { + varargout_1 = x; + } + + return varargout_1; + } + } +} + +// End of code generation (rescale.cpp) diff --git a/cpp/RAT/rescale.h b/cpp/RAT/rescale.h new file mode 100644 index 00000000..8a6dd769 --- /dev/null +++ b/cpp/RAT/rescale.h @@ -0,0 +1,34 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// rescale.h +// +// Code generation for function 'rescale' +// +#ifndef RESCALE_H +#define RESCALE_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void rescale(::coder::array &A, const ::coder::array + &varargin_2, const ::coder::array &varargin_4, :: + coder::array &R); + real_T rescale_anonFcn1(real_T x, real_T y); + real_T rescale_anonFcn2(real_T x, real_T y); + } +} + +#endif + +// End of code generation (rescale.h) diff --git a/cpp/RAT/rescaleKernel.cpp b/cpp/RAT/rescaleKernel.cpp new file mode 100644 index 00000000..0315c72e --- /dev/null +++ b/cpp/RAT/rescaleKernel.cpp @@ -0,0 +1,953 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// rescaleKernel.cpp +// +// Code generation for function 'rescaleKernel' +// + +// Include files +#include "rescaleKernel.h" +#include "abs.h" +#include "bsxfun.h" +#include "div.h" +#include "log2.h" +#include "minOrMax.h" +#include "pow2.h" +#include "rdivide_helper.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Declarations +namespace RAT +{ + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3, const ::coder:: + array &in4, const ::coder::array &in5, const ::coder:: + array &in6); + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3, const ::coder:: + array &in4, const ::coder::array &in5, const ::coder:: + array &in6, const ::coder::array &in7); +} + +// Function Definitions +namespace RAT +{ + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3, const ::coder:: + array &in4, const ::coder::array &in5, const ::coder:: + array &in6) + { + ::coder::array r; + int32_T i; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_1_0; + int32_T stride_2_0; + int32_T stride_3_0; + int32_T stride_4_0; + int32_T stride_5_0; + int32_T stride_6_0; + if (in4.size(0) == 1) { + i = in6.size(0); + stride_0_0 = in5.size(0); + if (i == 1) { + if (stride_0_0 == 1) { + if (in4.size(0) == 1) { + i = in3.size(0); + } else { + i = in4.size(0); + } + } else if (in4.size(0) == 1) { + i = in5.size(0); + } else { + i = in4.size(0); + } + } else if (in4.size(0) == 1) { + i = in6.size(0); + } else { + i = in4.size(0); + } + } else { + i = in4.size(0); + } + + r.set_size(i); + stride_0_0 = (in3.size(0) != 1); + stride_1_0 = (in4.size(0) != 1); + stride_2_0 = (in5.size(0) != 1); + stride_3_0 = (in4.size(0) != 1); + stride_4_0 = (in6.size(0) != 1); + stride_5_0 = (in4.size(0) != 1); + stride_6_0 = (in4.size(0) != 1); + if (in4.size(0) == 1) { + i = in6.size(0); + if (i == 1) { + if (in4.size(0) == 1) { + i = in5.size(0); + } else { + i = in4.size(0); + } + + if (i == 1) { + if (in4.size(0) == 1) { + loop_ub = in3.size(0); + } else { + loop_ub = in4.size(0); + } + } else if (in4.size(0) == 1) { + loop_ub = in5.size(0); + } else { + loop_ub = in4.size(0); + } + } else if (in4.size(0) == 1) { + loop_ub = in6.size(0); + } else { + loop_ub = in4.size(0); + } + } else { + loop_ub = in4.size(0); + } + + for (i = 0; i < loop_ub; i++) { + r[i] = 1.0 / ((in3[i * stride_0_0] / in4[i * stride_1_0] - in5[i * + stride_2_0] / in4[i * stride_3_0]) + static_cast + (in6[i * stride_4_0]) / in4[i * stride_5_0]) / in4[i * + stride_6_0]; + } + + coder::e_bsxfun(in2, r, in1); + } + + static void binary_expand_op(::coder::array &in1, const ::coder:: + array &in2, const ::coder::array &in3, const ::coder:: + array &in4, const ::coder::array &in5, const ::coder:: + array &in6, const ::coder::array &in7) + { + ::coder::array b_in3; + int32_T i; + int32_T i1; + int32_T i2; + int32_T i3; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_10_0; + int32_T stride_11_0; + int32_T stride_1_0; + int32_T stride_2_0; + int32_T stride_3_0; + int32_T stride_4_0; + int32_T stride_5_0; + int32_T stride_6_0; + int32_T stride_7_0; + int32_T stride_8_0; + int32_T stride_9_0; + if (in7.size(0) == 1) { + i = in6.size(0); + } else { + i = in7.size(0); + } + + if (i == 1) { + if (in5.size(0) == 1) { + i = in1.size(0); + } else { + i = in5.size(0); + } + } else if (in7.size(0) == 1) { + i = in6.size(0); + } else { + i = in7.size(0); + } + + if (in4.size(0) == 1) { + if (in7.size(0) == 1) { + i1 = in6.size(0); + } else { + i1 = in7.size(0); + } + } else { + i1 = in4.size(0); + } + + if (in3.size(0) == 1) { + i2 = in5.size(0); + } else { + i2 = in3.size(0); + } + + if (in7.size(0) == 1) { + i3 = in6.size(0); + } else { + i3 = in7.size(0); + } + + if (i == 1) { + if (i1 == 1) { + if (i2 == 1) { + if (in4.size(0) == 1) { + i = in1.size(0); + } else { + i = in4.size(0); + } + } else if (in3.size(0) == 1) { + i = in5.size(0); + } else { + i = in3.size(0); + } + } else if (in4.size(0) == 1) { + if (in7.size(0) == 1) { + i = in6.size(0); + } else { + i = in7.size(0); + } + } else { + i = in4.size(0); + } + } else if (i3 == 1) { + if (in5.size(0) == 1) { + i = in1.size(0); + } else { + i = in5.size(0); + } + } else if (in7.size(0) == 1) { + i = in6.size(0); + } else { + i = in7.size(0); + } + + if (in7.size(0) == 1) { + i1 = in6.size(0); + } else { + i1 = in7.size(0); + } + + if (i1 == 1) { + if (in5.size(0) == 1) { + i1 = in1.size(0); + } else { + i1 = in5.size(0); + } + } else if (in7.size(0) == 1) { + i1 = in6.size(0); + } else { + i1 = in7.size(0); + } + + if (in4.size(0) == 1) { + if (in7.size(0) == 1) { + i2 = in6.size(0); + } else { + i2 = in7.size(0); + } + } else { + i2 = in4.size(0); + } + + if (in3.size(0) == 1) { + i3 = in5.size(0); + } else { + i3 = in3.size(0); + } + + if (in7.size(0) == 1) { + loop_ub = in6.size(0); + } else { + loop_ub = in7.size(0); + } + + if (i == 1) { + i = in3.size(0); + } else if (i1 == 1) { + if (i2 == 1) { + if (i3 == 1) { + if (in4.size(0) == 1) { + i = in1.size(0); + } else { + i = in4.size(0); + } + } else if (in3.size(0) == 1) { + i = in5.size(0); + } else { + i = in3.size(0); + } + } else if (in4.size(0) == 1) { + if (in7.size(0) == 1) { + i = in6.size(0); + } else { + i = in7.size(0); + } + } else { + i = in4.size(0); + } + } else if (loop_ub == 1) { + if (in5.size(0) == 1) { + i = in1.size(0); + } else { + i = in5.size(0); + } + } else if (in7.size(0) == 1) { + i = in6.size(0); + } else { + i = in7.size(0); + } + + b_in3.set_size(i); + stride_0_0 = (in3.size(0) != 1); + stride_1_0 = (in1.size(0) != 1); + stride_2_0 = (in4.size(0) != 1); + stride_3_0 = (in5.size(0) != 1); + stride_4_0 = (in3.size(0) != 1); + stride_5_0 = (in6.size(0) != 1); + stride_6_0 = (in7.size(0) != 1); + stride_7_0 = (in4.size(0) != 1); + stride_8_0 = (in1.size(0) != 1); + stride_9_0 = (in5.size(0) != 1); + stride_10_0 = (in6.size(0) != 1); + stride_11_0 = (in7.size(0) != 1); + if (in7.size(0) == 1) { + i = in6.size(0); + } else { + i = in7.size(0); + } + + if (i == 1) { + if (in5.size(0) == 1) { + i = in1.size(0); + } else { + i = in5.size(0); + } + } else if (in7.size(0) == 1) { + i = in6.size(0); + } else { + i = in7.size(0); + } + + if (in4.size(0) == 1) { + if (in7.size(0) == 1) { + i1 = in6.size(0); + } else { + i1 = in7.size(0); + } + } else { + i1 = in4.size(0); + } + + if (in3.size(0) == 1) { + i2 = in5.size(0); + } else { + i2 = in3.size(0); + } + + if (in7.size(0) == 1) { + i3 = in6.size(0); + } else { + i3 = in7.size(0); + } + + if (i == 1) { + if (i1 == 1) { + if (i2 == 1) { + if (in4.size(0) == 1) { + i = in1.size(0); + } else { + i = in4.size(0); + } + } else if (in3.size(0) == 1) { + i = in5.size(0); + } else { + i = in3.size(0); + } + } else if (in4.size(0) == 1) { + if (in7.size(0) == 1) { + i = in6.size(0); + } else { + i = in7.size(0); + } + } else { + i = in4.size(0); + } + } else if (i3 == 1) { + if (in5.size(0) == 1) { + i = in1.size(0); + } else { + i = in5.size(0); + } + } else if (in7.size(0) == 1) { + i = in6.size(0); + } else { + i = in7.size(0); + } + + if (i == 1) { + loop_ub = in3.size(0); + } else { + if (in7.size(0) == 1) { + i = in6.size(0); + } else { + i = in7.size(0); + } + + if (i == 1) { + if (in5.size(0) == 1) { + i = in1.size(0); + } else { + i = in5.size(0); + } + } else if (in7.size(0) == 1) { + i = in6.size(0); + } else { + i = in7.size(0); + } + + if (i == 1) { + if (in4.size(0) == 1) { + if (in7.size(0) == 1) { + i = in6.size(0); + } else { + i = in7.size(0); + } + } else { + i = in4.size(0); + } + + if (i == 1) { + if (in3.size(0) == 1) { + i = in5.size(0); + } else { + i = in3.size(0); + } + + if (i == 1) { + if (in4.size(0) == 1) { + loop_ub = in1.size(0); + } else { + loop_ub = in4.size(0); + } + } else if (in3.size(0) == 1) { + loop_ub = in5.size(0); + } else { + loop_ub = in3.size(0); + } + } else if (in4.size(0) == 1) { + if (in7.size(0) == 1) { + loop_ub = in6.size(0); + } else { + loop_ub = in7.size(0); + } + } else { + loop_ub = in4.size(0); + } + } else { + if (in7.size(0) == 1) { + i = in6.size(0); + } else { + i = in7.size(0); + } + + if (i == 1) { + if (in5.size(0) == 1) { + loop_ub = in1.size(0); + } else { + loop_ub = in5.size(0); + } + } else if (in7.size(0) == 1) { + loop_ub = in6.size(0); + } else { + loop_ub = in7.size(0); + } + } + } + + for (i = 0; i < loop_ub; i++) { + b_in3[i] = in3[i * stride_0_0] * (((in1[i * stride_1_0] * in4[i * + stride_2_0] - in5[i * stride_3_0] * (1.0 / in3[i * stride_4_0])) + + static_cast(in6[i * stride_5_0]) / in7[i * stride_6_0] * in4[i * + stride_7_0]) / ((in1[i * stride_8_0] - in5[i * stride_9_0]) + + static_cast(in6[i * stride_10_0]) / in7[i * + stride_11_0])); + } + + coder::f_bsxfun(in2, b_in3, in1); + } + + namespace coder + { + void rescaleKernel(::coder::array &A, const ::coder::array< + real_T, 1U> &inputMin, const ::coder::array + &inputMax) + { + ::coder::array b_r1; + ::coder::array e1; + ::coder::array iMax; + ::coder::array iMin; + ::coder::array r; + ::coder::array r1; + ::coder::array r3; + ::coder::array sigma; + ::coder::array x_tmp; + if (A.size(0) != 0) { + real_T varargin_2; + int32_T i; + int32_T i1; + int32_T i10; + int32_T i11; + int32_T i12; + int32_T i2; + int32_T i3; + int32_T i4; + int32_T i5; + int32_T i6; + int32_T i7; + int32_T i8; + int32_T i9; + int32_T k; + r.set_size(inputMax.size(0)); + k = inputMax.size(0); + for (i = 0; i < k; i++) { + varargin_2 = inputMax[i]; + r[i] = std::fmin(0.0, varargin_2); + } + + c_bsxfun(r, inputMin, sigma); + e1.set_size(A.size(0)); + k = A.size(0) - 1; + for (i = 0; i <= k; i++) { + e1[i] = A[i]; + } + + d_bsxfun(e1, sigma, A); + d_bsxfun(inputMin, sigma, iMin); + d_bsxfun(inputMax, sigma, iMax); + b_abs(iMax, r); + b_abs(iMin, e1); + internal::maximum2(r, e1, r1); + b_log2(r1, sigma, e1); + r3.set_size(e1.size(0)); + k = e1.size(0); + for (i = 0; i < k; i++) { + r3[i] = e1[i] - 1.0; + } + + pow2(r3, b_r1); + k = e1.size(0); + for (i = 0; i < k; i++) { + e1[i] = (e1[i] + 1.0) / 2.0; + } + + i = e1.size(0); + for (k = 0; k < i; k++) { + e1[k] = std::trunc(e1[k]); + } + + k = e1.size(0); + for (i = 0; i < k; i++) { + e1[i] = e1[i] - 1.0; + } + + pow2(e1, r3); + if (iMax.size(0) == b_r1.size(0)) { + r.set_size(iMax.size(0)); + k = iMax.size(0); + for (i = 0; i < k; i++) { + r[i] = iMax[i] / b_r1[i]; + } + } else { + rdivide(r, iMax, b_r1); + } + + e1.set_size(r3.size(0)); + k = r3.size(0); + for (i = 0; i < k; i++) { + e1[i] = 0.0 / r3[i]; + } + + if (iMin.size(0) == b_r1.size(0)) { + r1.set_size(iMin.size(0)); + k = iMin.size(0); + for (i = 0; i < k; i++) { + r1[i] = iMin[i] / b_r1[i]; + } + } else { + rdivide(r1, iMin, b_r1); + } + + if (iMin.size(0) == iMax.size(0)) { + x_tmp.set_size(iMin.size(0)); + k = iMin.size(0); + for (i = 0; i < k; i++) { + x_tmp[i] = static_cast(iMin[i] == iMax[i]); + } + } else { + binary_expand_op(x_tmp, iMin, iMax); + } + + if (iMax.size(0) == 1) { + i = r3.size(0); + } else { + i = iMax.size(0); + } + + if (iMin.size(0) == 1) { + k = r3.size(0); + } else { + k = iMin.size(0); + } + + if (iMax.size(0) == 1) { + i1 = r3.size(0); + } else { + i1 = iMax.size(0); + } + + if (i1 == 1) { + if (iMin.size(0) == 1) { + i1 = r3.size(0); + } else { + i1 = iMin.size(0); + } + } else if (iMax.size(0) == 1) { + i1 = r3.size(0); + } else { + i1 = iMax.size(0); + } + + if (x_tmp.size(0) == 1) { + i2 = r3.size(0); + } else { + i2 = x_tmp.size(0); + } + + if (iMax.size(0) == 1) { + i3 = r3.size(0); + } else { + i3 = iMax.size(0); + } + + if (i3 == 1) { + if (iMin.size(0) == 1) { + i3 = r3.size(0); + } else { + i3 = iMin.size(0); + } + } else if (iMax.size(0) == 1) { + i3 = r3.size(0); + } else { + i3 = iMax.size(0); + } + + if (iMax.size(0) == 1) { + i4 = r3.size(0); + } else { + i4 = iMax.size(0); + } + + if (i3 == 1) { + if (x_tmp.size(0) == 1) { + i3 = r3.size(0); + } else { + i3 = x_tmp.size(0); + } + } else if (i4 == 1) { + if (iMin.size(0) == 1) { + i3 = r3.size(0); + } else { + i3 = iMin.size(0); + } + } else if (iMax.size(0) == 1) { + i3 = r3.size(0); + } else { + i3 = iMax.size(0); + } + + if ((iMax.size(0) == r3.size(0)) && (iMin.size(0) == r3.size(0)) && (i == + k) && (x_tmp.size(0) == r3.size(0)) && (i1 == i2) && (i3 == r3.size + (0))) { + k = iMax.size(0); + for (i = 0; i < k; i++) { + iMax[i] = 1.0 / ((iMax[i] / r3[i] - iMin[i] / r3[i]) + + static_cast(x_tmp[i]) / r3[i]) / r3[i]; + } + + e_bsxfun(A, iMax, sigma); + } else { + binary_expand_op(sigma, A, iMax, r3, iMin, x_tmp); + } + + if (r.size(0) == 1) { + i = e1.size(0); + } else { + i = r.size(0); + } + + if (r1.size(0) == 1) { + k = r3.size(0); + } else { + k = r1.size(0); + } + + if (x_tmp.size(0) == 1) { + i1 = b_r1.size(0); + } else { + i1 = x_tmp.size(0); + } + + if (r.size(0) == 1) { + i2 = e1.size(0); + } else { + i2 = r.size(0); + } + + if (i2 == 1) { + if (r1.size(0) == 1) { + i2 = r3.size(0); + } else { + i2 = r1.size(0); + } + } else if (r.size(0) == 1) { + i2 = e1.size(0); + } else { + i2 = r.size(0); + } + + if (x_tmp.size(0) == 1) { + i3 = b_r1.size(0); + } else { + i3 = x_tmp.size(0); + } + + if (i3 == 1) { + i3 = e1.size(0); + } else if (x_tmp.size(0) == 1) { + i3 = b_r1.size(0); + } else { + i3 = x_tmp.size(0); + } + + if (r.size(0) == 1) { + i4 = r1.size(0); + } else { + i4 = r.size(0); + } + + if (x_tmp.size(0) == 1) { + i5 = b_r1.size(0); + } else { + i5 = x_tmp.size(0); + } + + if (r.size(0) == 1) { + i6 = e1.size(0); + } else { + i6 = r.size(0); + } + + if (i6 == 1) { + if (r1.size(0) == 1) { + i6 = r3.size(0); + } else { + i6 = r1.size(0); + } + } else if (r.size(0) == 1) { + i6 = e1.size(0); + } else { + i6 = r.size(0); + } + + if (x_tmp.size(0) == 1) { + i7 = b_r1.size(0); + } else { + i7 = x_tmp.size(0); + } + + if (r.size(0) == 1) { + i8 = e1.size(0); + } else { + i8 = r.size(0); + } + + if (i6 == 1) { + if (i7 == 1) { + i6 = e1.size(0); + } else if (x_tmp.size(0) == 1) { + i6 = b_r1.size(0); + } else { + i6 = x_tmp.size(0); + } + } else if (i8 == 1) { + if (r1.size(0) == 1) { + i6 = r3.size(0); + } else { + i6 = r1.size(0); + } + } else if (r.size(0) == 1) { + i6 = e1.size(0); + } else { + i6 = r.size(0); + } + + if (r.size(0) == 1) { + i7 = r1.size(0); + } else { + i7 = r.size(0); + } + + if (i7 == 1) { + if (x_tmp.size(0) == 1) { + i7 = b_r1.size(0); + } else { + i7 = x_tmp.size(0); + } + } else if (r.size(0) == 1) { + i7 = r1.size(0); + } else { + i7 = r.size(0); + } + + if (r.size(0) == 1) { + i8 = e1.size(0); + } else { + i8 = r.size(0); + } + + if (i8 == 1) { + if (r1.size(0) == 1) { + i8 = r3.size(0); + } else { + i8 = r1.size(0); + } + } else if (r.size(0) == 1) { + i8 = e1.size(0); + } else { + i8 = r.size(0); + } + + if (x_tmp.size(0) == 1) { + i9 = b_r1.size(0); + } else { + i9 = x_tmp.size(0); + } + + if (r.size(0) == 1) { + i10 = e1.size(0); + } else { + i10 = r.size(0); + } + + if (i8 == 1) { + if (i9 == 1) { + i8 = e1.size(0); + } else if (x_tmp.size(0) == 1) { + i8 = b_r1.size(0); + } else { + i8 = x_tmp.size(0); + } + } else if (i10 == 1) { + if (r1.size(0) == 1) { + i8 = r3.size(0); + } else { + i8 = r1.size(0); + } + } else if (r.size(0) == 1) { + i8 = e1.size(0); + } else { + i8 = r.size(0); + } + + if (r.size(0) == 1) { + i9 = r1.size(0); + } else { + i9 = r.size(0); + } + + if (r.size(0) == 1) { + i10 = e1.size(0); + } else { + i10 = r.size(0); + } + + if (i10 == 1) { + if (r1.size(0) == 1) { + i10 = r3.size(0); + } else { + i10 = r1.size(0); + } + } else if (r.size(0) == 1) { + i10 = e1.size(0); + } else { + i10 = r.size(0); + } + + if (x_tmp.size(0) == 1) { + i11 = b_r1.size(0); + } else { + i11 = x_tmp.size(0); + } + + if (r.size(0) == 1) { + i12 = e1.size(0); + } else { + i12 = r.size(0); + } + + if (i8 == 1) { + if (i9 == 1) { + if (x_tmp.size(0) == 1) { + i8 = b_r1.size(0); + } else { + i8 = x_tmp.size(0); + } + } else if (r.size(0) == 1) { + i8 = r1.size(0); + } else { + i8 = r.size(0); + } + } else if (i10 == 1) { + if (i11 == 1) { + i8 = e1.size(0); + } else if (x_tmp.size(0) == 1) { + i8 = b_r1.size(0); + } else { + i8 = x_tmp.size(0); + } + } else if (i12 == 1) { + if (r1.size(0) == 1) { + i8 = r3.size(0); + } else { + i8 = r1.size(0); + } + } else if (r.size(0) == 1) { + i8 = e1.size(0); + } else { + i8 = r.size(0); + } + + if ((r.size(0) == e1.size(0)) && (r1.size(0) == r3.size(0)) && (i == k) && + (x_tmp.size(0) == b_r1.size(0)) && (i1 == e1.size(0)) && (i2 == i3) && + (r.size(0) == r1.size(0)) && (x_tmp.size(0) == b_r1.size(0)) && (i4 == + i5) && (i6 == i7) && (r3.size(0) == i8)) { + k = r3.size(0); + for (i = 0; i < k; i++) { + varargin_2 = static_cast(x_tmp[i]) / b_r1[i]; + r3[i] = r3[i] * (((r[i] * e1[i] - r1[i] * (1.0 / r3[i])) + + varargin_2 * e1[i]) / ((r[i] - r1[i]) + varargin_2)); + } + + f_bsxfun(sigma, r3, r); + } else { + binary_expand_op(r, sigma, r3, e1, r1, x_tmp, b_r1); + } + + bsxfun(r, e1); + b_bsxfun(e1, r); + c_bsxfun(r, A); + } + } + } +} + +// End of code generation (rescaleKernel.cpp) diff --git a/cpp/RAT/rescaleKernel.h b/cpp/RAT/rescaleKernel.h new file mode 100644 index 00000000..27e3d72d --- /dev/null +++ b/cpp/RAT/rescaleKernel.h @@ -0,0 +1,32 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// rescaleKernel.h +// +// Code generation for function 'rescaleKernel' +// +#ifndef RESCALEKERNEL_H +#define RESCALEKERNEL_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void rescaleKernel(::coder::array &A, const ::coder::array< + real_T, 1U> &inputMin, const ::coder::array + &inputMax); + } +} + +#endif + +// End of code generation (rescaleKernel.h) diff --git a/cpp/RAT/rescaleParameters.cpp b/cpp/RAT/rescaleParameters.cpp new file mode 100644 index 00000000..d022fb48 --- /dev/null +++ b/cpp/RAT/rescaleParameters.cpp @@ -0,0 +1,62 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// rescaleParameters.cpp +// +// Code generation for function 'rescaleParameters' +// + +// Include files +#include "rescaleParameters.h" +#include "RATMain_rtwutil.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + void rescaleParameters(const ::coder::array &prior, const ::coder:: + array ¶ms, ::coder::array &scaled) + { + int32_T i; + int32_T loop_ub; + + // scaled = rescaleParameters(prior, params) + // + // This function will do the reverse of scaleParameters. + scaled.set_size(params.size(1)); + loop_ub = params.size(1); + for (i = 0; i < loop_ub; i++) { + scaled[i] = 0.0; + } + + i = params.size(1); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T priortype; + priortype = prior[b_i]; + if (priortype == 1.0) { + real_T p3; + + // uniform + p3 = prior[b_i + prior.size(0) * 3]; + scaled[b_i] = params[b_i] * (prior[b_i + prior.size(0) * 4] - p3) + p3; + } else if (priortype == 2.0) { + // gaussian + scaled[b_i] = params[b_i] * prior[b_i + prior.size(0) * 2] + prior[b_i + + prior.size(0)]; + } else if (priortype == 3.0) { + real_T scaled_tmp; + + // jeffreys + scaled_tmp = std::log10(prior[b_i + prior.size(0)]); + scaled[b_i] = rt_powd_snf(10.0, params[b_i] * (std::log10(prior[b_i + + prior.size(0) * 2]) - scaled_tmp) + scaled_tmp); + } + } + } +} + +// End of code generation (rescaleParameters.cpp) diff --git a/cpp/RAT/rescaleParameters.h b/cpp/RAT/rescaleParameters.h new file mode 100644 index 00000000..2016b69f --- /dev/null +++ b/cpp/RAT/rescaleParameters.h @@ -0,0 +1,28 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// rescaleParameters.h +// +// Code generation for function 'rescaleParameters' +// +#ifndef RESCALEPARAMETERS_H +#define RESCALEPARAMETERS_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void rescaleParameters(const ::coder::array &prior, const ::coder:: + array ¶ms, ::coder::array &scaled); +} + +#endif + +// End of code generation (rescaleParameters.h) diff --git a/cpp/RAT/reshapeSizeChecks.cpp b/cpp/RAT/reshapeSizeChecks.cpp new file mode 100644 index 00000000..462d71c8 --- /dev/null +++ b/cpp/RAT/reshapeSizeChecks.cpp @@ -0,0 +1,42 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// reshapeSizeChecks.cpp +// +// Code generation for function 'reshapeSizeChecks' +// + +// Include files +#include "reshapeSizeChecks.h" +#include "rt_nonfinite.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + int32_T computeDimsData(real_T varargin_1) + { + int32_T b_calclen; + if (static_cast(varargin_1) > 0) { + if (static_cast(static_cast(varargin_1)) == 0U) { + b_calclen = MAX_int32_T; + } else { + b_calclen = static_cast(1000000U / static_cast( + static_cast(varargin_1))); + } + } else { + b_calclen = 0; + } + + return b_calclen; + } + } + } +} + +// End of code generation (reshapeSizeChecks.cpp) diff --git a/cpp/RAT/reshapeSizeChecks.h b/cpp/RAT/reshapeSizeChecks.h new file mode 100644 index 00000000..2bb4f96e --- /dev/null +++ b/cpp/RAT/reshapeSizeChecks.h @@ -0,0 +1,32 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// reshapeSizeChecks.h +// +// Code generation for function 'reshapeSizeChecks' +// +#ifndef RESHAPESIZECHECKS_H +#define RESHAPESIZECHECKS_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + int32_T computeDimsData(real_T varargin_1); + } + } +} + +#endif + +// End of code generation (reshapeSizeChecks.h) diff --git a/cpp/RAT/resolutionPolly.cpp b/cpp/RAT/resolutionPolly.cpp new file mode 100644 index 00000000..2fc6b78a --- /dev/null +++ b/cpp/RAT/resolutionPolly.cpp @@ -0,0 +1,73 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// resolutionPolly.cpp +// +// Code generation for function 'resolutionPolly' +// + +// Include files +#include "resolutionPolly.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + void resolutionPolly(const ::coder::array &xdata, const ::coder:: + array &ydata, real_T res, real_T points, :: + coder::array &out) + { + int32_T i; + int32_T loop_ub_tmp; + + // Apply resolution correction + res += 0.0001; + loop_ub_tmp = static_cast(points); + out.set_size(loop_ub_tmp); + for (i = 0; i < loop_ub_tmp; i++) { + out[i] = 0.0; + } + + for (int32_T j{0}; j < loop_ub_tmp; j++) { + real_T a; + real_T sumg; + int32_T ilow; + sumg = 0.0; + out[j] = 0.0; + if (static_cast(j) + 1U > 10U) { + ilow = -10; + } else { + ilow = static_cast(-(static_cast(j) + 1.0)) + 1; + } + + // try + if (static_cast(j) + 1.0 < points - 10.0) { + a = 10.0; + } else { + a = points - (static_cast(j) + 1.0); + } + + i = static_cast(a + (1.0 - static_cast(ilow))); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T g; + int32_T a_tmp; + a_tmp = static_cast((static_cast(j) + 1.0) + + static_cast(ilow + b_i)) - 1; + a = (xdata[a_tmp] - xdata[j]) / (res * xdata[j]); + g = std::exp(-(a * a)); + sumg += g; + out[j] = out[j] + ydata[a_tmp] * g; + } + + if (sumg != 0.0) { + out[j] = out[j] / sumg; + } + } + } +} + +// End of code generation (resolutionPolly.cpp) diff --git a/cpp/RAT/resolutionPolly.h b/cpp/RAT/resolutionPolly.h new file mode 100644 index 00000000..37354ea9 --- /dev/null +++ b/cpp/RAT/resolutionPolly.h @@ -0,0 +1,29 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// resolutionPolly.h +// +// Code generation for function 'resolutionPolly' +// +#ifndef RESOLUTIONPOLLY_H +#define RESOLUTIONPOLLY_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void resolutionPolly(const ::coder::array &xdata, const ::coder:: + array &ydata, real_T res, real_T points, :: + coder::array &out); +} + +#endif + +// End of code generation (resolutionPolly.h) diff --git a/cpp/RAT/rng.cpp b/cpp/RAT/rng.cpp new file mode 100644 index 00000000..e30212e3 --- /dev/null +++ b/cpp/RAT/rng.cpp @@ -0,0 +1,38 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// rng.cpp +// +// Code generation for function 'rng' +// + +// Include files +#include "rng.h" +#include "RATMain_data.h" +#include "rt_nonfinite.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + void rng() + { + uint32_T r; + std::memset(&state[0], 0, 625U * sizeof(uint32_T)); + r = 5489U; + state[0] = 5489U; + for (int32_T mti{0}; mti < 623; mti++) { + r = ((r ^ r >> 30U) * 1812433253U + static_cast(mti)) + 1U; + state[mti + 1] = r; + } + + state[624] = 624U; + } + } +} + +// End of code generation (rng.cpp) diff --git a/cpp/RAT/rng.h b/cpp/RAT/rng.h new file mode 100644 index 00000000..e70796c2 --- /dev/null +++ b/cpp/RAT/rng.h @@ -0,0 +1,29 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// rng.h +// +// Code generation for function 'rng' +// +#ifndef RNG_H +#define RNG_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void rng(); + } +} + +#endif + +// End of code generation (rng.h) diff --git a/cpp/RAT/rtGetInf.cpp b/cpp/RAT/rtGetInf.cpp new file mode 100644 index 00000000..169f0848 --- /dev/null +++ b/cpp/RAT/rtGetInf.cpp @@ -0,0 +1,49 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// rtGetInf.cpp +// +// Code generation for function 'RATMain' +// + +// Abstract: +// MATLAB for code generation function to initialize non-finite, Inf and MinusInf +// Include files +#include "rtGetInf.h" +#include "rt_nonfinite.h" + +// Function: rtGetInf ================================================================== +// Abstract: +// Initialize rtInf needed by the generated code. +real_T rtGetInf(void) +{ + return rtInf; +} + +// Function: rtGetInfF ================================================================= +// Abstract: +// Initialize rtInfF needed by the generated code. +real32_T rtGetInfF(void) +{ + return rtInfF; +} + +// Function: rtGetMinusInf ============================================================= +// Abstract: +// Initialize rtMinusInf needed by the generated code. +real_T rtGetMinusInf(void) +{ + return rtMinusInf; +} + +// Function: rtGetMinusInfF ============================================================ +// Abstract: +// Initialize rtMinusInfF needed by the generated code. +real32_T rtGetMinusInfF(void) +{ + return rtMinusInfF; +} + +// End of code generation (rtGetInf.cpp) diff --git a/cpp/RAT/rtGetInf.h b/cpp/RAT/rtGetInf.h new file mode 100644 index 00000000..ec33c0ba --- /dev/null +++ b/cpp/RAT/rtGetInf.h @@ -0,0 +1,34 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// rtGetInf.h +// +// Code generation for function 'RATMain' +// +#ifndef RTGETINF_H +#define RTGETINF_H + +// Include files +#include "rtwtypes.h" +#ifdef __cplusplus + +extern "C" +{ + +#endif + + extern real_T rtGetInf(void); + extern real32_T rtGetInfF(void); + extern real_T rtGetMinusInf(void); + extern real32_T rtGetMinusInfF(void); + +#ifdef __cplusplus + +} + +#endif +#endif + +// End of code generation (rtGetInf.h) diff --git a/cpp/RAT/rtGetNaN.cpp b/cpp/RAT/rtGetNaN.cpp new file mode 100644 index 00000000..57d67f72 --- /dev/null +++ b/cpp/RAT/rtGetNaN.cpp @@ -0,0 +1,35 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// rtGetNaN.cpp +// +// Code generation for function 'RATMain' +// + +// Abstract: +// MATLAB for code generation function to initialize non-finite, NaN +// Include files +#include "rtGetNaN.h" +#include "rt_nonfinite.h" + +// Function: rtGetNaN ====================================================================== +// Abstract: +// Initialize rtNaN needed by the generated code. +// NaN is initialized as non-signaling. Assumes IEEE. +real_T rtGetNaN(void) +{ + return rtNaN; +} + +// Function: rtGetNaNF ===================================================================== +// Abstract: +// Initialize rtNaNF needed by the generated code. +// NaN is initialized as non-signaling. Assumes IEEE +real32_T rtGetNaNF(void) +{ + return rtNaNF; +} + +// End of code generation (rtGetNaN.cpp) diff --git a/cpp/RAT/rtGetNaN.h b/cpp/RAT/rtGetNaN.h new file mode 100644 index 00000000..27cd60fd --- /dev/null +++ b/cpp/RAT/rtGetNaN.h @@ -0,0 +1,32 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// rtGetNaN.h +// +// Code generation for function 'RATMain' +// +#ifndef RTGETNAN_H +#define RTGETNAN_H + +// Include files +#include "rtwtypes.h" +#ifdef __cplusplus + +extern "C" +{ + +#endif + + extern real_T rtGetNaN(void); + extern real32_T rtGetNaNF(void); + +#ifdef __cplusplus + +} + +#endif +#endif + +// End of code generation (rtGetNaN.h) diff --git a/cpp/RAT/rt_defines.h b/cpp/RAT/rt_defines.h new file mode 100644 index 00000000..833437e5 --- /dev/null +++ b/cpp/RAT/rt_defines.h @@ -0,0 +1,45 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// rt_defines.h +// +// Code generation for function 'RATMain' +// +#ifndef RT_DEFINES_H +#define RT_DEFINES_H + +// Include files +#include "rtwtypes.h" +#ifdef __cplusplus + +extern "C" +{ + +#endif + + static const real_T RT_PI { 3.14159265358979323846 }; + + static const real32_T RT_PIF { 3.1415927F }; + + static const real_T RT_LN_10 { 2.30258509299404568402 }; + + static const real32_T RT_LN_10F { 2.3025851F }; + + static const real_T RT_LOG10E { 0.43429448190325182765 }; + + static const real32_T RT_LOG10EF { 0.43429449F }; + + static const real_T RT_E { 2.7182818284590452354 }; + + static const real32_T RT_EF { 2.7182817F }; + +#ifdef __cplusplus + +} + +#endif +#endif + +// End of code generation (rt_defines.h) diff --git a/cpp/RAT/rt_nonfinite.cpp b/cpp/RAT/rt_nonfinite.cpp new file mode 100644 index 00000000..5a37904c --- /dev/null +++ b/cpp/RAT/rt_nonfinite.cpp @@ -0,0 +1,31 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// rt_nonfinite.cpp +// +// Code generation for function 'RATMain' +// + +// Abstract: +// MATLAB for code generation function to initialize non-finites, +// (Inf, NaN and -Inf). +// Include files +#include "rt_nonfinite.h" +#include +#include + +real_T rtNaN { std::numeric_limits::quiet_NaN() }; + +real_T rtInf { std::numeric_limits::infinity() }; + +real_T rtMinusInf { -std::numeric_limits::infinity() }; + +real32_T rtNaNF { std::numeric_limits::quiet_NaN() }; + +real32_T rtInfF { std::numeric_limits::infinity() }; + +real32_T rtMinusInfF { -std::numeric_limits::infinity() }; + +// End of code generation (rt_nonfinite.cpp) diff --git a/cpp/RAT/rt_nonfinite.h b/cpp/RAT/rt_nonfinite.h new file mode 100644 index 00000000..3d779da1 --- /dev/null +++ b/cpp/RAT/rt_nonfinite.h @@ -0,0 +1,36 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// rt_nonfinite.h +// +// Code generation for function 'RATMain' +// +#ifndef RT_NONFINITE_H +#define RT_NONFINITE_H + +// Include files +#include "rtwtypes.h" +#ifdef __cplusplus + +extern "C" +{ + +#endif + + extern real_T rtInf; + extern real_T rtMinusInf; + extern real_T rtNaN; + extern real32_T rtInfF; + extern real32_T rtMinusInfF; + extern real32_T rtNaNF; + +#ifdef __cplusplus + +} + +#endif +#endif + +// End of code generation (rt_nonfinite.h) diff --git a/cpp/RAT/rtwtypes.h b/cpp/RAT/rtwtypes.h new file mode 100644 index 00000000..30d76340 --- /dev/null +++ b/cpp/RAT/rtwtypes.h @@ -0,0 +1,42 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// rtwtypes.h +// +// Code generation for function 'RATMain' +// +#ifndef RTWTYPES_H +#define RTWTYPES_H + +/*=======================================================================* + * Fixed width word size data types: * + * int64_T - signed 64 bit integers * + * uint64_T - unsigned 64 bit integers * + *=======================================================================*/ +#if defined(__APPLE__) +# ifndef INT64_T +# define INT64_T long +# define FMT64 "l" +# if defined(__LP64__) && !defined(INT_TYPE_64_IS_LONG) +# define INT_TYPE_64_IS_LONG +# endif +# endif +#endif + +#if defined(__APPLE__) +# ifndef UINT64_T +# define UINT64_T unsigned long +# define FMT64 "l" +# if defined(__LP64__) && !defined(INT_TYPE_64_IS_LONG) +# define INT_TYPE_64_IS_LONG +# endif +# endif +#endif + +// Include files +#include "tmwtypes.h" +#endif + +// End of code generation (rtwtypes.h) diff --git a/cpp/RAT/runDE.cpp b/cpp/RAT/runDE.cpp new file mode 100644 index 00000000..103c6aa0 --- /dev/null +++ b/cpp/RAT/runDE.cpp @@ -0,0 +1,285 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// runDE.cpp +// +// Code generation for function 'runDE' +// + +// Include files +#include "runDE.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "deopt.h" +#include "length.h" +#include "packParams.h" +#include "reflectivityCalculation.h" +#include "rt_nonfinite.h" +#include "strcmp.h" +#include "unpackParams.h" +#include "coder_array.h" +#include "coder_bounded_array.h" +#include +#include + +// Function Definitions +namespace RAT +{ + l_struct_T intrafun(const ::coder::array &p, c_struct_T + *problemStruct, const char_T controls_parallel_data[], + const int32_T controls_parallel_size[2], const real_T + controls_resamPars[2], boolean_T controls_calcSldDuringFit, + const struct3_T *controls_checks, const ::coder::array< + cell_wrap_2, 2U> &problemCells_f1, const ::coder::array< + cell_wrap_8, 2U> &problemCells_f2, const ::coder::array< + cell_wrap_2, 2U> &problemCells_f3, const ::coder::array< + cell_wrap_2, 2U> &problemCells_f4, const ::coder::array< + cell_wrap_8, 2U> &problemCells_f5, const ::coder::array< + cell_wrap_8, 1U> &problemCells_f6, const ::coder::array< + cell_wrap_1, 2U> &problemCells_f14, const ::coder::array< + cell_wrap_8, 2U> &problemCells_f19) + { + cell_11 expl_temp; + cell_wrap_9 a__2[6]; + d_struct_T b_problemStruct; + l_struct_T S_MSE; + struct2_T b_expl_temp; + int32_T loop_ub; + problemStruct->fitParams.set_size(1, p.size(1)); + loop_ub = p.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + problemStruct->fitParams[problemStruct->fitParams.size(0) * i] = p[i]; + } + + unpackParams(problemStruct, controls_checks->fitParam, + controls_checks->fitBackgroundParam, + controls_checks->fitQzshift, controls_checks->fitScalefactor, + controls_checks->fitBulkIn, controls_checks->fitBulkOut, + controls_checks->fitResolutionParam, + controls_checks->fitDomainRatio); + expl_temp.f19.set_size(1, problemCells_f19.size(1)); + loop_ub = problemCells_f19.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + expl_temp.f19[i] = problemCells_f19[i]; + } + + expl_temp.f14.set_size(1, problemCells_f14.size(1)); + loop_ub = problemCells_f14.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + expl_temp.f14[i] = problemCells_f14[i]; + } + + expl_temp.f6.set_size(problemCells_f6.size(0)); + loop_ub = problemCells_f6.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + expl_temp.f6[i] = problemCells_f6[i]; + } + + expl_temp.f5.set_size(1, problemCells_f5.size(1)); + loop_ub = problemCells_f5.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + expl_temp.f5[i] = problemCells_f5[i]; + } + + expl_temp.f4.set_size(1, problemCells_f4.size(1)); + loop_ub = problemCells_f4.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + expl_temp.f4[i] = problemCells_f4[i]; + } + + expl_temp.f3.set_size(1, problemCells_f3.size(1)); + loop_ub = problemCells_f3.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + expl_temp.f3[i] = problemCells_f3[i]; + } + + expl_temp.f2.set_size(1, problemCells_f2.size(1)); + loop_ub = problemCells_f2.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + expl_temp.f2[i] = problemCells_f2[i]; + } + + expl_temp.f1.set_size(1, problemCells_f1.size(1)); + loop_ub = problemCells_f1.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + expl_temp.f1[i] = problemCells_f1[i]; + } + + b_expl_temp.checks = *controls_checks; + b_expl_temp.calcSldDuringFit = controls_calcSldDuringFit; + b_expl_temp.resamPars[0] = controls_resamPars[0]; + b_expl_temp.resamPars[1] = controls_resamPars[1]; + b_expl_temp.parallel.size[0] = 1; + b_expl_temp.parallel.size[1] = controls_parallel_size[1]; + loop_ub = controls_parallel_size[1]; + if (loop_ub - 1 >= 0) { + std::copy(&controls_parallel_data[0], &controls_parallel_data[loop_ub], + &b_expl_temp.parallel.data[0]); + } + + reflectivityCalculation(problemStruct, &expl_temp, &b_expl_temp, + &b_problemStruct, a__2); + S_MSE.FVr_oa = b_problemStruct.calculations.sumChi; + + // no constraints THESE FIRST FEW VALS MAY BE WRONG + // no constraint array + S_MSE.I_no = 1.0; + + // number of objectives (costs) + return S_MSE; + } + + void runDE(c_struct_T *problemStruct, const cell_11 *problemCells, const + struct1_T *problemLimits, const struct2_T *controls, d_struct_T + *contrastParams, cell_wrap_9 result[6]) + { + static const real_T FVr_x[50]{ -1.0, -0.95918367346938771, + -0.91836734693877542, -0.87755102040816324, -0.836734693877551, + -0.79591836734693866, -0.75510204081632648, -0.71428571428571419, + -0.673469387755102, -0.63265306122448972, -0.59183673469387754, + -0.55102040816326525, -0.51020408163265307, -0.46938775510204078, + -0.42857142857142855, -0.38775510204081631, -0.34693877551020408, + -0.30612244897959179, -0.26530612244897955, -0.22448979591836732, + -0.18367346938775508, -0.14285714285714285, -0.1020408163265306, + -0.061224489795918366, -0.020408163265306121, 0.020408163265306121, + 0.061224489795918366, 0.1020408163265306, 0.14285714285714285, + 0.18367346938775508, 0.22448979591836732, 0.26530612244897955, + 0.30612244897959179, 0.34693877551020408, 0.38775510204081631, + 0.42857142857142855, 0.46938775510204078, 0.51020408163265307, + 0.55102040816326525, 0.59183673469387754, 0.63265306122448972, + 0.673469387755102, 0.71428571428571419, 0.75510204081632648, + 0.79591836734693866, 0.836734693877551, 0.87755102040816324, + 0.91836734693877542, 0.95918367346938771, 1.0 }; + + ::coder::array b_problemStruct; + ::coder::array res; + ::coder::array S_struct_FM_pop; + j_struct_T expl_temp; + int32_T loop_ub; + packParams(problemStruct, problemCells->f7, problemCells->f8, + problemCells->f9, problemCells->f10, problemCells->f11, + problemCells->f12, problemCells->f13, problemCells->f20, + problemLimits, &controls->checks, b_problemStruct); + + // Value to reach + expl_temp.FVr_minbound.set_size(1, problemStruct->fitLimits.size(0)); + loop_ub = problemStruct->fitLimits.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + expl_temp.FVr_minbound[i] = problemStruct->fitLimits[i]; + } + + expl_temp.FVr_maxbound.set_size(1, problemStruct->fitLimits.size(0)); + loop_ub = problemStruct->fitLimits.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + expl_temp.FVr_maxbound[i] = problemStruct->fitLimits[i + + problemStruct->fitLimits.size(0)]; + } + + // 1: use bounds as bound constraints, 0: no bound constraints + // I_NP number of population members + // I_itermax maximum number of iterations (generations) + // fWeight DE-stepsize fWeight ex [0, 2] + // F_CR crossover probability constant ex [0, 1] + // I_strategy 1 --> DE/rand/1: + // the classical version of DE. + // 2 --> DE/local-to-best/1: + // a version which has been used by quite a number + // of scientists. Attempts a balance between robustness + // and fast convergence. + // 3 --> DE/best/1 with jitter: + // taylored for small population sizes and fast convergence. + // Dimensionality should not be too high. + // 4 --> DE/rand/1 with per-vector-dither: + // Classical DE with dither to become even more robust. + // 5 --> DE/rand/1 with per-generation-dither: + // Classical DE with dither to become even more robust. + // Choosing fWeight = 0.3 is a good start here. + // 6 --> DE/rand/1 either-or-algorithm: + // Alternates between differential mutation and three-point- + // recombination. + // I_refresh intermediate output will be produced after "I_refresh" + // iterations. No intermediate output will be produced + // if I_refresh is < 1 + // I_plotting Will use plotting if set to 1. Will skip plotting otherwise. + // -----Definition of tolerance scheme-------------------------------------- + // -----The scheme is sampled at I_lentol points---------------------------- + // ordinate running from -1 to +1 + // upper limit is 1 + // lower limit is -1 + // Tell compiler abut variable sizes + // -----tie all important values to a structure that can be passed along---- + expl_temp.FVr_x.size[0] = 1; + expl_temp.FVr_x.size[1] = 50; + std::copy(&FVr_x[0], &FVr_x[50], &expl_temp.FVr_x.data[0]); + loop_ub = static_cast(controls->populationSize); + S_struct_FM_pop.set_size(loop_ub, 2); + expl_temp.FVr_bestmem.set_size(1, 2); + for (int32_T i{0}; i < 2; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + S_struct_FM_pop[i1 + S_struct_FM_pop.size(0) * i] = 0; + } + + expl_temp.FVr_bestmem[i] = 0.0; + } + + expl_temp.FM_pop.set_size(S_struct_FM_pop.size(0), 2); + loop_ub = S_struct_FM_pop.size(0); + for (int32_T i{0}; i < 2; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + expl_temp.FM_pop[i1 + expl_temp.FM_pop.size(0) * i] = 0.0; + } + } + + expl_temp.I_plotting = 0.0; + expl_temp.I_refresh = 1.0; + expl_temp.I_strategy = 5.0; + expl_temp.F_VTR = controls->targetValue; + expl_temp.I_itermax = controls->numGenerations; + expl_temp.I_bnd_constr = 1.0; + expl_temp.I_D = coder::internal::intlength(problemStruct->fitParams.size(0), + problemStruct->fitParams.size(1)); + expl_temp.F_CR = controls->crossoverProbability; + expl_temp.fWeight = controls->fWeight; + expl_temp.I_NP = controls->populationSize; + expl_temp.FVr_lim_lo.size[0] = 1; + expl_temp.FVr_lim_lo.size[1] = 50; + expl_temp.FVr_lim_up.size[0] = 1; + expl_temp.FVr_lim_up.size[1] = 50; + for (int32_T i{0}; i < 50; i++) { + expl_temp.FVr_lim_lo.data[i] = -1.0; + expl_temp.FVr_lim_up.data[i] = 1.0; + } + + expl_temp.I_lentol.size[0] = 1; + expl_temp.I_lentol.data[0] = 50.0; + deopt(problemStruct, problemCells->f1, problemCells->f2, problemCells->f3, + problemCells->f4, problemCells->f5, problemCells->f6, + problemCells->f14, problemCells->f19, controls->parallel.data, + controls->parallel.size, controls->resamPars, + controls->calcSldDuringFit, controls->display.data, + controls->display.size, &controls->checks, &expl_temp, res); + problemStruct->fitParams.set_size(1, res.size(1)); + loop_ub = res.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + problemStruct->fitParams[problemStruct->fitParams.size(0) * i] = res[i]; + } + + unpackParams(problemStruct, controls->checks.fitParam, + controls->checks.fitBackgroundParam, + controls->checks.fitQzshift, controls->checks.fitScalefactor, + controls->checks.fitBulkIn, controls->checks.fitBulkOut, + controls->checks.fitResolutionParam, + controls->checks.fitDomainRatio); + reflectivityCalculation(problemStruct, problemCells, controls, + contrastParams, result); + if (!coder::internal::d_strcmp(controls->display.data, + controls->display.size)) { + printf("Final chi squared is %g\n", contrastParams->calculations.sumChi); + fflush(stdout); + } + } +} + +// End of code generation (runDE.cpp) diff --git a/cpp/RAT/runDE.h b/cpp/RAT/runDE.h new file mode 100644 index 00000000..5fa529ba --- /dev/null +++ b/cpp/RAT/runDE.h @@ -0,0 +1,52 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// runDE.h +// +// Code generation for function 'runDE' +// +#ifndef RUNDE_H +#define RUNDE_H + +// Include files +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct c_struct_T; + struct l_struct_T; + struct cell_11; + struct d_struct_T; +} + +// Function Declarations +namespace RAT +{ + l_struct_T intrafun(const ::coder::array &p, c_struct_T + *problemStruct, const char_T controls_parallel_data[], + const int32_T controls_parallel_size[2], const real_T + controls_resamPars[2], boolean_T controls_calcSldDuringFit, + const struct3_T *controls_checks, const ::coder::array< + cell_wrap_2, 2U> &problemCells_f1, const ::coder::array< + cell_wrap_8, 2U> &problemCells_f2, const ::coder::array< + cell_wrap_2, 2U> &problemCells_f3, const ::coder::array< + cell_wrap_2, 2U> &problemCells_f4, const ::coder::array< + cell_wrap_8, 2U> &problemCells_f5, const ::coder::array< + cell_wrap_8, 1U> &problemCells_f6, const ::coder::array< + cell_wrap_1, 2U> &problemCells_f14, const ::coder::array< + cell_wrap_8, 2U> &problemCells_f19); + void runDE(c_struct_T *problemStruct, const cell_11 *problemCells, const + struct1_T *problemLimits, const struct2_T *controls, d_struct_T + *contrastParams, cell_wrap_9 result[6]); +} + +#endif + +// End of code generation (runDE.h) diff --git a/cpp/RAT/runDREAM.cpp b/cpp/RAT/runDREAM.cpp new file mode 100644 index 00000000..2ba2514d --- /dev/null +++ b/cpp/RAT/runDREAM.cpp @@ -0,0 +1,293 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// runDREAM.cpp +// +// Code generation for function 'runDREAM' +// + +// Include files +#include "runDREAM.h" +#include "RATMain_internal_types.h" +#include "RATMain_rtwutil.h" +#include "RATMain_types.h" +#include "getFittedPriors.h" +#include "makeEmptyBayesResultsStruct.h" +#include "mean.h" +#include "packParams.h" +#include "processBayes.h" +#include "ratDREAM.h" +#include "rt_nonfinite.h" +#include "strcmp.h" +#include "coder_array.h" +#include "coder_bounded_array.h" +#include +#include + +// Function Definitions +namespace RAT +{ + void runDREAM(const c_struct_T *problemStruct, const cell_11 *problemCells, + const struct1_T *problemLimits, const struct2_T *controls, const + struct4_T *priors, c_struct_T *outProblemStruct, d_struct_T + *contrastParams, cell_wrap_9 result[6], g_struct_T *bayesResults) + { + ::coder::array fitParamNames; + ::coder::array Par_info_max; + ::coder::array Par_info_min; + ::coder::array a__1; + ::coder::array b_bayesResults; + ::coder::array c_bayesResults; + ::coder::array r; + c_struct_T b_problemStruct; + e_struct_T dreamResults_bestFitsMean; + f_struct_T dreamResults_predlims; + int32_T b_loop_ub; + int32_T i; + int32_T i1; + int32_T i2; + int32_T loop_ub; + + // Make an empty struct for bayesResults to hold the outputs of the + // calculation + makeEmptyBayesResultsStruct(problemStruct->numberOfContrasts, coder:: + internal::b_strcmp(problemStruct->TF.data, problemStruct->TF.size), + controls->nChains, bayesResults->bestFitsMean.ref, + bayesResults->bestFitsMean.sld, &bayesResults->bestFitsMean.chi, + bayesResults->bestFitsMean.data, bayesResults->predlims.refPredInts, + bayesResults->predlims.sldPredInts, bayesResults->predlims.refXdata, + bayesResults->predlims.sldXdata, bayesResults->predlims.sampleChi.data, + &bayesResults->predlims.sampleChi.size[0], bayesResults->parConfInts.par95, + bayesResults->parConfInts.par65, bayesResults->parConfInts.mean, + bayesResults->bestPars, &bayesResults->bayesRes, bayesResults->chain); + + // Pre-allocation + b_problemStruct = *problemStruct; + packParams(&b_problemStruct, problemCells->f7, problemCells->f8, + problemCells->f9, problemCells->f10, problemCells->f11, + problemCells->f12, problemCells->f13, problemCells->f20, + problemLimits, &controls->checks, fitParamNames); + + // Get the priors for the fitted parameters... + // Put all the RAT parameters together into one array... + // Get the parameters from the user + // Total number of generations + // Number of chains + // Set the relevant parameters for the DREAM sampler.... + // Dimension of the problem + // Number of Markov Chains + // Number of generations per chain + // DREAMPar.lik = 1; % Model output is likelihood + // Parallel or not... + // Jump probabilities... + // This will change... + // Initial sampling and parameter range + Par_info_min.set_size(1, b_problemStruct.fitLimits.size(0)); + loop_ub = b_problemStruct.fitLimits.size(0); + for (i = 0; i < loop_ub; i++) { + Par_info_min[i] = b_problemStruct.fitLimits[i]; + } + + Par_info_max.set_size(1, b_problemStruct.fitLimits.size(0)); + loop_ub = b_problemStruct.fitLimits.size(0); + for (i = 0; i < loop_ub; i++) { + Par_info_max[i] = b_problemStruct.fitLimits[i + + b_problemStruct.fitLimits.size(0)]; + } + + // if dreamC.prior + // end + // Run the sampler.... + // [chain,output,fx] = rat_DREAM(DREAMPar,Par_info,[],ratInputs); + // Func_name = @DREAMWrapper; + getFittedPriors(fitParamNames, priors->priorNames, priors->priorValues, + b_problemStruct.fitLimits, r); + ratDREAM(static_cast(fitParamNames.size(0)), controls->nChains, std:: + ceil(controls->nSamples / controls->nChains), + controls->jumpProbability, controls->pUnitGamma, controls->adaptPCR, + Par_info_min, Par_info_max, controls->boundHandling.data, + controls->boundHandling.size, &b_problemStruct, problemCells, + controls, r, bayesResults->bayesRes.allChains, + &bayesResults->bayesRes.dreamOutput, a__1); + + // Combine all chains.... + bayesResults->chain.set_size(0, 0); + i = static_cast(controls->nChains); + if (i - 1 >= 0) { + int32_T cutoff; + if (fitParamNames.size(0) < 1) { + b_loop_ub = 0; + } else { + b_loop_ub = fitParamNames.size(0); + } + + cutoff = static_cast(std::floor(static_cast + (bayesResults->bayesRes.allChains.size(0)) * 0.25)); + if (cutoff > bayesResults->bayesRes.allChains.size(0)) { + i1 = 0; + i2 = 0; + } else { + i1 = cutoff - 1; + i2 = bayesResults->bayesRes.allChains.size(0); + } + } + + for (int32_T b_i{0}; b_i < i; b_i++) { + int32_T b_result; + int32_T c_loop_ub; + int32_T sizes_idx_0; + boolean_T empty_non_axis_sizes; + + // Keep only the last 75% of the chain.. + // Combine the parallel chains into one.... + if ((bayesResults->chain.size(0) != 0) && (bayesResults->chain.size(1) != + 0)) { + b_result = bayesResults->chain.size(1); + } else if ((i2 - i1 != 0) && (b_loop_ub != 0)) { + b_result = b_loop_ub; + } else { + b_result = bayesResults->chain.size(1); + if (b_loop_ub > bayesResults->chain.size(1)) { + b_result = b_loop_ub; + } + } + + empty_non_axis_sizes = (b_result == 0); + if (empty_non_axis_sizes || ((bayesResults->chain.size(0) != 0) && + (bayesResults->chain.size(1) != 0))) { + loop_ub = bayesResults->chain.size(0); + } else { + loop_ub = 0; + } + + if (empty_non_axis_sizes || ((i2 - i1 != 0) && (b_loop_ub != 0))) { + sizes_idx_0 = i2 - i1; + } else { + sizes_idx_0 = 0; + } + + c_loop_ub = i2 - i1; + b_bayesResults.set_size(c_loop_ub, b_loop_ub); + for (int32_T i3{0}; i3 < b_loop_ub; i3++) { + for (int32_T i4{0}; i4 < c_loop_ub; i4++) { + b_bayesResults[i4 + b_bayesResults.size(0) * i3] = + bayesResults->bayesRes.allChains[((i1 + i4) + + bayesResults->bayesRes.allChains.size(0) * i3) + + bayesResults->bayesRes.allChains.size(0) * + bayesResults->bayesRes.allChains.size(1) * b_i]; + } + } + + c_bayesResults.set_size(loop_ub + sizes_idx_0, b_result); + for (int32_T i3{0}; i3 < b_result; i3++) { + for (int32_T i4{0}; i4 < loop_ub; i4++) { + c_bayesResults[i4 + c_bayesResults.size(0) * i3] = bayesResults-> + chain[i4 + loop_ub * i3]; + } + } + + for (int32_T i3{0}; i3 < b_result; i3++) { + for (int32_T i4{0}; i4 < sizes_idx_0; i4++) { + c_bayesResults[(i4 + loop_ub) + c_bayesResults.size(0) * i3] = + b_bayesResults[i4 + sizes_idx_0 * i3]; + } + } + + bayesResults->chain.set_size(c_bayesResults.size(0), c_bayesResults.size(1)); + loop_ub = c_bayesResults.size(1); + for (int32_T i3{0}; i3 < loop_ub; i3++) { + c_loop_ub = c_bayesResults.size(0); + for (int32_T i4{0}; i4 < c_loop_ub; i4++) { + bayesResults->chain[i4 + bayesResults->chain.size(0) * i3] = + c_bayesResults[i4 + c_bayesResults.size(0) * i3]; + } + } + } + + coder::mean(bayesResults->chain, bayesResults->bestPars); + processBayes(bayesResults->bestPars, bayesResults->chain, &b_problemStruct, + controls, problemCells, outProblemStruct, contrastParams, + result, &dreamResults_bestFitsMean, &dreamResults_predlims, + &bayesResults->parConfInts); + + // Populate the output struct + // bayesResults.bayesRes.allChains = chain; + cast(dreamResults_predlims.refPredInts, bayesResults->predlims.refPredInts); + cast(dreamResults_predlims.sldPredInts, bayesResults->predlims.sldPredInts); + bayesResults->predlims.refXdata.set_size(dreamResults_predlims.refXdata.size + (0)); + for (i = 0; i < dreamResults_predlims.refXdata.size(0); i++) { + bayesResults->predlims.refXdata[i].f1.set_size(1, + dreamResults_predlims.refXdata[i].f1.size(1)); + loop_ub = dreamResults_predlims.refXdata[i].f1.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + bayesResults->predlims.refXdata[i].f1[bayesResults->predlims.refXdata[i] + .f1.size(0) * i1] = dreamResults_predlims.refXdata[i].f1[i1]; + } + } + + cast(dreamResults_predlims.sldXdata, bayesResults->predlims.sldXdata); + bayesResults->predlims.sampleChi.size[0] = 1000; + std::copy(&dreamResults_predlims.sampleChi[0], + &dreamResults_predlims.sampleChi[1000], + &bayesResults->predlims.sampleChi.data[0]); + bayesResults->bestFitsMean.ref.set_size(dreamResults_bestFitsMean.ref.size(0)); + for (i = 0; i < dreamResults_bestFitsMean.ref.size(0) * + dreamResults_bestFitsMean.ref.size(1); i++) { + bayesResults->bestFitsMean.ref[i].f1.set_size + (dreamResults_bestFitsMean.ref[i].f1.size(0), + dreamResults_bestFitsMean.ref[i].f1.size(1)); + loop_ub = dreamResults_bestFitsMean.ref[i].f1.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + b_loop_ub = dreamResults_bestFitsMean.ref[i].f1.size(0); + for (i2 = 0; i2 < b_loop_ub; i2++) { + bayesResults->bestFitsMean.ref[i].f1[i2 + + bayesResults->bestFitsMean.ref[i].f1.size(0) * i1] = + dreamResults_bestFitsMean.ref[i].f1[i2 + + dreamResults_bestFitsMean.ref[i].f1.size(0) * i1]; + } + } + } + + bayesResults->bestFitsMean.sld.set_size(dreamResults_bestFitsMean.sld.size(0), + dreamResults_bestFitsMean.sld.size(1)); + loop_ub = dreamResults_bestFitsMean.sld.size(1); + for (i = 0; i < loop_ub; i++) { + b_loop_ub = dreamResults_bestFitsMean.sld.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + bayesResults->bestFitsMean.sld[i1 + bayesResults->bestFitsMean.sld.size + (0) * i] = dreamResults_bestFitsMean.sld[i1 + + dreamResults_bestFitsMean.sld.size(0) * i]; + } + } + + bayesResults->bestFitsMean.chi = dreamResults_bestFitsMean.chi; + bayesResults->bestFitsMean.data.set_size(dreamResults_bestFitsMean.data.size + (0)); + for (i = 0; i < dreamResults_bestFitsMean.data.size(0) * + dreamResults_bestFitsMean.data.size(1); i++) { + bayesResults->bestFitsMean.data[i].f1.set_size + (dreamResults_bestFitsMean.data[i].f1.size(0), + dreamResults_bestFitsMean.data[i].f1.size(1)); + loop_ub = dreamResults_bestFitsMean.data[i].f1.size(1); + for (i1 = 0; i1 < loop_ub; i1++) { + b_loop_ub = dreamResults_bestFitsMean.data[i].f1.size(0); + for (i2 = 0; i2 < b_loop_ub; i2++) { + bayesResults->bestFitsMean.data[i].f1[i2 + + bayesResults->bestFitsMean.data[i].f1.size(0) * i1] = + dreamResults_bestFitsMean.data[i].f1[i2 + + dreamResults_bestFitsMean.data[i].f1.size(0) * i1]; + } + } + } + + // These are not defined in makeEmptyBayesResultsStruct + // bayesResults.bayesRes.DREAMPar = DREAMPar; + // bayesResults.bayesRes.Meas_info = Meas_info; + // bayesResults.bayesRes.dreamOutput = output; + } +} + +// End of code generation (runDREAM.cpp) diff --git a/cpp/RAT/runDREAM.h b/cpp/RAT/runDREAM.h new file mode 100644 index 00000000..603d72ba --- /dev/null +++ b/cpp/RAT/runDREAM.h @@ -0,0 +1,42 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// runDREAM.h +// +// Code generation for function 'runDREAM' +// +#ifndef RUNDREAM_H +#define RUNDREAM_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct c_struct_T; + struct cell_11; + struct struct1_T; + struct struct2_T; + struct struct4_T; + struct d_struct_T; + struct cell_wrap_9; + struct g_struct_T; +} + +// Function Declarations +namespace RAT +{ + void runDREAM(const c_struct_T *problemStruct, const cell_11 *problemCells, + const struct1_T *problemLimits, const struct2_T *controls, const + struct4_T *priors, c_struct_T *outProblemStruct, d_struct_T + *contrastParams, cell_wrap_9 result[6], g_struct_T *bayesResults); +} + +#endif + +// End of code generation (runDREAM.h) diff --git a/cpp/RAT/runNestedSampler.cpp b/cpp/RAT/runNestedSampler.cpp new file mode 100644 index 00000000..8db4c48e --- /dev/null +++ b/cpp/RAT/runNestedSampler.cpp @@ -0,0 +1,239 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// runNestedSampler.cpp +// +// Code generation for function 'runNestedSampler' +// + +// Include files +#include "runNestedSampler.h" +#include "RATMain_internal_types.h" +#include "RATMain_rtwutil.h" +#include "RATMain_types.h" +#include "blockedSummation.h" +#include "getFittedPriors.h" +#include "makeEmptyBayesResultsStruct.h" +#include "mean.h" +#include "nestedSampler.h" +#include "packParams.h" +#include "processBayes.h" +#include "rt_nonfinite.h" +#include "strcmp.h" +#include "coder_array.h" +#include "coder_bounded_array.h" +#include + +// Function Definitions +namespace RAT +{ + void runNestedSampler(c_struct_T *problemStruct, const cell_11 *problemCells, + const struct1_T *problemLimits, const struct2_T + *controls, const struct4_T *inPriors, d_struct_T + *contrastParams, cell_wrap_9 result[6], struct7_T + *bayesResults) + { + static b_struct_T t8_bayesRes; + ::coder::array fitNames; + ::coder::array t8_bestFitsMean_sld; + ::coder::array t8_predlims_sldPredInts; + ::coder::array t8_predlims_sldXdata; + ::coder::array t8_predlims_refPredInts; + ::coder::array b_expl_temp; + ::coder::array bayesOutputs_chain; + ::coder::array chain; + ::coder::array expl_temp; + ::coder::array expl_temp_mean; + ::coder::array expl_temp_par65; + ::coder::array expl_temp_par95; + ::coder::array r; + ::coder::array r1; + c_struct_T b_problemStruct; + e_struct_T nestResults_bestFitsMean; + f_struct_T nestResults_predlims; + real_T t8_predlims_sampleChi_data[1000]; + real_T logZ; + real_T t8_bestFitsMean_chi; + int32_T b_loop_ub; + int32_T loop_ub; + int32_T t8_predlims_sampleChi_size; + packParams(problemStruct, problemCells->f7, problemCells->f8, + problemCells->f9, problemCells->f10, problemCells->f11, + problemCells->f12, problemCells->f13, problemCells->f20, + problemLimits, &controls->checks, fitNames); + + // Make an empty struct for bayesResults to hold the outputs of the + // calculation + b_makeEmptyBayesResultsStruct(problemStruct->numberOfContrasts, coder:: + internal::b_strcmp(problemStruct->TF.data, problemStruct->TF.size), + bayesResults->bestFitsMean.ref, t8_bestFitsMean_sld, &t8_bestFitsMean_chi, + bayesResults->bestFitsMean.data, t8_predlims_refPredInts, + t8_predlims_sldPredInts, bayesResults->predlims.refXdata, + t8_predlims_sldXdata, t8_predlims_sampleChi_data, + &t8_predlims_sampleChi_size, expl_temp_par95, expl_temp_par65, + expl_temp_mean, expl_temp, &t8_bayesRes, b_expl_temp); + bayesResults->bayesRes.allChains.set_size(t8_bayesRes.allChains.size(0), + t8_bayesRes.allChains.size(1), t8_bayesRes.allChains.size(2)); + t8_predlims_sampleChi_size = t8_bayesRes.allChains.size(2); + for (int32_T i{0}; i < t8_predlims_sampleChi_size; i++) { + loop_ub = t8_bayesRes.allChains.size(1); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = t8_bayesRes.allChains.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + bayesResults->bayesRes.allChains[(i2 + + bayesResults->bayesRes.allChains.size(0) * i1) + + bayesResults->bayesRes.allChains.size(0) * + bayesResults->bayesRes.allChains.size(1) * i] = + t8_bayesRes.allChains[(i2 + t8_bayesRes.allChains.size(0) * i1) + + t8_bayesRes.allChains.size(0) * t8_bayesRes.allChains.size(1) * i]; + } + } + } + + bayesResults->bayesRes.dreamOutput = t8_bayesRes.dreamOutput; + + // Deal with priors. + // Tuning Parameters + getFittedPriors(fitNames, inPriors->priorNames, inPriors->priorValues, + problemStruct->fitLimits, r); + nestedSampler(problemStruct, controls, problemCells, controls->Nlive, + controls->Nmcmc, controls->nsTolerance, r, &logZ, + bayesResults->bayesRes.nestOutput.nestSamples, + bayesResults->bayesRes.nestOutput.postSamples, + &t8_bestFitsMean_chi); + + // Process the results... + // chain = nest_samples(:,1:end-1); + if (fitNames.size(0) < 1) { + t8_predlims_sampleChi_size = 0; + } else { + t8_predlims_sampleChi_size = fitNames.size(0); + } + + chain.set_size(bayesResults->bayesRes.nestOutput.postSamples.size(0), + t8_predlims_sampleChi_size); + bayesOutputs_chain.set_size + (bayesResults->bayesRes.nestOutput.postSamples.size(0), + t8_predlims_sampleChi_size); + for (int32_T i{0}; i < t8_predlims_sampleChi_size; i++) { + loop_ub = bayesResults->bayesRes.nestOutput.postSamples.size(0); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + chain[i1 + chain.size(0) * i] = + bayesResults->bayesRes.nestOutput.postSamples[i1 + + bayesResults->bayesRes.nestOutput.postSamples.size(0) * i]; + } + + loop_ub = bayesResults->bayesRes.nestOutput.postSamples.size(0); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + bayesOutputs_chain[i1 + bayesOutputs_chain.size(0) * i] = + bayesResults->bayesRes.nestOutput.postSamples[i1 + + bayesResults->bayesRes.nestOutput.postSamples.size(0) * i]; + } + } + + int32_T iv[2]; + coder::mean(chain, r1); + b_problemStruct = *problemStruct; + iv[0] = (*(int32_T (*)[2])r1.size())[0]; + iv[1] = (*(int32_T (*)[2])r1.size())[1]; + processBayes((const real_T *)r1.data(), iv, bayesOutputs_chain, + &b_problemStruct, controls, problemCells, problemStruct, + contrastParams, result, &nestResults_bestFitsMean, + &nestResults_predlims, &bayesResults->parConfInts); + cast(nestResults_predlims.refPredInts, bayesResults->predlims.refPredInts); + cast(nestResults_predlims.sldPredInts, bayesResults->predlims.sldPredInts); + bayesResults->predlims.refXdata.set_size(nestResults_predlims.refXdata.size + (0)); + for (int32_T i{0}; i < nestResults_predlims.refXdata.size(0); i++) { + bayesResults->predlims.refXdata[i].f1.set_size(1, + nestResults_predlims.refXdata[i].f1.size(1)); + loop_ub = nestResults_predlims.refXdata[i].f1.size(1); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + bayesResults->predlims.refXdata[i].f1[bayesResults->predlims.refXdata[i] + .f1.size(0) * i1] = nestResults_predlims.refXdata[i].f1[i1]; + } + } + + cast(nestResults_predlims.sldXdata, bayesResults->predlims.sldXdata); + bayesResults->predlims.sampleChi.size[0] = 1000; + std::copy(&nestResults_predlims.sampleChi[0], + &nestResults_predlims.sampleChi[1000], + &bayesResults->predlims.sampleChi.data[0]); + bayesResults->bestFitsMean.ref.set_size(nestResults_bestFitsMean.ref.size(0)); + for (int32_T i{0}; i < nestResults_bestFitsMean.ref.size(0) * + nestResults_bestFitsMean.ref.size(1); i++) { + bayesResults->bestFitsMean.ref[i].f1.set_size + (nestResults_bestFitsMean.ref[i].f1.size(0), + nestResults_bestFitsMean.ref[i].f1.size(1)); + loop_ub = nestResults_bestFitsMean.ref[i].f1.size(1); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = nestResults_bestFitsMean.ref[i].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + bayesResults->bestFitsMean.ref[i].f1[i2 + + bayesResults->bestFitsMean.ref[i].f1.size(0) * i1] = + nestResults_bestFitsMean.ref[i].f1[i2 + + nestResults_bestFitsMean.ref[i].f1.size(0) * i1]; + } + } + } + + bayesResults->bestFitsMean.sld.set_size(nestResults_bestFitsMean.sld.size(0), + nestResults_bestFitsMean.sld.size(1)); + loop_ub = nestResults_bestFitsMean.sld.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = nestResults_bestFitsMean.sld.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + bayesResults->bestFitsMean.sld[i1 + bayesResults->bestFitsMean.sld.size + (0) * i] = nestResults_bestFitsMean.sld[i1 + + nestResults_bestFitsMean.sld.size(0) * i]; + } + } + + bayesResults->bestFitsMean.chi = nestResults_bestFitsMean.chi; + bayesResults->bestFitsMean.data.set_size(nestResults_bestFitsMean.data.size + (0)); + for (int32_T i{0}; i < nestResults_bestFitsMean.data.size(0) * + nestResults_bestFitsMean.data.size(1); i++) { + bayesResults->bestFitsMean.data[i].f1.set_size + (nestResults_bestFitsMean.data[i].f1.size(0), + nestResults_bestFitsMean.data[i].f1.size(1)); + loop_ub = nestResults_bestFitsMean.data[i].f1.size(1); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = nestResults_bestFitsMean.data[i].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + bayesResults->bestFitsMean.data[i].f1[i2 + + bayesResults->bestFitsMean.data[i].f1.size(0) * i1] = + nestResults_bestFitsMean.data[i].f1[i2 + + nestResults_bestFitsMean.data[i].f1.size(0) * i1]; + } + } + } + + coder::blockedSummation(chain, + bayesResults->bayesRes.nestOutput.postSamples.size(0), r1); + bayesResults->bestPars.set_size(1, r1.size(1)); + loop_ub = r1.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + bayesResults->bestPars[i] = r1[i] / static_cast + (bayesResults->bayesRes.nestOutput.postSamples.size(0)); + } + + bayesResults->chain.set_size + (bayesResults->bayesRes.nestOutput.postSamples.size(0), + t8_predlims_sampleChi_size); + for (int32_T i{0}; i < t8_predlims_sampleChi_size; i++) { + loop_ub = bayesResults->bayesRes.nestOutput.postSamples.size(0); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + bayesResults->chain[i1 + bayesResults->chain.size(0) * i] = + bayesResults->bayesRes.nestOutput.postSamples[i1 + + bayesResults->bayesRes.nestOutput.postSamples.size(0) * i]; + } + } + + bayesResults->bayesRes.nestOutput.LogZ = logZ; + } +} + +// End of code generation (runNestedSampler.cpp) diff --git a/cpp/RAT/runNestedSampler.h b/cpp/RAT/runNestedSampler.h new file mode 100644 index 00000000..653ac381 --- /dev/null +++ b/cpp/RAT/runNestedSampler.h @@ -0,0 +1,43 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// runNestedSampler.h +// +// Code generation for function 'runNestedSampler' +// +#ifndef RUNNESTEDSAMPLER_H +#define RUNNESTEDSAMPLER_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct c_struct_T; + struct cell_11; + struct struct1_T; + struct struct2_T; + struct struct4_T; + struct d_struct_T; + struct cell_wrap_9; + struct struct7_T; +} + +// Function Declarations +namespace RAT +{ + void runNestedSampler(c_struct_T *problemStruct, const cell_11 *problemCells, + const struct1_T *problemLimits, const struct2_T + *controls, const struct4_T *inPriors, d_struct_T + *contrastParams, cell_wrap_9 result[6], struct7_T + *bayesResults); +} + +#endif + +// End of code generation (runNestedSampler.h) diff --git a/cpp/RAT/runSimplex.cpp b/cpp/RAT/runSimplex.cpp new file mode 100644 index 00000000..8caae4c0 --- /dev/null +++ b/cpp/RAT/runSimplex.cpp @@ -0,0 +1,251 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// runSimplex.cpp +// +// Code generation for function 'runSimplex' +// + +// Include files +#include "runSimplex.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "fMinSearch.h" +#include "packParams.h" +#include "reflectivityCalculation.h" +#include "rt_nonfinite.h" +#include "simplexXTransform.h" +#include "strcmp.h" +#include "unpackParams.h" +#include "coder_array.h" +#include "coder_bounded_array.h" +#include + +// Function Definitions +namespace RAT +{ + void runSimplex(c_struct_T *problemStruct, const cell_11 *problemCells, const + struct1_T *problemLimits, const struct2_T *controls, + d_struct_T *contrastParams, cell_wrap_9 result[6]) + { + static const char_T b_cv1[6]{ 'n', 'o', 't', 'i', 'f', 'y' }; + + static const char_T b_cv[5]{ 'f', 'i', 'n', 'a', 'l' }; + + ::coder::array b_problemStruct; + ::coder::array x; + ::coder::array x0u; + i_struct_T a__4; + k_struct_T expl_temp; + real_T a__2; + real_T a__3; + int32_T dis_size[2]; + int32_T i; + int32_T outsize_idx_0; + char_T dis_data[6]; + packParams(problemStruct, problemCells->f7, problemCells->f8, + problemCells->f9, problemCells->f10, problemCells->f11, + problemCells->f12, problemCells->f13, problemCells->f20, + problemLimits, &controls->checks, b_problemStruct); + if (coder::internal::r_strcmp(controls->display.data, controls->display.size)) + { + outsize_idx_0 = 0; + } else if (coder::internal::s_strcmp(controls->display.data, + controls->display.size)) { + outsize_idx_0 = 1; + } else if (coder::internal::t_strcmp(controls->display.data, + controls->display.size)) { + outsize_idx_0 = 2; + } else if (coder::internal::u_strcmp(controls->display.data, + controls->display.size)) { + outsize_idx_0 = 3; + } else { + outsize_idx_0 = -1; + } + + switch (outsize_idx_0) { + case 0: + dis_size[0] = 1; + dis_size[1] = 4; + dis_data[0] = 'n'; + dis_data[1] = 'o'; + dis_data[2] = 'n'; + dis_data[3] = 'e'; + break; + + case 1: + dis_size[0] = 1; + dis_size[1] = 4; + dis_data[0] = 'i'; + dis_data[1] = 't'; + dis_data[2] = 'e'; + dis_data[3] = 'r'; + break; + + case 2: + dis_size[0] = 1; + dis_size[1] = 6; + for (i = 0; i < 6; i++) { + dis_data[i] = b_cv1[i]; + } + break; + + case 3: + dis_size[0] = 1; + dis_size[1] = 5; + for (i = 0; i < 5; i++) { + dis_data[i] = b_cv[i]; + } + break; + + default: + dis_size[0] = 1; + dis_size[1] = 5; + for (i = 0; i < 5; i++) { + dis_data[i] = b_cv[i]; + } + break; + } + + expl_temp.LB.set_size(problemStruct->fitLimits.size(0)); + outsize_idx_0 = problemStruct->fitLimits.size(0); + for (i = 0; i < outsize_idx_0; i++) { + expl_temp.LB[i] = problemStruct->fitLimits[i]; + } + + expl_temp.UB.set_size(problemStruct->fitLimits.size(0)); + outsize_idx_0 = problemStruct->fitLimits.size(0); + for (i = 0; i < outsize_idx_0; i++) { + expl_temp.UB[i] = problemStruct->fitLimits[i + + problemStruct->fitLimits.size(0)]; + } + + // size checks + if (problemStruct->fitLimits.size(0) == 0) { + outsize_idx_0 = problemStruct->fitParams.size(0) * + problemStruct->fitParams.size(1); + expl_temp.LB.set_size(outsize_idx_0); + for (i = 0; i < outsize_idx_0; i++) { + expl_temp.LB[i] = rtMinusInf; + } + } + + if (problemStruct->fitLimits.size(0) == 0) { + outsize_idx_0 = problemStruct->fitParams.size(0) * + problemStruct->fitParams.size(1); + expl_temp.UB.set_size(outsize_idx_0); + for (i = 0; i < outsize_idx_0; i++) { + expl_temp.UB[i] = rtInf; + } + } + + // stuff into a struct to pass around + // varargin; + // problemStruct.modelFilename;%fun; + // 0 --> unconstrained variable + // 1 --> lower bound only + // 2 --> upper bound only + // 3 --> dual finite bounds + outsize_idx_0 = problemStruct->fitParams.size(0) * + problemStruct->fitParams.size(1); + expl_temp.BoundClass.set_size(outsize_idx_0); + for (i = 0; i < outsize_idx_0; i++) { + expl_temp.BoundClass[i] = 0.0; + } + + i = problemStruct->fitParams.size(0) * problemStruct->fitParams.size(1); + for (int32_T b_i{0}; b_i < i; b_i++) { + expl_temp.BoundClass[b_i] = static_cast((!std::isinf + (expl_temp.LB[b_i])) && (!std::isnan(expl_temp.LB[b_i]))) + static_cast< + real_T>(((!std::isinf(expl_temp.UB[b_i])) && (!std::isnan + (expl_temp.UB[b_i]))) << 1); + } + + // transform starting values into their unconstrained + // surrogates. Check for infeasible starting guesses. + outsize_idx_0 = problemStruct->fitParams.size(0) * + problemStruct->fitParams.size(1); + x0u.set_size(outsize_idx_0); + for (i = 0; i < outsize_idx_0; i++) { + x0u[i] = problemStruct->fitParams[i]; + } + + i = problemStruct->fitParams.size(0) * problemStruct->fitParams.size(1); + for (int32_T b_i{0}; b_i < i; b_i++) { + switch (static_cast(expl_temp.BoundClass[b_i])) { + case 1: + // lower bound only + if (problemStruct->fitParams[b_i] <= expl_temp.LB[b_i]) { + // infeasible starting value. Use bound. + x0u[b_i] = 0.0; + } else { + x0u[b_i] = std::sqrt(problemStruct->fitParams[b_i] - expl_temp.LB[b_i]); + } + break; + + case 2: + // upper bound only + if (problemStruct->fitParams[b_i] >= expl_temp.UB[b_i]) { + // infeasible starting value. use bound. + x0u[b_i] = 0.0; + } else { + x0u[b_i] = std::sqrt(expl_temp.UB[b_i] - problemStruct->fitParams[b_i]); + } + break; + + case 3: + // lower and upper bounds + if (problemStruct->fitParams[b_i] <= expl_temp.LB[b_i]) { + // infeasible starting value + x0u[b_i] = -1.5707963267948966; + } else if (problemStruct->fitParams[b_i] >= expl_temp.UB[b_i]) { + // infeasible starting value + x0u[b_i] = 1.5707963267948966; + } else { + x0u[b_i] = std::asin(std::fmax(-1.0, std::fmin(1.0, 2.0 * + (problemStruct->fitParams[b_i] - expl_temp.LB[b_i]) / + (expl_temp.UB[b_i] - expl_temp.LB[b_i]) - 1.0))); + } + break; + + default: + // unconstrained variable. x0u(i) is set. + break; + } + } + + // now we can call fminsearch, but with our own + // intra-objective function. + fMinSearch(x0u, controls->maxIter, controls->maxFunEvals, controls->tolX, + controls->tolFun, dis_data, dis_size, problemStruct, + problemCells->f1, problemCells->f2, problemCells->f3, + problemCells->f4, problemCells->f5, problemCells->f6, + problemCells->f14, problemCells->f19, controls, &expl_temp, &a__2, + &a__3, &a__4); + + // [xu,fval,exitflag,output] = simplex(@simplexIntrafun,x0u,problemStruct,problemCells,problemLimits,controls,options,params,300); + // undo the variable transformations into the original space + simplexXTransform(x0u, expl_temp.LB, expl_temp.UB, expl_temp.BoundClass, x); + + // final reshape + // x = reshape(x,xsize); + outsize_idx_0 = x.size(0); + problemStruct->fitParams.set_size(x.size(0), 1); + for (i = 0; i < outsize_idx_0; i++) { + problemStruct->fitParams[i] = x[i]; + } + + unpackParams(problemStruct, controls->checks.fitParam, + controls->checks.fitBackgroundParam, + controls->checks.fitQzshift, controls->checks.fitScalefactor, + controls->checks.fitBulkIn, controls->checks.fitBulkOut, + controls->checks.fitResolutionParam, + controls->checks.fitDomainRatio); + reflectivityCalculation(problemStruct, problemCells, controls, + contrastParams, result); + } +} + +// End of code generation (runSimplex.cpp) diff --git a/cpp/RAT/runSimplex.h b/cpp/RAT/runSimplex.h new file mode 100644 index 00000000..6712ec30 --- /dev/null +++ b/cpp/RAT/runSimplex.h @@ -0,0 +1,39 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// runSimplex.h +// +// Code generation for function 'runSimplex' +// +#ifndef RUNSIMPLEX_H +#define RUNSIMPLEX_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct c_struct_T; + struct cell_11; + struct struct1_T; + struct struct2_T; + struct d_struct_T; + struct cell_wrap_9; +} + +// Function Declarations +namespace RAT +{ + void runSimplex(c_struct_T *problemStruct, const cell_11 *problemCells, const + struct1_T *problemLimits, const struct2_T *controls, + d_struct_T *contrastParams, cell_wrap_9 result[6]); +} + +#endif + +// End of code generation (runSimplex.h) diff --git a/cpp/RAT/scaleParameters.cpp b/cpp/RAT/scaleParameters.cpp new file mode 100644 index 00000000..14313a3a --- /dev/null +++ b/cpp/RAT/scaleParameters.cpp @@ -0,0 +1,78 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// scaleParameters.cpp +// +// Code generation for function 'scaleParameters' +// + +// Include files +#include "scaleParameters.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + void scaleParameters(const ::coder::array &prior, const ::coder:: + array ¶ms, ::coder::array + &scaled) + { + int32_T i; + int32_T loop_ub; + + // scaled = scaleParameters(prior, params) + // + // This function will scale parameters based on their priors. If a prior is + // uniform over a range then the parameter will be scaled, such that the + // range covers 0->1. If a prior is Gaussian then the parameter will be + // scaled such that it will be a Gaussian with zero mean and unit variance. + scaled.set_size(params.size(1)); + loop_ub = params.size(1); + for (i = 0; i < loop_ub; i++) { + scaled[i] = 0.0; + } + + i = params.size(1); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T priortype; + priortype = prior[b_i]; + if (priortype == 1.0) { + real_T p3; + + // uniform + p3 = prior[b_i + prior.size(0) * 3]; + scaled[b_i] = (params[b_i] - p3) / (prior[b_i + prior.size(0) * 4] - p3); + } else if (priortype == 2.0) { + // gaussian + scaled[b_i] = (params[b_i] - prior[b_i + prior.size(0)]) / prior[b_i + + prior.size(0) * 2]; + } else if (priortype == 3.0) { + real_T scaled_tmp; + + // jeffreys + scaled_tmp = std::log10(prior[b_i + prior.size(0)]); + scaled[b_i] = (std::log10(params[b_i]) - scaled_tmp) / (std::log10 + (prior[b_i + prior.size(0) * 2]) - scaled_tmp); + } + } + + // priortype = char(prior(i,2)); + // p3 = prior{i,3}; + // p4 = prior{i,4}; + // + // % currently only handles uniform or Gaussian priors + // if strcmp(priortype, 'uniform') + // scaled(i) = (params(i) - p3)/(p4 - p3); + // elseif strcmp(priortype, 'gaussian') + // scaled(i) = (params(i) - p3)/p4; + // elseif strcmp(priortype, 'jeffreys') + // scaled(i) = (log10(params(i)) - log10(p3))/(log10(p4) - log10(p3)); + // end + } +} + +// End of code generation (scaleParameters.cpp) diff --git a/cpp/RAT/scaleParameters.h b/cpp/RAT/scaleParameters.h new file mode 100644 index 00000000..f17bcf29 --- /dev/null +++ b/cpp/RAT/scaleParameters.h @@ -0,0 +1,29 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// scaleParameters.h +// +// Code generation for function 'scaleParameters' +// +#ifndef SCALEPARAMETERS_H +#define SCALEPARAMETERS_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void scaleParameters(const ::coder::array &prior, const ::coder:: + array ¶ms, ::coder::array + &scaled); +} + +#endif + +// End of code generation (scaleParameters.h) diff --git a/cpp/RAT/scaledGaussPrior.cpp b/cpp/RAT/scaledGaussPrior.cpp new file mode 100644 index 00000000..2f20ba81 --- /dev/null +++ b/cpp/RAT/scaledGaussPrior.cpp @@ -0,0 +1,157 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// scaledGaussPrior.cpp +// +// Code generation for function 'scaledGaussPrior' +// + +// Include files +#include "scaledGaussPrior.h" +#include "find.h" +#include "rescale.h" +#include "rt_nonfinite.h" +#include "sum.h" +#include "unsafeSxfun.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + real_T scaledGaussPrior(const ::coder::array &m, const ::coder:: + array &extras_problemStruct_fitLimits, const ::coder::array< + real_T, 2U> &extras_priors) + { + ::coder::array usedConstr; + ::coder::array usedPriors; + ::coder::array b_m; + ::coder::array b_usedConstr; + ::coder::array c_usedConstr; + ::coder::array r; + ::coder::array r1; + ::coder::array r2; + ::coder::array usedPriorInd; + ::coder::array b_extras_priors; + real_T pVal2; + int32_T i; + int32_T loop_ub; + + // All are in range, so check for Gaussian priors.... + // We pick out any priors that are Gaussians and calculate the mvnpdf + // Find all the Gaussian priors.... + // usedPriorInd = find(strcmpi(priorList(:,1),'gaussian')); + b_extras_priors.set_size(extras_priors.size(0)); + loop_ub = extras_priors.size(0); + for (i = 0; i < loop_ub; i++) { + b_extras_priors[i] = (extras_priors[i] == 2.0); + } + + coder::eml_find(b_extras_priors, usedPriorInd); + usedPriors.set_size(usedPriorInd.size(0), 5); + loop_ub = usedPriorInd.size(0); + for (i = 0; i < 5; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + usedPriors[i1 + usedPriors.size(0) * i] = extras_priors[(usedPriorInd[i1] + + extras_priors.size(0) * i) - 1]; + } + } + + usedConstr.set_size(usedPriorInd.size(0), 2); + loop_ub = usedPriorInd.size(0); + for (i = 0; i < 2; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + usedConstr[i1 + usedConstr.size(0) * i] = + extras_problemStruct_fitLimits[(usedPriorInd[i1] + + extras_problemStruct_fitLimits.size(0) * i) - 1]; + } + } + + if (usedPriorInd.size(0) != 0) { + // There may be no Gaussian priors defined! + // Scale (minVal+prior) will give scaled sigma since minVal goes to 0... + b_m.set_size(usedPriorInd.size(0)); + loop_ub = usedPriorInd.size(0); + for (i = 0; i < loop_ub; i++) { + b_m[i] = m[usedPriorInd[i] - 1]; + } + + b_usedConstr.set_size(usedPriorInd.size(0)); + loop_ub = usedPriorInd.size(0); + for (i = 0; i < loop_ub; i++) { + b_usedConstr[i] = usedConstr[i]; + } + + c_usedConstr.set_size(usedPriorInd.size(0)); + loop_ub = usedPriorInd.size(0); + for (i = 0; i < loop_ub; i++) { + c_usedConstr[i] = usedConstr[i + usedConstr.size(0)]; + } + + coder::rescale(b_m, b_usedConstr, c_usedConstr, r); + b_m.set_size(usedPriorInd.size(0)); + loop_ub = usedPriorInd.size(0); + for (i = 0; i < loop_ub; i++) { + b_m[i] = usedPriors[i + usedPriors.size(0)]; + } + + b_usedConstr.set_size(usedPriorInd.size(0)); + loop_ub = usedPriorInd.size(0); + for (i = 0; i < loop_ub; i++) { + b_usedConstr[i] = usedConstr[i]; + } + + c_usedConstr.set_size(usedPriorInd.size(0)); + loop_ub = usedPriorInd.size(0); + for (i = 0; i < loop_ub; i++) { + c_usedConstr[i] = usedConstr[i + usedConstr.size(0)]; + } + + coder::rescale(b_m, b_usedConstr, c_usedConstr, r1); + b_m.set_size(usedPriorInd.size(0)); + loop_ub = usedPriorInd.size(0); + for (i = 0; i < loop_ub; i++) { + b_m[i] = usedPriors[i + usedPriors.size(0) * 2] + usedConstr[i]; + } + + b_usedConstr.set_size(usedPriorInd.size(0)); + loop_ub = usedPriorInd.size(0); + for (i = 0; i < loop_ub; i++) { + b_usedConstr[i] = usedConstr[i]; + } + + c_usedConstr.set_size(usedPriorInd.size(0)); + loop_ub = usedPriorInd.size(0); + for (i = 0; i < loop_ub; i++) { + c_usedConstr[i] = usedConstr[i + usedConstr.size(0)]; + } + + coder::rescale(b_m, b_usedConstr, c_usedConstr, r2); + if (r.size(0) == 1) { + i = r1.size(0); + } else { + i = r.size(0); + } + + if ((r.size(0) == r1.size(0)) && (i == r2.size(0))) { + loop_ub = r.size(0); + for (i = 0; i < loop_ub; i++) { + real_T varargin_1; + varargin_1 = (r[i] - r1[i]) / r2[i]; + r[i] = varargin_1 * varargin_1; + } + } else { + binary_expand_op(r, r1, r2); + } + + pVal2 = -coder::sum(r); + } else { + pVal2 = 0.0; + } + + return pVal2; + } +} + +// End of code generation (scaledGaussPrior.cpp) diff --git a/cpp/RAT/scaledGaussPrior.h b/cpp/RAT/scaledGaussPrior.h new file mode 100644 index 00000000..1c93780b --- /dev/null +++ b/cpp/RAT/scaledGaussPrior.h @@ -0,0 +1,29 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// scaledGaussPrior.h +// +// Code generation for function 'scaledGaussPrior' +// +#ifndef SCALEDGAUSSPRIOR_H +#define SCALEDGAUSSPRIOR_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + real_T scaledGaussPrior(const ::coder::array &m, const ::coder:: + array &extras_problemStruct_fitLimits, const ::coder::array< + real_T, 2U> &extras_priors); +} + +#endif + +// End of code generation (scaledGaussPrior.h) diff --git a/cpp/RAT/schur.cpp b/cpp/RAT/schur.cpp new file mode 100644 index 00000000..25771d0e --- /dev/null +++ b/cpp/RAT/schur.cpp @@ -0,0 +1,84 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// schur.cpp +// +// Code generation for function 'schur' +// + +// Include files +#include "schur.h" +#include "anyNonFinite.h" +#include "rt_nonfinite.h" +#include "triu.h" +#include "xdhseqr.h" +#include "xgehrd.h" +#include "xungorghr.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + void schur(const ::coder::array &A, ::coder::array + &V, ::coder::array &T) + { + ::coder::array tau; + if (internal::anyNonFinite(A)) { + int32_T b_loop_ub; + int32_T loop_ub; + uint32_T unnamed_idx_0; + unnamed_idx_0 = static_cast(A.size(0)); + V.set_size(A.size(0), A.size(1)); + loop_ub = A.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = static_cast(unnamed_idx_0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + V[i1 + V.size(0) * i] = rtNaN; + } + } + + triu(V); + unnamed_idx_0 = static_cast(A.size(0)); + T.set_size(A.size(0), A.size(1)); + loop_ub = A.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = static_cast(unnamed_idx_0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + T[i1 + T.size(0) * i] = rtNaN; + } + } + } else { + int32_T b_loop_ub; + int32_T loop_ub; + T.set_size(A.size(0), A.size(1)); + loop_ub = A.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = A.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + T[i1 + T.size(0) * i] = A[i1 + A.size(0) * i]; + } + } + + internal::lapack::xgehrd(T, tau); + V.set_size(T.size(0), T.size(1)); + loop_ub = T.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = T.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + V[i1 + V.size(0) * i] = T[i1 + T.size(0) * i]; + } + } + + internal::lapack::xungorghr(A.size(0), A.size(0), V, A.size(0), tau); + internal::reflapack::eml_dlahqr(T, V); + b_triu(T); + } + } + } +} + +// End of code generation (schur.cpp) diff --git a/cpp/RAT/schur.h b/cpp/RAT/schur.h new file mode 100644 index 00000000..ad1feed3 --- /dev/null +++ b/cpp/RAT/schur.h @@ -0,0 +1,31 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// schur.h +// +// Code generation for function 'schur' +// +#ifndef SCHUR_H +#define SCHUR_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void schur(const ::coder::array &A, ::coder::array + &V, ::coder::array &T); + } +} + +#endif + +// End of code generation (schur.h) diff --git a/cpp/RAT/setupDREAM.cpp b/cpp/RAT/setupDREAM.cpp new file mode 100644 index 00000000..65232011 --- /dev/null +++ b/cpp/RAT/setupDREAM.cpp @@ -0,0 +1,274 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// setupDREAM.cpp +// +// Code generation for function 'setupDREAM' +// + +// Include files +#include "setupDREAM.h" +#include "RATMain_types.h" +#include "eml_setop.h" +#include "rng.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include "coder_bounded_array.h" +#include + +// Function Definitions +namespace RAT +{ + void setupDREAM(real_T DREAMPar_d, real_T DREAMPar_N, real_T DREAMPar_T, + real_T DREAMPar_lambda, real_T DREAMPar_pUnitGamma, boolean_T + DREAMPar_adaptPCR, struct13_T *outDREAMPar, struct14_T + *Meas_info, ::coder::array &chain, struct12_T + *output, ::coder::array &log_L, ::coder::array< + real_T, 2U> &Table_gamma) + { + ::coder::array c; + ::coder::array y; + ::coder::array r; + ::coder::array ia; + real_T value_f3_tmp; + int32_T b_loop_ub_tmp; + int32_T i; + int32_T k; + int32_T loop_ub; + int32_T loop_ub_tmp; + Meas_info->Y = 0.0; + Meas_info->N = 0.0; + + // Initializes the main variables used in DREAM + // To keep coder happy, we have to define the full version of DREAMPar here + // fieldNames = {'d','N','T','parallel','CPU','lambda','pUnitGamma','nCR','delta','steps',... + // 'zeta','outlier','adaptPCR','thinning','epsilon','ABC','IO','modout','restart','save','R'}; + // values = cell(length(fieldNames),1); + // outDREAMPar = cell2struct(values,fieldNames); + loop_ub_tmp = static_cast(DREAMPar_N); + outDREAMPar->R.set_size(loop_ub_tmp, loop_ub_tmp); + for (i = 0; i < loop_ub_tmp; i++) { + for (int32_T i1{0}; i1 < loop_ub_tmp; i1++) { + outDREAMPar->R[i1 + outDREAMPar->R.size(0) * i] = 0.0; + } + } + + // Generate new seed + coder::rng(); + + // randn('state', sum(100*clock)); % random number generator state + // Now make sure that all strings are lower case --> **TURNS OUT THIS BREAKS + // THINGS IF IMPLEMENTED!** + // for i = 1 : numel(field_names) + // % evalstr = strcat('DREAMPar.',field_names(i),' = lower(DREAMPar.',field_names(i),');'); + // % Now evaluate + // %eval(char(evalstr)); + // DREAMPar = lowerCaseStruct(DREAMPar); + // end + // Do an initial copy of all set fields from DREAMPar to outDREAMPar.... + outDREAMPar->d = DREAMPar_d; + outDREAMPar->N = DREAMPar_N; + outDREAMPar->T = DREAMPar_T; + outDREAMPar->CPU = 1.0; + + // Set default values algorithmic variables DREAM - if not specified + value_f3_tmp = std::fmax(std::fmax(std::floor(DREAMPar_T / 50.0), 1.0), 50.0); + + // Name variable + // Set variable of DREAMPar to "No" + // evalstr = strcat('DREAMPar.',char(name(j)),'=',value(j),';'); eval(char(evalstr)); + outDREAMPar->nCR = 3.0; + + // Set variable of DREAMPar to "No" + // evalstr = strcat('DREAMPar.',char(name(j)),'=',value(j),';'); eval(char(evalstr)); + outDREAMPar->delta = 3.0; + + // Set variable of DREAMPar to "No" + // evalstr = strcat('DREAMPar.',char(name(j)),'=',value(j),';'); eval(char(evalstr)); + outDREAMPar->steps = value_f3_tmp; + outDREAMPar->lambda = DREAMPar_lambda; + + // Set variable of DREAMPar to "No" + // evalstr = strcat('DREAMPar.',char(name(j)),'=',value(j),';'); eval(char(evalstr)); + outDREAMPar->zeta = 1.0E-12; + + // Set variable of DREAMPar to "No" + // evalstr = strcat('DREAMPar.',char(name(j)),'=',value(j),';'); eval(char(evalstr)); + outDREAMPar->outlier[0] = 'i'; + outDREAMPar->outlier[1] = 'q'; + outDREAMPar->outlier[2] = 'r'; + outDREAMPar->pUnitGamma = DREAMPar_pUnitGamma; + outDREAMPar->adaptPCR = DREAMPar_adaptPCR; + + // Set variable of DREAMPar to "No" + // evalstr = strcat('DREAMPar.',char(name(j)),'=',value(j),';'); eval(char(evalstr)); + outDREAMPar->thinning = 1.0; + + // Set variable of DREAMPar to "No" + // evalstr = strcat('DREAMPar.',char(name(j)),'=',value(j),';'); eval(char(evalstr)); + outDREAMPar->epsilon = 0.025; + + // Set default value to 'No' if not specified + // Set variable of DREAMPar to false + // evalstr = strcat('DREAMPar.',char(default(j)),'=false',';'); eval(evalstr); + outDREAMPar->ABC = false; + outDREAMPar->parallel = false; + + // Set variable of DREAMPar to false + // evalstr = strcat('DREAMPar.',char(default(j)),'=false',';'); eval(evalstr); + outDREAMPar->IO = false; + + // Set variable of DREAMPar to false + // evalstr = strcat('DREAMPar.',char(default(j)),'=false',';'); eval(evalstr); + outDREAMPar->modout = false; + + // Set variable of DREAMPar to false + // evalstr = strcat('DREAMPar.',char(default(j)),'=false',';'); eval(evalstr); + outDREAMPar->restart = false; + + // Set variable of DREAMPar to false + // evalstr = strcat('DREAMPar.',char(default(j)),'=false',';'); eval(evalstr); + outDREAMPar->save = false; + + // Matrix DREAMPar.R: Store for each chain (as row) the index of all other chains available for DE + if (static_cast(DREAMPar_N) - 1 >= 0) { + if (DREAMPar_N < 1.0) { + y.set_size(1, 0); + } else { + y.set_size(1, static_cast(DREAMPar_N - 1.0) + 1); + loop_ub = static_cast(DREAMPar_N - 1.0); + for (i = 0; i <= loop_ub; i++) { + y[i] = static_cast(i) + 1.0; + } + } + } + + for (int32_T b_i{0}; b_i < loop_ub_tmp; b_i++) { + coder::do_vectors(y, static_cast(b_i) + 1.0, c, ia, &k); + loop_ub = c.size(1); + for (i = 0; i < loop_ub; i++) { + outDREAMPar->R[b_i + outDREAMPar->R.size(0) * i] = c[i]; + } + } + + // Check whether parameter ranges have been defined or not + // Initialize output information -- Outlier chains + output->outlier.size[0] = 1; + output->outlier.size[1] = 2; + output->outlier.data[0] = 0.0; + output->outlier.data[output->outlier.size[0]] = 0.0; + + // ..also run time + output->RunTime = 0.0; + output->DREAMPar = *outDREAMPar; + output->Meas_info = *Meas_info; + output->iteration = 1.0; + output->iloc = 0.0; + output->fx = 0.0; + + // Initialize matrix with log_likelihood of each chain + loop_ub = static_cast(DREAMPar_T); + b_loop_ub_tmp = static_cast(DREAMPar_N + 1.0); + log_L.set_size(loop_ub, b_loop_ub_tmp); + for (i = 0; i < b_loop_ub_tmp; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + log_L[i1 + log_L.size(0) * i] = rtNaN; + } + } + + // Initialize vector with acceptance rates + b_loop_ub_tmp = static_cast(std::floor(DREAMPar_T / value_f3_tmp) + + 1.0); + output->AR.size[0] = static_cast(std::floor(DREAMPar_T / + value_f3_tmp) + 1.0); + output->AR.size[1] = 2; + for (i = 0; i < 2; i++) { + for (int32_T i1{0}; i1 < b_loop_ub_tmp; i1++) { + output->AR.data[i1 + output->AR.size[0] * i] = rtNaN; + } + } + + // NaN(floor(outDREAMPar.T/outDREAMPar.steps)+1,2); + output->AR.data[0] = DREAMPar_N; + + // Initialize matrix with potential scale reduction convergence diagnostic + k = static_cast(DREAMPar_d + 1.0); + output->R_stat.set_size(b_loop_ub_tmp, k); + for (i = 0; i < k; i++) { + for (int32_T i1{0}; i1 < b_loop_ub_tmp; i1++) { + output->R_stat[i1 + output->R_stat.size(0) * i] = rtNaN; + } + } + + // Initialize matix with crossover values + output->CR.set_size(b_loop_ub_tmp, 4); + for (i = 0; i < 4; i++) { + for (int32_T i1{0}; i1 < b_loop_ub_tmp; i1++) { + output->CR[i1 + output->CR.size(0) * i] = rtNaN; + } + } + + // Initialize array (3D-matrix) of chain trajectories + b_loop_ub_tmp = static_cast(DREAMPar_d + 2.0); + chain.set_size(loop_ub, b_loop_ub_tmp, loop_ub_tmp); + for (i = 0; i < loop_ub_tmp; i++) { + for (int32_T i1{0}; i1 < b_loop_ub_tmp; i1++) { + for (k = 0; k < loop_ub; k++) { + chain[(k + chain.size(0) * i1) + chain.size(0) * chain.size(1) * i] = + rtNaN; + } + } + } + + // Generate Table with jump rates (dependent on DREAMPar.d and DREAMPar.delta) + // More efficient to read from Table + loop_ub_tmp = static_cast(DREAMPar_d); + Table_gamma.set_size(loop_ub_tmp, 3); + for (i = 0; i < 3; i++) { + for (int32_T i1{0}; i1 < loop_ub_tmp; i1++) { + Table_gamma[i1 + Table_gamma.size(0) * i] = 0.0; + } + } + + if (std::isnan(DREAMPar_d)) { + y.set_size(1, 1); + y[0] = rtNaN; + } else if (DREAMPar_d < 1.0) { + y.set_size(1, 0); + } else { + y.set_size(1, static_cast(DREAMPar_d - 1.0) + 1); + loop_ub = static_cast(DREAMPar_d - 1.0); + for (i = 0; i <= loop_ub; i++) { + y[i] = static_cast(i) + 1.0; + } + } + + loop_ub = y.size(1); + for (int32_T zz{0}; zz < 3; zz++) { + k = (zz + 1) << 1; + r.set_size(y.size(1)); + for (i = 0; i < loop_ub; i++) { + r[i] = static_cast(k) * y[i]; + } + + i = r.size(0); + for (k = 0; k < i; k++) { + r[k] = std::sqrt(r[k]); + } + + k = r.size(0); + for (i = 0; i < k; i++) { + Table_gamma[i + Table_gamma.size(0) * zz] = 2.38 / r[i]; + } + } + + // First calculate the number of calibration data measurements + Meas_info->N = 0.0; + + // Initialize few important counters + } +} + +// End of code generation (setupDREAM.cpp) diff --git a/cpp/RAT/setupDREAM.h b/cpp/RAT/setupDREAM.h new file mode 100644 index 00000000..693e8502 --- /dev/null +++ b/cpp/RAT/setupDREAM.h @@ -0,0 +1,40 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// setupDREAM.h +// +// Code generation for function 'setupDREAM' +// +#ifndef SETUPDREAM_H +#define SETUPDREAM_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct struct13_T; + struct struct14_T; + struct struct12_T; +} + +// Function Declarations +namespace RAT +{ + void setupDREAM(real_T DREAMPar_d, real_T DREAMPar_N, real_T DREAMPar_T, + real_T DREAMPar_lambda, real_T DREAMPar_pUnitGamma, boolean_T + DREAMPar_adaptPCR, struct13_T *outDREAMPar, struct14_T + *Meas_info, ::coder::array &chain, struct12_T + *output, ::coder::array &log_L, ::coder::array< + real_T, 2U> &Table_gamma); +} + +#endif + +// End of code generation (setupDREAM.h) diff --git a/cpp/RAT/shiftData.cpp b/cpp/RAT/shiftData.cpp new file mode 100644 index 00000000..f3baeb95 --- /dev/null +++ b/cpp/RAT/shiftData.cpp @@ -0,0 +1,153 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// shiftData.cpp +// +// Code generation for function 'shiftData' +// + +// Include files +#include "shiftData.h" +#include "find.h" +#include "linspace.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void shiftData(real_T scalefactor, real_T qzshift, real_T dataPresent, ::coder:: + array &data, const real_T dataLimits[2], const + real_T simLimits[2], ::coder::array &shiftedData) + { + ::coder::array b_data; + ::coder::array b_i; + ::coder::array b_data_data; + ::coder::array c_data_data; + boolean_T data_data[10000]; + + // Shifts the data according to scale factor. If there is no data, makes + // x-data over the simulation range. + // + // INPUTS: + // * scalefactor: problemStruct.scalefactors + // * qzshift: problemStruct.qzhifts + // * dataPresent: problemStruct.dataPresent + // * data: problemStruct.data + // * dataLimits: problemStruct.dataLimits + // * simLimits: problemStruct.simLimits + // + // OUTPUTS: + // * shiftedData: Data shifted using given scale factor + if (static_cast(dataPresent) == 1) { + int32_T data_size; + int32_T hiIndex; + int32_T i; + int32_T i1; + int32_T loop_ub; + int32_T lowIndex; + if (scalefactor == 0.0) { + scalefactor = 1.0E-30; + } + + b_data.set_size(data.size(0)); + loop_ub = data.size(0); + for (i = 0; i < loop_ub; i++) { + b_data[i] = data[i] + qzshift; + } + + loop_ub = b_data.size(0); + for (i = 0; i < loop_ub; i++) { + data[i] = b_data[i]; + } + + b_data.set_size(data.size(0)); + loop_ub = data.size(0); + for (i = 0; i < loop_ub; i++) { + b_data[i] = data[i + data.size(0)] / scalefactor; + } + + loop_ub = b_data.size(0); + for (i = 0; i < loop_ub; i++) { + data[i + data.size(0)] = b_data[i]; + } + + b_data.set_size(data.size(0)); + loop_ub = data.size(0); + for (i = 0; i < loop_ub; i++) { + b_data[i] = data[i + data.size(0) * 2] / scalefactor; + } + + loop_ub = b_data.size(0); + for (i = 0; i < loop_ub; i++) { + data[i + data.size(0) * 2] = b_data[i]; + } + + data_size = data.size(0); + loop_ub = data.size(0); + for (i = 0; i < loop_ub; i++) { + data_data[i] = (data[i] < dataLimits[0]); + } + + b_data_data.set(&data_data[0], data_size); + coder::eml_find(b_data_data, b_i); + if (b_i.size(0) != 0) { + lowIndex = b_i[b_i.size(0) - 1]; + } else { + lowIndex = 1; + } + + data_size = data.size(0); + loop_ub = data.size(0); + for (i = 0; i < loop_ub; i++) { + data_data[i] = (data[i] > dataLimits[1]); + } + + c_data_data.set(&data_data[0], data_size); + coder::eml_find(c_data_data, b_i); + if (b_i.size(0) != 0) { + hiIndex = b_i[0]; + } else { + hiIndex = data.size(0); + } + + if (lowIndex > hiIndex) { + i = 0; + i1 = 0; + } else { + i = lowIndex - 1; + i1 = hiIndex; + } + + loop_ub = i1 - i; + shiftedData.set_size(loop_ub, data.size(1)); + data_size = data.size(1); + for (i1 = 0; i1 < data_size; i1++) { + for (int32_T i2{0}; i2 < loop_ub; i2++) { + shiftedData[i2 + shiftedData.size(0) * i1] = data[(i + i2) + data.size + (0) * i1]; + } + } + } else { + real_T b_dv1[3][500]; + real_T b_dv[500]; + coder::linspace(simLimits[0], simLimits[1], b_dv); + for (int32_T i{0}; i < 500; i++) { + b_dv1[0][i] = b_dv[i]; + b_dv1[1][i] = 0.0; + b_dv1[2][i] = 0.0; + } + + shiftedData.set_size(500, 3); + for (int32_T i{0}; i < 3; i++) { + for (int32_T i1{0}; i1 < 500; i1++) { + shiftedData[i1 + shiftedData.size(0) * i] = b_dv1[i][i1]; + } + } + } + } +} + +// End of code generation (shiftData.cpp) diff --git a/cpp/RAT/shiftData.h b/cpp/RAT/shiftData.h new file mode 100644 index 00000000..67fbe177 --- /dev/null +++ b/cpp/RAT/shiftData.h @@ -0,0 +1,29 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// shiftData.h +// +// Code generation for function 'shiftData' +// +#ifndef SHIFTDATA_H +#define SHIFTDATA_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void shiftData(real_T scalefactor, real_T qzshift, real_T dataPresent, ::coder:: + array &data, const real_T dataLimits[2], const + real_T simLimits[2], ::coder::array &shiftedData); +} + +#endif + +// End of code generation (shiftData.h) diff --git a/cpp/RAT/simplexIntrafun.cpp b/cpp/RAT/simplexIntrafun.cpp new file mode 100644 index 00000000..c07a7ab4 --- /dev/null +++ b/cpp/RAT/simplexIntrafun.cpp @@ -0,0 +1,113 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// simplexIntrafun.cpp +// +// Code generation for function 'simplexIntrafun' +// + +// Include files +#include "simplexIntrafun.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "reflectivityCalculation.h" +#include "rt_nonfinite.h" +#include "simplexXTransform.h" +#include "unpackParams.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void simplexIntrafun(const ::coder::array &x, const c_struct_T + *problemStruct, const ::coder::array + &problemCells_f1, const ::coder::array + &problemCells_f2, const ::coder::array + &problemCells_f3, const ::coder::array + &problemCells_f4, const ::coder::array + &problemCells_f5, const ::coder::array + &problemCells_f6, const ::coder::array + &problemCells_f14, const ::coder::array + &problemCells_f19, const struct2_T *controls, const + k_struct_T *params, real_T *fval, d_struct_T + *b_problemStruct, cell_wrap_9 result[6]) + { + ::coder::array xtrans; + c_struct_T c_problemStruct; + cell_11 expl_temp; + int32_T xtrans_idx_0; + c_problemStruct = *problemStruct; + + // transform variables, then call original function + simplexXTransform(x, params->LB, params->UB, params->BoundClass, xtrans); + + // Unpck the params.. + xtrans_idx_0 = xtrans.size(0); + c_problemStruct.fitParams.set_size(xtrans.size(0), 1); + for (int32_T i{0}; i < xtrans_idx_0; i++) { + c_problemStruct.fitParams[i] = xtrans[i]; + } + + unpackParams(&c_problemStruct, controls->checks.fitParam, + controls->checks.fitBackgroundParam, + controls->checks.fitQzshift, controls->checks.fitScalefactor, + controls->checks.fitBulkIn, controls->checks.fitBulkOut, + controls->checks.fitResolutionParam, + controls->checks.fitDomainRatio); + expl_temp.f19.set_size(1, problemCells_f19.size(1)); + xtrans_idx_0 = problemCells_f19.size(1); + for (int32_T i{0}; i < xtrans_idx_0; i++) { + expl_temp.f19[i] = problemCells_f19[i]; + } + + expl_temp.f14.set_size(1, problemCells_f14.size(1)); + xtrans_idx_0 = problemCells_f14.size(1); + for (int32_T i{0}; i < xtrans_idx_0; i++) { + expl_temp.f14[i] = problemCells_f14[i]; + } + + expl_temp.f6.set_size(problemCells_f6.size(0)); + xtrans_idx_0 = problemCells_f6.size(0); + for (int32_T i{0}; i < xtrans_idx_0; i++) { + expl_temp.f6[i] = problemCells_f6[i]; + } + + expl_temp.f5.set_size(1, problemCells_f5.size(1)); + xtrans_idx_0 = problemCells_f5.size(1); + for (int32_T i{0}; i < xtrans_idx_0; i++) { + expl_temp.f5[i] = problemCells_f5[i]; + } + + expl_temp.f4.set_size(1, problemCells_f4.size(1)); + xtrans_idx_0 = problemCells_f4.size(1); + for (int32_T i{0}; i < xtrans_idx_0; i++) { + expl_temp.f4[i] = problemCells_f4[i]; + } + + expl_temp.f3.set_size(1, problemCells_f3.size(1)); + xtrans_idx_0 = problemCells_f3.size(1); + for (int32_T i{0}; i < xtrans_idx_0; i++) { + expl_temp.f3[i] = problemCells_f3[i]; + } + + expl_temp.f2.set_size(1, problemCells_f2.size(1)); + xtrans_idx_0 = problemCells_f2.size(1); + for (int32_T i{0}; i < xtrans_idx_0; i++) { + expl_temp.f2[i] = problemCells_f2[i]; + } + + expl_temp.f1.set_size(1, problemCells_f1.size(1)); + xtrans_idx_0 = problemCells_f1.size(1); + for (int32_T i{0}; i < xtrans_idx_0; i++) { + expl_temp.f1[i] = problemCells_f1[i]; + } + + reflectivityCalculation(&c_problemStruct, &expl_temp, controls, + b_problemStruct, result); + *fval = b_problemStruct->calculations.sumChi; + } +} + +// End of code generation (simplexIntrafun.cpp) diff --git a/cpp/RAT/simplexIntrafun.h b/cpp/RAT/simplexIntrafun.h new file mode 100644 index 00000000..3bca5bc8 --- /dev/null +++ b/cpp/RAT/simplexIntrafun.h @@ -0,0 +1,47 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// simplexIntrafun.h +// +// Code generation for function 'simplexIntrafun' +// +#ifndef SIMPLEXINTRAFUN_H +#define SIMPLEXINTRAFUN_H + +// Include files +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct c_struct_T; + struct k_struct_T; + struct d_struct_T; +} + +// Function Declarations +namespace RAT +{ + void simplexIntrafun(const ::coder::array &x, const c_struct_T + *problemStruct, const ::coder::array + &problemCells_f1, const ::coder::array + &problemCells_f2, const ::coder::array + &problemCells_f3, const ::coder::array + &problemCells_f4, const ::coder::array + &problemCells_f5, const ::coder::array + &problemCells_f6, const ::coder::array + &problemCells_f14, const ::coder::array + &problemCells_f19, const struct2_T *controls, const + k_struct_T *params, real_T *fval, d_struct_T + *b_problemStruct, cell_wrap_9 result[6]); +} + +#endif + +// End of code generation (simplexIntrafun.h) diff --git a/cpp/RAT/simplexXTransform.cpp b/cpp/RAT/simplexXTransform.cpp new file mode 100644 index 00000000..fbe69a40 --- /dev/null +++ b/cpp/RAT/simplexXTransform.cpp @@ -0,0 +1,62 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// simplexXTransform.cpp +// +// Code generation for function 'simplexXTransform' +// + +// Include files +#include "simplexXTransform.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + void simplexXTransform(const ::coder::array &x, const ::coder:: + array ¶ms_LB, const ::coder::array ¶ms_UB, + const ::coder::array ¶ms_BoundClass, ::coder::array &xtrans) + { + int32_T i; + int32_T loop_ub; + + // converts unconstrained variables into their original domains + xtrans.set_size(x.size(0)); + loop_ub = x.size(0); + for (i = 0; i < loop_ub; i++) { + xtrans[i] = x[i]; + } + + i = x.size(0); + for (int32_T b_i{0}; b_i < i; b_i++) { + switch (static_cast(params_BoundClass[b_i])) { + case 1: + // lower bound only + xtrans[b_i] = params_LB[b_i] + x[b_i] * x[b_i]; + break; + + case 2: + // upper bound only + xtrans[b_i] = params_UB[b_i] - x[b_i] * x[b_i]; + break; + + case 3: + // lower and upper bounds + xtrans[b_i] = (std::sin(x[b_i]) + 1.0) / 2.0 * (params_UB[b_i] - + params_LB[b_i]) + params_LB[b_i]; + break; + + default: + // unconstrained variable. xtrans(i) is set. + break; + } + } + } +} + +// End of code generation (simplexXTransform.cpp) diff --git a/cpp/RAT/simplexXTransform.h b/cpp/RAT/simplexXTransform.h new file mode 100644 index 00000000..1325c969 --- /dev/null +++ b/cpp/RAT/simplexXTransform.h @@ -0,0 +1,30 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// simplexXTransform.h +// +// Code generation for function 'simplexXTransform' +// +#ifndef SIMPLEXXTRANSFORM_H +#define SIMPLEXXTRANSFORM_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void simplexXTransform(const ::coder::array &x, const ::coder:: + array ¶ms_LB, const ::coder::array ¶ms_UB, + const ::coder::array ¶ms_BoundClass, ::coder::array &xtrans); +} + +#endif + +// End of code generation (simplexXTransform.h) diff --git a/cpp/RAT/single.cpp b/cpp/RAT/single.cpp new file mode 100644 index 00000000..86892148 --- /dev/null +++ b/cpp/RAT/single.cpp @@ -0,0 +1,207 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// single.cpp +// +// Code generation for function 'single' +// + +// Include files +#include "single.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "allocateLayersForContrast.h" +#include "allocateParamsToLayers.h" +#include "backSort.h" +#include "coreLayersCalculation.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include "coder_bounded_array.h" + +// Function Definitions +namespace RAT +{ + namespace nonPolarisedTF + { + namespace standardLayers + { + void b_single(const c_struct_T *problemStruct, const cell_11 *problemCells, + const struct2_T *controls, ::coder::array + &outSsubs, ::coder::array &backgroundParams, :: + coder::array &qzshifts, ::coder::array &scalefactors, ::coder::array &bulkIns, :: + coder::array &bulkOuts, ::coder::array &resolutionParams, ::coder::array &chis, :: + coder::array &reflectivity, ::coder::array< + cell_wrap_20, 1U> &simulation, ::coder::array &shiftedData, ::coder::array &layerSlds, + ::coder::array &sldProfiles, ::coder::array< + cell_wrap_8, 1U> &allLayers, ::coder::array + &allRoughs) + { + static real_T thisContrastLayers_data[6000]; + ::coder::array outParameterisedLayers; + ::coder::array b_thisContrastLayers_data; + ::coder::array shiftedDat; + ::coder::array sldProfile; + real_T thisBackground; + real_T thisBulkIn; + real_T thisBulkOut; + real_T thisQzshift; + real_T thisResol; + real_T thisScalefactor; + int32_T i; + boolean_T useImaginary; + + // Single threaded version of the Standard Layers calculation + // This is the main reflectivity calculation of the standard layers + // calculation type. It extracts the required parameters for the contrasts + // from the input arrays, then passes the main calculation to + // 'standardLayersCore', which carries out the calculation itself. + // The core calculation is common for both standard and custom layers. + // Extract individual cell arrays + // Splits up the master input list of all arrays into separate arrays + // + // INPUTS: + // * problemCells: cell array where all the project data is grouped together. + // + // OUTPUTS: + // * repeatLayers: controls repeating of the layers stack. + // * allData: Array of all the data arrays. + // * dataLimits: Min max limits in q for the data arrays. + // * simLimits: Limits in Q for the reflectivity simulations. + // * layersDetails: Master array of all available layers. + // * contrastLayers: Which specific combination of arrays are needed for each contrast. + // * customFiles:Filenames and path for any custom files used. + // Extract individual parameters from problemStruct + // Extract individual parameters from problem + useImaginary = problemStruct->useImaginary; + + // Allocate the memory for the output arrays before the main loop + i = static_cast(problemStruct->numberOfContrasts); + backgroundParams.set_size(i); + + // end memory allocation. + // First we need to allocate the absolute values of the input + // parameters to all the layers in the layers list. This only needs + // to be done once, and so is done outside the contrasts loop + allocateParamsToLayers(problemStruct->params, problemCells->f6, + outParameterisedLayers); + + // Resample params if requiired + // Loop over all the contrasts + outSsubs.set_size(i); + sldProfiles.set_size(i); + reflectivity.set_size(i); + simulation.set_size(i); + shiftedData.set_size(i); + layerSlds.set_size(i); + chis.set_size(i); + qzshifts.set_size(i); + scalefactors.set_size(i); + bulkIns.set_size(i); + bulkOuts.set_size(i); + resolutionParams.set_size(i); + allRoughs.set_size(i); + allLayers.set_size(i); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T b_dv[2]; + real_T b_dv1[2]; + real_T dv2[2]; + int32_T thisContrastLayers_size[2]; + int32_T b_loop_ub; + int32_T loop_ub; + + // Extract the relevant parameter values for this contrast + // from the input arrays. + // First need to decide which values of the backgrounds, scalefactors + // data shifts and bulk contrasts are associated with this contrast + backSort(problemStruct->contrastBackgrounds[b_i], + problemStruct->contrastQzshifts[b_i], + problemStruct->contrastScalefactors[b_i], + problemStruct->contrastBulkIns[b_i], + problemStruct->contrastBulkOuts[b_i], + problemStruct->contrastResolutions[b_i], + problemStruct->backgroundParams, problemStruct->qzshifts, + problemStruct->scalefactors, problemStruct->bulkIn, + problemStruct->bulkOut, problemStruct->resolutionParams, + &thisBackground, &thisQzshift, &thisScalefactor, &thisBulkIn, + &thisBulkOut, &thisResol); + + // Also need to determine which layers from the overall layers list + // are required for this contrast, and put them in the correct order + // according to geometry + allocateLayersForContrast(problemCells->f5[b_i].f1, + outParameterisedLayers, useImaginary, thisContrastLayers_data, + thisContrastLayers_size); + + // For the other parameters, we extract the correct ones from the input + // arrays + // Substrate roughness is always first parameter for standard layers + // Now call the core layers reflectivity calculation + // In this case we are single cored, so we do not parallelise over + // points + // Call the core layers calculation + b_thisContrastLayers_data.set(&thisContrastLayers_data[0], + thisContrastLayers_size[0], thisContrastLayers_size[1]); + b_dv[0] = problemCells->f3[b_i].f1[0]; + b_dv[1] = problemCells->f3[b_i].f1[1]; + b_dv1[0] = problemCells->f4[b_i].f1[0]; + b_dv1[1] = problemCells->f4[b_i].f1[1]; + dv2[0] = problemCells->f1[b_i].f1[0]; + dv2[1] = problemCells->f1[b_i].f1[1]; + coreLayersCalculation(b_thisContrastLayers_data, problemStruct-> + params[0], problemStruct->geometry.data, + problemStruct->geometry.size, thisBulkIn, + thisBulkOut, problemStruct->resample[b_i], + controls->calcSldDuringFit, thisScalefactor, + thisQzshift, problemStruct->dataPresent[b_i], + problemCells->f2[b_i].f1, b_dv, b_dv1, dv2, + thisBackground, thisResol, + problemStruct->contrastBackgroundsType[b_i], + static_cast(problemStruct->params.size(1)), + controls->resamPars, useImaginary, sldProfile, + reflectivity[b_i].f1, simulation[b_i].f1, + shiftedDat, layerSlds[b_i].f1, allLayers[b_i].f1, + &chis[b_i], &outSsubs[b_i]); + + // Store returned values for this contrast in the output arrays. + // As well as the calculated profiles, we also store a record of + // the other values (background, scalefactors etc) for each contrast + // for future use. + loop_ub = sldProfile.size(1); + sldProfiles[b_i].f1.set_size(sldProfile.size(0), sldProfile.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = sldProfile.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + sldProfiles[b_i].f1[i2 + sldProfiles[b_i].f1.size(0) * i1] = + sldProfile[i2 + sldProfile.size(0) * i1]; + } + } + + loop_ub = shiftedDat.size(1); + shiftedData[b_i].f1.set_size(shiftedDat.size(0), shiftedDat.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = shiftedDat.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + shiftedData[b_i].f1[i2 + shiftedData[b_i].f1.size(0) * i1] = + shiftedDat[i2 + shiftedDat.size(0) * i1]; + } + } + + backgroundParams[b_i] = thisBackground; + qzshifts[b_i] = thisQzshift; + scalefactors[b_i] = thisScalefactor; + bulkIns[b_i] = thisBulkIn; + bulkOuts[b_i] = thisBulkOut; + resolutionParams[b_i] = thisResol; + allRoughs[b_i] = problemStruct->params[0]; + } + } + } + } +} + +// End of code generation (single.cpp) diff --git a/cpp/RAT/single.h b/cpp/RAT/single.h new file mode 100644 index 00000000..ff1a6cac --- /dev/null +++ b/cpp/RAT/single.h @@ -0,0 +1,47 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// single.h +// +// Code generation for function 'single' +// +#ifndef SINGLE_H +#define SINGLE_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace nonPolarisedTF + { + namespace standardLayers + { + void b_single(const c_struct_T *problemStruct, const cell_11 *problemCells, + const struct2_T *controls, ::coder::array + &outSsubs, ::coder::array &backgroundParams, :: + coder::array &qzshifts, ::coder::array &scalefactors, ::coder::array &bulkIns, :: + coder::array &bulkOuts, ::coder::array &resolutionParams, ::coder::array &chis, :: + coder::array &reflectivity, ::coder::array< + cell_wrap_20, 1U> &simulation, ::coder::array &shiftedData, ::coder::array &layerSlds, + ::coder::array &sldProfiles, ::coder::array< + cell_wrap_8, 1U> &allLayers, ::coder::array + &allRoughs); + } + } +} + +#endif + +// End of code generation (single.h) diff --git a/cpp/RAT/single1.cpp b/cpp/RAT/single1.cpp new file mode 100644 index 00000000..b1ed81c6 --- /dev/null +++ b/cpp/RAT/single1.cpp @@ -0,0 +1,201 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// single1.cpp +// +// Code generation for function 'single1' +// + +// Include files +#include "single1.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "backSort.h" +#include "coreLayersCalculation.h" +#include "processCustomFunction.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include "coder_bounded_array.h" + +// Function Definitions +namespace RAT +{ + namespace nonPolarisedTF + { + namespace customLayers + { + void b_single(const c_struct_T *problemStruct, const cell_11 *problemCells, + const struct2_T *controls, ::coder::array + &outSsubs, ::coder::array &backgroundParams, :: + coder::array &qzshifts, ::coder::array &scalefactors, ::coder::array &bulkIns, :: + coder::array &bulkOuts, ::coder::array &resolutionParams, ::coder::array &chis, :: + coder::array &reflectivity, ::coder::array< + cell_wrap_20, 1U> &simulation, ::coder::array &shiftedData, ::coder::array &layerSlds, + ::coder::array &sldProfiles, ::coder::array< + cell_wrap_8, 1U> &allLayers, ::coder::array + &allRoughs) + { + ::coder::array b_allLayers; + ::coder::array shiftedDat; + ::coder::array sldProfile; + real_T thisBackground; + real_T thisBulkIn; + real_T thisBulkOut; + real_T thisQzshift; + real_T thisResol; + real_T thisScalefactor; + int32_T i; + + // Single threaded version of the custom layers, nonPolarisedTF reflectivity + // calculation. The function extracts the relevant parameters from the input + // arrays, allocates these on a pre-contrast basis, then calls the 'core' + // calculation (the core layers nonPolarisedTF calc is shared between + // multiple calculation types). + // Extract individual cell arrays + // Splits up the master input list of all arrays into separate arrays + // + // INPUTS: + // * problemCells: cell array where all the project data is grouped together. + // + // OUTPUTS: + // * repeatLayers: controls repeating of the layers stack. + // * allData: Array of all the data arrays. + // * dataLimits: Min max limits in q for the data arrays. + // * simLimits: Limits in Q for the reflectivity simulations. + // * layersDetails: Master array of all available layers. + // * contrastLayers: Which specific combination of arrays are needed for each contrast. + // * customFiles:Filenames and path for any custom files used. + // Extract individual parameters from problemStruct + // Extract individual parameters from problem + // Pre-Allocation of output arrays... + i = static_cast(problemStruct->numberOfContrasts); + backgroundParams.set_size(i); + + // --- End Memory Allocation --- + // Resampling parameters + // Process the custom models.... + processCustomFunction(problemStruct->contrastBulkIns, + problemStruct->contrastBulkOuts, + problemStruct->bulkIn, problemStruct->bulkOut, + problemStruct->contrastCustomFiles, + problemStruct->numberOfContrasts, + problemCells->f14, problemStruct->params, + problemStruct->useImaginary, allLayers, allRoughs); + + // Single cored over all contrasts + outSsubs.set_size(i); + sldProfiles.set_size(i); + reflectivity.set_size(i); + simulation.set_size(i); + shiftedData.set_size(i); + layerSlds.set_size(i); + chis.set_size(i); + qzshifts.set_size(i); + scalefactors.set_size(i); + bulkIns.set_size(i); + bulkOuts.set_size(i); + resolutionParams.set_size(i); + for (int32_T b_i{0}; b_i < i; b_i++) { + int32_T b_loop_ub; + int32_T loop_ub; + + // Extract the relevant parameter values for this contrast + // from the input arrays. + // First need to decide which values of the backgrounds, scalefactors + // data shifts and bulk contrasts are associated with this contrast + backSort(problemStruct->contrastBackgrounds[b_i], + problemStruct->contrastQzshifts[b_i], + problemStruct->contrastScalefactors[b_i], + problemStruct->contrastBulkIns[b_i], + problemStruct->contrastBulkOuts[b_i], + problemStruct->contrastResolutions[b_i], + problemStruct->backgroundParams, problemStruct->qzshifts, + problemStruct->scalefactors, problemStruct->bulkIn, + problemStruct->bulkOut, problemStruct->resolutionParams, + &thisBackground, &thisQzshift, &thisScalefactor, &thisBulkIn, + &thisBulkOut, &thisResol); + + // Get the custom layers output for this contrast + // For the other parameters, we extract the correct ones from the input + // arrays + // Now call the core layers reflectivity calculation + // In this case we are single cored, so we do not parallelise over + // points + // Call the reflectivity calculation + b_allLayers.set_size(allLayers[b_i].f1.size(0), allLayers[b_i].f1.size + (1)); + loop_ub = allLayers[b_i].f1.size(1) - 1; + for (int32_T i1{0}; i1 <= loop_ub; i1++) { + b_loop_ub = allLayers[b_i].f1.size(0) - 1; + for (int32_T i2{0}; i2 <= b_loop_ub; i2++) { + b_allLayers[i2 + b_allLayers.size(0) * i1] = allLayers[b_i].f1[i2 + + allLayers[b_i].f1.size(0) * i1]; + } + } + + real_T b_dv[2]; + real_T b_dv1[2]; + real_T dv2[2]; + b_dv[0] = problemCells->f3[b_i].f1[0]; + b_dv[1] = problemCells->f3[b_i].f1[1]; + b_dv1[0] = problemCells->f4[b_i].f1[0]; + b_dv1[1] = problemCells->f4[b_i].f1[1]; + dv2[0] = problemCells->f1[b_i].f1[0]; + dv2[1] = problemCells->f1[b_i].f1[1]; + coreLayersCalculation(b_allLayers, allRoughs[b_i], + problemStruct->geometry.data, + problemStruct->geometry.size, thisBulkIn, + thisBulkOut, problemStruct->resample[b_i], + controls->calcSldDuringFit, thisScalefactor, + thisQzshift, problemStruct->dataPresent[b_i], + problemCells->f2[b_i].f1, b_dv, b_dv1, dv2, + thisBackground, thisResol, + problemStruct->contrastBackgroundsType[b_i], + static_cast(problemStruct->params.size(1)), + controls->resamPars, problemStruct->useImaginary, + sldProfile, reflectivity[b_i].f1, simulation[b_i] + .f1, shiftedDat, layerSlds[b_i].f1, + allLayers[b_i].f1, &chis[b_i], &outSsubs[b_i]); + + // Store returned values for this contrast in the output arrays. + // As well as the calculated profiles, we also store a record of + // the other values (background, scalefactors etc) for each contrast + // for future use. + loop_ub = sldProfile.size(1); + sldProfiles[b_i].f1.set_size(sldProfile.size(0), sldProfile.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = sldProfile.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + sldProfiles[b_i].f1[i2 + sldProfiles[b_i].f1.size(0) * i1] = + sldProfile[i2 + sldProfile.size(0) * i1]; + } + } + + loop_ub = shiftedDat.size(1); + shiftedData[b_i].f1.set_size(shiftedDat.size(0), shiftedDat.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = shiftedDat.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + shiftedData[b_i].f1[i2 + shiftedData[b_i].f1.size(0) * i1] = + shiftedDat[i2 + shiftedDat.size(0) * i1]; + } + } + + backgroundParams[b_i] = thisBackground; + qzshifts[b_i] = thisQzshift; + scalefactors[b_i] = thisScalefactor; + bulkIns[b_i] = thisBulkIn; + bulkOuts[b_i] = thisBulkOut; + resolutionParams[b_i] = thisResol; + } + } + } + } +} + +// End of code generation (single1.cpp) diff --git a/cpp/RAT/single1.h b/cpp/RAT/single1.h new file mode 100644 index 00000000..43438148 --- /dev/null +++ b/cpp/RAT/single1.h @@ -0,0 +1,47 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// single1.h +// +// Code generation for function 'single1' +// +#ifndef SINGLE1_H +#define SINGLE1_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace nonPolarisedTF + { + namespace customLayers + { + void b_single(const c_struct_T *problemStruct, const cell_11 *problemCells, + const struct2_T *controls, ::coder::array + &outSsubs, ::coder::array &backgroundParams, :: + coder::array &qzshifts, ::coder::array &scalefactors, ::coder::array &bulkIns, :: + coder::array &bulkOuts, ::coder::array &resolutionParams, ::coder::array &chis, :: + coder::array &reflectivity, ::coder::array< + cell_wrap_20, 1U> &simulation, ::coder::array &shiftedData, ::coder::array &layerSlds, + ::coder::array &sldProfiles, ::coder::array< + cell_wrap_8, 1U> &allLayers, ::coder::array + &allRoughs); + } + } +} + +#endif + +// End of code generation (single1.h) diff --git a/cpp/RAT/single2.cpp b/cpp/RAT/single2.cpp new file mode 100644 index 00000000..a67e0233 --- /dev/null +++ b/cpp/RAT/single2.cpp @@ -0,0 +1,214 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// single2.cpp +// +// Code generation for function 'single2' +// + +// Include files +#include "single2.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "applyBackgroundCorrection.h" +#include "backSort.h" +#include "callReflectivity.h" +#include "chiSquared.h" +#include "processCustomFunction1.h" +#include "resampleLayers.h" +#include "resampleLayersReIm.h" +#include "rt_nonfinite.h" +#include "shiftData.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace nonPolarisedTF + { + namespace customXY + { + void b_single(const c_struct_T *problemStruct, const cell_11 *problemCells, + const struct2_T *controls, ::coder::array + &outSsubs, ::coder::array &backgroundParams, :: + coder::array &qzshifts, ::coder::array &scalefactors, ::coder::array &bulkIns, :: + coder::array &bulkOuts, ::coder::array &resolutionParams, ::coder::array &chis, :: + coder::array &reflectivity, ::coder::array< + cell_wrap_20, 1U> &simulation, ::coder::array &shiftedData, ::coder::array &layerSlds, + ::coder::array &sldProfiles, ::coder::array< + cell_wrap_8, 1U> &allLayers, ::coder::array + &allRoughs) + { + ::coder::array b_problemCells; + ::coder::array b_sldProfiles; + ::coder::array c_sldProfiles; + ::coder::array layerSld; + ::coder::array reflect; + ::coder::array shiftedDat; + int32_T loop_ub_tmp; + boolean_T useImaginary; + + // Extract individual cell arrays + // Splits up the master input list of all arrays into separate arrays + // + // INPUTS: + // * problemCells: cell array where all the project data is grouped together. + // + // OUTPUTS: + // * repeatLayers: controls repeating of the layers stack. + // * allData: Array of all the data arrays. + // * dataLimits: Min max limits in q for the data arrays. + // * simLimits: Limits in Q for the reflectivity simulations. + // * layersDetails: Master array of all available layers. + // * contrastLayers: Which specific combination of arrays are needed for each contrast. + // * customFiles:Filenames and path for any custom files used. + // % Layers details N/A + // Extract individual parameters from problemStruct + // Extract individual parameters from problem + // Pre-Allocation... + loop_ub_tmp = static_cast(problemStruct->numberOfContrasts); + backgroundParams.set_size(loop_ub_tmp); + outSsubs.set_size(loop_ub_tmp); + for (int32_T i{0}; i < loop_ub_tmp; i++) { + outSsubs[i] = 0.0; + } + + // Resampling parameters + useImaginary = problemStruct->useImaginary; + processCustomFunction(problemStruct->contrastBulkIns, + problemStruct->contrastBulkOuts, + problemStruct->bulkIn, problemStruct->bulkOut, + problemStruct->contrastCustomFiles, + problemStruct->numberOfContrasts, + problemCells->f14, problemStruct->params, + sldProfiles, allRoughs); + qzshifts.set_size(loop_ub_tmp); + scalefactors.set_size(loop_ub_tmp); + bulkIns.set_size(loop_ub_tmp); + bulkOuts.set_size(loop_ub_tmp); + resolutionParams.set_size(loop_ub_tmp); + layerSlds.set_size(loop_ub_tmp); + allLayers.set_size(loop_ub_tmp); + shiftedData.set_size(loop_ub_tmp); + chis.set_size(loop_ub_tmp); + simulation.set_size(loop_ub_tmp); + reflectivity.set_size(loop_ub_tmp); + for (int32_T b_i{0}; b_i < loop_ub_tmp; b_i++) { + real_T b_dv[2]; + real_T b_dv1[2]; + int32_T b_loop_ub; + int32_T loop_ub; + backSort(problemStruct->contrastBackgrounds[b_i], + problemStruct->contrastQzshifts[b_i], + problemStruct->contrastScalefactors[b_i], + problemStruct->contrastBulkIns[b_i], + problemStruct->contrastBulkOuts[b_i], + problemStruct->contrastResolutions[b_i], + problemStruct->backgroundParams, problemStruct->qzshifts, + problemStruct->scalefactors, problemStruct->bulkIn, + problemStruct->bulkOut, problemStruct->resolutionParams, + &backgroundParams[b_i], &qzshifts[b_i], &scalefactors[b_i], + &bulkIns[b_i], &bulkOuts[b_i], &resolutionParams[b_i]); + + // Resample the layers + if (!useImaginary) { + resampleLayers(sldProfiles[b_i].f1, controls->resamPars, layerSld); + } else { + loop_ub = sldProfiles[b_i].f1.size(0); + b_sldProfiles.set_size(sldProfiles[b_i].f1.size(0), 2); + for (int32_T i{0}; i < 2; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_sldProfiles[i1 + b_sldProfiles.size(0) * i] = sldProfiles[b_i] + .f1[i1 + sldProfiles[b_i].f1.size(0) * i]; + } + } + + loop_ub = sldProfiles[b_i].f1.size(0); + c_sldProfiles.set_size(sldProfiles[b_i].f1.size(0), 2); + for (int32_T i{0}; i < loop_ub; i++) { + c_sldProfiles[i] = sldProfiles[b_i].f1[i]; + c_sldProfiles[i + c_sldProfiles.size(0)] = sldProfiles[b_i].f1[i + + sldProfiles[b_i].f1.size(0) * 2]; + } + + b_resampleLayersReIm(b_sldProfiles, c_sldProfiles, + controls->resamPars, layerSld); + } + + layerSlds[b_i].f1.set_size(layerSld.size(0), layerSld.size(1)); + loop_ub = layerSld.size(1); + allLayers[b_i].f1.set_size(layerSld.size(0), layerSld.size(1)); + b_loop_ub = layerSld.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + layerSlds[b_i].f1[i1 + layerSlds[b_i].f1.size(0) * i] = + layerSld[i1 + layerSld.size(0) * i]; + allLayers[b_i].f1[i1 + allLayers[b_i].f1.size(0) * i] = + layerSld[i1 + layerSld.size(0) * i]; + } + } + + b_problemCells.set_size(problemCells->f2[problemCells->f2.size(0) * + b_i].f1.size(0), problemCells->f2[problemCells->f2.size(0) * b_i]. + f1.size(1)); + loop_ub = problemCells->f2[b_i].f1.size(1) - 1; + for (int32_T i{0}; i <= loop_ub; i++) { + b_loop_ub = problemCells->f2[b_i].f1.size(0) - 1; + for (int32_T i1{0}; i1 <= b_loop_ub; i1++) { + b_problemCells[i1 + b_problemCells.size(0) * i] = problemCells-> + f2[b_i].f1[i1 + problemCells->f2[b_i].f1.size(0) * i]; + } + } + + b_dv[0] = problemCells->f3[b_i].f1[0]; + b_dv[1] = problemCells->f3[b_i].f1[1]; + b_dv1[0] = problemCells->f4[b_i].f1[0]; + b_dv1[1] = problemCells->f4[b_i].f1[1]; + shiftData(scalefactors[b_i], qzshifts[b_i], problemStruct-> + dataPresent[b_i], b_problemCells, b_dv, b_dv1, shiftedDat); + shiftedData[b_i].f1.set_size(shiftedDat.size(0), shiftedDat.size(1)); + loop_ub = shiftedDat.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = shiftedDat.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + shiftedData[b_i].f1[i1 + shiftedData[b_i].f1.size(0) * i] = + shiftedDat[i1 + shiftedDat.size(0) * i]; + } + } + + b_dv[0] = problemCells->f4[b_i].f1[0]; + b_dv[1] = problemCells->f4[b_i].f1[1]; + b_dv1[0] = problemCells->f1[b_i].f1[0]; + b_dv1[1] = problemCells->f1[b_i].f1[1]; + callReflectivity(bulkIns[b_i], bulkOuts[b_i], b_dv, b_dv1, shiftedDat, + layerSld, 0.0, resolutionParams[b_i], useImaginary, + reflect, simulation[b_i].f1); + applyBackgroundCorrection(reflect, simulation[b_i].f1, shiftedDat, + backgroundParams[b_i], problemStruct->contrastBackgroundsType[b_i]); + loop_ub = reflect.size(0); + reflectivity[b_i].f1.set_size(reflect.size(0), 2); + for (int32_T i{0}; i < 2; i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + reflectivity[b_i].f1[i1 + reflectivity[b_i].f1.size(0) * i] = + reflect[i1 + reflect.size(0) * i]; + } + } + + if (problemStruct->dataPresent[b_i] != 0.0) { + chis[b_i] = chiSquared(shiftedDat, reflect, static_cast + (problemStruct->params.size(1))); + } else { + chis[b_i] = 0.0; + } + } + } + } + } +} + +// End of code generation (single2.cpp) diff --git a/cpp/RAT/single2.h b/cpp/RAT/single2.h new file mode 100644 index 00000000..7cc63ce0 --- /dev/null +++ b/cpp/RAT/single2.h @@ -0,0 +1,47 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// single2.h +// +// Code generation for function 'single2' +// +#ifndef SINGLE2_H +#define SINGLE2_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace nonPolarisedTF + { + namespace customXY + { + void b_single(const c_struct_T *problemStruct, const cell_11 *problemCells, + const struct2_T *controls, ::coder::array + &outSsubs, ::coder::array &backgroundParams, :: + coder::array &qzshifts, ::coder::array &scalefactors, ::coder::array &bulkIns, :: + coder::array &bulkOuts, ::coder::array &resolutionParams, ::coder::array &chis, :: + coder::array &reflectivity, ::coder::array< + cell_wrap_20, 1U> &simulation, ::coder::array &shiftedData, ::coder::array &layerSlds, + ::coder::array &sldProfiles, ::coder::array< + cell_wrap_8, 1U> &allLayers, ::coder::array + &allRoughs); + } + } +} + +#endif + +// End of code generation (single2.h) diff --git a/cpp/RAT/single3.cpp b/cpp/RAT/single3.cpp new file mode 100644 index 00000000..f9146186 --- /dev/null +++ b/cpp/RAT/single3.cpp @@ -0,0 +1,346 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// single3.cpp +// +// Code generation for function 'single3' +// + +// Include files +#include "single3.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "allocateLayersForContrast.h" +#include "allocateParamsToLayers.h" +#include "averageReflectivity.h" +#include "backSort.h" +#include "chiSquared.h" +#include "coreLayersCalculation.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include "coder_bounded_array.h" + +// Function Definitions +namespace RAT +{ + namespace domainsTF + { + namespace standardLayers + { + void b_single(const c_struct_T *problemStruct, const cell_11 *problemCells, + const struct2_T *controls, ::coder::array + &outSsubs, ::coder::array &backgroundParams, :: + coder::array &qzshifts, ::coder::array &scalefactors, ::coder::array &bulkIns, :: + coder::array &bulkOuts, ::coder::array &resolutionParams, ::coder::array &chis, :: + coder::array &reflectivity, ::coder::array< + cell_wrap_20, 1U> &simulation, ::coder::array &shiftedData, ::coder::array &layerSlds, + ::coder::array &domainSldProfiles, ::coder:: + array &allLayers, ::coder::array + &allRoughs) + { + static real_T thisContrastLayers1_data[6000]; + static real_T thisContrastLayers2_data[6000]; + ::coder::array outParameterisedLayers; + ::coder::array tempAllLayers; + ::coder::array tempLayerSlds; + ::coder::array tempSldProfiles; + ::coder::array a__6; + ::coder::array b_thisContrastLayers1_data; + ::coder::array b_thisContrastLayers2_data; + ::coder::array reflect1; + ::coder::array reflect2; + ::coder::array shiftedDat; + ::coder::array simul1; + ::coder::array simul2; + ::coder::array totReflect; + cell_wrap_8 r; + cell_wrap_8 r1; + cell_wrap_8 r2; + cell_wrap_8 r3; + cell_wrap_8 r4; + cell_wrap_8 r5; + real_T a__5; + real_T a__7; + real_T a__8; + real_T thisBackground; + real_T thisBulkIn; + real_T thisBulkOut; + real_T thisQzshift; + real_T thisResol; + real_T thisScalefactor; + int32_T b_loop_ub; + int32_T i; + int32_T loop_ub; + int32_T nParams; + boolean_T calcSld; + boolean_T useImaginary; + + // Single threaded version of the Standard Layers calculation + // This is the main reflectivity calculation of the standard layers + // calculation type. It extracts the required parameters for the contrasts + // from the input arrays, then passes the main calculation to + // 'standardLayersCore', which carries out the calculation itself. + // The core calculation is common for both standard and custom layers. + // Extract individual cell arrays + // Splits up the master input list of all arrays into separate arrays + // + // INPUTS: + // * problemCells: cell array where all the project data is grouped together. + // + // OUTPUTS: + // * repeatLayers: controls repeating of the layers stack. + // * allData: Array of all the data arrays. + // * dataLimits: Min max limits in q for the data arrays. + // * simLimits: Limits in Q for the reflectivity simulations. + // * layersDetails: Master array of all available layers. + // * contrastLayers: Which specific combination of arrays are needed for each contrast. + // * customFiles:Filenames and path for any custom files used. + // Additionally extract the additional domain layers details + // Extract individual parameters from problemStruct + // Extract individual parameters from problem + nParams = problemStruct->params.size(1); + calcSld = controls->calcSldDuringFit; + useImaginary = problemStruct->useImaginary; + + // Default for compile. + // Allocate the memory for the output arrays before the main loop + i = static_cast(problemStruct->numberOfContrasts); + backgroundParams.set_size(i); + + // end memory allocation. + // First we need to allocate the absolute values of the input + // parameters to all the layers in the layers list. This only needs + // to be done once, and so is done outside the contrasts loop + allocateParamsToLayers(problemStruct->params, problemCells->f6, + outParameterisedLayers); + + // Resample params if requiired + // Loop over all the contrasts + outSsubs.set_size(i); + tempSldProfiles.set_size(i); + reflectivity.set_size(i); + simulation.set_size(i); + shiftedData.set_size(i); + tempLayerSlds.set_size(i); + tempAllLayers.set_size(i); + chis.set_size(i); + qzshifts.set_size(i); + scalefactors.set_size(i); + bulkIns.set_size(i); + bulkOuts.set_size(i); + resolutionParams.set_size(i); + allRoughs.set_size(i); + layerSlds.set_size(i, 2); + domainSldProfiles.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T b_dv[2]; + real_T b_dv1[2]; + real_T dv2[2]; + int32_T thisContrastLayers1_size[2]; + int32_T thisContrastLayers2_size[2]; + + // Get the domain ratio for this contrast + // Extract the relevant parameter values for this contrast + // from the input arrays. + // First need to decide which values of the backgrounds, scalefactors + // data shifts and bulk contrasts are associated with this contrast + backSort(problemStruct->contrastBackgrounds[b_i], + problemStruct->contrastQzshifts[b_i], + problemStruct->contrastScalefactors[b_i], + problemStruct->contrastBulkIns[b_i], + problemStruct->contrastBulkOuts[b_i], + problemStruct->contrastResolutions[b_i], + problemStruct->backgroundParams, problemStruct->qzshifts, + problemStruct->scalefactors, problemStruct->bulkIn, + problemStruct->bulkOut, problemStruct->resolutionParams, + &thisBackground, &thisQzshift, &thisScalefactor, &thisBulkIn, + &thisBulkOut, &thisResol); + + // Also need to determine which layers from the overall layers list + // are required for this contrast, and put them in the correct order + // according to geometry. We run it twice, once for each domain... + allocateLayersForContrast(problemCells->f19[0].f1, + outParameterisedLayers, useImaginary, thisContrastLayers1_data, + thisContrastLayers1_size); + allocateLayersForContrast(problemCells->f19[1].f1, + outParameterisedLayers, useImaginary, thisContrastLayers2_data, + thisContrastLayers2_size); + + // For the other parameters, we extract the correct ones from the input + // arrays + // Substrate roughness is always first parameter for standard layers + // Now call the core layers reflectivity calculation + // In this case we are single cored, so we do not parallelise over + // points + // Call the core layers calculation - need to do this once for each + // domain + b_thisContrastLayers1_data.set(&thisContrastLayers1_data[0], + thisContrastLayers1_size[0], thisContrastLayers1_size[1]); + b_dv[0] = problemCells->f3[b_i].f1[0]; + b_dv[1] = problemCells->f3[b_i].f1[1]; + b_dv1[0] = problemCells->f4[b_i].f1[0]; + b_dv1[1] = problemCells->f4[b_i].f1[1]; + dv2[0] = problemCells->f1[b_i].f1[0]; + dv2[1] = problemCells->f1[b_i].f1[1]; + nonPolarisedTF::coreLayersCalculation(b_thisContrastLayers1_data, + problemStruct->params[0], problemStruct->geometry.data, + problemStruct->geometry.size, thisBulkIn, thisBulkOut, + problemStruct->resample[b_i], calcSld, thisScalefactor, thisQzshift, + problemStruct->dataPresent[b_i], problemCells->f2[b_i].f1, b_dv, + b_dv1, dv2, thisBackground, thisResol, + problemStruct->contrastBackgroundsType[b_i], static_cast + (nParams), controls->resamPars, useImaginary, r.f1, reflect1, simul1, + shiftedDat, r1.f1, r2.f1, &a__5, &outSsubs[b_i]); + b_thisContrastLayers2_data.set(&thisContrastLayers2_data[0], + thisContrastLayers2_size[0], thisContrastLayers2_size[1]); + b_dv[0] = problemCells->f3[b_i].f1[0]; + b_dv[1] = problemCells->f3[b_i].f1[1]; + b_dv1[0] = problemCells->f4[b_i].f1[0]; + b_dv1[1] = problemCells->f4[b_i].f1[1]; + dv2[0] = problemCells->f1[b_i].f1[0]; + dv2[1] = problemCells->f1[b_i].f1[1]; + nonPolarisedTF::coreLayersCalculation(b_thisContrastLayers2_data, + problemStruct->params[0], problemStruct->geometry.data, + problemStruct->geometry.size, thisBulkIn, thisBulkOut, + problemStruct->resample[b_i], calcSld, thisScalefactor, thisQzshift, + problemStruct->dataPresent[b_i], problemCells->f2[b_i].f1, b_dv, + b_dv1, dv2, thisBackground, thisResol, + problemStruct->contrastBackgroundsType[b_i], static_cast + (nParams), controls->resamPars, useImaginary, r3.f1, reflect2, + simul2, a__6, r4.f1, r5.f1, &a__7, &a__8); + + // Calculate the average reflectivities.... + averageReflectivity(reflect1, reflect2, simul1, simul2, + problemStruct->domainRatio[static_cast + (problemStruct->contrastDomainRatios[b_i]) - 1], + totReflect, simulation[b_i].f1); + + // Get an overall chi-squared for the new averaged curve.. + chis[b_i] = chiSquared(shiftedDat, totReflect, static_cast + (problemStruct->params.size(1))); + + // Store returned values for this contrast in the output arrays. + // As well as the calculated profiles, we also store a record of + // the other values (background, scalefactors etc) for each contrast + // for future use. + tempSldProfiles[b_i].f1[0] = r; + tempSldProfiles[b_i].f1[1] = r3; + reflectivity[b_i].f1.set_size(totReflect.size(0), 2); + loop_ub = totReflect.size(0); + for (int32_T i1{0}; i1 < 2; i1++) { + for (int32_T i2{0}; i2 < loop_ub; i2++) { + reflectivity[b_i].f1[i2 + reflectivity[b_i].f1.size(0) * i1] = + totReflect[i2 + totReflect.size(0) * i1]; + } + } + + shiftedData[b_i].f1.set_size(shiftedDat.size(0), shiftedDat.size(1)); + loop_ub = shiftedDat.size(1); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = shiftedDat.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + shiftedData[b_i].f1[i2 + shiftedData[b_i].f1.size(0) * i1] = + shiftedDat[i2 + shiftedDat.size(0) * i1]; + } + } + + tempLayerSlds[b_i].f1[0] = r1; + tempLayerSlds[b_i].f1[1] = r4; + tempAllLayers[b_i].f1[0] = r2; + tempAllLayers[b_i].f1[1] = r5; + backgroundParams[b_i] = thisBackground; + qzshifts[b_i] = thisQzshift; + scalefactors[b_i] = thisScalefactor; + bulkIns[b_i] = thisBulkIn; + bulkOuts[b_i] = thisBulkOut; + resolutionParams[b_i] = thisResol; + allRoughs[b_i] = problemStruct->params[0]; + } + + allLayers.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + loop_ub = tempSldProfiles[b_i].f1[0].f1.size(1); + domainSldProfiles[b_i].f1.set_size(tempSldProfiles[b_i].f1[0].f1.size + (0), tempSldProfiles[b_i].f1[0].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempSldProfiles[b_i].f1[0].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + domainSldProfiles[b_i].f1[i2 + domainSldProfiles[b_i].f1.size(0) * + i1] = tempSldProfiles[b_i].f1[0].f1[i2 + tempSldProfiles[b_i] + .f1[0].f1.size(0) * i1]; + } + } + + loop_ub = tempSldProfiles[b_i].f1[1].f1.size(1); + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.set_size + (tempSldProfiles[b_i].f1[1].f1.size(0), tempSldProfiles[b_i].f1[1]. + f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempSldProfiles[b_i].f1[1].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1[i2 + + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size(0) * + i1] = tempSldProfiles[b_i].f1[1].f1[i2 + tempSldProfiles[b_i] + .f1[1].f1.size(0) * i1]; + } + } + + loop_ub = tempAllLayers[b_i].f1[0].f1.size(1); + allLayers[b_i].f1.set_size(tempAllLayers[b_i].f1[0].f1.size(0), + tempAllLayers[b_i].f1[0].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempAllLayers[b_i].f1[0].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + allLayers[b_i].f1[i2 + allLayers[b_i].f1.size(0) * i1] = + tempAllLayers[b_i].f1[0].f1[i2 + tempAllLayers[b_i].f1[0]. + f1.size(0) * i1]; + } + } + + loop_ub = tempAllLayers[b_i].f1[1].f1.size(1); + allLayers[b_i + allLayers.size(0)].f1.set_size(tempAllLayers[b_i].f1[1] + .f1.size(0), tempAllLayers[b_i].f1[1].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempAllLayers[b_i].f1[1].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + allLayers[b_i + allLayers.size(0)].f1[i2 + allLayers[b_i + + allLayers.size(0)].f1.size(0) * i1] = tempAllLayers[b_i].f1[1]. + f1[i2 + tempAllLayers[b_i].f1[1].f1.size(0) * i1]; + } + } + + loop_ub = tempLayerSlds[b_i].f1[0].f1.size(1); + layerSlds[b_i].f1.set_size(tempLayerSlds[b_i].f1[0].f1.size(0), + tempLayerSlds[b_i].f1[0].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempLayerSlds[b_i].f1[0].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + layerSlds[b_i].f1[i2 + layerSlds[b_i].f1.size(0) * i1] = + tempLayerSlds[b_i].f1[0].f1[i2 + tempLayerSlds[b_i].f1[0]. + f1.size(0) * i1]; + } + } + + loop_ub = tempLayerSlds[b_i].f1[1].f1.size(1); + layerSlds[b_i + layerSlds.size(0)].f1.set_size(tempLayerSlds[b_i].f1[1] + .f1.size(0), tempLayerSlds[b_i].f1[1].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempLayerSlds[b_i].f1[1].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + layerSlds[b_i + layerSlds.size(0)].f1[i2 + layerSlds[b_i + + layerSlds.size(0)].f1.size(0) * i1] = tempLayerSlds[b_i].f1[1]. + f1[i2 + tempLayerSlds[b_i].f1[1].f1.size(0) * i1]; + } + } + } + } + } + } +} + +// End of code generation (single3.cpp) diff --git a/cpp/RAT/single3.h b/cpp/RAT/single3.h new file mode 100644 index 00000000..3b11cbfa --- /dev/null +++ b/cpp/RAT/single3.h @@ -0,0 +1,47 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// single3.h +// +// Code generation for function 'single3' +// +#ifndef SINGLE3_H +#define SINGLE3_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace domainsTF + { + namespace standardLayers + { + void b_single(const c_struct_T *problemStruct, const cell_11 *problemCells, + const struct2_T *controls, ::coder::array + &outSsubs, ::coder::array &backgroundParams, :: + coder::array &qzshifts, ::coder::array &scalefactors, ::coder::array &bulkIns, :: + coder::array &bulkOuts, ::coder::array &resolutionParams, ::coder::array &chis, :: + coder::array &reflectivity, ::coder::array< + cell_wrap_20, 1U> &simulation, ::coder::array &shiftedData, ::coder::array &layerSlds, + ::coder::array &domainSldProfiles, ::coder:: + array &allLayers, ::coder::array + &allRoughs); + } + } +} + +#endif + +// End of code generation (single3.h) diff --git a/cpp/RAT/single4.cpp b/cpp/RAT/single4.cpp new file mode 100644 index 00000000..3f3685fe --- /dev/null +++ b/cpp/RAT/single4.cpp @@ -0,0 +1,330 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// single4.cpp +// +// Code generation for function 'single4' +// + +// Include files +#include "single4.h" +#include "RATMain_internal_types.h" +#include "RATMain_rtwutil.h" +#include "RATMain_types.h" +#include "averageReflectivity.h" +#include "backSort.h" +#include "chiSquared.h" +#include "coreLayersCalculation.h" +#include "processCustomFunction2.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include "coder_bounded_array.h" + +// Function Definitions +namespace RAT +{ + namespace domainsTF + { + namespace customLayers + { + void b_single(const c_struct_T *problemStruct, const cell_11 *problemCells, + const struct2_T *controls, ::coder::array + &outSsubs, ::coder::array &backgroundParams, :: + coder::array &qzshifts, ::coder::array &scalefactors, ::coder::array &bulkIns, :: + coder::array &bulkOuts, ::coder::array &resolutionParams, ::coder::array &chis, :: + coder::array &reflectivity, ::coder::array< + cell_wrap_20, 1U> &simulation, ::coder::array &shiftedData, ::coder::array &layerSlds, + ::coder::array &domainSldProfiles, ::coder:: + array &allLayers, ::coder::array + &allRoughs) + { + ::coder::array r; + ::coder::array tempAllLayers; + ::coder::array tempLayerSlds; + ::coder::array tempSldProfiles; + ::coder::array calcAllLayers; + ::coder::array a__5; + ::coder::array reflect1; + ::coder::array reflect2; + ::coder::array shiftedDat; + ::coder::array simul1; + ::coder::array simul2; + ::coder::array totReflect; + cell_wrap_8 r1; + cell_wrap_8 r2; + cell_wrap_8 r3; + cell_wrap_8 r4; + cell_wrap_8 r5; + cell_wrap_8 r6; + real_T a__4; + real_T a__6; + real_T a__7; + real_T thisBackground; + real_T thisBulkIn; + real_T thisBulkOut; + real_T thisQzshift; + real_T thisResol; + real_T thisScalefactor; + int32_T b_loop_ub; + int32_T i; + int32_T loop_ub; + int32_T nParams; + boolean_T calcSld; + boolean_T useImaginary; + + // Single threaded version of the custom layers, domainsTF reflectivity + // calculation. The function extracts the relevant parameters from the input + // arrays, allocates these on a pre-contrast basis, then calls the 'core' + // calculation (the core layers domainsTF calc is shared between multiple + // calculation types). + // Extract individual cell arrays + // Splits up the master input list of all arrays into separate arrays + // + // INPUTS: + // * problemCells: cell array where all the project data is grouped together. + // + // OUTPUTS: + // * repeatLayers: controls repeating of the layers stack. + // * allData: Array of all the data arrays. + // * dataLimits: Min max limits in q for the data arrays. + // * simLimits: Limits in Q for the reflectivity simulations. + // * layersDetails: Master array of all available layers. + // * contrastLayers: Which specific combination of arrays are needed for each contrast. + // * customFiles:Filenames and path for any custom files used. + // Extract individual parameters from problemStruct + // Extract individual parameters from problem + nParams = problemStruct->params.size(1); + calcSld = controls->calcSldDuringFit; + useImaginary = problemStruct->useImaginary; + + // Default for compile. + // Pre-Allocation of output arrays... + i = static_cast(problemStruct->numberOfContrasts); + backgroundParams.set_size(i); + + // Resampling parameters + // Process the custom models.... + processCustomFunction(problemStruct->contrastBulkIns, + problemStruct->contrastBulkOuts, + problemStruct->bulkIn, problemStruct->bulkOut, + problemStruct->contrastCustomFiles, + problemStruct->numberOfContrasts, + problemCells->f14, problemStruct->params, + problemStruct->useImaginary, r, allRoughs); + cast(r, calcAllLayers); + + // Parallel over all contrasts + // layersCounter = 1; + outSsubs.set_size(i); + tempSldProfiles.set_size(i); + reflectivity.set_size(i); + simulation.set_size(i); + shiftedData.set_size(i); + tempLayerSlds.set_size(i); + tempAllLayers.set_size(i); + chis.set_size(i); + qzshifts.set_size(i); + scalefactors.set_size(i); + bulkIns.set_size(i); + bulkOuts.set_size(i); + resolutionParams.set_size(i); + layerSlds.set_size(i, 2); + domainSldProfiles.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T b_dv[2]; + real_T b_dv1[2]; + real_T dv2[2]; + + // Get the domain ratio for this contrast + // Extract the relevant parameter values for this contrast + // from the input arrays. + // First need to decide which values of the backgrounds, scalefactors + // data shifts and bulk contrasts are associated with this contrast + backSort(problemStruct->contrastBackgrounds[b_i], + problemStruct->contrastQzshifts[b_i], + problemStruct->contrastScalefactors[b_i], + problemStruct->contrastBulkIns[b_i], + problemStruct->contrastBulkOuts[b_i], + problemStruct->contrastResolutions[b_i], + problemStruct->backgroundParams, problemStruct->qzshifts, + problemStruct->scalefactors, problemStruct->bulkIn, + problemStruct->bulkOut, problemStruct->resolutionParams, + &thisBackground, &thisQzshift, &thisScalefactor, &thisBulkIn, + &thisBulkOut, &thisResol); + + // Get the custom layers output for this contrast + // We have two for each contrast - one for each domain + // For the other parameters, we extract the correct ones from the input + // arrays + // Now call the core layers reflectivity calculation + // In this case we are single cored, so we do not parallelise over + // points + // Call the reflectivity calculation for each domain + // Domain 1 + b_dv[0] = problemCells->f3[b_i].f1[0]; + b_dv[1] = problemCells->f3[b_i].f1[1]; + b_dv1[0] = problemCells->f4[b_i].f1[0]; + b_dv1[1] = problemCells->f4[b_i].f1[1]; + dv2[0] = problemCells->f1[b_i].f1[0]; + dv2[1] = problemCells->f1[b_i].f1[1]; + nonPolarisedTF::coreLayersCalculation(calcAllLayers[b_i].f1, + allRoughs[b_i], problemStruct->geometry.data, + problemStruct->geometry.size, thisBulkIn, thisBulkOut, + problemStruct->resample[b_i], calcSld, thisScalefactor, thisQzshift, + problemStruct->dataPresent[b_i], problemCells->f2[b_i].f1, b_dv, + b_dv1, dv2, thisBackground, thisResol, + problemStruct->contrastBackgroundsType[b_i], static_cast + (nParams), controls->resamPars, useImaginary, r1.f1, reflect1, + simul1, shiftedDat, r2.f1, r3.f1, &a__4, &outSsubs[b_i]); + + // Domain 2 + b_dv[0] = problemCells->f3[b_i].f1[0]; + b_dv[1] = problemCells->f3[b_i].f1[1]; + b_dv1[0] = problemCells->f4[b_i].f1[0]; + b_dv1[1] = problemCells->f4[b_i].f1[1]; + dv2[0] = problemCells->f1[b_i].f1[0]; + dv2[1] = problemCells->f1[b_i].f1[1]; + nonPolarisedTF::coreLayersCalculation(calcAllLayers[b_i + + calcAllLayers.size(0)].f1, allRoughs[b_i], + problemStruct->geometry.data, problemStruct->geometry.size, + thisBulkIn, thisBulkOut, problemStruct->resample[b_i], calcSld, + thisScalefactor, thisQzshift, problemStruct->dataPresent[b_i], + problemCells->f2[b_i].f1, b_dv, b_dv1, dv2, thisBackground, + thisResol, problemStruct->contrastBackgroundsType[b_i], + static_cast(nParams), controls->resamPars, useImaginary, + r4.f1, reflect2, simul2, a__5, r5.f1, r6.f1, &a__6, &a__7); + + // Calculate the average reflectivities.... + averageReflectivity(reflect1, reflect2, simul1, simul2, + problemStruct->domainRatio[static_cast + (problemStruct->contrastDomainRatios[b_i]) - 1], + totReflect, simulation[b_i].f1); + + // Get an overall chi-squared for the new averaged curve.. + chis[b_i] = chiSquared(shiftedDat, totReflect, static_cast + (problemStruct->params.size(1))); + + // Store returned values for this contrast in the output arrays. + // As well as the calculated profiles, we also store a record of + // the other values (background, scalefactors etc) for each contrast + // for future use. + tempSldProfiles[b_i].f1[0] = r1; + tempSldProfiles[b_i].f1[1] = r4; + reflectivity[b_i].f1.set_size(totReflect.size(0), 2); + loop_ub = totReflect.size(0); + for (int32_T i1{0}; i1 < 2; i1++) { + for (int32_T i2{0}; i2 < loop_ub; i2++) { + reflectivity[b_i].f1[i2 + reflectivity[b_i].f1.size(0) * i1] = + totReflect[i2 + totReflect.size(0) * i1]; + } + } + + shiftedData[b_i].f1.set_size(shiftedDat.size(0), shiftedDat.size(1)); + loop_ub = shiftedDat.size(1); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = shiftedDat.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + shiftedData[b_i].f1[i2 + shiftedData[b_i].f1.size(0) * i1] = + shiftedDat[i2 + shiftedDat.size(0) * i1]; + } + } + + tempLayerSlds[b_i].f1[0] = r2; + tempLayerSlds[b_i].f1[1] = r5; + tempAllLayers[b_i].f1[0] = r3; + tempAllLayers[b_i].f1[1] = r6; + backgroundParams[b_i] = thisBackground; + qzshifts[b_i] = thisQzshift; + scalefactors[b_i] = thisScalefactor; + bulkIns[b_i] = thisBulkIn; + bulkOuts[b_i] = thisBulkOut; + resolutionParams[b_i] = thisResol; + } + + allLayers.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + loop_ub = tempSldProfiles[b_i].f1[0].f1.size(1); + domainSldProfiles[b_i].f1.set_size(tempSldProfiles[b_i].f1[0].f1.size + (0), tempSldProfiles[b_i].f1[0].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempSldProfiles[b_i].f1[0].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + domainSldProfiles[b_i].f1[i2 + domainSldProfiles[b_i].f1.size(0) * + i1] = tempSldProfiles[b_i].f1[0].f1[i2 + tempSldProfiles[b_i] + .f1[0].f1.size(0) * i1]; + } + } + + loop_ub = tempSldProfiles[b_i].f1[1].f1.size(1); + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.set_size + (tempSldProfiles[b_i].f1[1].f1.size(0), tempSldProfiles[b_i].f1[1]. + f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempSldProfiles[b_i].f1[1].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1[i2 + + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size(0) * + i1] = tempSldProfiles[b_i].f1[1].f1[i2 + tempSldProfiles[b_i] + .f1[1].f1.size(0) * i1]; + } + } + + loop_ub = tempAllLayers[b_i].f1[0].f1.size(1); + allLayers[b_i].f1.set_size(tempAllLayers[b_i].f1[0].f1.size(0), + tempAllLayers[b_i].f1[0].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempAllLayers[b_i].f1[0].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + allLayers[b_i].f1[i2 + allLayers[b_i].f1.size(0) * i1] = + tempAllLayers[b_i].f1[0].f1[i2 + tempAllLayers[b_i].f1[0]. + f1.size(0) * i1]; + } + } + + loop_ub = tempAllLayers[b_i].f1[1].f1.size(1); + allLayers[b_i + allLayers.size(0)].f1.set_size(tempAllLayers[b_i].f1[1] + .f1.size(0), tempAllLayers[b_i].f1[1].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempAllLayers[b_i].f1[1].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + allLayers[b_i + allLayers.size(0)].f1[i2 + allLayers[b_i + + allLayers.size(0)].f1.size(0) * i1] = tempAllLayers[b_i].f1[1]. + f1[i2 + tempAllLayers[b_i].f1[1].f1.size(0) * i1]; + } + } + + loop_ub = tempLayerSlds[b_i].f1[0].f1.size(1); + layerSlds[b_i].f1.set_size(tempLayerSlds[b_i].f1[0].f1.size(0), + tempLayerSlds[b_i].f1[0].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempLayerSlds[b_i].f1[0].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + layerSlds[b_i].f1[i2 + layerSlds[b_i].f1.size(0) * i1] = + tempLayerSlds[b_i].f1[0].f1[i2 + tempLayerSlds[b_i].f1[0]. + f1.size(0) * i1]; + } + } + + loop_ub = tempLayerSlds[b_i].f1[1].f1.size(1); + layerSlds[b_i + layerSlds.size(0)].f1.set_size(tempLayerSlds[b_i].f1[1] + .f1.size(0), tempLayerSlds[b_i].f1[1].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempLayerSlds[b_i].f1[1].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + layerSlds[b_i + layerSlds.size(0)].f1[i2 + layerSlds[b_i + + layerSlds.size(0)].f1.size(0) * i1] = tempLayerSlds[b_i].f1[1]. + f1[i2 + tempLayerSlds[b_i].f1[1].f1.size(0) * i1]; + } + } + } + } + } + } +} + +// End of code generation (single4.cpp) diff --git a/cpp/RAT/single4.h b/cpp/RAT/single4.h new file mode 100644 index 00000000..331b6760 --- /dev/null +++ b/cpp/RAT/single4.h @@ -0,0 +1,47 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// single4.h +// +// Code generation for function 'single4' +// +#ifndef SINGLE4_H +#define SINGLE4_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace domainsTF + { + namespace customLayers + { + void b_single(const c_struct_T *problemStruct, const cell_11 *problemCells, + const struct2_T *controls, ::coder::array + &outSsubs, ::coder::array &backgroundParams, :: + coder::array &qzshifts, ::coder::array &scalefactors, ::coder::array &bulkIns, :: + coder::array &bulkOuts, ::coder::array &resolutionParams, ::coder::array &chis, :: + coder::array &reflectivity, ::coder::array< + cell_wrap_20, 1U> &simulation, ::coder::array &shiftedData, ::coder::array &layerSlds, + ::coder::array &domainSldProfiles, ::coder:: + array &allLayers, ::coder::array + &allRoughs); + } + } +} + +#endif + +// End of code generation (single4.h) diff --git a/cpp/RAT/single5.cpp b/cpp/RAT/single5.cpp new file mode 100644 index 00000000..6f49df04 --- /dev/null +++ b/cpp/RAT/single5.cpp @@ -0,0 +1,406 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// single5.cpp +// +// Code generation for function 'single5' +// + +// Include files +#include "single5.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "applyBackgroundCorrection.h" +#include "averageReflectivity.h" +#include "backSort.h" +#include "callReflectivity.h" +#include "chiSquared.h" +#include "processCustomFunction3.h" +#include "resampleLayers.h" +#include "resampleLayersReIm.h" +#include "rt_nonfinite.h" +#include "shiftData.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace domainsTF + { + namespace customXY + { + void b_single(const c_struct_T *problemStruct, const cell_11 *problemCells, + const struct2_T *controls, ::coder::array + &outSsubs, ::coder::array &backgroundParams, :: + coder::array &qzshifts, ::coder::array &scalefactors, ::coder::array &bulkIns, :: + coder::array &bulkOuts, ::coder::array &resolutionParams, ::coder::array &chis, :: + coder::array &reflectivity, ::coder::array< + cell_wrap_20, 1U> &simulation, ::coder::array &shiftedData, ::coder::array &layerSlds, + ::coder::array &domainSldProfiles, ::coder:: + array &allLayers, ::coder::array + &allRoughs) + { + ::coder::array tempAllLayers; + ::coder::array tempLayerSlds; + ::coder::array tempSldProfiles; + ::coder::array b_domainSldProfiles; + ::coder::array b_problemCells; + ::coder::array c_domainSldProfiles; + ::coder::array r4; + ::coder::array reflect1; + ::coder::array reflect2; + ::coder::array shiftedDat; + ::coder::array simul1; + ::coder::array simul2; + ::coder::array totReflect; + cell_wrap_8 r; + cell_wrap_8 r1; + cell_wrap_8 r2; + cell_wrap_8 r3; + int32_T b_loop_ub; + int32_T i; + int32_T loop_ub; + boolean_T useImaginary; + + // Extract individual cell arrays + // Splits up the master input list of all arrays into separate arrays + // + // INPUTS: + // * problemCells: cell array where all the project data is grouped together. + // + // OUTPUTS: + // * repeatLayers: controls repeating of the layers stack. + // * allData: Array of all the data arrays. + // * dataLimits: Min max limits in q for the data arrays. + // * simLimits: Limits in Q for the reflectivity simulations. + // * layersDetails: Master array of all available layers. + // * contrastLayers: Which specific combination of arrays are needed for each contrast. + // * customFiles:Filenames and path for any custom files used. + // % Layers details N/A + // Extract individual parameters from problemStruct + // Extract individual parameters from problem + // Pre-Allocation... + i = static_cast(problemStruct->numberOfContrasts); + backgroundParams.set_size(i); + + // Resampling parameters + useImaginary = problemStruct->useImaginary; + + // Default for compile. + processCustomFunction(problemStruct->contrastBulkIns, + problemStruct->contrastBulkOuts, + problemStruct->bulkIn, problemStruct->bulkOut, + problemStruct->contrastCustomFiles, + problemStruct->numberOfContrasts, + problemCells->f14, problemStruct->params, + domainSldProfiles, allRoughs); + outSsubs.set_size(i); + qzshifts.set_size(i); + scalefactors.set_size(i); + bulkIns.set_size(i); + bulkOuts.set_size(i); + resolutionParams.set_size(i); + tempLayerSlds.set_size(i); + tempAllLayers.set_size(i); + tempSldProfiles.set_size(i); + shiftedData.set_size(i); + reflectivity.set_size(i); + simulation.set_size(i); + chis.set_size(i); + layerSlds.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T b_dv[2]; + real_T b_dv1[2]; + outSsubs[b_i] = allRoughs[b_i]; + backSort(problemStruct->contrastBackgrounds[b_i], + problemStruct->contrastQzshifts[b_i], + problemStruct->contrastScalefactors[b_i], + problemStruct->contrastBulkIns[b_i], + problemStruct->contrastBulkOuts[b_i], + problemStruct->contrastResolutions[b_i], + problemStruct->backgroundParams, problemStruct->qzshifts, + problemStruct->scalefactors, problemStruct->bulkIn, + problemStruct->bulkOut, problemStruct->resolutionParams, + &backgroundParams[b_i], &qzshifts[b_i], &scalefactors[b_i], + &bulkIns[b_i], &bulkOuts[b_i], &resolutionParams[b_i]); + + // Get the domain ratio for this contrast + // Resample the sld profiles + if (!useImaginary) { + resampleLayers(domainSldProfiles[b_i].f1, controls->resamPars, r.f1); + r1.f1.set_size(r.f1.size(0), 3); + for (int32_T i1{0}; i1 < 3; i1++) { + loop_ub = r.f1.size(0); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + r1.f1[i2 + r1.f1.size(0) * i1] = r.f1[i2 + r.f1.size(0) * i1]; + } + } + + resampleLayers(domainSldProfiles[b_i + domainSldProfiles.size(0)].f1, + controls->resamPars, r.f1); + } else { + loop_ub = domainSldProfiles[b_i].f1.size(0); + b_domainSldProfiles.set_size(domainSldProfiles[b_i].f1.size(0), 2); + for (int32_T i1{0}; i1 < 2; i1++) { + for (int32_T i2{0}; i2 < loop_ub; i2++) { + b_domainSldProfiles[i2 + b_domainSldProfiles.size(0) * i1] = + domainSldProfiles[b_i].f1[i2 + domainSldProfiles[b_i].f1.size + (0) * i1]; + } + } + + loop_ub = domainSldProfiles[b_i].f1.size(0); + c_domainSldProfiles.set_size(domainSldProfiles[b_i].f1.size(0), 2); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + c_domainSldProfiles[i1] = domainSldProfiles[b_i].f1[i1]; + c_domainSldProfiles[i1 + c_domainSldProfiles.size(0)] = + domainSldProfiles[b_i].f1[i1 + domainSldProfiles[b_i].f1.size(0) + * 2]; + } + + b_resampleLayersReIm(b_domainSldProfiles, c_domainSldProfiles, + controls->resamPars, r.f1); + r1.f1.set_size(r.f1.size(0), 4); + for (int32_T i1{0}; i1 < 4; i1++) { + loop_ub = r.f1.size(0); + for (int32_T i2{0}; i2 < loop_ub; i2++) { + r1.f1[i2 + r1.f1.size(0) * i1] = r.f1[i2 + r.f1.size(0) * i1]; + } + } + + loop_ub = domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size + (0); + b_domainSldProfiles.set_size(domainSldProfiles[b_i + + domainSldProfiles.size(0)].f1.size(0), 2); + for (int32_T i1{0}; i1 < 2; i1++) { + for (int32_T i2{0}; i2 < loop_ub; i2++) { + b_domainSldProfiles[i2 + b_domainSldProfiles.size(0) * i1] = + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1[i2 + + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size(0) * + i1]; + } + } + + loop_ub = domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size + (0); + c_domainSldProfiles.set_size(domainSldProfiles[b_i + + domainSldProfiles.size(0)].f1.size(0), 2); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + c_domainSldProfiles[i1] = domainSldProfiles[b_i + + domainSldProfiles.size(0)].f1[i1]; + c_domainSldProfiles[i1 + c_domainSldProfiles.size(0)] = + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1[i1 + + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size(0) * + 2]; + } + + b_resampleLayersReIm(b_domainSldProfiles, c_domainSldProfiles, + controls->resamPars, r.f1); + } + + tempLayerSlds[b_i].f1[0] = r1; + tempLayerSlds[b_i].f1[1] = r; + tempAllLayers[b_i].f1[0] = r1; + tempAllLayers[b_i].f1[1] = r; + r2.f1.set_size(domainSldProfiles[b_i].f1.size(0), + domainSldProfiles[b_i].f1.size(1)); + loop_ub = domainSldProfiles[b_i].f1.size(1); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = domainSldProfiles[b_i].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + r2.f1[i2 + r2.f1.size(0) * i1] = domainSldProfiles[b_i].f1[i2 + + domainSldProfiles[b_i].f1.size(0) * i1]; + } + } + + r3.f1.set_size(domainSldProfiles[b_i + domainSldProfiles.size(0)]. + f1.size(0), domainSldProfiles[b_i + + domainSldProfiles.size(0)].f1.size(1)); + loop_ub = domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size(1); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = domainSldProfiles[b_i + domainSldProfiles.size(0)]. + f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + r3.f1[i2 + r3.f1.size(0) * i1] = domainSldProfiles[b_i + + domainSldProfiles.size(0)].f1[i2 + domainSldProfiles[b_i + + domainSldProfiles.size(0)].f1.size(0) * i1]; + } + } + + tempSldProfiles[b_i].f1[0] = r2; + tempSldProfiles[b_i].f1[1] = r3; + b_problemCells.set_size(problemCells->f2[problemCells->f2.size(0) * + b_i].f1.size(0), problemCells->f2[problemCells->f2.size(0) * b_i]. + f1.size(1)); + loop_ub = problemCells->f2[b_i].f1.size(1) - 1; + for (int32_T i1{0}; i1 <= loop_ub; i1++) { + b_loop_ub = problemCells->f2[b_i].f1.size(0) - 1; + for (int32_T i2{0}; i2 <= b_loop_ub; i2++) { + b_problemCells[i2 + b_problemCells.size(0) * i1] = + problemCells->f2[b_i].f1[i2 + problemCells->f2[b_i].f1.size(0) * + i1]; + } + } + + b_dv[0] = problemCells->f3[b_i].f1[0]; + b_dv[1] = problemCells->f3[b_i].f1[1]; + b_dv1[0] = problemCells->f4[b_i].f1[0]; + b_dv1[1] = problemCells->f4[b_i].f1[1]; + shiftData(scalefactors[b_i], qzshifts[b_i], problemStruct-> + dataPresent[b_i], b_problemCells, b_dv, b_dv1, shiftedDat); + shiftedData[b_i].f1.set_size(shiftedDat.size(0), shiftedDat.size(1)); + loop_ub = shiftedDat.size(1); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = shiftedDat.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + shiftedData[b_i].f1[i2 + shiftedData[b_i].f1.size(0) * i1] = + shiftedDat[i2 + shiftedDat.size(0) * i1]; + } + } + + r4.set_size(r1.f1.size(0), r1.f1.size(1)); + loop_ub = r1.f1.size(1) - 1; + for (int32_T i1{0}; i1 <= loop_ub; i1++) { + b_loop_ub = r1.f1.size(0) - 1; + for (int32_T i2{0}; i2 <= b_loop_ub; i2++) { + r4[i2 + r4.size(0) * i1] = r1.f1[i2 + r1.f1.size(0) * i1]; + } + } + + b_dv[0] = problemCells->f4[b_i].f1[0]; + b_dv[1] = problemCells->f4[b_i].f1[1]; + b_dv1[0] = problemCells->f1[b_i].f1[0]; + b_dv1[1] = problemCells->f1[b_i].f1[1]; + callReflectivity(bulkIns[b_i], bulkOuts[b_i], b_dv, b_dv1, shiftedDat, + r4, allRoughs[b_i], resolutionParams[b_i], + useImaginary, reflect1, simul1); + r4.set_size(r.f1.size(0), r.f1.size(1)); + loop_ub = r.f1.size(1) - 1; + for (int32_T i1{0}; i1 <= loop_ub; i1++) { + b_loop_ub = r.f1.size(0) - 1; + for (int32_T i2{0}; i2 <= b_loop_ub; i2++) { + r4[i2 + r4.size(0) * i1] = r.f1[i2 + r.f1.size(0) * i1]; + } + } + + b_dv[0] = problemCells->f4[b_i].f1[0]; + b_dv[1] = problemCells->f4[b_i].f1[1]; + b_dv1[0] = problemCells->f1[b_i].f1[0]; + b_dv1[1] = problemCells->f1[b_i].f1[1]; + callReflectivity(bulkIns[b_i], bulkOuts[b_i], b_dv, b_dv1, shiftedDat, + r4, allRoughs[b_i], resolutionParams[b_i], + useImaginary, reflect2, simul2); + applyBackgroundCorrection(reflect1, simul1, shiftedDat, + backgroundParams[b_i], problemStruct->contrastBackgroundsType[b_i]); + applyBackgroundCorrection(reflect2, simul2, shiftedDat, + backgroundParams[b_i], problemStruct->contrastBackgroundsType[b_i]); + + // Calculate the average reflectivities.... + averageReflectivity(reflect1, reflect2, simul1, simul2, + problemStruct->domainRatio[static_cast + (problemStruct->contrastDomainRatios[b_i]) - 1], + totReflect, simulation[b_i].f1); + loop_ub = totReflect.size(0); + reflectivity[b_i].f1.set_size(totReflect.size(0), 2); + for (int32_T i1{0}; i1 < 2; i1++) { + for (int32_T i2{0}; i2 < loop_ub; i2++) { + reflectivity[b_i].f1[i2 + reflectivity[b_i].f1.size(0) * i1] = + totReflect[i2 + totReflect.size(0) * i1]; + } + } + + if (problemStruct->dataPresent[b_i] != 0.0) { + chis[b_i] = chiSquared(shiftedDat, totReflect, static_cast + (problemStruct->params.size(1))); + } else { + chis[b_i] = 0.0; + } + } + + allLayers.set_size(i, 2); + for (int32_T b_i{0}; b_i < i; b_i++) { + loop_ub = tempSldProfiles[b_i].f1[0].f1.size(1); + domainSldProfiles[b_i].f1.set_size(tempSldProfiles[b_i].f1[0].f1.size + (0), tempSldProfiles[b_i].f1[0].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempSldProfiles[b_i].f1[0].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + domainSldProfiles[b_i].f1[i2 + domainSldProfiles[b_i].f1.size(0) * + i1] = tempSldProfiles[b_i].f1[0].f1[i2 + tempSldProfiles[b_i] + .f1[0].f1.size(0) * i1]; + } + } + + loop_ub = tempSldProfiles[b_i].f1[1].f1.size(1); + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.set_size + (tempSldProfiles[b_i].f1[1].f1.size(0), tempSldProfiles[b_i].f1[1]. + f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempSldProfiles[b_i].f1[1].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1[i2 + + domainSldProfiles[b_i + domainSldProfiles.size(0)].f1.size(0) * + i1] = tempSldProfiles[b_i].f1[1].f1[i2 + tempSldProfiles[b_i] + .f1[1].f1.size(0) * i1]; + } + } + + loop_ub = tempAllLayers[b_i].f1[0].f1.size(1); + allLayers[b_i].f1.set_size(tempAllLayers[b_i].f1[0].f1.size(0), + tempAllLayers[b_i].f1[0].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempAllLayers[b_i].f1[0].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + allLayers[b_i].f1[i2 + allLayers[b_i].f1.size(0) * i1] = + tempAllLayers[b_i].f1[0].f1[i2 + tempAllLayers[b_i].f1[0]. + f1.size(0) * i1]; + } + } + + loop_ub = tempAllLayers[b_i].f1[1].f1.size(1); + allLayers[b_i + allLayers.size(0)].f1.set_size(tempAllLayers[b_i].f1[1] + .f1.size(0), tempAllLayers[b_i].f1[1].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempAllLayers[b_i].f1[1].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + allLayers[b_i + allLayers.size(0)].f1[i2 + allLayers[b_i + + allLayers.size(0)].f1.size(0) * i1] = tempAllLayers[b_i].f1[1]. + f1[i2 + tempAllLayers[b_i].f1[1].f1.size(0) * i1]; + } + } + + loop_ub = tempLayerSlds[b_i].f1[0].f1.size(1); + layerSlds[b_i].f1.set_size(tempLayerSlds[b_i].f1[0].f1.size(0), + tempLayerSlds[b_i].f1[0].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempLayerSlds[b_i].f1[0].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + layerSlds[b_i].f1[i2 + layerSlds[b_i].f1.size(0) * i1] = + tempLayerSlds[b_i].f1[0].f1[i2 + tempLayerSlds[b_i].f1[0]. + f1.size(0) * i1]; + } + } + + loop_ub = tempLayerSlds[b_i].f1[1].f1.size(1); + layerSlds[b_i + layerSlds.size(0)].f1.set_size(tempLayerSlds[b_i].f1[1] + .f1.size(0), tempLayerSlds[b_i].f1[1].f1.size(1)); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_loop_ub = tempLayerSlds[b_i].f1[1].f1.size(0); + for (int32_T i2{0}; i2 < b_loop_ub; i2++) { + layerSlds[b_i + layerSlds.size(0)].f1[i2 + layerSlds[b_i + + layerSlds.size(0)].f1.size(0) * i1] = tempLayerSlds[b_i].f1[1]. + f1[i2 + tempLayerSlds[b_i].f1[1].f1.size(0) * i1]; + } + } + } + } + } + } +} + +// End of code generation (single5.cpp) diff --git a/cpp/RAT/single5.h b/cpp/RAT/single5.h new file mode 100644 index 00000000..dcee3403 --- /dev/null +++ b/cpp/RAT/single5.h @@ -0,0 +1,47 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// single5.h +// +// Code generation for function 'single5' +// +#ifndef SINGLE5_H +#define SINGLE5_H + +// Include files +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace domainsTF + { + namespace customXY + { + void b_single(const c_struct_T *problemStruct, const cell_11 *problemCells, + const struct2_T *controls, ::coder::array + &outSsubs, ::coder::array &backgroundParams, :: + coder::array &qzshifts, ::coder::array &scalefactors, ::coder::array &bulkIns, :: + coder::array &bulkOuts, ::coder::array &resolutionParams, ::coder::array &chis, :: + coder::array &reflectivity, ::coder::array< + cell_wrap_20, 1U> &simulation, ::coder::array &shiftedData, ::coder::array &layerSlds, + ::coder::array &domainSldProfiles, ::coder:: + array &allLayers, ::coder::array + &allRoughs); + } + } +} + +#endif + +// End of code generation (single5.h) diff --git a/cpp/RAT/sort.cpp b/cpp/RAT/sort.cpp new file mode 100644 index 00000000..74681592 --- /dev/null +++ b/cpp/RAT/sort.cpp @@ -0,0 +1,338 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// sort.cpp +// +// Code generation for function 'sort' +// + +// Include files +#include "sort.h" +#include "nonSingletonDim.h" +#include "rt_nonfinite.h" +#include "sortIdx.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + void b_sort(::coder::array &x, ::coder::array + &idx) + { + ::coder::array vwork; + ::coder::array iidx; + int32_T dim; + int32_T i; + int32_T lowerDim; + int32_T npages; + int32_T vlen; + int32_T vstride; + dim = nonSingletonDim(x) - 1; + vlen = x.size(dim) - 1; + vwork.set_size(x.size(dim)); + idx.set_size(x.size(0), x.size(1)); + vstride = 1; + i = static_cast(dim); + for (int32_T k{0}; k < i; k++) { + vstride *= x.size(0); + } + + npages = 1; + lowerDim = dim + 2; + for (int32_T k{lowerDim}; k < 3; k++) { + npages *= x.size(1); + } + + lowerDim = x.size(dim) * vstride; + for (int32_T b_i{0}; b_i < npages; b_i++) { + dim = b_i * lowerDim; + for (int32_T j{0}; j < vstride; j++) { + int32_T idx0; + idx0 = dim + j; + for (int32_T k{0}; k <= vlen; k++) { + vwork[k] = x[idx0 + k * vstride]; + } + + b_sortIdx(vwork, iidx); + for (int32_T k{0}; k <= vlen; k++) { + i = idx0 + k * vstride; + x[i] = vwork[k]; + idx[i] = iidx[k]; + } + } + } + } + + void sort(::coder::array &x, ::coder::array &idx) + { + ::coder::array xwork; + ::coder::array iwork; + real_T x4[4]; + int32_T idx4[4]; + int32_T i1; + int32_T i3; + int32_T i4; + int32_T ib; + int32_T n; + int32_T nNaNs; + int32_T quartetOffset; + ib = x.size(1); + idx.set_size(1, ib); + for (i1 = 0; i1 < ib; i1++) { + idx[i1] = 0; + } + + n = x.size(1); + x4[0] = 0.0; + idx4[0] = 0; + x4[1] = 0.0; + idx4[1] = 0; + x4[2] = 0.0; + idx4[2] = 0; + x4[3] = 0.0; + idx4[3] = 0; + ib = x.size(1); + iwork.set_size(ib); + for (i1 = 0; i1 < ib; i1++) { + iwork[i1] = 0; + } + + ib = x.size(1); + xwork.set_size(ib); + for (i1 = 0; i1 < ib; i1++) { + xwork[i1] = 0.0; + } + + nNaNs = 0; + ib = 0; + for (int32_T k{0}; k < n; k++) { + if (std::isnan(x[k])) { + i3 = (n - nNaNs) - 1; + idx[i3] = k + 1; + xwork[i3] = x[k]; + nNaNs++; + } else { + ib++; + idx4[ib - 1] = k + 1; + x4[ib - 1] = x[k]; + if (ib == 4) { + real_T d; + real_T d1; + int8_T b_i1; + int8_T b_i3; + int8_T i; + int8_T i2; + quartetOffset = k - nNaNs; + if (x4[0] <= x4[1]) { + i1 = 1; + ib = 2; + } else { + i1 = 2; + ib = 1; + } + + if (x4[2] <= x4[3]) { + i3 = 3; + i4 = 4; + } else { + i3 = 4; + i4 = 3; + } + + d = x4[i1 - 1]; + d1 = x4[i3 - 1]; + if (d <= d1) { + d = x4[ib - 1]; + if (d <= d1) { + i = static_cast(i1); + b_i1 = static_cast(ib); + i2 = static_cast(i3); + b_i3 = static_cast(i4); + } else if (d <= x4[i4 - 1]) { + i = static_cast(i1); + b_i1 = static_cast(i3); + i2 = static_cast(ib); + b_i3 = static_cast(i4); + } else { + i = static_cast(i1); + b_i1 = static_cast(i3); + i2 = static_cast(i4); + b_i3 = static_cast(ib); + } + } else { + d1 = x4[i4 - 1]; + if (d <= d1) { + if (x4[ib - 1] <= d1) { + i = static_cast(i3); + b_i1 = static_cast(i1); + i2 = static_cast(ib); + b_i3 = static_cast(i4); + } else { + i = static_cast(i3); + b_i1 = static_cast(i1); + i2 = static_cast(i4); + b_i3 = static_cast(ib); + } + } else { + i = static_cast(i3); + b_i1 = static_cast(i4); + i2 = static_cast(i1); + b_i3 = static_cast(ib); + } + } + + idx[quartetOffset - 3] = idx4[i - 1]; + idx[quartetOffset - 2] = idx4[b_i1 - 1]; + idx[quartetOffset - 1] = idx4[i2 - 1]; + idx[quartetOffset] = idx4[b_i3 - 1]; + x[quartetOffset - 3] = x4[i - 1]; + x[quartetOffset - 2] = x4[b_i1 - 1]; + x[quartetOffset - 1] = x4[i2 - 1]; + x[quartetOffset] = x4[b_i3 - 1]; + ib = 0; + } + } + } + + i4 = x.size(1) - nNaNs; + if (ib > 0) { + int8_T perm[4]; + perm[1] = 0; + perm[2] = 0; + perm[3] = 0; + if (ib == 1) { + perm[0] = 1; + } else if (ib == 2) { + if (x4[0] <= x4[1]) { + perm[0] = 1; + perm[1] = 2; + } else { + perm[0] = 2; + perm[1] = 1; + } + } else if (x4[0] <= x4[1]) { + if (x4[1] <= x4[2]) { + perm[0] = 1; + perm[1] = 2; + perm[2] = 3; + } else if (x4[0] <= x4[2]) { + perm[0] = 1; + perm[1] = 3; + perm[2] = 2; + } else { + perm[0] = 3; + perm[1] = 1; + perm[2] = 2; + } + } else if (x4[0] <= x4[2]) { + perm[0] = 2; + perm[1] = 1; + perm[2] = 3; + } else if (x4[1] <= x4[2]) { + perm[0] = 2; + perm[1] = 3; + perm[2] = 1; + } else { + perm[0] = 3; + perm[1] = 2; + perm[2] = 1; + } + + i1 = static_cast(ib); + for (int32_T k{0}; k < i1; k++) { + i3 = perm[k] - 1; + quartetOffset = (i4 - ib) + k; + idx[quartetOffset] = idx4[i3]; + x[quartetOffset] = x4[i3]; + } + } + + ib = nNaNs >> 1; + for (int32_T k{0}; k < ib; k++) { + quartetOffset = i4 + k; + i1 = idx[quartetOffset]; + i3 = (n - k) - 1; + idx[quartetOffset] = idx[i3]; + idx[i3] = i1; + x[quartetOffset] = xwork[i3]; + x[i3] = xwork[quartetOffset]; + } + + if ((nNaNs & 1) != 0) { + i1 = i4 + ib; + x[i1] = xwork[i1]; + } + + i1 = x.size(1) - nNaNs; + ib = 2; + if (i1 > 1) { + if (x.size(1) >= 256) { + quartetOffset = i1 >> 8; + if (quartetOffset > 0) { + for (ib = 0; ib < quartetOffset; ib++) { + merge_pow2_block(idx, x, ib << 8); + } + + ib = quartetOffset << 8; + quartetOffset = i1 - ib; + if (quartetOffset > 0) { + merge_block(idx, x, ib, quartetOffset, 2, iwork, xwork); + } + + ib = 8; + } + } + + merge_block(idx, x, 0, i1, ib, iwork, xwork); + } + } + + void sort(::coder::array &x, ::coder::array &idx) + { + ::coder::array vwork; + ::coder::array iidx; + int32_T dim; + int32_T i; + int32_T vlen; + int32_T vstride; + dim = nonSingletonDim(x); + if (dim <= 1) { + i = x.size(0); + } else { + i = 1; + } + + vlen = i - 1; + vwork.set_size(i); + idx.set_size(x.size(0)); + vstride = 1; + i = static_cast(dim - 1); + for (dim = 0; dim < i; dim++) { + vstride *= x.size(0); + } + + for (int32_T j{0}; j < vstride; j++) { + for (dim = 0; dim <= vlen; dim++) { + vwork[dim] = x[j + dim * vstride]; + } + + b_sortIdx(vwork, iidx); + for (dim = 0; dim <= vlen; dim++) { + i = j + dim * vstride; + x[i] = vwork[dim]; + idx[i] = iidx[dim]; + } + } + } + } + } +} + +// End of code generation (sort.cpp) diff --git a/cpp/RAT/sort.h b/cpp/RAT/sort.h new file mode 100644 index 00000000..de2ea93a --- /dev/null +++ b/cpp/RAT/sort.h @@ -0,0 +1,36 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// sort.h +// +// Code generation for function 'sort' +// +#ifndef SORT_H +#define SORT_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + void b_sort(::coder::array &x, ::coder::array + &idx); + void sort(::coder::array &x, ::coder::array &idx); + void sort(::coder::array &x, ::coder::array &idx); + } + } +} + +#endif + +// End of code generation (sort.h) diff --git a/cpp/RAT/sortAscendLE.cpp b/cpp/RAT/sortAscendLE.cpp new file mode 100644 index 00000000..04a6cb7c --- /dev/null +++ b/cpp/RAT/sortAscendLE.cpp @@ -0,0 +1,38 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// sortAscendLE.cpp +// +// Code generation for function 'sortAscendLE' +// + +// Include files +#include "sortAscendLE.h" +#include "rt_nonfinite.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + boolean_T sortAscendLE(real_T a, real_T b) + { + boolean_T p; + if ((a <= b) || std::isnan(b)) { + p = true; + } else { + p = false; + } + + return p; + } + } + } +} + +// End of code generation (sortAscendLE.cpp) diff --git a/cpp/RAT/sortAscendLE.h b/cpp/RAT/sortAscendLE.h new file mode 100644 index 00000000..2e96f3b8 --- /dev/null +++ b/cpp/RAT/sortAscendLE.h @@ -0,0 +1,32 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// sortAscendLE.h +// +// Code generation for function 'sortAscendLE' +// +#ifndef SORTASCENDLE_H +#define SORTASCENDLE_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + boolean_T sortAscendLE(real_T a, real_T b); + } + } +} + +#endif + +// End of code generation (sortAscendLE.h) diff --git a/cpp/RAT/sortIdx.cpp b/cpp/RAT/sortIdx.cpp new file mode 100644 index 00000000..807c17d2 --- /dev/null +++ b/cpp/RAT/sortIdx.cpp @@ -0,0 +1,667 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// sortIdx.cpp +// +// Code generation for function 'sortIdx' +// + +// Include files +#include "sortIdx.h" +#include "mergesort.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + static void merge(::coder::array &idx, ::coder::array &x, int32_T offset, int32_T np, int32_T nq, ::coder:: + array &iwork, ::coder::array + &xwork); + static void merge(::coder::array &idx, ::coder::array &x, int32_T offset, int32_T np, int32_T nq, ::coder:: + array &iwork, ::coder::array + &xwork); + static void merge_block(::coder::array &idx, ::coder::array< + real_T, 1U> &x, int32_T offset, int32_T n, int32_T preSortLevel, ::coder:: + array &iwork, ::coder::array &xwork); + static void merge_pow2_block(::coder::array &idx, ::coder:: + array &x, int32_T offset); + } + } +} + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + static void merge(::coder::array &idx, ::coder::array &x, int32_T offset, int32_T np, int32_T nq, ::coder:: + array &iwork, ::coder::array + &xwork) + { + if (nq != 0) { + int32_T iout; + int32_T n_tmp; + int32_T p; + int32_T q; + n_tmp = np + nq; + for (int32_T j{0}; j < n_tmp; j++) { + iout = offset + j; + iwork[j] = idx[iout]; + xwork[j] = x[iout]; + } + + p = 0; + q = np; + iout = offset - 1; + int32_T exitg1; + do { + exitg1 = 0; + iout++; + if (xwork[p] <= xwork[q]) { + idx[iout] = iwork[p]; + x[iout] = xwork[p]; + if (p + 1 < np) { + p++; + } else { + exitg1 = 1; + } + } else { + idx[iout] = iwork[q]; + x[iout] = xwork[q]; + if (q + 1 < n_tmp) { + q++; + } else { + q = iout - p; + for (int32_T j{p + 1}; j <= np; j++) { + iout = q + j; + idx[iout] = iwork[j - 1]; + x[iout] = xwork[j - 1]; + } + + exitg1 = 1; + } + } + } while (exitg1 == 0); + } + } + + static void merge(::coder::array &idx, ::coder::array &x, int32_T offset, int32_T np, int32_T nq, ::coder:: + array &iwork, ::coder::array + &xwork) + { + if (nq != 0) { + int32_T iout; + int32_T n_tmp; + int32_T p; + int32_T q; + n_tmp = np + nq; + for (int32_T j{0}; j < n_tmp; j++) { + iout = offset + j; + iwork[j] = idx[iout]; + xwork[j] = x[iout]; + } + + p = 0; + q = np; + iout = offset - 1; + int32_T exitg1; + do { + exitg1 = 0; + iout++; + if (xwork[p] <= xwork[q]) { + idx[iout] = iwork[p]; + x[iout] = xwork[p]; + if (p + 1 < np) { + p++; + } else { + exitg1 = 1; + } + } else { + idx[iout] = iwork[q]; + x[iout] = xwork[q]; + if (q + 1 < n_tmp) { + q++; + } else { + q = iout - p; + for (int32_T j{p + 1}; j <= np; j++) { + iout = q + j; + idx[iout] = iwork[j - 1]; + x[iout] = xwork[j - 1]; + } + + exitg1 = 1; + } + } + } while (exitg1 == 0); + } + } + + static void merge_block(::coder::array &idx, ::coder::array< + real_T, 1U> &x, int32_T offset, int32_T n, int32_T preSortLevel, ::coder:: + array &iwork, ::coder::array &xwork) + { + int32_T bLen; + int32_T nPairs; + nPairs = n >> preSortLevel; + bLen = 1 << preSortLevel; + while (nPairs > 1) { + int32_T nTail; + int32_T tailOffset; + if ((nPairs & 1) != 0) { + nPairs--; + tailOffset = bLen * nPairs; + nTail = n - tailOffset; + if (nTail > bLen) { + merge(idx, x, offset + tailOffset, bLen, nTail - bLen, iwork, + xwork); + } + } + + tailOffset = bLen << 1; + nPairs >>= 1; + for (nTail = 0; nTail < nPairs; nTail++) { + merge(idx, x, offset + nTail * tailOffset, bLen, bLen, iwork, xwork); + } + + bLen = tailOffset; + } + + if (n > bLen) { + merge(idx, x, offset, bLen, n - bLen, iwork, xwork); + } + } + + static void merge_pow2_block(::coder::array &idx, ::coder:: + array &x, int32_T offset) + { + real_T xwork[256]; + int32_T iwork[256]; + for (int32_T b{0}; b < 6; b++) { + int32_T bLen; + int32_T bLen2; + int32_T i; + bLen = 1 << (b + 2); + bLen2 = bLen << 1; + i = 256 >> (b + 3); + for (int32_T k{0}; k < i; k++) { + int32_T blockOffset; + int32_T iout; + int32_T p; + int32_T q; + blockOffset = offset + k * bLen2; + for (int32_T j{0}; j < bLen2; j++) { + iout = blockOffset + j; + iwork[j] = idx[iout]; + xwork[j] = x[iout]; + } + + p = 0; + q = bLen; + iout = blockOffset - 1; + int32_T exitg1; + do { + exitg1 = 0; + iout++; + if (xwork[p] <= xwork[q]) { + idx[iout] = iwork[p]; + x[iout] = xwork[p]; + if (p + 1 < bLen) { + p++; + } else { + exitg1 = 1; + } + } else { + idx[iout] = iwork[q]; + x[iout] = xwork[q]; + if (q + 1 < bLen2) { + q++; + } else { + iout -= p; + for (int32_T j{p + 1}; j <= bLen; j++) { + q = iout + j; + idx[q] = iwork[j - 1]; + x[q] = xwork[j - 1]; + } + + exitg1 = 1; + } + } + } while (exitg1 == 0); + } + } + } + + void b_sortIdx(::coder::array &x, ::coder::array + &idx) + { + ::coder::array b_x; + ::coder::array xwork; + ::coder::array b_idx; + ::coder::array iwork; + int32_T i1; + int32_T ib; + uint32_T unnamed_idx_0; + unnamed_idx_0 = static_cast(x.size(0)); + idx.set_size(static_cast(unnamed_idx_0)); + ib = static_cast(unnamed_idx_0); + for (i1 = 0; i1 < ib; i1++) { + idx[i1] = 0; + } + + if (x.size(0) != 0) { + real_T x4[4]; + int32_T idx4[4]; + int32_T i3; + int32_T i4; + int32_T n; + int32_T nNaNs; + int32_T quartetOffset; + ib = static_cast(unnamed_idx_0); + b_idx.set_size(static_cast(unnamed_idx_0)); + for (i1 = 0; i1 < ib; i1++) { + b_idx[i1] = 0; + } + + b_x.set_size(x.size(0)); + ib = x.size(0); + for (i1 = 0; i1 < ib; i1++) { + b_x[i1] = x[i1]; + } + + n = x.size(0); + x4[0] = 0.0; + idx4[0] = 0; + x4[1] = 0.0; + idx4[1] = 0; + x4[2] = 0.0; + idx4[2] = 0; + x4[3] = 0.0; + idx4[3] = 0; + iwork.set_size(static_cast(unnamed_idx_0)); + ib = static_cast(unnamed_idx_0); + for (i1 = 0; i1 < ib; i1++) { + iwork[i1] = 0; + } + + ib = x.size(0); + xwork.set_size(ib); + for (i1 = 0; i1 < ib; i1++) { + xwork[i1] = 0.0; + } + + nNaNs = 0; + ib = 0; + for (int32_T k{0}; k < n; k++) { + if (std::isnan(b_x[k])) { + i3 = (n - nNaNs) - 1; + b_idx[i3] = k + 1; + xwork[i3] = b_x[k]; + nNaNs++; + } else { + ib++; + idx4[ib - 1] = k + 1; + x4[ib - 1] = b_x[k]; + if (ib == 4) { + real_T d; + real_T d1; + int8_T b_i1; + int8_T b_i3; + int8_T i; + int8_T i2; + quartetOffset = k - nNaNs; + if (x4[0] <= x4[1]) { + i1 = 1; + ib = 2; + } else { + i1 = 2; + ib = 1; + } + + if (x4[2] <= x4[3]) { + i3 = 3; + i4 = 4; + } else { + i3 = 4; + i4 = 3; + } + + d = x4[i1 - 1]; + d1 = x4[i3 - 1]; + if (d <= d1) { + d = x4[ib - 1]; + if (d <= d1) { + i = static_cast(i1); + b_i1 = static_cast(ib); + i2 = static_cast(i3); + b_i3 = static_cast(i4); + } else if (d <= x4[i4 - 1]) { + i = static_cast(i1); + b_i1 = static_cast(i3); + i2 = static_cast(ib); + b_i3 = static_cast(i4); + } else { + i = static_cast(i1); + b_i1 = static_cast(i3); + i2 = static_cast(i4); + b_i3 = static_cast(ib); + } + } else { + d1 = x4[i4 - 1]; + if (d <= d1) { + if (x4[ib - 1] <= d1) { + i = static_cast(i3); + b_i1 = static_cast(i1); + i2 = static_cast(ib); + b_i3 = static_cast(i4); + } else { + i = static_cast(i3); + b_i1 = static_cast(i1); + i2 = static_cast(i4); + b_i3 = static_cast(ib); + } + } else { + i = static_cast(i3); + b_i1 = static_cast(i4); + i2 = static_cast(i1); + b_i3 = static_cast(ib); + } + } + + b_idx[quartetOffset - 3] = idx4[i - 1]; + b_idx[quartetOffset - 2] = idx4[b_i1 - 1]; + b_idx[quartetOffset - 1] = idx4[i2 - 1]; + b_idx[quartetOffset] = idx4[b_i3 - 1]; + b_x[quartetOffset - 3] = x4[i - 1]; + b_x[quartetOffset - 2] = x4[b_i1 - 1]; + b_x[quartetOffset - 1] = x4[i2 - 1]; + b_x[quartetOffset] = x4[b_i3 - 1]; + ib = 0; + } + } + } + + i4 = b_x.size(0) - nNaNs; + if (ib > 0) { + int8_T perm[4]; + perm[1] = 0; + perm[2] = 0; + perm[3] = 0; + if (ib == 1) { + perm[0] = 1; + } else if (ib == 2) { + if (x4[0] <= x4[1]) { + perm[0] = 1; + perm[1] = 2; + } else { + perm[0] = 2; + perm[1] = 1; + } + } else if (x4[0] <= x4[1]) { + if (x4[1] <= x4[2]) { + perm[0] = 1; + perm[1] = 2; + perm[2] = 3; + } else if (x4[0] <= x4[2]) { + perm[0] = 1; + perm[1] = 3; + perm[2] = 2; + } else { + perm[0] = 3; + perm[1] = 1; + perm[2] = 2; + } + } else if (x4[0] <= x4[2]) { + perm[0] = 2; + perm[1] = 1; + perm[2] = 3; + } else if (x4[1] <= x4[2]) { + perm[0] = 2; + perm[1] = 3; + perm[2] = 1; + } else { + perm[0] = 3; + perm[1] = 2; + perm[2] = 1; + } + + i1 = static_cast(ib); + for (int32_T k{0}; k < i1; k++) { + i3 = perm[k] - 1; + quartetOffset = (i4 - ib) + k; + b_idx[quartetOffset] = idx4[i3]; + b_x[quartetOffset] = x4[i3]; + } + } + + ib = nNaNs >> 1; + for (int32_T k{0}; k < ib; k++) { + quartetOffset = i4 + k; + i1 = b_idx[quartetOffset]; + i3 = (n - k) - 1; + b_idx[quartetOffset] = b_idx[i3]; + b_idx[i3] = i1; + b_x[quartetOffset] = xwork[i3]; + b_x[i3] = xwork[quartetOffset]; + } + + if ((nNaNs & 1) != 0) { + ib += i4; + b_x[ib] = xwork[ib]; + } + + i1 = b_x.size(0) - nNaNs; + ib = 2; + if (i1 > 1) { + if (b_x.size(0) >= 256) { + quartetOffset = i1 >> 8; + if (quartetOffset > 0) { + for (ib = 0; ib < quartetOffset; ib++) { + merge_pow2_block(b_idx, b_x, ib << 8); + } + + ib = quartetOffset << 8; + quartetOffset = i1 - ib; + if (quartetOffset > 0) { + merge_block(b_idx, b_x, ib, quartetOffset, 2, iwork, xwork); + } + + ib = 8; + } + } + + merge_block(b_idx, b_x, 0, i1, ib, iwork, xwork); + } + + ib = b_idx.size(0); + for (i1 = 0; i1 < ib; i1++) { + idx[i1] = b_idx[i1]; + } + + ib = b_x.size(0); + for (i1 = 0; i1 < ib; i1++) { + x[i1] = b_x[i1]; + } + } + } + + void merge_block(::coder::array &idx, ::coder::array &x, int32_T offset, int32_T n, int32_T preSortLevel, :: + coder::array &iwork, ::coder::array &xwork) + { + int32_T bLen; + int32_T nPairs; + nPairs = n >> preSortLevel; + bLen = 1 << preSortLevel; + while (nPairs > 1) { + int32_T nTail; + int32_T tailOffset; + if ((nPairs & 1) != 0) { + nPairs--; + tailOffset = bLen * nPairs; + nTail = n - tailOffset; + if (nTail > bLen) { + merge(idx, x, offset + tailOffset, bLen, nTail - bLen, iwork, + xwork); + } + } + + tailOffset = bLen << 1; + nPairs >>= 1; + for (nTail = 0; nTail < nPairs; nTail++) { + merge(idx, x, offset + nTail * tailOffset, bLen, bLen, iwork, xwork); + } + + bLen = tailOffset; + } + + if (n > bLen) { + merge(idx, x, offset, bLen, n - bLen, iwork, xwork); + } + } + + void merge_pow2_block(::coder::array &idx, ::coder::array< + real_T, 2U> &x, int32_T offset) + { + real_T xwork[256]; + int32_T iwork[256]; + for (int32_T b{0}; b < 6; b++) { + int32_T bLen; + int32_T bLen2; + int32_T i; + bLen = 1 << (b + 2); + bLen2 = bLen << 1; + i = 256 >> (b + 3); + for (int32_T k{0}; k < i; k++) { + int32_T blockOffset; + int32_T iout; + int32_T p; + int32_T q; + blockOffset = offset + k * bLen2; + for (int32_T j{0}; j < bLen2; j++) { + iout = blockOffset + j; + iwork[j] = idx[iout]; + xwork[j] = x[iout]; + } + + p = 0; + q = bLen; + iout = blockOffset - 1; + int32_T exitg1; + do { + exitg1 = 0; + iout++; + if (xwork[p] <= xwork[q]) { + idx[iout] = iwork[p]; + x[iout] = xwork[p]; + if (p + 1 < bLen) { + p++; + } else { + exitg1 = 1; + } + } else { + idx[iout] = iwork[q]; + x[iout] = xwork[q]; + if (q + 1 < bLen2) { + q++; + } else { + iout -= p; + for (int32_T j{p + 1}; j <= bLen; j++) { + q = iout + j; + idx[q] = iwork[j - 1]; + x[q] = xwork[j - 1]; + } + + exitg1 = 1; + } + } + } while (exitg1 == 0); + } + } + } + + void sortIdx(const ::coder::array &x, ::coder::array &idx) + { + int32_T loop_ub; + idx.set_size(1, x.size(1)); + loop_ub = x.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + idx[i] = 0; + } + + if (x.size(1) != 0) { + b_mergesort(idx, x, x.size(1)); + } + } + + void sortIdx(const ::coder::array &x, ::coder::array &idx) + { + ::coder::array b_x; + ::coder::array r; + int32_T loop_ub; + idx.set_size(x.size(0)); + loop_ub = x.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + idx[i] = 0; + } + + loop_ub = x.size(0); + r.set_size(x.size(0)); + for (int32_T i{0}; i < loop_ub; i++) { + r[i] = 0; + } + + b_x.set_size(x.size(0)); + loop_ub = x.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + b_x[i] = x[i]; + } + + b_mergesort(r, b_x, x.size(0)); + loop_ub = r.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + idx[i] = r[i]; + } + } + + void sortIdx(const ::coder::array &x, const int32_T col_data[], + ::coder::array &idx) + { + int32_T k; + int32_T n; + n = x.size(0); + idx.set_size(x.size(0)); + k = x.size(0); + for (int32_T i{0}; i < k; i++) { + idx[i] = 0; + } + + if (x.size(0) == 0) { + for (k = 0; k < n; k++) { + idx[k] = k + 1; + } + } else { + b_mergesort(idx, x, col_data, x.size(0)); + } + } + } + } +} + +// End of code generation (sortIdx.cpp) diff --git a/cpp/RAT/sortIdx.h b/cpp/RAT/sortIdx.h new file mode 100644 index 00000000..1c967d5f --- /dev/null +++ b/cpp/RAT/sortIdx.h @@ -0,0 +1,46 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// sortIdx.h +// +// Code generation for function 'sortIdx' +// +#ifndef SORTIDX_H +#define SORTIDX_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + void b_sortIdx(::coder::array &x, ::coder::array + &idx); + void merge_block(::coder::array &idx, ::coder::array &x, int32_T offset, int32_T n, int32_T preSortLevel, :: + coder::array &iwork, ::coder::array &xwork); + void merge_pow2_block(::coder::array &idx, ::coder::array< + real_T, 2U> &x, int32_T offset); + void sortIdx(const ::coder::array &x, ::coder::array &idx); + void sortIdx(const ::coder::array &x, ::coder::array &idx); + void sortIdx(const ::coder::array &x, const int32_T col_data[], + ::coder::array &idx); + } + } +} + +#endif + +// End of code generation (sortIdx.h) diff --git a/cpp/RAT/sortLE.cpp b/cpp/RAT/sortLE.cpp new file mode 100644 index 00000000..5f667c05 --- /dev/null +++ b/cpp/RAT/sortLE.cpp @@ -0,0 +1,97 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// sortLE.cpp +// +// Code generation for function 'sortLE' +// + +// Include files +#include "sortLE.h" +#include "rt_nonfinite.h" +#include "sortAscendLE.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + boolean_T sortLE(const real_T v[4], int32_T idx1, int32_T idx2) + { + real_T d; + boolean_T p; + d = v[idx2 - 1]; + if ((v[idx1 - 1] <= d) || std::isnan(d)) { + p = true; + } else { + p = false; + } + + return p; + } + + boolean_T sortLE(const ::coder::array &v, int32_T idx1, + int32_T idx2) + { + real_T d; + boolean_T p; + d = v[idx2 - 1]; + if ((v[idx1 - 1] <= d) || std::isnan(d)) { + p = true; + } else { + p = false; + } + + return p; + } + + boolean_T sortLE(const ::coder::array &v, int32_T idx1, + int32_T idx2) + { + real_T d; + boolean_T p; + d = v[idx2 - 1]; + if ((v[idx1 - 1] <= d) || std::isnan(d)) { + p = true; + } else { + p = false; + } + + return p; + } + + boolean_T sortLE(const ::coder::array &v, const int32_T + dir_data[], int32_T idx1, int32_T idx2) + { + int32_T k; + boolean_T exitg1; + boolean_T p; + p = true; + k = 0; + exitg1 = false; + while ((!exitg1) && (k < 2)) { + real_T v1; + real_T v2; + v1 = v[(idx1 + v.size(0) * (dir_data[k] - 1)) - 1]; + v2 = v[(idx2 + v.size(0) * (dir_data[k] - 1)) - 1]; + if ((v1 == v2) || (std::isnan(v1) && std::isnan(v2))) { + k++; + } else { + p = sortAscendLE(v1, v2); + exitg1 = true; + } + } + + return p; + } + } + } +} + +// End of code generation (sortLE.cpp) diff --git a/cpp/RAT/sortLE.h b/cpp/RAT/sortLE.h new file mode 100644 index 00000000..c0db007b --- /dev/null +++ b/cpp/RAT/sortLE.h @@ -0,0 +1,39 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// sortLE.h +// +// Code generation for function 'sortLE' +// +#ifndef SORTLE_H +#define SORTLE_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + boolean_T sortLE(const real_T v[4], int32_T idx1, int32_T idx2); + boolean_T sortLE(const ::coder::array &v, int32_T idx1, + int32_T idx2); + boolean_T sortLE(const ::coder::array &v, int32_T idx1, + int32_T idx2); + boolean_T sortLE(const ::coder::array &v, const int32_T + dir_data[], int32_T idx1, int32_T idx2); + } + } +} + +#endif + +// End of code generation (sortLE.h) diff --git a/cpp/RAT/sortrows.cpp b/cpp/RAT/sortrows.cpp new file mode 100644 index 00000000..de789474 --- /dev/null +++ b/cpp/RAT/sortrows.cpp @@ -0,0 +1,62 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// sortrows.cpp +// +// Code generation for function 'sortrows' +// + +// Include files +#include "sortrows.h" +#include "rt_nonfinite.h" +#include "sortIdx.h" +#include "coder_array.h" + +// Function Declarations +namespace RAT +{ + namespace coder + { + static void apply_row_permutation(::coder::array &y, const :: + coder::array &idx); + } +} + +// Function Definitions +namespace RAT +{ + namespace coder + { + static void apply_row_permutation(::coder::array &y, const :: + coder::array &idx) + { + ::coder::array ycol; + int32_T m; + m = y.size(0) - 1; + ycol.set_size(y.size(0)); + for (int32_T j{0}; j < 2; j++) { + for (int32_T i{0}; i <= m; i++) { + ycol[i] = y[(idx[i] + y.size(0) * j) - 1]; + } + + for (int32_T i{0}; i <= m; i++) { + y[i + y.size(0) * j] = ycol[i]; + } + } + } + + void sortrows(::coder::array &y) + { + ::coder::array r; + int32_T col_data[2]; + col_data[0] = 1; + col_data[1] = 2; + internal::sortIdx(y, col_data, r); + apply_row_permutation(y, r); + } + } +} + +// End of code generation (sortrows.cpp) diff --git a/cpp/RAT/sortrows.h b/cpp/RAT/sortrows.h new file mode 100644 index 00000000..75d95ae2 --- /dev/null +++ b/cpp/RAT/sortrows.h @@ -0,0 +1,30 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// sortrows.h +// +// Code generation for function 'sortrows' +// +#ifndef SORTROWS_H +#define SORTROWS_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void sortrows(::coder::array &y); + } +} + +#endif + +// End of code generation (sortrows.h) diff --git a/cpp/RAT/splitEllipsoid.cpp b/cpp/RAT/splitEllipsoid.cpp new file mode 100644 index 00000000..9b08aa4e --- /dev/null +++ b/cpp/RAT/splitEllipsoid.cpp @@ -0,0 +1,550 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// splitEllipsoid.cpp +// +// Code generation for function 'splitEllipsoid' +// + +// Include files +#include "splitEllipsoid.h" +#include "RATMain_data.h" +#include "RATMain_types.h" +#include "calcEllipsoid.h" +#include "eml_mtimes_helper.h" +#include "ifWhileCond.h" +#include "kmeans.h" +#include "makeCell.h" +#include "minOrMax.h" +#include "mrdivide_helper.h" +#include "mtimes.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Declarations +namespace RAT +{ + static void binary_expand_op(real_T in1[50], int32_T in2, const real_T + in3_data[], const int32_T in3_size[2], const real_T in4_data[], const + int32_T in4_size[2], real_T in5); +} + +// Function Definitions +namespace RAT +{ + static void binary_expand_op(real_T in1[50], int32_T in2, const real_T + in3_data[], const int32_T in3_size[2], const real_T in4_data[], const + int32_T in4_size[2], real_T in5) + { + real_T b_in3_data; + int32_T aux_0_1; + int32_T aux_1_1; + int32_T loop_ub; + int32_T stride_0_1; + int32_T stride_1_1; + stride_0_1 = (in3_size[1] != 1); + stride_1_1 = (in4_size[1] != 1); + aux_0_1 = 0; + aux_1_1 = 0; + if (in4_size[1] == 1) { + loop_ub = in3_size[1]; + } else { + loop_ub = in4_size[1]; + } + + for (int32_T i{0}; i < loop_ub; i++) { + int32_T b_loop_ub; + int32_T i1; + i1 = in4_size[0]; + if (i1 == 1) { + b_loop_ub = in3_size[0]; + } else { + b_loop_ub = i1; + } + + for (i1 = 0; i1 < b_loop_ub; i1++) { + b_in3_data = in3_data[in3_size[0] * aux_0_1] + in4_data[in4_size[0] * + aux_1_1]; + } + + aux_1_1 += stride_1_1; + aux_0_1 += stride_0_1; + } + + in1[in2] = b_in3_data / in5; + } + + void splitEllipsoid(const ::coder::array &u, real_T VS, ::coder:: + array &u1, ::coder::array &u2, + real_T VE1_data[], int32_T VE1_size[2], real_T VE2_data[], + int32_T VE2_size[2], real_T *nosplit) + { + ::coder::array B1; + ::coder::array B2; + ::coder::array b_u; + ::coder::array idx; + ::coder::array mu1; + ::coder::array mu2; + ::coder::array r2; + ::coder::array u1new; + ::coder::array u2new; + ::coder::array r; + ::coder::array r1; + ::coder::array d_tmp_data; + cell_wrap_8 temp_u1_tmp[50]; + real_T mu[2]; + real_T VE1_tmp_data; + real_T b_tmp_data; + real_T flag1; + real_T flag2; + real_T minFS; + real_T tmp_data; + int32_T VE1_tmp_size[2]; + int32_T D; + int32_T N; + int32_T b_nosplit; + int32_T iindx; + boolean_T c_tmp_data; + + // function [u1, u2, VE1, VE2, nosplit] = split_ellipsiod(u, VS) + // + // This function takes in a set of multi-dimensional data points u and the + // sample volume (VS) that they occupy. It uses the k-means algorthim to + // split the points into two sub-clusters and uses an optimisation scheme to + // re-assign points, if necessary, between the sub-clusters. This is based + // on the description in Algorithm 1 of the MULTINEST paper by Feroz, + // Hobson, and Bridges, MNRAS, 398, 1601-1614 (2009). + // + // The function returns the points in the two sub-cluster u1 and u2, and + // the volumes of the ellipsoid subclusters VE1 and VE2. The flag nosplit + // is set to 1 if the splitting cannot be done; otherwise = 0. + // + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // maximum number of attempts to recluster points + // default return values + b_nosplit = 0; + VE1_tmp_size[0] = 0; + VE1_tmp_size[1] = 0; + VE1_size[0] = 0; + VE1_size[1] = 0; + VE2_size[0] = 0; + VE2_size[1] = 0; + u1.set_size(0, 0); + u2.set_size(0, 0); + + // extract number of samples and number of dimensions + N = u.size(0); + D = u.size(1); + + // check total number of samples + if (u.size(0) < 2.0 * (static_cast(u.size(1)) + 1.0)) { + if (DEBUG != 0.0) { + printf("CANT SPLIT: total number of samples is too small! N = %d\n", + u.size(0)); + fflush(stdout); + } + + b_nosplit = 1; + } else { + int32_T b_loop_ub; + int32_T end; + int32_T loop_ub; + int32_T n1; + int32_T n2; + + // use kmeans to separate the data points into two sub-clusters + kmeans(u, idx, mu); + end = (idx.size(1) << 1) - 1; + iindx = 0; + for (int32_T i{0}; i <= end; i++) { + if (idx[i] == 1.0) { + iindx++; + } + } + + r.set_size(iindx); + iindx = 0; + for (int32_T i{0}; i <= end; i++) { + if (idx[i] == 1.0) { + r[iindx] = i + 1; + iindx++; + } + } + + u1.set_size(r.size(0), u.size(1)); + loop_ub = u.size(1); + for (int32_T b_i{0}; b_i < loop_ub; b_i++) { + b_loop_ub = r.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + u1[i1 + u1.size(0) * b_i] = u[(r[i1] + u.size(0) * b_i) - 1]; + } + } + + end = (idx.size(1) << 1) - 1; + iindx = 0; + for (int32_T i{0}; i <= end; i++) { + if (idx[i] == 2.0) { + iindx++; + } + } + + r1.set_size(iindx); + iindx = 0; + for (int32_T i{0}; i <= end; i++) { + if (idx[i] == 2.0) { + r1[iindx] = i + 1; + iindx++; + } + } + + u2.set_size(r1.size(0), u.size(1)); + loop_ub = u.size(1); + for (int32_T b_i{0}; b_i < loop_ub; b_i++) { + b_loop_ub = r1.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + u2[i1 + u2.size(0) * b_i] = u[(r1[i1] + u.size(0) * b_i) - 1]; + } + } + + n1 = r.size(0); + + // number of samples in S1 + n2 = r1.size(0); + + // number of samples in S2 + // check number of points in subclusters + if ((static_cast(r.size(0)) < static_cast(u.size(1)) + + 1U) || (static_cast(r1.size(0)) < static_cast + (u.size(1)) + 1U)) { + if (DEBUG != 0.0) { + printf("CANT SPLIT: number of samples in subclusters is too small! n1 = %d, n2 = %d\n", + r.size(0), r1.size(0)); + fflush(stdout); + } + + b_nosplit = 1; + } else { + cell_wrap_8 temp_u2[50]; + real_T FS[50]; + real_T temp_VE1[50]; + real_T temp_VE2[50]; + int32_T counter; + + // preallocate temp arrays + makeCell(temp_u1_tmp); + for (int32_T i{0}; i < 50; i++) { + temp_u2[i] = temp_u1_tmp[i]; + temp_VE1[i] = 0.0; + temp_VE2[i] = 0.0; + FS[i] = 0.0; + } + + // %%%%%%%%%%%%%%%%%%%%%%%%% + counter = 0; + real_T VS1; + real_T VS2; + int32_T exitg1; + do { + exitg1 = 0; + + // calculate minimum volume of ellipsoids + VS1 = VS * static_cast(n1) / static_cast(N); + VS2 = VS * static_cast(n2) / static_cast(N); + + // calculate properties of bounding ellipsoids for the two subclusters + calcEllipsoid(u1, VS1, B1, mu1, VE1_data, VE1_size, &flag1); + calcEllipsoid(u2, VS2, B2, mu2, VE2_data, VE2_size, &flag2); + + // check flags + if ((flag1 != 0.0) || (flag2 != 0.0)) { + if (DEBUG != 0.0) { + printf("CANT SPLIT!!\n"); + fflush(stdout); + } + + b_nosplit = 1; + exitg1 = 1; + } else { + int32_T reassign; + uint32_T m1; + uint32_T m2; + + // construct temporary arrays and cell arrays containing results for + // each pass through the loop + temp_u1_tmp[counter].f1.set_size(u1.size(0), u1.size(1)); + loop_ub = u1.size(1); + for (int32_T b_i{0}; b_i < loop_ub; b_i++) { + b_loop_ub = u1.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + temp_u1_tmp[counter].f1[i1 + temp_u1_tmp[counter].f1.size(0) * + b_i] = u1[i1 + u1.size(0) * b_i]; + } + } + + temp_u2[counter].f1.set_size(u2.size(0), u2.size(1)); + loop_ub = u2.size(1); + for (int32_T b_i{0}; b_i < loop_ub; b_i++) { + b_loop_ub = u2.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + temp_u2[counter].f1[i1 + temp_u2[counter].f1.size(0) * b_i] = + u2[i1 + u2.size(0) * b_i]; + } + } + + temp_VE1[counter] = VE1_data[0]; + temp_VE2[counter] = VE2_data[0]; + if ((VE1_size[0] == VE2_size[0]) && (VE1_size[1] == VE2_size[1])) { + FS[counter] = (VE1_data[0] + VE2_data[0]) / VS; + } else { + binary_expand_op(FS, counter, VE1_data, VE1_size, VE2_data, + VE2_size, VS); + } + + // DEBUG print statement + // if DEBUG + // fprintf('SPLIT ELLIPSOID: counter = %d, numreassigned = %d\n', ... + // int32(counter), int32(numreassigned)); + // end + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // check if points need to be reassigned to the other subcluster + reassign = 0; + m1 = 0U; + m2 = 0U; + u1new.set_size(N, D); + u2new.set_size(N, D); + for (int32_T b_i{0}; b_i < D; b_i++) { + for (int32_T i1{0}; i1 < N; i1++) { + u1new[i1 + u1new.size(0) * b_i] = 0.0; + u2new[i1 + u2new.size(0) * b_i] = 0.0; + } + } + + // for all points get the Mahalanobis distance between each point and + // the centroid of each ellipse and assign accordingly + loop_ub = u.size(1); + b_loop_ub = u.size(1); + iindx = u.size(1); + end = u.size(1); + for (int32_T i{0}; i < N; i++) { + int32_T b_tmp_size[2]; + int32_T tmp_size[2]; + int32_T c_loop_ub; + int32_T tmp_size_idx_0; + int32_T tmp_size_idx_1; + + // get d = (u-mu)^T * B^-1 * (u-mu) + // calculate hk = VEk * duk / VSk; + if (u.size(1) == mu1.size(1)) { + b_u.set_size(mu1.size(0), u.size(1)); + for (int32_T b_i{0}; b_i < loop_ub; b_i++) { + c_loop_ub = mu1.size(0); + for (int32_T i1{0}; i1 < c_loop_ub; i1++) { + b_u[b_u.size(0) * b_i] = u[i + u.size(0) * b_i] - + mu1[mu1.size(0) * b_i]; + } + } + + coder::internal::mrdiv(b_u, B1, r2); + } else { + c_binary_expand_op(r2, u, i, mu1, B1); + } + + if (u.size(1) == mu1.size(1)) { + b_u.set_size(mu1.size(0), u.size(1)); + for (int32_T b_i{0}; b_i < b_loop_ub; b_i++) { + c_loop_ub = mu1.size(0); + for (int32_T i1{0}; i1 < c_loop_ub; i1++) { + b_u[b_u.size(0) * b_i] = u[i + u.size(0) * b_i] - + mu1[mu1.size(0) * b_i]; + } + } + + coder::internal::blas::mtimes(r2, b_u, (real_T *)&VE1_tmp_data, + VE1_tmp_size); + } else { + c_binary_expand_op((real_T *)&VE1_tmp_data, VE1_tmp_size, r2, u, + i, mu1); + } + + coder::internal::blas::mtimes(VE1_data, VE1_size, (const real_T *) + &VE1_tmp_data, VE1_tmp_size, (real_T *)&tmp_data, tmp_size); + if (u.size(1) == mu2.size(1)) { + b_u.set_size(mu2.size(0), u.size(1)); + for (int32_T b_i{0}; b_i < iindx; b_i++) { + c_loop_ub = mu2.size(0); + for (int32_T i1{0}; i1 < c_loop_ub; i1++) { + b_u[b_u.size(0) * b_i] = u[i + u.size(0) * b_i] - + mu2[mu2.size(0) * b_i]; + } + } + + coder::internal::mrdiv(b_u, B2, r2); + } else { + c_binary_expand_op(r2, u, i, mu2, B2); + } + + if (u.size(1) == mu2.size(1)) { + b_u.set_size(mu2.size(0), u.size(1)); + for (int32_T b_i{0}; b_i < end; b_i++) { + c_loop_ub = mu2.size(0); + for (int32_T i1{0}; i1 < c_loop_ub; i1++) { + b_u[b_u.size(0) * b_i] = u[i + u.size(0) * b_i] - + mu2[mu2.size(0) * b_i]; + } + } + + coder::internal::blas::mtimes(r2, b_u, (real_T *)&VE1_tmp_data, + VE1_tmp_size); + } else { + c_binary_expand_op((real_T *)&VE1_tmp_data, VE1_tmp_size, r2, u, + i, mu2); + } + + coder::internal::blas::mtimes(VE2_data, VE2_size, (const real_T *) + &VE1_tmp_data, VE1_tmp_size, (real_T *)&b_tmp_data, b_tmp_size); + if (b_tmp_size[0] == 1) { + tmp_size_idx_0 = tmp_size[0]; + } else { + tmp_size_idx_0 = b_tmp_size[0]; + } + + if (b_tmp_size[1] == 1) { + tmp_size_idx_1 = tmp_size[1]; + c_loop_ub = tmp_size[1]; + } else { + tmp_size_idx_1 = b_tmp_size[1]; + c_loop_ub = b_tmp_size[1]; + } + + for (int32_T b_i{0}; b_i < c_loop_ub; b_i++) { + int32_T d_loop_ub; + if (b_tmp_size[0] == 1) { + d_loop_ub = tmp_size[0]; + } else { + d_loop_ub = b_tmp_size[0]; + } + + for (int32_T i1{0}; i1 < d_loop_ub; i1++) { + c_tmp_data = (tmp_data / VS1 < b_tmp_data / VS2); + } + } + + d_tmp_data.set(&c_tmp_data, tmp_size_idx_0, tmp_size_idx_1); + if (coder::internal::ifWhileCond(d_tmp_data)) { + m1++; + c_loop_ub = u.size(1); + for (int32_T b_i{0}; b_i < c_loop_ub; b_i++) { + u1new[(static_cast(m1) + u1new.size(0) * b_i) - 1] = + u[i + u.size(0) * b_i]; + } + + // check if point has been reassigned or not + if (idx[i] != 1.0) { + reassign = 1; + idx[i] = 1.0; + } + } else { + m2++; + c_loop_ub = u.size(1); + for (int32_T b_i{0}; b_i < c_loop_ub; b_i++) { + u2new[(static_cast(m2) + u2new.size(0) * b_i) - 1] = + u[i + u.size(0) * b_i]; + } + + // check if point has been reassigned or not + if (idx[i] != 2.0) { + reassign = 1; + idx[i] = 2.0; + } + } + } + + n1 = static_cast(m1); + n2 = static_cast(m2); + if (static_cast(m1) < 1) { + loop_ub = 0; + } else { + loop_ub = static_cast(m1); + } + + u1.set_size(loop_ub, u1new.size(1)); + b_loop_ub = u1new.size(1); + for (int32_T b_i{0}; b_i < b_loop_ub; b_i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + u1[i1 + u1.size(0) * b_i] = u1new[i1 + u1new.size(0) * b_i]; + } + } + + if (static_cast(m2) < 1) { + loop_ub = 0; + } else { + loop_ub = static_cast(m2); + } + + u2.set_size(loop_ub, u2new.size(1)); + b_loop_ub = u2new.size(1); + for (int32_T b_i{0}; b_i < b_loop_ub; b_i++) { + for (int32_T i1{0}; i1 < loop_ub; i1++) { + u2[i1 + u2.size(0) * b_i] = u2new[i1 + u2new.size(0) * b_i]; + } + } + + // update counter + counter++; + if ((reassign == 0) || (counter + 1 > 50)) { + // DEBUG print statement + // if DEBUG + // %fprintf('SPLIT ELLIPSOID: counter = %d, FS = %f, numreassigned = %d\n', counter, (VE1+VE2)/VS, numreassigned); + // if counter > max_attempt + // fprintf('SPLIT ELLIPSOID: exceeded maximum attempts; take min F(S).\n'); + // end + // end + exitg1 = 1; + } + } + } while (exitg1 == 0); + + // find minimum F(S) and return + coder::internal::minimum(FS, &minFS, &iindx); + u1.set_size(temp_u1_tmp[iindx - 1].f1.size(0), temp_u1_tmp[iindx - 1]. + f1.size(1)); + loop_ub = temp_u1_tmp[iindx - 1].f1.size(1); + for (int32_T b_i{0}; b_i < loop_ub; b_i++) { + b_loop_ub = temp_u1_tmp[iindx - 1].f1.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + u1[i1 + u1.size(0) * b_i] = temp_u1_tmp[iindx - 1].f1[i1 + + temp_u1_tmp[iindx - 1].f1.size(0) * b_i]; + } + } + + u2.set_size(temp_u2[iindx - 1].f1.size(0), temp_u2[iindx - 1].f1.size(1)); + loop_ub = temp_u2[iindx - 1].f1.size(1); + for (int32_T b_i{0}; b_i < loop_ub; b_i++) { + b_loop_ub = temp_u2[iindx - 1].f1.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + u2[i1 + u2.size(0) * b_i] = temp_u2[iindx - 1].f1[i1 + temp_u2[iindx + - 1].f1.size(0) * b_i]; + } + } + + VE1_size[0] = 1; + VE1_size[1] = 1; + VE1_data[0] = temp_VE1[iindx - 1]; + VE2_size[0] = 1; + VE2_size[1] = 1; + VE2_data[0] = temp_VE2[iindx - 1]; + if (DEBUG != 0.0) { + printf("SPLIT ELLIPSOID: min F(S) = %f\n", minFS); + fflush(stdout); + } + } + } + + *nosplit = b_nosplit; + } +} + +// End of code generation (splitEllipsoid.cpp) diff --git a/cpp/RAT/splitEllipsoid.h b/cpp/RAT/splitEllipsoid.h new file mode 100644 index 00000000..23c5f1f9 --- /dev/null +++ b/cpp/RAT/splitEllipsoid.h @@ -0,0 +1,30 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// splitEllipsoid.h +// +// Code generation for function 'splitEllipsoid' +// +#ifndef SPLITELLIPSOID_H +#define SPLITELLIPSOID_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void splitEllipsoid(const ::coder::array &u, real_T VS, ::coder:: + array &u1, ::coder::array &u2, + real_T VE1_data[], int32_T VE1_size[2], real_T VE2_data[], + int32_T VE2_size[2], real_T *nosplit); +} + +#endif + +// End of code generation (splitEllipsoid.h) diff --git a/cpp/RAT/sprintf.cpp b/cpp/RAT/sprintf.cpp new file mode 100644 index 00000000..524788c2 --- /dev/null +++ b/cpp/RAT/sprintf.cpp @@ -0,0 +1,73 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// sprintf.cpp +// +// Code generation for function 'sprintf' +// + +// Include files +#include "sprintf.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + void b_sprintf(real_T varargin_1, real_T varargin_2, ::coder::array &str) + { + int32_T nbytes; + nbytes = snprintf(nullptr, 0, + "Exiting - X satisfies termination criteria: TolX %e, TolF %e", + varargin_1, varargin_2); + str.set_size(1, nbytes + 1); + snprintf(&str[0], (size_t)(nbytes + 1), + "Exiting - X satisfies termination criteria: TolX %e, TolF %e", + varargin_1, varargin_2); + if (nbytes < 1) { + nbytes = 0; + } + + str.set_size(str.size(0), nbytes); + } + + void snPrint(real_T varargin_2, const ::coder::array &varargin_3, + ::coder::array &str) + { + ::coder::array b_varargin_3; + int32_T loop_ub; + int32_T nbytes; + b_varargin_3.set_size(1, varargin_3.size(1)); + loop_ub = varargin_3.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_varargin_3[i] = varargin_3[i]; + } + + nbytes = snprintf(nullptr, 0, "\n %s %5.1f%% %s", "DREAM: ", varargin_2, + &b_varargin_3[0]); + str.set_size(1, nbytes + 1); + b_varargin_3.set_size(1, varargin_3.size(1)); + loop_ub = varargin_3.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_varargin_3[i] = varargin_3[i]; + } + + snprintf(&str[0], (size_t)(nbytes + 1), "\n %s %5.1f%% %s", "DREAM: ", + varargin_2, &b_varargin_3[0]); + if (nbytes < 1) { + nbytes = 0; + } + + str.set_size(str.size(0), nbytes); + } + } +} + +// End of code generation (sprintf.cpp) diff --git a/cpp/RAT/sprintf.h b/cpp/RAT/sprintf.h new file mode 100644 index 00000000..cf1bcf69 --- /dev/null +++ b/cpp/RAT/sprintf.h @@ -0,0 +1,33 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// sprintf.h +// +// Code generation for function 'sprintf' +// +#ifndef SPRINTF_H +#define SPRINTF_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void b_sprintf(real_T varargin_1, real_T varargin_2, ::coder::array &str); + void snPrint(real_T varargin_2, const ::coder::array &varargin_3, + ::coder::array &str); + } +} + +#endif + +// End of code generation (sprintf.h) diff --git a/cpp/RAT/sqrt.cpp b/cpp/RAT/sqrt.cpp new file mode 100644 index 00000000..01dcb5b8 --- /dev/null +++ b/cpp/RAT/sqrt.cpp @@ -0,0 +1,104 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// sqrt.cpp +// +// Code generation for function 'sqrt' +// + +// Include files +#include "sqrt.h" +#include "RATMain_rtwutil.h" +#include "rt_nonfinite.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace scalar + { + void d_sqrt(creal_T *x) + { + real_T absxi; + real_T absxr; + real_T xi; + real_T xr; + xr = x->re; + xi = x->im; + if (xi == 0.0) { + if (xr < 0.0) { + absxr = 0.0; + absxi = std::sqrt(-xr); + } else { + absxr = std::sqrt(xr); + absxi = 0.0; + } + } else if (xr == 0.0) { + if (xi < 0.0) { + absxr = std::sqrt(-xi / 2.0); + absxi = -absxr; + } else { + absxr = std::sqrt(xi / 2.0); + absxi = absxr; + } + } else if (std::isnan(xr)) { + absxr = rtNaN; + absxi = rtNaN; + } else if (std::isnan(xi)) { + absxr = rtNaN; + absxi = rtNaN; + } else if (std::isinf(xi)) { + absxr = std::abs(xi); + absxi = xi; + } else if (std::isinf(xr)) { + if (xr < 0.0) { + absxr = 0.0; + absxi = xi * -xr; + } else { + absxr = xr; + absxi = 0.0; + } + } else { + absxr = std::abs(xr); + absxi = std::abs(xi); + if ((absxr > 4.4942328371557893E+307) || (absxi > + 4.4942328371557893E+307)) { + absxr *= 0.5; + absxi = rt_hypotd_snf(absxr, absxi * 0.5); + if (absxi > absxr) { + absxr = std::sqrt(absxi) * std::sqrt(absxr / absxi + 1.0); + } else { + absxr = std::sqrt(absxi) * 1.4142135623730951; + } + } else { + absxr = std::sqrt((rt_hypotd_snf(absxr, absxi) + absxr) * 0.5); + } + + if (xr > 0.0) { + absxi = 0.5 * (xi / absxr); + } else { + if (xi < 0.0) { + absxi = -absxr; + } else { + absxi = absxr; + } + + absxr = 0.5 * (xi / absxi); + } + } + + x->re = absxr; + x->im = absxi; + } + } + } + } +} + +// End of code generation (sqrt.cpp) diff --git a/cpp/RAT/sqrt.h b/cpp/RAT/sqrt.h new file mode 100644 index 00000000..3c640d1c --- /dev/null +++ b/cpp/RAT/sqrt.h @@ -0,0 +1,35 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// sqrt.h +// +// Code generation for function 'sqrt' +// +#ifndef SQRT_H +#define SQRT_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace scalar + { + void d_sqrt(creal_T *x); + } + } + } +} + +#endif + +// End of code generation (sqrt.h) diff --git a/cpp/RAT/sqrt1.cpp b/cpp/RAT/sqrt1.cpp new file mode 100644 index 00000000..4402a245 --- /dev/null +++ b/cpp/RAT/sqrt1.cpp @@ -0,0 +1,46 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// sqrt1.cpp +// +// Code generation for function 'sqrt1' +// + +// Include files +#include "sqrt1.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + void b_sqrt(::coder::array &x) + { + int32_T i; + i = x.size(1); + for (int32_T k{0}; k < i; k++) { + int32_T i1; + i1 = x.size(0); + for (int32_T b_k{0}; b_k < i1; b_k++) { + x[b_k + x.size(0) * k] = std::sqrt(x[b_k + x.size(0) * k]); + } + } + } + + void c_sqrt(::coder::array &x) + { + int32_T i; + i = x.size(1); + for (int32_T k{0}; k < i; k++) { + x[k] = std::sqrt(x[k]); + } + } + } +} + +// End of code generation (sqrt1.cpp) diff --git a/cpp/RAT/sqrt1.h b/cpp/RAT/sqrt1.h new file mode 100644 index 00000000..ded682bd --- /dev/null +++ b/cpp/RAT/sqrt1.h @@ -0,0 +1,31 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// sqrt1.h +// +// Code generation for function 'sqrt1' +// +#ifndef SQRT1_H +#define SQRT1_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void b_sqrt(::coder::array &x); + void c_sqrt(::coder::array &x); + } +} + +#endif + +// End of code generation (sqrt1.h) diff --git a/cpp/RAT/std.cpp b/cpp/RAT/std.cpp new file mode 100644 index 00000000..c8fd25e6 --- /dev/null +++ b/cpp/RAT/std.cpp @@ -0,0 +1,59 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// std.cpp +// +// Code generation for function 'std' +// + +// Include files +#include "std.h" +#include "rt_nonfinite.h" +#include "varstd.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + void b_std(const ::coder::array &x, ::coder::array + &y) + { + ::coder::array xv; + int32_T hi; + int32_T loop_ub; + int32_T nx; + int32_T outsize_idx_0; + y.set_size(1, x.size(1)); + hi = x.size(1); + for (int32_T k{0}; k < hi; k++) { + y[k] = 0.0; + } + + hi = x.size(1); + if (x.size(1) - 1 >= 0) { + nx = x.size(0); + outsize_idx_0 = x.size(0); + loop_ub = x.size(0); + } + + for (int32_T b_k{0}; b_k < hi; b_k++) { + xv.set_size(outsize_idx_0); + for (int32_T k{0}; k < loop_ub; k++) { + xv[k] = 0.0; + } + + for (int32_T k{0}; k < nx; k++) { + xv[k] = x[k + x.size(0) * b_k]; + } + + y[b_k] = varstd_anonFcn3(x.size(0), xv); + } + } + } +} + +// End of code generation (std.cpp) diff --git a/cpp/RAT/std.h b/cpp/RAT/std.h new file mode 100644 index 00000000..23ae5d28 --- /dev/null +++ b/cpp/RAT/std.h @@ -0,0 +1,31 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// std.h +// +// Code generation for function 'std' +// +#ifndef STD_H +#define STD_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void b_std(const ::coder::array &x, ::coder::array + &y); + } +} + +#endif + +// End of code generation (std.h) diff --git a/cpp/RAT/str2double.cpp b/cpp/RAT/str2double.cpp new file mode 100644 index 00000000..9234d0d5 --- /dev/null +++ b/cpp/RAT/str2double.cpp @@ -0,0 +1,98 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// str2double.cpp +// +// Code generation for function 'str2double' +// + +// Include files +#include "str2double.h" +#include "rt_nonfinite.h" +#include "str2double1.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + creal_T str2double(const char_T s_data[], const int32_T s_size[2]) + { + creal_T x; + real_T v1; + real_T v2; + int32_T idx; + int32_T k; + char_T s1_data[10002]; + boolean_T a__1; + boolean_T foundsign; + boolean_T isfinite1; + boolean_T isfinite2; + boolean_T isimag1; + boolean_T success; + x.re = rtNaN; + x.im = 0.0; + if (s_size[1] >= 1) { + int32_T ntoread; + ntoread = 0; + k = s_size[1] + 2; + std::memset(&s1_data[0], 0, static_cast(k) * sizeof(char_T)); + idx = 1; + k = internal::skipspaces(s_data, s_size[1]); + internal::readfloat(s1_data, &idx, s_data, &k, s_size[1], &isimag1, + &isfinite1, &v1, &a__1, &success); + if (isfinite1) { + ntoread = 1; + } + + if (success && (k <= s_size[1])) { + s1_data[idx - 1] = ' '; + idx++; + internal::readfloat(s1_data, &idx, s_data, &k, s_size[1], &a__1, + &isfinite2, &v2, &foundsign, &success); + if (isfinite2) { + ntoread++; + } + + if (success && (k > s_size[1]) && (isimag1 ^ a__1) && foundsign) { + success = true; + } else { + success = false; + } + } else { + v2 = 0.0; + } + + if (success) { + s1_data[idx - 1] = '\x00'; + if (ntoread == 2) { + internal::sscanfd(s1_data, &v1, &v2); + } else if (ntoread == 1) { + real_T a; + a = internal::sscanfd(s1_data); + if (isfinite1) { + v1 = a; + } else { + v2 = a; + } + } + + if (isimag1) { + x.re = v2; + x.im = v1; + } else { + x.re = v1; + x.im = v2; + } + } + } + + return x; + } + } +} + +// End of code generation (str2double.cpp) diff --git a/cpp/RAT/str2double.h b/cpp/RAT/str2double.h new file mode 100644 index 00000000..4f7fb9ea --- /dev/null +++ b/cpp/RAT/str2double.h @@ -0,0 +1,29 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// str2double.h +// +// Code generation for function 'str2double' +// +#ifndef STR2DOUBLE_H +#define STR2DOUBLE_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + creal_T str2double(const char_T s_data[], const int32_T s_size[2]); + } +} + +#endif + +// End of code generation (str2double.h) diff --git a/cpp/RAT/str2double1.cpp b/cpp/RAT/str2double1.cpp new file mode 100644 index 00000000..4ccb9d97 --- /dev/null +++ b/cpp/RAT/str2double1.cpp @@ -0,0 +1,478 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// str2double1.cpp +// +// Code generation for function 'str2double1' +// + +// Include files +#include "str2double1.h" +#include "rt_nonfinite.h" +#include + +// Variable Definitions +namespace RAT +{ + static const boolean_T bv[128]{ false, false, false, false, false, false, + false, false, false, true, true, true, true, true, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, + true, true, true, true, true, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, + false }; +} + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + static void b_copysign(char_T s1_data[], int32_T *idx, const char_T + s_data[], int32_T *k, int32_T n, boolean_T *foundsign, boolean_T + *success); + static void b_readNonFinite(const char_T s_data[], int32_T *k, int32_T n, + boolean_T *b_finite, real_T *fv); + static void b_readfloat(char_T s1_data[], int32_T *idx, const char_T + s_data[], int32_T *k, int32_T n, boolean_T *isimag, boolean_T *b_finite, + real_T *nfv, boolean_T *foundsign, boolean_T *success); + static boolean_T copydigits(char_T s1_data[], int32_T *idx, const char_T + s_data[], int32_T *k, int32_T n, boolean_T allowpoint); + static boolean_T copyexponent(char_T s1_data[], int32_T *idx, const char_T + s_data[], int32_T *k, int32_T n); + static boolean_T isUnitImag(const char_T s_data[], int32_T k, int32_T n); + static boolean_T readNonFinite(const char_T s_data[], int32_T k, int32_T n); + static void skipspaces(const char_T s_data[], int32_T *k, int32_T n); + } + } +} + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + static void b_copysign(char_T s1_data[], int32_T *idx, const char_T + s_data[], int32_T *k, int32_T n, boolean_T *foundsign, boolean_T + *success) + { + boolean_T exitg1; + boolean_T isneg; + isneg = false; + *foundsign = false; + exitg1 = false; + while ((!exitg1) && (*k <= n)) { + char_T c; + c = s_data[*k - 1]; + if (c == '-') { + isneg = !isneg; + *foundsign = true; + (*k)++; + } else if (c == ',') { + (*k)++; + } else if (c == '+') { + *foundsign = true; + (*k)++; + } else if (!bv[static_cast(c) & 127]) { + exitg1 = true; + } else { + (*k)++; + } + } + + *success = (*k <= n); + if ((*success) && isneg) { + if ((*idx >= 2) && (s1_data[*idx - 2] == '-')) { + s1_data[*idx - 2] = ' '; + } else { + s1_data[*idx - 1] = '-'; + (*idx)++; + } + } + } + + static void b_readNonFinite(const char_T s_data[], int32_T *k, int32_T n, + boolean_T *b_finite, real_T *fv) + { + int32_T ksaved; + char_T c_idx_0; + char_T c_idx_1; + char_T c_idx_2; + ksaved = *k; + c_idx_0 = '\x00'; + while ((*k <= n) && (s_data[*k - 1] == ',')) { + (*k)++; + } + + if (*k <= n) { + c_idx_0 = s_data[*k - 1]; + } + + (*k)++; + c_idx_1 = '\x00'; + while ((*k <= n) && (s_data[*k - 1] == ',')) { + (*k)++; + } + + if (*k <= n) { + c_idx_1 = s_data[*k - 1]; + } + + (*k)++; + c_idx_2 = '\x00'; + while ((*k <= n) && (s_data[*k - 1] == ',')) { + (*k)++; + } + + if (*k <= n) { + c_idx_2 = s_data[*k - 1]; + } + + (*k)++; + if (((c_idx_0 == 'I') || (c_idx_0 == 'i')) && ((c_idx_1 == 'N') || + (c_idx_1 == 'n')) && ((c_idx_2 == 'F') || (c_idx_2 == 'f'))) { + *b_finite = false; + *fv = rtInf; + } else if (((c_idx_0 == 'N') || (c_idx_0 == 'n')) && ((c_idx_1 == 'A') || + (c_idx_1 == 'a')) && ((c_idx_2 == 'N') || (c_idx_2 == 'n'))) + { + *b_finite = false; + *fv = rtNaN; + } else { + *b_finite = true; + *fv = 0.0; + *k = ksaved; + } + } + + static void b_readfloat(char_T s1_data[], int32_T *idx, const char_T + s_data[], int32_T *k, int32_T n, boolean_T *isimag, boolean_T *b_finite, + real_T *nfv, boolean_T *foundsign, boolean_T *success) + { + int32_T b_idx; + *isimag = false; + *b_finite = true; + *nfv = 0.0; + b_idx = *idx; + b_copysign(s1_data, &b_idx, s_data, k, n, foundsign, success); + *idx = b_idx; + if (*success) { + if (isUnitImag(s_data, *k, n)) { + *success = false; + } else { + b_readNonFinite(s_data, k, n, b_finite, nfv); + if (*b_finite) { + *success = copydigits(s1_data, idx, s_data, k, n, true); + if (*success) { + *success = copyexponent(s1_data, idx, s_data, k, n); + } + } else if ((b_idx >= 2) && (s1_data[b_idx - 2] == '-')) { + *idx = b_idx - 1; + s1_data[b_idx - 2] = ' '; + *nfv = -*nfv; + } + + skipspaces(s_data, k, n); + if ((*k <= n) && (s_data[*k - 1] == '*')) { + (*k)++; + skipspaces(s_data, k, n); + } + + if (*k <= n) { + char_T c; + c = s_data[*k - 1]; + if ((c == 'i') || (c == 'j')) { + (*k)++; + *isimag = true; + } + } + } + + skipspaces(s_data, k, n); + } + } + + static boolean_T copydigits(char_T s1_data[], int32_T *idx, const char_T + s_data[], int32_T *k, int32_T n, boolean_T allowpoint) + { + boolean_T exitg1; + boolean_T haspoint; + boolean_T success; + success = (*k <= n); + haspoint = false; + exitg1 = false; + while ((!exitg1) && (success && (*k <= n))) { + char_T c; + c = s_data[*k - 1]; + if ((c >= '0') && (c <= '9')) { + s1_data[*idx - 1] = c; + (*idx)++; + (*k)++; + } else if (c == '.') { + if (allowpoint && (!haspoint)) { + success = true; + } else { + success = false; + } + + if (success) { + s1_data[*idx - 1] = '.'; + (*idx)++; + haspoint = true; + } + + (*k)++; + } else if (c == ',') { + (*k)++; + } else { + exitg1 = true; + } + } + + return success; + } + + static boolean_T copyexponent(char_T s1_data[], int32_T *idx, const char_T + s_data[], int32_T *k, int32_T n) + { + boolean_T success; + success = true; + if (*k <= n) { + char_T c; + c = s_data[*k - 1]; + if ((c == 'E') || (c == 'e')) { + int32_T kexp; + boolean_T b_success; + s1_data[*idx - 1] = 'e'; + (*idx)++; + (*k)++; + while ((*k <= n) && (s_data[*k - 1] == ',')) { + (*k)++; + } + + if (*k <= n) { + if (s_data[*k - 1] == '-') { + s1_data[*idx - 1] = '-'; + (*idx)++; + (*k)++; + } else if (s_data[*k - 1] == '+') { + (*k)++; + } + } + + kexp = *k; + b_success = copydigits(s1_data, idx, s_data, k, n, false); + if ((!b_success) || (*k <= kexp)) { + success = false; + } + } + } + + return success; + } + + static boolean_T isUnitImag(const char_T s_data[], int32_T k, int32_T n) + { + boolean_T p; + p = false; + if (k <= n) { + char_T c; + c = s_data[k - 1]; + if (c == 'j') { + p = true; + } else if (c == 'i') { + if (k >= n - 1) { + p = true; + } else { + p = readNonFinite(s_data, k, n); + } + } + } + + return p; + } + + static boolean_T readNonFinite(const char_T s_data[], int32_T k, int32_T n) + { + int32_T b_k; + char_T c_idx_0; + char_T c_idx_1; + char_T c_idx_2; + boolean_T b_finite; + b_k = k; + c_idx_0 = '\x00'; + while ((b_k <= n) && (s_data[b_k - 1] == ',')) { + b_k++; + } + + if (b_k <= n) { + c_idx_0 = s_data[b_k - 1]; + } + + b_k++; + c_idx_1 = '\x00'; + while ((b_k <= n) && (s_data[b_k - 1] == ',')) { + b_k++; + } + + if (b_k <= n) { + c_idx_1 = s_data[b_k - 1]; + } + + b_k++; + c_idx_2 = '\x00'; + while ((b_k <= n) && (s_data[b_k - 1] == ',')) { + b_k++; + } + + if (b_k <= n) { + c_idx_2 = s_data[b_k - 1]; + } + + if (((c_idx_0 == 'I') || (c_idx_0 == 'i')) && ((c_idx_1 == 'N') || + (c_idx_1 == 'n')) && ((c_idx_2 == 'F') || (c_idx_2 == 'f'))) { + b_finite = false; + } else if (((c_idx_0 == 'N') || (c_idx_0 == 'n')) && ((c_idx_1 == 'A') || + (c_idx_1 == 'a')) && ((c_idx_2 == 'N') || (c_idx_2 == 'n'))) + { + b_finite = false; + } else { + b_finite = true; + } + + return b_finite; + } + + static void skipspaces(const char_T s_data[], int32_T *k, int32_T n) + { + boolean_T exitg1; + exitg1 = false; + while ((!exitg1) && (*k <= n)) { + char_T c; + c = s_data[*k - 1]; + if (bv[static_cast(c) & 127] || (c == '\x00') || (c == ',')) + { + (*k)++; + } else { + exitg1 = true; + } + } + } + + void readfloat(char_T s1_data[], int32_T *idx, const char_T s_data[], + int32_T *k, int32_T n, boolean_T *isimag, boolean_T + *b_finite, real_T *nfv, boolean_T *foundsign, boolean_T + *success) + { + int32_T b_idx; + boolean_T a__2; + boolean_T a__3; + *isimag = false; + *b_finite = true; + *nfv = 0.0; + b_idx = *idx; + b_copysign(s1_data, &b_idx, s_data, k, n, foundsign, success); + *idx = b_idx; + if (*success) { + if (isUnitImag(s_data, *k, n)) { + *isimag = true; + (*k)++; + skipspaces(s_data, k, n); + if ((*k <= n) && (s_data[*k - 1] == '*')) { + (*k)++; + b_readfloat(s1_data, idx, s_data, k, n, &a__2, b_finite, nfv, + &a__3, success); + } else { + s1_data[b_idx - 1] = '1'; + *idx = b_idx + 1; + } + } else { + b_readNonFinite(s_data, k, n, b_finite, nfv); + if (*b_finite) { + *success = copydigits(s1_data, idx, s_data, k, n, true); + if (*success) { + *success = copyexponent(s1_data, idx, s_data, k, n); + } + } else if ((b_idx >= 2) && (s1_data[b_idx - 2] == '-')) { + *idx = b_idx - 1; + s1_data[b_idx - 2] = ' '; + *nfv = -*nfv; + } + + skipspaces(s_data, k, n); + if ((*k <= n) && (s_data[*k - 1] == '*')) { + (*k)++; + skipspaces(s_data, k, n); + } + + if (*k <= n) { + char_T c; + c = s_data[*k - 1]; + if ((c == 'i') || (c == 'j')) { + (*k)++; + *isimag = true; + } + } + } + + skipspaces(s_data, k, n); + } + } + + int32_T skipspaces(const char_T s_data[], int32_T n) + { + int32_T k; + boolean_T exitg1; + k = 1; + exitg1 = false; + while ((!exitg1) && (k <= n)) { + char_T c; + c = s_data[k - 1]; + if (bv[static_cast(c) & 127] || (c == '\x00')) { + k++; + } else { + exitg1 = true; + } + } + + return k; + } + + real_T sscanfd(const char_T s_data[]) + { + real_T out1; + int32_T nread; + nread = sscanf(&s_data[0], "%lf", &out1); + if (nread != 1) { + out1 = rtNaN; + } + + return out1; + } + + void sscanfd(const char_T s_data[], real_T *out1, real_T *out2) + { + int32_T nread; + nread = sscanf(&s_data[0], "%lf %lf", out1, out2); + if (nread != 2) { + *out1 = rtNaN; + *out2 = rtNaN; + } + } + } + } +} + +// End of code generation (str2double1.cpp) diff --git a/cpp/RAT/str2double1.h b/cpp/RAT/str2double1.h new file mode 100644 index 00000000..ebe9877e --- /dev/null +++ b/cpp/RAT/str2double1.h @@ -0,0 +1,38 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// str2double1.h +// +// Code generation for function 'str2double1' +// +#ifndef STR2DOUBLE1_H +#define STR2DOUBLE1_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + void readfloat(char_T s1_data[], int32_T *idx, const char_T s_data[], + int32_T *k, int32_T n, boolean_T *isimag, boolean_T + *b_finite, real_T *nfv, boolean_T *foundsign, boolean_T + *success); + int32_T skipspaces(const char_T s_data[], int32_T n); + real_T sscanfd(const char_T s_data[]); + void sscanfd(const char_T s_data[], real_T *out1, real_T *out2); + } + } +} + +#endif + +// End of code generation (str2double1.h) diff --git a/cpp/RAT/strcmp.cpp b/cpp/RAT/strcmp.cpp new file mode 100644 index 00000000..62b501d4 --- /dev/null +++ b/cpp/RAT/strcmp.cpp @@ -0,0 +1,880 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// strcmp.cpp +// +// Code generation for function 'strcmp' +// + +// Include files +#include "strcmp.h" +#include "RATMain_data.h" +#include "RATMain_types.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + boolean_T ab_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + static const char_T b_cv[5]{ 'b', 'o', 'u', 'n', 'd' }; + + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 5) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 5) { + if (a_data[kstr] != b_cv[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T b_strcmp(const char_T a_data[], const int32_T a_size[2], const + char_T b[6]) + { + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 6) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 6) { + if (a_data[kstr] != b[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T b_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + static const char_T b_cv[7]{ 'd', 'o', 'm', 'a', 'i', 'n', 's' }; + + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 7) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 7) { + if (cv[static_cast(a_data[kstr]) & 127] != cv[ + static_cast(b_cv[kstr])]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T bb_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + static const char_T b_cv[4]{ 'f', 'o', 'l', 'd' }; + + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 4) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 4) { + if (a_data[kstr] != b_cv[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T c_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 9) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 9) { + if (a_data[kstr] != cv1[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T c_strcmp(const char_T a_data[], const int32_T a_size[2], const + char_T b[4]) + { + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 4) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 4) { + if (a_data[kstr] != b[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T d_strcmp(const char_T a_data[], const int32_T a_size[2], const + char_T b[3]) + { + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 3) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 3) { + if (a_data[kstr] != b[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T d_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + static const char_T b_cv[3]{ 'o', 'f', 'f' }; + + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 3) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 3) { + if (cv[static_cast(a_data[kstr]) & 127] != cv[ + static_cast(b_cv[kstr])]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T e_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + static const char_T b_cv[7]{ 's', 'i', 'm', 'p', 'l', 'e', 'x' }; + + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 7) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 7) { + if (a_data[kstr] != b_cv[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T e_strcmp(const char_T a_data[], const int32_T a_size[2], const + char_T b[5]) + { + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 5) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 5) { + if (a_data[kstr] != b[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T f_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + static const char_T b_cv[2]{ 'd', 'e' }; + + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 2) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 2) { + if (a_data[kstr] != b_cv[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T g_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + static const char_T b_cv[2]{ 'n', 's' }; + + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 2) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 2) { + if (a_data[kstr] != b_cv[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T h_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + static const char_T b_cv[5]{ 'd', 'r', 'e', 'a', 'm' }; + + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 5) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 5) { + if (a_data[kstr] != b_cv[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T i_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + static const char_T b_cv[13]{ 'n', 'o', 'n', ' ', 'p', 'o', 'l', 'a', + 'r', 'i', 's', 'e', 'd' }; + + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 13) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 13) { + if (a_data[kstr] != b_cv[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T j_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + static const char_T b_cv[7]{ 'd', 'o', 'm', 'a', 'i', 'n', 's' }; + + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 7) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 7) { + if (a_data[kstr] != b_cv[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T k_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + static const char_T b_cv[15]{ 's', 't', 'a', 'n', 'd', 'a', 'r', 'd', + ' ', 'l', 'a', 'y', 'e', 'r', 's' }; + + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 15) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 15) { + if (a_data[kstr] != b_cv[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T l_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + static const char_T b_cv[13]{ 'c', 'u', 's', 't', 'o', 'm', ' ', 'l', + 'a', 'y', 'e', 'r', 's' }; + + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 13) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 13) { + if (a_data[kstr] != b_cv[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T m_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + static const char_T b_cv[9]{ 'c', 'u', 's', 't', 'o', 'm', ' ', 'x', 'y' + }; + + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 9) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 9) { + if (a_data[kstr] != b_cv[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T n_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + static const char_T b_cv[6]{ 's', 'i', 'n', 'g', 'l', 'e' }; + + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 6) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 6) { + if (a_data[kstr] != b_cv[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T o_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + static const char_T b_cv[6]{ 'p', 'o', 'i', 'n', 't', 's' }; + + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 6) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 6) { + if (a_data[kstr] != b_cv[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T p_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + static const char_T b_cv[9]{ 'c', 'o', 'n', 't', 'r', 'a', 's', 't', 's' + }; + + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 9) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 9) { + if (a_data[kstr] != b_cv[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T q_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + static const char_T b_cv[13]{ 'a', 'i', 'r', '/', 's', 'u', 'b', 's', + 't', 'r', 'a', 't', 'e' }; + + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 13) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 13) { + if (cv[static_cast(a_data[kstr]) & 127] != cv[ + static_cast(b_cv[kstr])]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T r_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + static const char_T b_cv[3]{ 'o', 'f', 'f' }; + + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 3) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 3) { + if (a_data[kstr] != b_cv[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T s_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + static const char_T b_cv[4]{ 'i', 't', 'e', 'r' }; + + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 4) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 4) { + if (a_data[kstr] != b_cv[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T t_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + static const char_T b_cv[6]{ 'n', 'o', 't', 'i', 'f', 'y' }; + + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 6) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 6) { + if (a_data[kstr] != b_cv[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T u_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + static const char_T b_cv[5]{ 'f', 'i', 'n', 'a', 'l' }; + + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 5) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 5) { + if (a_data[kstr] != b_cv[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T v_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + static const char_T b_cv[6]{ 's', 'h', 'r', 'i', 'n', 'k' }; + + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 6) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 6) { + if (a_data[kstr] != b_cv[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + boolean_T w_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + static const char_T b_cv[4]{ 'i', 't', 'e', 'r' }; + + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 4) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 4) { + if (cv[static_cast(a_data[kstr]) & 127] != cv[ + static_cast(b_cv[kstr])]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + + void x_strcmp(const cell_wrap_1 *a, const ::coder::array + &b, ::coder::array &b_bool) + { + int32_T nb; + b_bool.set_size(b.size(0)); + nb = b.size(0); + for (int32_T k{0}; k < nb; k++) { + int32_T i; + boolean_T b_b; + b_bool[k] = false; + i = b[k].f1.size(1); + b_b = (a->f1.size(1) == 0); + if (b_b && (i == 0)) { + b_bool[k] = true; + } else if (a->f1.size(1) == i) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr <= i - 1) { + if (cv[static_cast(a->f1[kstr]) & 127] != cv[ + static_cast(b[k].f1[kstr]) & 127]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool[k] = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + } + } + + boolean_T y_strcmp(const char_T a_data[], const int32_T a_size[2]) + { + static const char_T b_cv[7]{ 'r', 'e', 'f', 'l', 'e', 'c', 't' }; + + boolean_T b_bool; + b_bool = false; + if (a_size[1] == 7) { + int32_T kstr; + kstr = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (kstr < 7) { + if (a_data[kstr] != b_cv[kstr]) { + exitg1 = 1; + } else { + kstr++; + } + } else { + b_bool = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } + + return b_bool; + } + } + } +} + +// End of code generation (strcmp.cpp) diff --git a/cpp/RAT/strcmp.h b/cpp/RAT/strcmp.h new file mode 100644 index 00000000..78d6f01a --- /dev/null +++ b/cpp/RAT/strcmp.h @@ -0,0 +1,68 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// strcmp.h +// +// Code generation for function 'strcmp' +// +#ifndef STRCMP_H +#define STRCMP_H + +// Include files +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + boolean_T ab_strcmp(const char_T a_data[], const int32_T a_size[2]); + boolean_T b_strcmp(const char_T a_data[], const int32_T a_size[2], const + char_T b[6]); + boolean_T b_strcmp(const char_T a_data[], const int32_T a_size[2]); + boolean_T bb_strcmp(const char_T a_data[], const int32_T a_size[2]); + boolean_T c_strcmp(const char_T a_data[], const int32_T a_size[2]); + boolean_T c_strcmp(const char_T a_data[], const int32_T a_size[2], const + char_T b[4]); + boolean_T d_strcmp(const char_T a_data[], const int32_T a_size[2], const + char_T b[3]); + boolean_T d_strcmp(const char_T a_data[], const int32_T a_size[2]); + boolean_T e_strcmp(const char_T a_data[], const int32_T a_size[2]); + boolean_T e_strcmp(const char_T a_data[], const int32_T a_size[2], const + char_T b[5]); + boolean_T f_strcmp(const char_T a_data[], const int32_T a_size[2]); + boolean_T g_strcmp(const char_T a_data[], const int32_T a_size[2]); + boolean_T h_strcmp(const char_T a_data[], const int32_T a_size[2]); + boolean_T i_strcmp(const char_T a_data[], const int32_T a_size[2]); + boolean_T j_strcmp(const char_T a_data[], const int32_T a_size[2]); + boolean_T k_strcmp(const char_T a_data[], const int32_T a_size[2]); + boolean_T l_strcmp(const char_T a_data[], const int32_T a_size[2]); + boolean_T m_strcmp(const char_T a_data[], const int32_T a_size[2]); + boolean_T n_strcmp(const char_T a_data[], const int32_T a_size[2]); + boolean_T o_strcmp(const char_T a_data[], const int32_T a_size[2]); + boolean_T p_strcmp(const char_T a_data[], const int32_T a_size[2]); + boolean_T q_strcmp(const char_T a_data[], const int32_T a_size[2]); + boolean_T r_strcmp(const char_T a_data[], const int32_T a_size[2]); + boolean_T s_strcmp(const char_T a_data[], const int32_T a_size[2]); + boolean_T t_strcmp(const char_T a_data[], const int32_T a_size[2]); + boolean_T u_strcmp(const char_T a_data[], const int32_T a_size[2]); + boolean_T v_strcmp(const char_T a_data[], const int32_T a_size[2]); + boolean_T w_strcmp(const char_T a_data[], const int32_T a_size[2]); + void x_strcmp(const cell_wrap_1 *a, const ::coder::array + &b, ::coder::array &b_bool); + boolean_T y_strcmp(const char_T a_data[], const int32_T a_size[2]); + } + } +} + +#endif + +// End of code generation (strcmp.h) diff --git a/cpp/RAT/structConstructorHelper.cpp b/cpp/RAT/structConstructorHelper.cpp new file mode 100644 index 00000000..f931a836 --- /dev/null +++ b/cpp/RAT/structConstructorHelper.cpp @@ -0,0 +1,109 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// structConstructorHelper.cpp +// +// Code generation for function 'structConstructorHelper' +// + +// Include files +#include "structConstructorHelper.h" +#include "RATMain_internal_types.h" +#include "RATMain_types.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + void structConstructorHelper(const cell_wrap_12 *varargin_2, const + cell_wrap_9 *varargin_4, const cell_wrap_12 *varargin_8, ::coder::array< + cell_wrap_8, 1U> &s_ref, ::coder::array &s_sld, real_T * + s_chi, ::coder::array &s_data) + { + int32_T loop_ub; + s_ref.set_size(varargin_2->f1.size(0)); + loop_ub = varargin_2->f1.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + s_ref[i] = varargin_2->f1[i]; + } + + s_sld.set_size(varargin_4->f1.size(0), varargin_4->f1.size(1)); + loop_ub = varargin_4->f1.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + int32_T b_loop_ub; + b_loop_ub = varargin_4->f1.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + s_sld[i1 + s_sld.size(0) * i] = varargin_4->f1[i1 + + varargin_4->f1.size(0) * i]; + } + } + + s_data.set_size(varargin_8->f1.size(0)); + loop_ub = varargin_8->f1.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + s_data[i] = varargin_8->f1[i]; + } + + *s_chi = 0.0; + } + + void structConstructorHelper(const cell_wrap_12 *varargin_2, const + cell_wrap_9 *varargin_4, const cell_wrap_12 *varargin_6, const + cell_wrap_9 *varargin_8, const cell_wrap_14 *varargin_10, ::coder::array< + cell_wrap_8, 1U> &s_refPredInts, ::coder::array + &s_sldPredInts, ::coder::array &s_refXdata, ::coder:: + array &s_sldXdata, real_T s_sampleChi_data[], int32_T + *s_sampleChi_size) + { + int32_T b_loop_ub; + int32_T loop_ub; + s_refPredInts.set_size(varargin_2->f1.size(0)); + loop_ub = varargin_2->f1.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + s_refPredInts[i] = varargin_2->f1[i]; + } + + s_sldPredInts.set_size(varargin_4->f1.size(0), varargin_4->f1.size(1)); + loop_ub = varargin_4->f1.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = varargin_4->f1.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + s_sldPredInts[i1 + s_sldPredInts.size(0) * i] = varargin_4->f1[i1 + + varargin_4->f1.size(0) * i]; + } + } + + s_refXdata.set_size(varargin_6->f1.size(0)); + loop_ub = varargin_6->f1.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + s_refXdata[i] = varargin_6->f1[i]; + } + + s_sldXdata.set_size(varargin_8->f1.size(0), varargin_8->f1.size(1)); + loop_ub = varargin_8->f1.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + b_loop_ub = varargin_8->f1.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + s_sldXdata[i1 + s_sldXdata.size(0) * i] = varargin_8->f1[i1 + + varargin_8->f1.size(0) * i]; + } + } + + *s_sampleChi_size = varargin_10->f1.size(0); + loop_ub = varargin_10->f1.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + s_sampleChi_data[i] = varargin_10->f1[i]; + } + } + } + } +} + +// End of code generation (structConstructorHelper.cpp) diff --git a/cpp/RAT/structConstructorHelper.h b/cpp/RAT/structConstructorHelper.h new file mode 100644 index 00000000..f8014177 --- /dev/null +++ b/cpp/RAT/structConstructorHelper.h @@ -0,0 +1,51 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// structConstructorHelper.h +// +// Code generation for function 'structConstructorHelper' +// +#ifndef STRUCTCONSTRUCTORHELPER_H +#define STRUCTCONSTRUCTORHELPER_H + +// Include files +#include "RATMain_types.h" +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct cell_wrap_12; + struct cell_wrap_14; +} + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + void structConstructorHelper(const cell_wrap_12 *varargin_2, const + cell_wrap_9 *varargin_4, const cell_wrap_12 *varargin_8, ::coder::array< + cell_wrap_8, 1U> &s_ref, ::coder::array &s_sld, real_T * + s_chi, ::coder::array &s_data); + void structConstructorHelper(const cell_wrap_12 *varargin_2, const + cell_wrap_9 *varargin_4, const cell_wrap_12 *varargin_6, const + cell_wrap_9 *varargin_8, const cell_wrap_14 *varargin_10, ::coder::array< + cell_wrap_8, 1U> &s_refPredInts, ::coder::array + &s_sldPredInts, ::coder::array &s_refXdata, ::coder:: + array &s_sldXdata, real_T s_sampleChi_data[], int32_T + *s_sampleChi_size); + } + } +} + +#endif + +// End of code generation (structConstructorHelper.h) diff --git a/cpp/RAT/sum.cpp b/cpp/RAT/sum.cpp new file mode 100644 index 00000000..a3ae1a5e --- /dev/null +++ b/cpp/RAT/sum.cpp @@ -0,0 +1,75 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// sum.cpp +// +// Code generation for function 'sum' +// + +// Include files +#include "sum.h" +#include "blockedSummation.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + void sum(const ::coder::array &x, ::coder::array &y) + { + if ((x.size(0) == 0) || (x.size(1) == 0)) { + int32_T loop_ub; + y.set_size(1, x.size(1)); + loop_ub = x.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + y[i] = 0.0; + } + } else { + nestedIter(x, x.size(0), y); + } + } + + creal_T sum(const ::coder::array &x) + { + creal_T y; + if (x.size(1) == 0) { + y.re = 0.0; + y.im = 0.0; + } else { + y = nestedIter(x, x.size(1)); + } + + return y; + } + + real_T sum(const ::coder::array &x) + { + real_T y; + if (x.size(1) == 0) { + y = 0.0; + } else { + y = nestedIter(x, x.size(1)); + } + + return y; + } + + real_T sum(const ::coder::array &x) + { + real_T y; + if (x.size(0) == 0) { + y = 0.0; + } else { + y = nestedIter(x, x.size(0)); + } + + return y; + } + } +} + +// End of code generation (sum.cpp) diff --git a/cpp/RAT/sum.h b/cpp/RAT/sum.h new file mode 100644 index 00000000..b8a0e338 --- /dev/null +++ b/cpp/RAT/sum.h @@ -0,0 +1,33 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// sum.h +// +// Code generation for function 'sum' +// +#ifndef SUM_H +#define SUM_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void sum(const ::coder::array &x, ::coder::array &y); + creal_T sum(const ::coder::array &x); + real_T sum(const ::coder::array &x); + real_T sum(const ::coder::array &x); + } +} + +#endif + +// End of code generation (sum.h) diff --git a/cpp/RAT/textProgressBar.cpp b/cpp/RAT/textProgressBar.cpp new file mode 100644 index 00000000..d844c995 --- /dev/null +++ b/cpp/RAT/textProgressBar.cpp @@ -0,0 +1,89 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// textProgressBar.cpp +// +// Code generation for function 'textProgressBar' +// + +// Include files +#include "textProgressBar.h" +#include "RATMain_data.h" +#include "repmat.h" +#include "rt_nonfinite.h" +#include "sprintf.h" +#include "coder_array.h" +#include +#include + +// Function Definitions +namespace RAT +{ + void lastNchar_not_empty_init() + { + lastNchar_not_empty = false; + } + + void textProgressBar(real_T pct) + { + ::coder::array progressmsg; + ::coder::array varargin_1; + ::coder::array varargin_2; + real_T nDots; + int32_T loop_ub; + if (!lastNchar_not_empty) { + lastNchar = 0.0; + lastNchar_not_empty = true; + } + + // curm = 'progress'; + nDots = std::floor(pct * 40.0); + coder::repmat(nDots, varargin_1); + coder::b_repmat(40.0 - nDots, varargin_2); + progressmsg.set_size(1, (varargin_1.size(1) + varargin_2.size(1)) + 2); + progressmsg[0] = '['; + loop_ub = varargin_1.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + progressmsg[i + 1] = varargin_1[i]; + } + + loop_ub = varargin_2.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + progressmsg[(i + varargin_1.size(1)) + 1] = varargin_2[i]; + } + + progressmsg[(varargin_1.size(1) + varargin_2.size(1)) + 1] = ']'; + + // progressmsg=[183-uint16((1:40)<=(pct*40)).*(183-'*') '']; + // %curmtxt=sprintf('% 9.3g\n',curm(1:min(end,20),1)); + varargin_1.set_size(1, progressmsg.size(1) + 1); + loop_ub = progressmsg.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + varargin_1[i] = progressmsg[i]; + } + + varargin_1[progressmsg.size(1)] = '\x00'; + coder::snPrint(pct * 100.0, varargin_1, progressmsg); + varargin_1.set_size(1, static_cast(lastNchar) + 1); + loop_ub = static_cast(lastNchar); + for (int32_T i{0}; i < loop_ub; i++) { + varargin_1[i] = '\x08'; + } + + varargin_1[static_cast(lastNchar)] = '\x00'; + varargin_2.set_size(1, progressmsg.size(1) + 1); + loop_ub = progressmsg.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + varargin_2[i] = progressmsg[i]; + } + + varargin_2[progressmsg.size(1)] = '\x00'; + printf("%s%s", &varargin_1[0], &varargin_2[0]); + fflush(stdout); + lastNchar = progressmsg.size(1); + } +} + +// End of code generation (textProgressBar.cpp) diff --git a/cpp/RAT/textProgressBar.h b/cpp/RAT/textProgressBar.h new file mode 100644 index 00000000..9ac452e2 --- /dev/null +++ b/cpp/RAT/textProgressBar.h @@ -0,0 +1,27 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// textProgressBar.h +// +// Code generation for function 'textProgressBar' +// +#ifndef TEXTPROGRESSBAR_H +#define TEXTPROGRESSBAR_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void lastNchar_not_empty_init(); + void textProgressBar(real_T pct); +} + +#endif + +// End of code generation (textProgressBar.h) diff --git a/cpp/RAT/tic.cpp b/cpp/RAT/tic.cpp new file mode 100644 index 00000000..4c0c2cb5 --- /dev/null +++ b/cpp/RAT/tic.cpp @@ -0,0 +1,37 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// tic.cpp +// +// Code generation for function 'tic' +// + +// Include files +#include "tic.h" +#include "RATMain_data.h" +#include "rt_nonfinite.h" +#include "timeKeeper.h" +#include "coder_posix_time.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + void tic() + { + coderTimespec b_timespec; + if (!freq_not_empty) { + freq_not_empty = true; + coderInitTimeFunctions(&freq); + } + + coderTimeClockGettimeMonotonic(&b_timespec, freq); + internal::time::impl::timeKeeper(b_timespec.tv_sec, b_timespec.tv_nsec); + } + } +} + +// End of code generation (tic.cpp) diff --git a/cpp/RAT/tic.h b/cpp/RAT/tic.h new file mode 100644 index 00000000..0189e9df --- /dev/null +++ b/cpp/RAT/tic.h @@ -0,0 +1,29 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// tic.h +// +// Code generation for function 'tic' +// +#ifndef TIC_H +#define TIC_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void tic(); + } +} + +#endif + +// End of code generation (tic.h) diff --git a/cpp/RAT/timeKeeper.cpp b/cpp/RAT/timeKeeper.cpp new file mode 100644 index 00000000..5af83d98 --- /dev/null +++ b/cpp/RAT/timeKeeper.cpp @@ -0,0 +1,62 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// timeKeeper.cpp +// +// Code generation for function 'timeKeeper' +// + +// Include files +#include "timeKeeper.h" +#include "getTime.h" +#include "rt_nonfinite.h" +#include "coder_posix_time.h" + +// Variable Definitions +namespace RAT +{ + static coderTimespec savedTime; + static boolean_T savedTime_not_empty; +} + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace time + { + namespace impl + { + void timeKeeper(real_T newTime_tv_sec, real_T newTime_tv_nsec) + { + if (!savedTime_not_empty) { + getTime(&savedTime.tv_sec, &savedTime.tv_nsec); + savedTime_not_empty = true; + } + + savedTime.tv_sec = newTime_tv_sec; + savedTime.tv_nsec = newTime_tv_nsec; + } + + void timeKeeper(real_T *outTime_tv_sec, real_T *outTime_tv_nsec) + { + *outTime_tv_sec = savedTime.tv_sec; + *outTime_tv_nsec = savedTime.tv_nsec; + } + } + } + } + } + + void savedTime_not_empty_init() + { + savedTime_not_empty = false; + } +} + +// End of code generation (timeKeeper.cpp) diff --git a/cpp/RAT/timeKeeper.h b/cpp/RAT/timeKeeper.h new file mode 100644 index 00000000..eb06a9de --- /dev/null +++ b/cpp/RAT/timeKeeper.h @@ -0,0 +1,41 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// timeKeeper.h +// +// Code generation for function 'timeKeeper' +// +#ifndef TIMEKEEPER_H +#define TIMEKEEPER_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace time + { + namespace impl + { + void timeKeeper(real_T newTime_tv_sec, real_T newTime_tv_nsec); + void timeKeeper(real_T *outTime_tv_sec, real_T *outTime_tv_nsec); + } + } + } + } + + void savedTime_not_empty_init(); +} + +#endif + +// End of code generation (timeKeeper.h) diff --git a/cpp/RAT/tmwtypes.h b/cpp/RAT/tmwtypes.h new file mode 100644 index 00000000..e7f52fc3 --- /dev/null +++ b/cpp/RAT/tmwtypes.h @@ -0,0 +1,888 @@ +/* + * Copyright 1984-2018 The MathWorks, Inc. + */ + +#if defined(_MSC_VER) +# pragma once +#endif +#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)) +# pragma once +#endif + +#ifndef tmwtypes_h +#define tmwtypes_h + +#ifndef __TMWTYPES__ +#define __TMWTYPES__ +/* + * File : tmwtypes.h + * Abstract: + * Data types for use with MATLAB/SIMULINK and the Real-Time Workshop. + * + * When compiling stand-alone model code, data types can be overridden + * via compiler switches. + * + * Define NO_FLOATS to eliminate reference to real_T, etc. + */ + +#ifdef MW_LIBTOOLING +#include "mwstdint.h" +#endif + +#include + +/* __STDC_VERSION__ version check below means "check for a C99 compiler". + + Visual Studio (checked on versions 2015 and 2017) does + not define __STDC_VERSION__, however it has stdbool.h available, + thus a separate check for _MSC_VER below. + */ +#if defined(__APPLE_CC__) \ + || (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) \ + || (defined(_MSC_VER) && (_MSC_VER >= 1900)) +#ifndef tmwtypes_do_not_include_stdbool +#include +#endif +#endif + +#define LOGICAL_IS_A_TYPE +#define SPARSE_GENERALIZATION + +#ifdef NO_FLOATS +# define double double_not_allowed +# define float float_not_allowed +#endif /*NO_FLOATS*/ + +#ifndef NO_FLOATS + +#ifndef __MWERKS__ +# ifdef __STDC__ +# include +# else +# ifndef FLT_MANT_DIG +# define FLT_MANT_DIG 24 +# endif +# ifndef DBL_MANT_DIG +# define DBL_MANT_DIG 53 +# endif +# endif +#endif + +#endif /*NO_FLOATS*/ + +/* + * The following data types cannot be overridden when building MEX files. + */ +#ifdef MATLAB_MEX_FILE +# undef CHARACTER_T +# undef INTEGER_T +# undef BOOLEAN_T +# undef REAL_T +# undef TIME_T +#endif + +/* + * The uchar_T, ushort_T and ulong_T types are needed for compilers which do + * not allow defines to be specified, at the command line, with spaces in them. + */ + +typedef unsigned char uchar_T; +typedef unsigned short ushort_T; +typedef unsigned long ulong_T; + +#if (defined(_MSC_VER) && _MSC_VER >= 1500) \ + || defined(__x86_64__) || defined(__LP64__) \ + || defined(__LCC64__) + +typedef unsigned long long ulonglong_T; +#endif + + + +/*=======================================================================* + * Fixed width word size data types: * + * int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers * + * uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers * + * real32_T, real64_T - 32 and 64 bit floating point numbers * + *=======================================================================*/ + +/* When used with Real Time Workshop generated code, this + * header file can be used with a variety of compilers. + * + * The compiler could be for an 8 bit embedded processor that + * only had 8 bits per integer and 16 bits per long. + * In that example, a 32 bit integer size is not even available. + * This header file should be robust to that. + * + * For the case of an 8 bit processor, the preprocessor + * may be limited to 16 bit math like its target. That limitation + * would mean that 32 bit comparisons can't be done accurately. + * To increase robustness to this, comparisons are done against + * smaller values first. An inaccurate 32 bit comparison isn't + * attempted if the 16 bit comparison has already succeeded. + * + * Limitations on preprocessor math can also be stricter than + * for the target. There are known cases where a compiler + * targeting processors with 64 bit longs can't do accurate + * preprocessor comparisons on more than 32 bits. + */ + +/* Determine the number of bits for int, long, short, and char. + * If one fails to be determined, set the number of bits to -1 + */ + +#ifndef TMW_BITS_PER_INT +# if INT_MAX == 0x7FL +# define TMW_BITS_PER_INT 8 +# elif INT_MAX == 0x7FFFL +# define TMW_BITS_PER_INT 16 +# elif INT_MAX == 0x7FFFFFFFL +# define TMW_BITS_PER_INT 32 +# else +# define TMW_BITS_PER_INT -1 +# endif +#endif + +#ifndef TMW_BITS_PER_LONG +# if LONG_MAX == 0x7FL +# define TMW_BITS_PER_LONG 8 +# elif LONG_MAX == 0x7FFFL +# define TMW_BITS_PER_LONG 16 +# elif LONG_MAX == 0x7FFFFFFFL +# define TMW_BITS_PER_LONG 32 +# else +# define TMW_BITS_PER_LONG -1 +# endif +#endif + +#ifndef TMW_BITS_PER_SHRT +# if SHRT_MAX == 0x7FL +# define TMW_BITS_PER_SHRT 8 +# elif SHRT_MAX == 0x7FFFL +# define TMW_BITS_PER_SHRT 16 +# elif SHRT_MAX == 0x7FFFFFFFL +# define TMW_BITS_PER_SHRT 32 +# else +# define TMW_BITS_PER_SHRT -1 +# endif +#endif + +#ifndef TMW_BITS_PER_SCHAR +# if SCHAR_MAX == 0x7FL +# define TMW_BITS_PER_SCHAR 8 +# elif SCHAR_MAX == 0x7FFFL +# define TMW_BITS_PER_SCHAR 16 +# elif SCHAR_MAX == 0x7FFFFFFFL +# define TMW_BITS_PER_SCHAR 32 +# else +# define TMW_BITS_PER_SCHAR -1 +# endif +#endif + +#ifndef TMW_CHAR_SIGNED +# if SCHAR_MAX == CHAR_MAX +# define TMW_CHAR_SIGNED 1 +# else +# define TMW_CHAR_SIGNED 0 +# endif +#endif + +/* It is common for one or more of the integer types + * to be the same size. For example, on many embedded + * processors, both shorts and ints are 16 bits. On + * processors used for workstations, it is quite common + * for both int and long to be 32 bits. + * When there is more than one choice for typdef'ing + * a portable type like int16_T or uint32_T, in + * concept, it should not matter which choice is made. + * However, some style guides and some code checking + * tools do identify and complain about seemingly + * irrelevant differences. For example, a code + * checking tool may complain about an implicit + * conversion from int to short even though both + * are 16 bits. To reduce these types of + * complaints, it is best to make int the + * preferred choice when more than one is available. + */ + +#ifndef INT8_T +# if defined(MW_LIBTOOLING) +# define INT8_T int8_t +# elif TMW_BITS_PER_INT == 8 +# define INT8_T int +# elif TMW_BITS_PER_LONG == 8 +# define INT8_T long +# elif TMW_BITS_PER_SCHAR == 8 +# define INT8_T signed char +# elif TMW_BITS_PER_SHRT == 8 +# define INT8_T short +# endif +#endif +#ifdef INT8_T + typedef INT8_T int8_T; +#endif + +#ifndef UINT8_T +# if defined(MW_LIBTOOLING) +# define UINT8_T uint8_t +# elif TMW_BITS_PER_INT == 8 +# define UINT8_T unsigned int +# elif TMW_BITS_PER_LONG == 8 +# define UINT8_T unsigned long +# elif TMW_BITS_PER_SCHAR == 8 +# define UINT8_T unsigned char +# elif TMW_BITS_PER_SHRT == 8 +# define UINT8_T unsigned short +# endif +#endif +#ifdef UINT8_T + typedef UINT8_T uint8_T; +#endif + + +#ifndef INT16_T +# if defined(MW_LIBTOOLING) +# define INT16_T int16_t +# elif TMW_BITS_PER_INT == 16 +# define INT16_T int +# elif TMW_BITS_PER_LONG == 16 +# define INT16_T long +# elif TMW_BITS_PER_SCHAR == 16 +# define INT16_T signed char +# elif TMW_BITS_PER_SHRT == 16 +# define INT16_T short +# endif +#endif +#ifdef INT16_T + typedef INT16_T int16_T; +#endif + + +#ifndef UINT16_T +# if defined(MW_LIBTOOLING) +# define UINT16_T uint16_t +# elif TMW_BITS_PER_INT == 16 +# define UINT16_T unsigned int +# elif TMW_BITS_PER_LONG == 16 +# define UINT16_T unsigned long +# elif TMW_BITS_PER_SCHAR == 16 +# define UINT16_T unsigned char +# elif TMW_BITS_PER_SHRT == 16 +# define UINT16_T unsigned short +# endif +#endif +#ifdef UINT16_T + typedef UINT16_T uint16_T; +#endif + + +#ifndef INT32_T +# if defined(MW_LIBTOOLING) +# define INT32_T int32_t +# elif TMW_BITS_PER_INT == 32 +# define INT32_T int +# elif TMW_BITS_PER_LONG == 32 +# define INT32_T long +# elif TMW_BITS_PER_SCHAR == 32 +# define INT32_T signed char +# elif TMW_BITS_PER_SHRT == 32 +# define INT32_T short +# endif +#endif +#ifdef INT32_T + typedef INT32_T int32_T; +#endif + + +#ifndef UINT32_T +# if defined(MW_LIBTOOLING) +# define UINT32_T uint32_t +# elif TMW_BITS_PER_INT == 32 +# define UINT32_T unsigned int +# elif TMW_BITS_PER_LONG == 32 +# define UINT32_T unsigned long +# elif TMW_BITS_PER_SCHAR == 32 +# define UINT32_T unsigned char +# elif TMW_BITS_PER_SHRT == 32 +# define UINT32_T unsigned short +# endif +#endif +#ifdef UINT32_T + typedef UINT32_T uint32_T; +#endif + +/* The following is used to emulate smaller integer types when only + * larger types are available. For example, compilers for TI C3x/C4x DSPs + * define char and short to be 32 bits, so 8 and 16 bits are not directly + * available. This target is commonly used with RTW rapid prototyping. + * Other DSPs define char to be 16 bits, so 8 bits is not directly + * available. + */ +#ifndef INT8_T +# ifdef INT16_T +# define INT8_T INT16_T + typedef INT8_T int8_T; +# else +# ifdef INT32_T +# define INT8_T INT32_T + typedef INT8_T int8_T; +# endif +# endif +#endif + +#ifndef UINT8_T +# ifdef UINT16_T +# define UINT8_T UINT16_T + typedef UINT8_T uint8_T; +# else +# ifdef UINT32_T +# define UINT8_T UINT32_T + typedef UINT8_T uint8_T; +# endif +# endif +#endif + +#ifndef INT16_T +# ifdef INT32_T +# define INT16_T INT32_T + typedef INT16_T int16_T; +# endif +#endif + +#ifndef UINT16_T +# ifdef UINT32_T +# define UINT16_T UINT32_T + typedef UINT16_T uint16_T; +# endif +#endif + + +#ifndef NO_FLOATS + +#ifndef REAL32_T +# ifndef __MWERKS__ +# if FLT_MANT_DIG >= 23 +# define REAL32_T float +# endif +# else +# define REAL32_T float +# endif +#endif +#ifdef REAL32_T + typedef REAL32_T real32_T; +#endif + + +#ifndef REAL64_T +# ifndef __MWERKS__ +# if DBL_MANT_DIG >= 52 +# define REAL64_T double +# endif +# else +# define REAL64_T double +# endif +#endif +#ifdef REAL64_T + typedef REAL64_T real64_T; +#endif + +#endif /* NO_FLOATS*/ + +/*=======================================================================* + * Fixed width word size data types: * + * int64_T - signed 64 bit integers * + * uint64_T - unsigned 64 bit integers * + *=======================================================================*/ + +# if defined(MW_LIBTOOLING) +# ifdef INT64_T +# undef INT64_T +# endif +# define INT64_T int64_t +# ifdef UINT64_T +# undef UINT64_T +# endif +# define UINT64_T uint64_t +# endif +#if !defined(INT64_T) || !defined(UINT64_T) || !defined(FMT64) +# if defined(__APPLE__) || defined(__clang__) +# ifndef INT64_T +# define INT64_T long long +# endif +# ifndef UINT64_T +# define UINT64_T unsigned long long +# endif +# ifndef FMT64 +# define FMT64 "ll" +# endif +# if defined(__LP64__) && !defined(INT_TYPE_64_IS_LONG) +# define INT_TYPE_64_IS_LONG +# endif +# elif (defined(__x86_64__) || defined(__LP64__))&& !defined(__MINGW64__) +# ifndef INT64_T +# define INT64_T long +# endif +# ifndef UINT64_T +# define UINT64_T unsigned long +# endif +# ifndef FMT64 +# define FMT64 "l" +# endif +# if !defined(INT_TYPE_64_IS_LONG) +# define INT_TYPE_64_IS_LONG +# endif +# elif defined(_MSC_VER) || (defined(__BORLANDC__) && __BORLANDC__ >= 0x530) \ + || (defined(__WATCOMC__) && __WATCOMC__ >= 1100) +# ifndef INT64_T +# define INT64_T __int64 +# endif +# ifndef UINT64_T +# define UINT64_T unsigned __int64 +# endif +# ifndef FMT64 +# define FMT64 "I64" +# endif +# elif defined(__GNUC__) || defined(TMW_ENABLE_INT64) \ + || defined(__LCC64__) +# ifndef INT64_T +# define INT64_T long long +# endif +# ifndef UINT64_T +# define UINT64_T unsigned long long +# endif +# ifndef FMT64 +# define FMT64 "ll" +# endif +# endif + +#endif + +#if defined(INT64_T) +# if defined(__GNUC__) && \ + ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >=9))) + __extension__ +# endif + typedef INT64_T int64_T; +#endif + +#if defined(_WIN64) || (defined(__APPLE__) && defined(__LP64__)) \ + || defined(__x86_64__) \ + || defined(__LP64__) +# define INT_TYPE_64_IS_SUPPORTED +#endif + +#if defined(UINT64_T) +# if defined(__GNUC__) && \ + ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >=9))) + __extension__ +# endif + typedef UINT64_T uint64_T; +#endif + +/*===========================================================================* + * Format string modifiers for using size_t variables in printf statements. * + *===========================================================================*/ + +#ifndef FMT_SIZE_T +# if (defined( __GNUC__ ) || defined(_STDC_C99))&& !defined(__MINGW64__) +# define FMT_SIZE_T "z" +# elif defined (__WATCOMC__) +# define FMT_SIZE_T "l" +# elif defined (_WIN32 ) +# define FMT_SIZE_T "I" +# else +# define FMT_SIZE_T "l" +# endif +#endif + +#ifndef FMT_PTRDIFF_T +# if defined(__APPLE__) +# define FMT_PTRDIFF_T "l" +# elif defined( __GNUC__ ) || defined(_STDC_C99) +# define FMT_PTRDIFF_T "t" +# elif defined (__WATCOMC__) +# define FMT_PTRDIFF_T "l" +# elif defined (_WIN32 ) +# define FMT_PTRDIFF_T "I" +# else +# define FMT_PTRDIFF_T "l" +# endif +#endif + +/*===========================================================================* + * General or logical data types where the word size is not guaranteed. * + * real_T - possible settings include real32_T or real64_T * + * time_T - possible settings include real32_T or real64_T * + * boolean_T * + * char_T * + * int_T * + * uint_T * + * byte_T * + *===========================================================================*/ + +#ifndef NO_FLOATS + +#ifndef REAL_T +# ifdef REAL64_T +# define REAL_T real64_T +# else +# ifdef REAL32_T +# define REAL_T real32_T +# endif +# endif +#endif +#ifdef REAL_T + typedef REAL_T real_T; +#endif + +#ifndef TIME_T +# ifdef REAL_T +# define TIME_T real_T +# endif +#endif +#ifdef TIME_T + typedef TIME_T time_T; +#endif + +#endif /* NO_FLOATS */ + +#ifndef BOOLEAN_T +# if defined(UINT8_T) +# define BOOLEAN_T UINT8_T +# else +# define BOOLEAN_T unsigned int +# endif +#endif +typedef BOOLEAN_T boolean_T; + + +#ifndef CHARACTER_T +# define CHARACTER_T char +#endif +typedef CHARACTER_T char_T; + + +#ifndef INTEGER_T +# define INTEGER_T int +#endif +typedef INTEGER_T int_T; + + +#ifndef UINTEGER_T +# define UINTEGER_T unsigned +#endif +typedef UINTEGER_T uint_T; + + +#ifndef BYTE_T +# define BYTE_T unsigned char +#endif +typedef BYTE_T byte_T; + + +/*===========================================================================* + * Define Complex Structures * + *===========================================================================*/ +#ifndef NO_FLOATS + +#ifndef CREAL32_T +# ifdef REAL32_T + typedef struct { + real32_T re, im; + } creal32_T; +# define CREAL32_T creal32_T +# endif +#endif + +#ifndef CREAL64_T +# ifdef REAL64_T + typedef struct { + real64_T re, im; + } creal64_T; +# define CREAL64_T creal64_T +# endif +#endif + +#ifndef CREAL_T +# ifdef REAL_T + typedef struct { + real_T re, im; + } creal_T; +# define CREAL_T creal_T +# endif +#endif + +#endif /* NO_FLOATS */ + +#ifndef CINT8_T +# ifdef INT8_T + typedef struct { + int8_T re, im; + } cint8_T; +# define CINT8_T cint8_T +# endif +#endif + +#ifndef CUINT8_T +# ifdef UINT8_T + typedef struct { + uint8_T re, im; + } cuint8_T; +# define CUINT8_T cuint8_T +# endif +#endif + +#ifndef CINT16_T +# ifdef INT16_T + typedef struct { + int16_T re, im; + } cint16_T; +# define CINT16_T cint16_T +# endif +#endif + +#ifndef CUINT16_T +# ifdef UINT16_T + typedef struct { + uint16_T re, im; + } cuint16_T; +# define CUINT16_T cuint16_T +# endif +#endif + +#ifndef CINT32_T +# ifdef INT32_T + typedef struct { + int32_T re, im; + } cint32_T; +# define CINT32_T cint32_T +# endif +#endif + +#ifndef CUINT32_T +# ifdef UINT32_T + typedef struct { + uint32_T re, im; + } cuint32_T; +# define CUINT32_T cuint32_T +# endif +#endif + +#ifndef CINT64_T +# ifdef INT64_T + typedef struct { + int64_T re, im; + } cint64_T; +# define CINT64_T cint64_T +# endif +#endif + +#ifndef CUINT64_T +# ifdef UINT64_T + typedef struct { + uint64_T re, im; + } cuint64_T; +# define CUINT64_T cuint64_T +# endif +#endif + +/*=======================================================================* + * Min and Max: * + * int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers * + * uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers * + *=======================================================================*/ + +#define MAX_int8_T ((int8_T)(127)) /* 127 */ +#define MIN_int8_T ((int8_T)(-128)) /* -128 */ +#define MAX_uint8_T ((uint8_T)(255)) /* 255 */ +#define MIN_uint8_T ((uint8_T)(0)) + +#define MAX_int16_T ((int16_T)(32767)) /* 32767 */ +#define MIN_int16_T ((int16_T)(-32768)) /* -32768 */ +#define MAX_uint16_T ((uint16_T)(65535)) /* 65535 */ +#define MIN_uint16_T ((uint16_T)(0)) + +#define MAX_int32_T ((int32_T)(2147483647)) /* 2147483647 */ +#define MIN_int32_T ((int32_T)(-2147483647-1)) /* -2147483648 */ +#define MAX_uint32_T ((uint32_T)(0xFFFFFFFFU)) /* 4294967295 */ +#define MIN_uint32_T ((uint32_T)(0)) + +#if defined(_MSC_VER) || (defined(__BORLANDC__) && __BORLANDC__ >= 0x530) \ + || (defined(__WATCOMC__) && __WATCOMC__ >= 1100) \ + || defined(__LCC64__) +# ifdef INT64_T +# define MAX_int64_T ((int64_T)(9223372036854775807LL)) +# define MIN_int64_T ((int64_T)(-9223372036854775807LL-1LL)) +# endif +# ifdef UINT64_T +# define MAX_uint64_T ((uint64_T)(0xFFFFFFFFFFFFFFFFULL)) +# define MIN_uint64_T ((uint64_T)(0)) +# endif +#else +# ifdef INT64_T +# ifdef INT_TYPE_64_IS_LONG +# define MAX_int64_T ((int64_T)(9223372036854775807L)) +# define MIN_int64_T ((int64_T)(-9223372036854775807L-1L)) +# else +# define MAX_int64_T ((int64_T)(9223372036854775807LL)) +# define MIN_int64_T ((int64_T)(-9223372036854775807LL-1LL)) +# endif +# endif +# ifdef UINT64_T +# ifdef INT_TYPE_64_IS_LONG +# define MAX_uint64_T ((uint64_T)(0xFFFFFFFFFFFFFFFFUL)) +# define MIN_uint64_T ((uint64_T)(0)) +# else +# define MAX_uint64_T ((uint64_T)(0xFFFFFFFFFFFFFFFFULL)) +# define MIN_uint64_T ((uint64_T)(0)) +# endif +# endif +#endif + +#if (defined(_MSC_VER) && !defined(__clang__)) + +/* Conversion from unsigned __int64 to double is not implemented in Visual Studio + * and results in a compile error, thus the value must first be cast to + * signed __int64, and then to double. + * + * If the 64 bit int value is greater than 2^63-1, which is the signed int64 max, + * the macro below provides a workaround for casting a uint64 value to a double + * in windows. + */ +# define uint64_to_double(u) ( ((u) > _I64_MAX) ? \ + (double)(__int64)((u) - _I64_MAX - 1) + (double)_I64_MAX + 1: \ + (double)(__int64)(u) ) + +/* The following inline function should only be used in the macro double_to_uint64, + * as it only handles the specfic range of double between 2^63 and 2^64-1 */ +__forceinline +uint64_T double_to_uint64_helper(double d) { + union double_to_uint64_union_type { + double dd; + uint64_T i64; + } di; + di.dd = d; + return (((di.i64 & 0x000fffffffffffff) | 0x0010000000000000) << 11); +} + +/* The largest double value that can be cast to uint64 in windows is the + * signed int64 max, which is 2^63-1. The macro below provides + * a workaround for casting large double values to uint64 in windows. + */ +/* The magic number 18446744073709551616.0 is 2^64 */ +/* The magic number 9223372036854775808.0 is 2^63 */ +# define double_to_uint64(d) ( ((d) >= 18446744073709551616.0) ? \ + 0xffffffffffffffffULL : \ + ((d) >= 0.0) ? \ + ((d) >= 9223372036854775808.0) ? \ + double_to_uint64_helper(d) : \ + (unsigned __int64)(d) : \ + 0ULL ) +#else +# define uint64_to_double(u) ((double)(u)) +# if defined(__BORLANDC__) || defined(__WATCOMC__) || defined(__TICCSC__) +/* double_to_uint64 defined only for MSVC and UNIX */ +# else +# define double_to_uint64(d) ( ((d) >= 18446744073709551616.0) ? \ + (unsigned long long) 0xffffffffffffffffULL : \ + ((d) >= 0) ? (unsigned long long)(d) : (unsigned long long) 0 ) +# endif +#endif + +#if !defined(__cplusplus) && !defined(__bool_true_false_are_defined) + +#ifndef _bool_T +#define _bool_T + +typedef boolean_T bool; + +#ifndef false +#define false (0) +#endif +#ifndef true +#define true (1) +#endif + +#endif /* _bool_T */ + +#endif /* !__cplusplus */ + +/* + * This software assumes that the code is being compiled on a target using a + * 2's complement representation for signed integer values. + */ +#if ((SCHAR_MIN + 1) != -SCHAR_MAX) +#error "This code must be compiled using a 2's complement representation for signed integer values" +#endif + +/* + * Maximum length of a MATLAB identifier (function/variable/model) + * including the null-termination character. + */ +#define TMW_NAME_LENGTH_MAX 64 + +/* + * Maximum values for indices and dimensions + */ +#include + +#ifdef MX_COMPAT_32 +typedef int mwSize; +typedef int mwIndex; +typedef int mwSignedIndex; +#else +typedef size_t mwSize; /* unsigned pointer-width integer */ +typedef size_t mwIndex; /* unsigned pointer-width integer */ +typedef ptrdiff_t mwSignedIndex; /* a signed pointer-width integer */ +#endif + + /* for the individual dim */ +/* If updating SLSize or SLIndex, update defintions in sl_types_def.h + as well. */ +#ifndef SLSIZE_SLINDEX + #define SLSIZE_SLINDEX + #ifdef INT_TYPE_64_IS_SUPPORTED + typedef int64_T SLIndex; + typedef int64_T SLSize; + #else + typedef int SLIndex; + typedef int SLSize; + #endif +#endif + +/* for the total size */ +#define SLIndexType size_t +#define INVALID_SIZET_VALUE (std::numeric_limits::max()) +#define MAX_VALID_SIZET_VALUE (std::numeric_limits::max() -1) + + +#if (defined(_LP64) || defined(_WIN64)) && !defined(MX_COMPAT_32) +/* Currently 2^48 based on hardware limitations */ +# define MWSIZE_MAX 281474976710655UL +# define MWINDEX_MAX 281474976710655UL +# define MWSINDEX_MAX 281474976710655L +# define MWSINDEX_MIN -281474976710655L +#else +# define MWSIZE_MAX 2147483647UL +# define MWINDEX_MAX 2147483647UL +# define MWSINDEX_MAX 2147483647L +# define MWSINDEX_MIN -2147483647L +#endif +#define MWSIZE_MIN 0UL +#define MWINDEX_MIN 0UL + +/** UTF-16 character type */ + +#if (defined(__cplusplus) && (__cplusplus >= 201103L)) || (defined(_HAS_CHAR16_T_LANGUAGE_SUPPORT) && _HAS_CHAR16_T_LANGUAGE_SUPPORT) +typedef char16_t CHAR16_T; +#define U16_STRING_LITERAL_PREFIX u +#elif defined(_MSC_VER) +typedef wchar_t CHAR16_T; +#define U16_STRING_LITERAL_PREFIX L +#else +typedef UINT16_T CHAR16_T; +#endif + +#endif /* __TMWTYPES__ */ + +#endif /* tmwtypes_h */ diff --git a/cpp/RAT/toc.cpp b/cpp/RAT/toc.cpp new file mode 100644 index 00000000..fd472805 --- /dev/null +++ b/cpp/RAT/toc.cpp @@ -0,0 +1,36 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// toc.cpp +// +// Code generation for function 'toc' +// + +// Include files +#include "toc.h" +#include "getTime.h" +#include "rt_nonfinite.h" +#include "timeKeeper.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + real_T toc() + { + real_T tnow_tv_nsec; + real_T tnow_tv_sec; + real_T tstart_tv_nsec; + real_T tstart_tv_sec; + internal::time::impl::timeKeeper(&tstart_tv_sec, &tstart_tv_nsec); + internal::time::getTime(&tnow_tv_sec, &tnow_tv_nsec); + return (tnow_tv_sec - tstart_tv_sec) + (tnow_tv_nsec - tstart_tv_nsec) / + 1.0E+9; + } + } +} + +// End of code generation (toc.cpp) diff --git a/cpp/RAT/toc.h b/cpp/RAT/toc.h new file mode 100644 index 00000000..3eef1cb6 --- /dev/null +++ b/cpp/RAT/toc.h @@ -0,0 +1,29 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// toc.h +// +// Code generation for function 'toc' +// +#ifndef TOC_H +#define TOC_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + real_T toc(); + } +} + +#endif + +// End of code generation (toc.h) diff --git a/cpp/RAT/triggerEvent.cpp b/cpp/RAT/triggerEvent.cpp new file mode 100644 index 00000000..58796a40 --- /dev/null +++ b/cpp/RAT/triggerEvent.cpp @@ -0,0 +1,462 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// triggerEvent.cpp +// +// Code generation for function 'triggerEvent' +// + +// Include files +#include "triggerEvent.h" +#include "RATMain_types.h" +#include "getenv.h" +#include "rt_nonfinite.h" +#include "strcmp.h" +#include "coder_array.h" +#include "eventHelper.hpp" +#include +#include + +// Variable Definitions +namespace RAT +{ + static boolean_T notified; + static boolean_T helper_not_empty; +} + +// Function Declarations +namespace RAT +{ + static void b_packCellArray(const ::coder::array &cellArray, :: + coder::array &packedArray, ::coder::array &counts); + static void c_packCellArray(const ::coder::array &cellArray, :: + coder::array &packedArray, ::coder::array &counts); + static void d_packCellArray(const ::coder::array &cellArray, :: + coder::array &packedArray, ::coder::array &counts); + static void e_packCellArray(const ::coder::array &cellArray, :: + coder::array &packedArray, ::coder::array &counts); + static void packCellArray(const ::coder::array &cellArray, :: + coder::array &packedArray, ::coder::array &counts); +} + +// Function Definitions +namespace RAT +{ + static void b_packCellArray(const ::coder::array &cellArray, :: + coder::array &packedArray, ::coder::array &counts) + { + real_T rowSize; + real_T start; + int32_T b_rowSize; + int32_T i; + + // Packs a specified column of a cell array with different sized arrays into a + // single row array and an array of counts for each cell. For the example below + // reflect will be [1, 2, 3, 4, 5, 6, 7] and nReflect will be [3, 4] + // + // [reflect, nReflect] = packCellArray({[1; 2; 3], [4; 5; 6; 7]}, 1); + rowSize = 0.0; + counts.set_size(cellArray.size(0)); + i = cellArray.size(0); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T d; + d = static_cast(cellArray[b_i].f1.size(0)) * 3.0; + counts[b_i] = d; + rowSize += d; + } + + b_rowSize = static_cast(rowSize); + packedArray.set_size(b_rowSize); + for (i = 0; i < b_rowSize; i++) { + packedArray[i] = 0.0; + } + + start = 1.0; + i = cellArray.size(0); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T stop; + int32_T i1; + stop = start + counts[b_i]; + if (start > stop - 1.0) { + i1 = 1; + } else { + i1 = static_cast(start); + } + + b_rowSize = cellArray[b_i].f1.size(0) * 3; + for (int32_T i2{0}; i2 < b_rowSize; i2++) { + packedArray[(i1 + i2) - 1] = cellArray[b_i].f1[i2]; + } + + start = stop; + } + } + + static void c_packCellArray(const ::coder::array &cellArray, :: + coder::array &packedArray, ::coder::array &counts) + { + real_T rowSize; + real_T start; + int32_T b_rowSize; + int32_T i; + + // Packs a specified column of a cell array with different sized arrays into a + // single row array and an array of counts for each cell. For the example below + // reflect will be [1, 2, 3, 4, 5, 6, 7] and nReflect will be [3, 4] + // + // [reflect, nReflect] = packCellArray({[1; 2; 3], [4; 5; 6; 7]}, 1); + rowSize = 0.0; + counts.set_size(cellArray.size(0)); + i = cellArray.size(0); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T d; + d = static_cast(cellArray[b_i].f1.size(0)) * static_cast + (cellArray[b_i].f1.size(1)); + counts[b_i] = d; + rowSize += d; + } + + b_rowSize = static_cast(rowSize); + packedArray.set_size(b_rowSize); + for (i = 0; i < b_rowSize; i++) { + packedArray[i] = 0.0; + } + + start = 1.0; + i = cellArray.size(0); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T stop; + int32_T i1; + stop = start + counts[b_i]; + if (start > stop - 1.0) { + i1 = 1; + } else { + i1 = static_cast(start); + } + + b_rowSize = cellArray[b_i].f1.size(0) * cellArray[b_i].f1.size(1); + for (int32_T i2{0}; i2 < b_rowSize; i2++) { + packedArray[(i1 + i2) - 1] = cellArray[b_i].f1[i2]; + } + + start = stop; + } + } + + static void d_packCellArray(const ::coder::array &cellArray, :: + coder::array &packedArray, ::coder::array &counts) + { + real_T rowSize; + real_T start; + int32_T b_rowSize; + int32_T i; + + // Packs a specified column of a cell array with different sized arrays into a + // single row array and an array of counts for each cell. For the example below + // reflect will be [1, 2, 3, 4, 5, 6, 7] and nReflect will be [3, 4] + // + // [reflect, nReflect] = packCellArray({[1; 2; 3], [4; 5; 6; 7]}, 1); + rowSize = 0.0; + counts.set_size(cellArray.size(0)); + i = cellArray.size(0); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T d; + d = static_cast(cellArray[b_i + cellArray.size(0)].f1.size(0)) * + static_cast(cellArray[b_i + cellArray.size(0)].f1.size(1)); + counts[b_i] = d; + rowSize += d; + } + + b_rowSize = static_cast(rowSize); + packedArray.set_size(b_rowSize); + for (i = 0; i < b_rowSize; i++) { + packedArray[i] = 0.0; + } + + start = 1.0; + i = cellArray.size(0); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T stop; + int32_T i1; + stop = start + counts[b_i]; + if (start > stop - 1.0) { + i1 = 1; + } else { + i1 = static_cast(start); + } + + b_rowSize = cellArray[b_i + cellArray.size(0)].f1.size(0) * cellArray[b_i + + cellArray.size(0)].f1.size(1); + for (int32_T i2{0}; i2 < b_rowSize; i2++) { + packedArray[(i1 + i2) - 1] = cellArray[b_i + cellArray.size(0)].f1[i2]; + } + + start = stop; + } + } + + static void e_packCellArray(const ::coder::array &cellArray, :: + coder::array &packedArray, ::coder::array &counts) + { + real_T rowSize; + real_T start; + int32_T b_rowSize; + int32_T i; + + // Packs a specified column of a cell array with different sized arrays into a + // single row array and an array of counts for each cell. For the example below + // reflect will be [1, 2, 3, 4, 5, 6, 7] and nReflect will be [3, 4] + // + // [reflect, nReflect] = packCellArray({[1; 2; 3], [4; 5; 6; 7]}, 1); + rowSize = 0.0; + counts.set_size(cellArray.size(0)); + i = cellArray.size(0); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T d; + d = static_cast(cellArray[b_i + cellArray.size(0)].f1.size(0)) * + 3.0; + counts[b_i] = d; + rowSize += d; + } + + b_rowSize = static_cast(rowSize); + packedArray.set_size(b_rowSize); + for (i = 0; i < b_rowSize; i++) { + packedArray[i] = 0.0; + } + + start = 1.0; + i = cellArray.size(0); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T stop; + int32_T i1; + stop = start + counts[b_i]; + if (start > stop - 1.0) { + i1 = 1; + } else { + i1 = static_cast(start); + } + + b_rowSize = cellArray[b_i + cellArray.size(0)].f1.size(0) * 3; + for (int32_T i2{0}; i2 < b_rowSize; i2++) { + packedArray[(i1 + i2) - 1] = cellArray[b_i + cellArray.size(0)].f1[i2]; + } + + start = stop; + } + } + + static void packCellArray(const ::coder::array &cellArray, :: + coder::array &packedArray, ::coder::array &counts) + { + real_T rowSize; + real_T start; + int32_T b_rowSize; + int32_T i; + + // Packs a specified column of a cell array with different sized arrays into a + // single row array and an array of counts for each cell. For the example below + // reflect will be [1, 2, 3, 4, 5, 6, 7] and nReflect will be [3, 4] + // + // [reflect, nReflect] = packCellArray({[1; 2; 3], [4; 5; 6; 7]}, 1); + rowSize = 0.0; + counts.set_size(cellArray.size(0)); + i = cellArray.size(0); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T d; + d = static_cast(cellArray[b_i].f1.size(0)) * 2.0; + counts[b_i] = d; + rowSize += d; + } + + b_rowSize = static_cast(rowSize); + packedArray.set_size(b_rowSize); + for (i = 0; i < b_rowSize; i++) { + packedArray[i] = 0.0; + } + + start = 1.0; + i = cellArray.size(0); + for (int32_T b_i{0}; b_i < i; b_i++) { + real_T stop; + int32_T i1; + stop = start + counts[b_i]; + if (start > stop - 1.0) { + i1 = 1; + } else { + i1 = static_cast(start); + } + + b_rowSize = cellArray[b_i].f1.size(0) << 1; + for (int32_T i2{0}; i2 < b_rowSize; i2++) { + packedArray[(i1 + i2) - 1] = cellArray[b_i].f1[i2]; + } + + start = stop; + } + } + + void helper_not_empty_init() + { + helper_not_empty = false; + } + + void triggerEvent(const cell_wrap_9 data_f1[6], const ::coder::array &data_f2, const char_T data_f3_TF_data[], const int32_T + data_f3_TF_size[2], const ::coder::array + &data_f3_resample, const ::coder::array + &data_f3_dataPresent, const char_T data_f3_modelType_data[], + const int32_T data_f3_modelType_size[2]) + { + static eventHelper helper; + ::coder::array b_nSldProfiles2; + ::coder::array dataPresent; + ::coder::array layers2; + ::coder::array nLayers2; + ::coder::array resample; + ::coder::array sldProfiles2; + ::coder::array b_sldProfiles2; + ::coder::array layers; + ::coder::array nLayers; + ::coder::array nReflect; + ::coder::array nShiftedData; + ::coder::array nSldProfiles; + ::coder::array nSldProfiles2; + ::coder::array reflect; + ::coder::array shiftedData; + ::coder::array sldProfiles; + ::coder::array ssubs; + ::coder::array path; + ::coder::array r; + int32_T i; + int32_T loop_ub; + char_T modelType_data[10001]; + boolean_T initialised; + + // Triggers the event type with the given data. The supported event types are + // 'message' and 'plot'. The data for message is a char array while for + // the plot it is a cell array containing the result cell, + // contrastParams.ssubs and problemStruct + // + // triggerEvent('message', 'Hello world'); + if (!helper_not_empty) { + // Declaration for coder + helper_not_empty = true; + + // Make an instance + helper = eventHelper(); + coder::b_getenv(r); + path.set_size(1, r.size(1) + 1); + loop_ub = r.size(1); + for (i = 0; i < loop_ub; i++) { + path[i] = r[i]; + } + + path[r.size(1)] = '\x00'; + std::mem_fn(&eventHelper::init)(helper, &path[0]); + } + + initialised = std::mem_fn(&eventHelper::isInitialised)(helper); + if (initialised) { + boolean_T hasPlotHandler; + hasPlotHandler = std::mem_fn(&eventHelper::hasPlotHandler)(helper); + if (hasPlotHandler) { + packCellArray(data_f1[0].f1, reflect, nReflect); + + // reflectivity + b_packCellArray(data_f1[2].f1, shiftedData, nShiftedData); + c_packCellArray(data_f1[4].f1, sldProfiles, nSldProfiles); + b_packCellArray(data_f1[5].f1, layers, nLayers); + if (coder::internal::j_strcmp(data_f3_TF_data, data_f3_TF_size)) { + i = 0; + } else { + i = -1; + } + + if (i == 0) { + d_packCellArray(data_f1[4].f1, b_sldProfiles2, nSldProfiles2); + loop_ub = b_sldProfiles2.size(0); + sldProfiles2.set_size(b_sldProfiles2.size(0), 1); + for (i = 0; i < loop_ub; i++) { + sldProfiles2[i] = b_sldProfiles2[i]; + } + + loop_ub = nSldProfiles2.size(0); + b_nSldProfiles2.set_size(nSldProfiles2.size(0), 1); + for (i = 0; i < loop_ub; i++) { + b_nSldProfiles2[i] = nSldProfiles2[i]; + } + + e_packCellArray(data_f1[5].f1, b_sldProfiles2, nSldProfiles2); + loop_ub = b_sldProfiles2.size(0); + layers2.set_size(b_sldProfiles2.size(0), 1); + for (i = 0; i < loop_ub; i++) { + layers2[i] = b_sldProfiles2[i]; + } + + loop_ub = nSldProfiles2.size(0); + nLayers2.set_size(nSldProfiles2.size(0), 1); + for (i = 0; i < loop_ub; i++) { + nLayers2[i] = nSldProfiles2[i]; + } + } else { + sldProfiles2.set_size(0, 0); + b_nSldProfiles2.set_size(0, 0); + layers2.set_size(0, 0); + nLayers2.set_size(0, 0); + } + + ssubs.set_size(data_f2.size(0)); + loop_ub = data_f2.size(0); + for (i = 0; i < loop_ub; i++) { + ssubs[i] = data_f2[i]; + } + + // ssubs + loop_ub = data_f3_modelType_size[1]; + if (loop_ub - 1 >= 0) { + std::copy(&data_f3_modelType_data[0], &data_f3_modelType_data[loop_ub], + &modelType_data[0]); + } + + modelType_data[data_f3_modelType_size[1]] = '\x00'; + resample.set_size(1, data_f3_resample.size(1)); + loop_ub = data_f3_resample.size(1); + for (i = 0; i < loop_ub; i++) { + resample[i] = data_f3_resample[i]; + } + + dataPresent.set_size(1, data_f3_dataPresent.size(1)); + loop_ub = data_f3_dataPresent.size(1); + for (i = 0; i < loop_ub; i++) { + dataPresent[i] = data_f3_dataPresent[i]; + } + + std::mem_fn(&eventHelper::updatePlot)(helper, static_cast + (data_f1[0].f1.size(0)), &(reflect.data())[0], &(nReflect.data())[0], + &(shiftedData.data())[0], &(nShiftedData.data())[0], + &(sldProfiles.data())[0], &(nSldProfiles.data())[0], &(layers.data()) + [0], &(nLayers.data())[0], &sldProfiles2[0], &b_nSldProfiles2[0], + &layers2[0], &nLayers2[0], &(ssubs.data())[0], &resample[0], + &dataPresent[0], &modelType_data[0]); + notified = false; + } + + // This avoids printing the error message multiple times during the optimization. + } else if (!notified) { + fprintf(stderr, + "\neventManager library could be loaded. Check that the dynamic library is present in the compile/events folder.\n"); + fflush(stderr); + notified = true; + } + } + + void triggerEvent_init() + { + notified = false; + } +} + +// End of code generation (triggerEvent.cpp) diff --git a/cpp/RAT/triggerEvent.h b/cpp/RAT/triggerEvent.h new file mode 100644 index 00000000..01085973 --- /dev/null +++ b/cpp/RAT/triggerEvent.h @@ -0,0 +1,40 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// triggerEvent.h +// +// Code generation for function 'triggerEvent' +// +#ifndef TRIGGEREVENT_H +#define TRIGGEREVENT_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct cell_wrap_9; +} + +// Function Declarations +namespace RAT +{ + void helper_not_empty_init(); + void triggerEvent(const cell_wrap_9 data_f1[6], const ::coder::array &data_f2, const char_T data_f3_TF_data[], const int32_T + data_f3_TF_size[2], const ::coder::array + &data_f3_resample, const ::coder::array + &data_f3_dataPresent, const char_T data_f3_modelType_data[], + const int32_T data_f3_modelType_size[2]); + void triggerEvent_init(); +} + +#endif + +// End of code generation (triggerEvent.h) diff --git a/cpp/RAT/triu.cpp b/cpp/RAT/triu.cpp new file mode 100644 index 00000000..67b01f06 --- /dev/null +++ b/cpp/RAT/triu.cpp @@ -0,0 +1,71 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// triu.cpp +// +// Code generation for function 'triu' +// + +// Include files +#include "triu.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + void b_triu(::coder::array &x) + { + int32_T m; + m = x.size(0); + if ((x.size(0) != 0) && (x.size(1) != 0) && (x.size(0) > 3)) { + int32_T istart; + int32_T jend; + istart = 4; + if (x.size(0) - 4 < x.size(1) - 1) { + jend = x.size(0) - 3; + } else { + jend = x.size(1); + } + + for (int32_T j{0}; j < jend; j++) { + for (int32_T i{istart}; i <= m; i++) { + x[(i + x.size(0) * j) - 1] = 0.0; + } + + istart++; + } + } + } + + void triu(::coder::array &x) + { + int32_T m; + m = x.size(0); + if ((x.size(0) != 0) && (x.size(1) != 0) && (x.size(0) > 1)) { + int32_T istart; + int32_T jend; + istart = 2; + if (x.size(0) - 2 < x.size(1) - 1) { + jend = x.size(0) - 1; + } else { + jend = x.size(1); + } + + for (int32_T j{0}; j < jend; j++) { + for (int32_T i{istart}; i <= m; i++) { + x[(i + x.size(0) * j) - 1] = 0.0; + } + + istart++; + } + } + } + } +} + +// End of code generation (triu.cpp) diff --git a/cpp/RAT/triu.h b/cpp/RAT/triu.h new file mode 100644 index 00000000..64348754 --- /dev/null +++ b/cpp/RAT/triu.h @@ -0,0 +1,31 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// triu.h +// +// Code generation for function 'triu' +// +#ifndef TRIU_H +#define TRIU_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void b_triu(::coder::array &x); + void triu(::coder::array &x); + } +} + +#endif + +// End of code generation (triu.h) diff --git a/cpp/RAT/unpackParams.cpp b/cpp/RAT/unpackParams.cpp new file mode 100644 index 00000000..aa9bce41 --- /dev/null +++ b/cpp/RAT/unpackParams.cpp @@ -0,0 +1,276 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// unpackParams.cpp +// +// Code generation for function 'unpackParams' +// + +// Include files +#include "unpackParams.h" +#include "RATMain_internal_types.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + void unpackParams(c_struct_T *problemStruct, const ::coder::array + &controls_checks_fitParam, const ::coder::array + &controls_checks_fitBackgroundParam, const ::coder::array< + real_T, 2U> &controls_checks_fitQzshift, const ::coder:: + array &controls_checks_fitScalefactor, const :: + coder::array &controls_checks_fitBulkIn, const :: + coder::array &controls_checks_fitBulkOut, const :: + coder::array &controls_checks_fitResolutionParam, + const ::coder::array + &controls_checks_fitDomainRatio) + { + ::coder::array uppars; + int32_T i; + int32_T unnamed_idx_1; + int32_T uppars_counter; + uint32_T packed_counter; + uint32_T unpacked_counter; + + // Unpack the params out of the fitParams and otherParams arrays + // back into problem.params + // problem = getappdata(0,'problem'); + unpacked_counter = 1U; + packed_counter = 1U; + uppars_counter = 0; + unnamed_idx_1 = problemStruct->params.size(1); + uppars.set_size(1, unnamed_idx_1); + for (i = 0; i < unnamed_idx_1; i++) { + uppars[i] = 0.0; + } + + i = controls_checks_fitParam.size(1); + for (int32_T b_i{0}; b_i < i; b_i++) { + if (controls_checks_fitParam[b_i] == 1.0) { + uppars[uppars_counter] = problemStruct->fitParams[static_cast + (unpacked_counter) - 1]; + unpacked_counter++; + uppars_counter++; + } else { + uppars[uppars_counter] = problemStruct->otherParams[static_cast + (packed_counter) - 1]; + packed_counter++; + uppars_counter++; + } + } + + problemStruct->params.set_size(1, uppars.size(1)); + unnamed_idx_1 = uppars.size(1); + for (i = 0; i < unnamed_idx_1; i++) { + problemStruct->params[i] = uppars[i]; + } + + // Also the backgrounds + unnamed_idx_1 = problemStruct->backgroundParams.size(1); + uppars.set_size(1, unnamed_idx_1); + for (i = 0; i < unnamed_idx_1; i++) { + uppars[i] = 0.0; + } + + uppars_counter = 0; + i = controls_checks_fitBackgroundParam.size(1); + for (int32_T b_i{0}; b_i < i; b_i++) { + if (controls_checks_fitBackgroundParam[b_i] == 1.0) { + uppars[uppars_counter] = problemStruct->fitParams[static_cast + (unpacked_counter) - 1]; + unpacked_counter++; + uppars_counter++; + } else { + uppars[uppars_counter] = problemStruct->otherParams[static_cast + (packed_counter) - 1]; + packed_counter++; + uppars_counter++; + } + } + + problemStruct->backgroundParams.set_size(1, uppars.size(1)); + unnamed_idx_1 = uppars.size(1); + for (i = 0; i < unnamed_idx_1; i++) { + problemStruct->backgroundParams[i] = uppars[i]; + } + + // Scalefactors + unnamed_idx_1 = problemStruct->scalefactors.size(1); + uppars.set_size(1, unnamed_idx_1); + for (i = 0; i < unnamed_idx_1; i++) { + uppars[i] = 0.0; + } + + uppars_counter = 0; + i = controls_checks_fitScalefactor.size(1); + for (int32_T b_i{0}; b_i < i; b_i++) { + if (controls_checks_fitScalefactor[b_i] == 1.0) { + uppars[uppars_counter] = problemStruct->fitParams[static_cast + (unpacked_counter) - 1]; + unpacked_counter++; + uppars_counter++; + } else { + uppars[uppars_counter] = problemStruct->otherParams[static_cast + (packed_counter) - 1]; + packed_counter++; + uppars_counter++; + } + } + + problemStruct->scalefactors.set_size(1, uppars.size(1)); + unnamed_idx_1 = uppars.size(1); + for (i = 0; i < unnamed_idx_1; i++) { + problemStruct->scalefactors[i] = uppars[i]; + } + + // qzshifts + unnamed_idx_1 = problemStruct->qzshifts.size(1); + uppars.set_size(1, unnamed_idx_1); + for (i = 0; i < unnamed_idx_1; i++) { + uppars[i] = 0.0; + } + + uppars_counter = 0; + i = controls_checks_fitQzshift.size(1); + for (int32_T b_i{0}; b_i < i; b_i++) { + if (controls_checks_fitQzshift[b_i] == 1.0) { + uppars[uppars_counter] = problemStruct->fitParams[static_cast + (unpacked_counter) - 1]; + unpacked_counter++; + uppars_counter++; + } else { + uppars[uppars_counter] = problemStruct->otherParams[static_cast + (packed_counter) - 1]; + packed_counter++; + uppars_counter++; + } + } + + problemStruct->qzshifts.set_size(1, uppars.size(1)); + unnamed_idx_1 = uppars.size(1); + for (i = 0; i < unnamed_idx_1; i++) { + problemStruct->qzshifts[i] = uppars[i]; + } + + // Bulk In + unnamed_idx_1 = problemStruct->bulkIn.size(1); + uppars.set_size(1, unnamed_idx_1); + for (i = 0; i < unnamed_idx_1; i++) { + uppars[i] = 0.0; + } + + uppars_counter = 0; + i = controls_checks_fitBulkIn.size(1); + for (int32_T b_i{0}; b_i < i; b_i++) { + if (controls_checks_fitBulkIn[b_i] == 1.0) { + uppars[uppars_counter] = problemStruct->fitParams[static_cast + (unpacked_counter) - 1]; + unpacked_counter++; + uppars_counter++; + } else { + uppars[uppars_counter] = problemStruct->otherParams[static_cast + (packed_counter) - 1]; + packed_counter++; + uppars_counter++; + } + } + + problemStruct->bulkIn.set_size(1, uppars.size(1)); + unnamed_idx_1 = uppars.size(1); + for (i = 0; i < unnamed_idx_1; i++) { + problemStruct->bulkIn[i] = uppars[i]; + } + + // Bulk Out + unnamed_idx_1 = problemStruct->bulkOut.size(1); + uppars.set_size(1, unnamed_idx_1); + for (i = 0; i < unnamed_idx_1; i++) { + uppars[i] = 0.0; + } + + uppars_counter = 0; + i = controls_checks_fitBulkOut.size(1); + for (int32_T b_i{0}; b_i < i; b_i++) { + if (controls_checks_fitBulkOut[b_i] == 1.0) { + uppars[uppars_counter] = problemStruct->fitParams[static_cast + (unpacked_counter) - 1]; + unpacked_counter++; + uppars_counter++; + } else { + uppars[uppars_counter] = problemStruct->otherParams[static_cast + (packed_counter) - 1]; + packed_counter++; + uppars_counter++; + } + } + + problemStruct->bulkOut.set_size(1, uppars.size(1)); + unnamed_idx_1 = uppars.size(1); + for (i = 0; i < unnamed_idx_1; i++) { + problemStruct->bulkOut[i] = uppars[i]; + } + + // Resolutions + unnamed_idx_1 = problemStruct->resolutionParams.size(1); + uppars.set_size(1, unnamed_idx_1); + for (i = 0; i < unnamed_idx_1; i++) { + uppars[i] = 0.0; + } + + uppars_counter = 0; + i = controls_checks_fitResolutionParam.size(1); + for (int32_T b_i{0}; b_i < i; b_i++) { + if (controls_checks_fitResolutionParam[b_i] == 1.0) { + uppars[uppars_counter] = problemStruct->fitParams[static_cast + (unpacked_counter) - 1]; + unpacked_counter++; + uppars_counter++; + } else { + uppars[uppars_counter] = problemStruct->otherParams[static_cast + (packed_counter) - 1]; + packed_counter++; + uppars_counter++; + } + } + + problemStruct->resolutionParams.set_size(1, uppars.size(1)); + unnamed_idx_1 = uppars.size(1); + for (i = 0; i < unnamed_idx_1; i++) { + problemStruct->resolutionParams[i] = uppars[i]; + } + + // Domain Ratios + unnamed_idx_1 = problemStruct->domainRatio.size(1); + uppars.set_size(1, unnamed_idx_1); + for (i = 0; i < unnamed_idx_1; i++) { + uppars[i] = 0.0; + } + + uppars_counter = 0; + i = controls_checks_fitDomainRatio.size(1); + for (int32_T b_i{0}; b_i < i; b_i++) { + if (controls_checks_fitDomainRatio[b_i] == 1.0) { + uppars[uppars_counter] = problemStruct->fitParams[static_cast + (unpacked_counter) - 1]; + unpacked_counter++; + uppars_counter++; + } else { + uppars[uppars_counter] = problemStruct->otherParams[static_cast + (packed_counter) - 1]; + packed_counter++; + uppars_counter++; + } + } + + problemStruct->domainRatio.set_size(1, uppars.size(1)); + unnamed_idx_1 = uppars.size(1); + for (i = 0; i < unnamed_idx_1; i++) { + problemStruct->domainRatio[i] = uppars[i]; + } + } +} + +// End of code generation (unpackParams.cpp) diff --git a/cpp/RAT/unpackParams.h b/cpp/RAT/unpackParams.h new file mode 100644 index 00000000..137a4ef7 --- /dev/null +++ b/cpp/RAT/unpackParams.h @@ -0,0 +1,42 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// unpackParams.h +// +// Code generation for function 'unpackParams' +// +#ifndef UNPACKPARAMS_H +#define UNPACKPARAMS_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Type Declarations +namespace RAT +{ + struct c_struct_T; +} + +// Function Declarations +namespace RAT +{ + void unpackParams(c_struct_T *problemStruct, const ::coder::array + &controls_checks_fitParam, const ::coder::array + &controls_checks_fitBackgroundParam, const ::coder::array< + real_T, 2U> &controls_checks_fitQzshift, const ::coder:: + array &controls_checks_fitScalefactor, const :: + coder::array &controls_checks_fitBulkIn, const :: + coder::array &controls_checks_fitBulkOut, const :: + coder::array &controls_checks_fitResolutionParam, + const ::coder::array + &controls_checks_fitDomainRatio); +} + +#endif + +// End of code generation (unpackParams.h) diff --git a/cpp/RAT/unsafeSxfun.cpp b/cpp/RAT/unsafeSxfun.cpp new file mode 100644 index 00000000..5e945531 --- /dev/null +++ b/cpp/RAT/unsafeSxfun.cpp @@ -0,0 +1,365 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// unsafeSxfun.cpp +// +// Code generation for function 'unsafeSxfun' +// + +// Include files +#include "unsafeSxfun.h" +#include "RATMain_data.h" +#include "RATMain_rtwutil.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in3, const ::coder::array &in4, + int32_T in5, const ::coder::array &in6, + const ::coder::array &in7) + { + ::coder::array b_in3; + ::coder::array c_in3; + ::coder::array d_in3; + real_T b_in3_re_tmp; + real_T c_in3_re_tmp; + real_T d_in3_re_tmp; + real_T in3_re_tmp; + int32_T b_loop_ub; + int32_T i; + int32_T loop_ub; + int32_T stride_0_1; + int32_T stride_1_1; + if (in4.size(1) == 1) { + i = in3.size(1); + } else { + i = in4.size(1); + } + + b_in3.set_size(1, i); + stride_0_1 = (in3.size(1) != 1); + stride_1_1 = (in4.size(1) != 1); + if (in4.size(1) == 1) { + loop_ub = in3.size(1); + } else { + loop_ub = in4.size(1); + } + + for (i = 0; i < loop_ub; i++) { + b_in3[i].re = in3[i * stride_0_1] - in4[in5 + in4.size(0) * (i * + stride_1_1)]; + b_in3[i].im = 0.0; + } + + c_in3.set_size(1, in6.size(1)); + loop_ub = in6.size(1); + for (i = 0; i < loop_ub; i++) { + c_in3[i].re = 0.0; + c_in3[i].im = 0.0; + b_loop_ub = b_in3.size(1); + for (stride_0_1 = 0; stride_0_1 < b_loop_ub; stride_0_1++) { + in3_re_tmp = b_in3[stride_0_1].re; + b_in3_re_tmp = in6[stride_0_1 + in6.size(0) * i].im; + c_in3_re_tmp = b_in3[stride_0_1].im; + d_in3_re_tmp = in6[stride_0_1 + in6.size(0) * i].re; + c_in3[i].re = c_in3[i].re + (in3_re_tmp * d_in3_re_tmp - c_in3_re_tmp * + b_in3_re_tmp); + c_in3[i].im = c_in3[i].im + (in3_re_tmp * b_in3_re_tmp + c_in3_re_tmp * + d_in3_re_tmp); + } + } + + if (in7.size(0) == 1) { + i = c_in3.size(1); + } else { + i = in7.size(0); + } + + d_in3.set_size(1, i); + stride_0_1 = (c_in3.size(1) != 1); + stride_1_1 = (in7.size(0) != 1); + if (in7.size(0) == 1) { + loop_ub = c_in3.size(1); + } else { + loop_ub = in7.size(0); + } + + for (i = 0; i < loop_ub; i++) { + real_T ai; + real_T ar; + b_loop_ub = i * stride_0_1; + ar = c_in3[b_loop_ub].re; + ai = c_in3[b_loop_ub].im; + b_loop_ub = i * stride_1_1; + c_in3_re_tmp = in7[b_loop_ub].re; + d_in3_re_tmp = -in7[b_loop_ub].im; + if (d_in3_re_tmp == 0.0) { + if (ai == 0.0) { + d_in3[i].re = ar / c_in3_re_tmp; + d_in3[i].im = 0.0; + } else if (ar == 0.0) { + d_in3[i].re = 0.0; + d_in3[i].im = ai / c_in3_re_tmp; + } else { + d_in3[i].re = ar / c_in3_re_tmp; + d_in3[i].im = ai / c_in3_re_tmp; + } + } else if (c_in3_re_tmp == 0.0) { + if (ar == 0.0) { + d_in3[i].re = ai / d_in3_re_tmp; + d_in3[i].im = 0.0; + } else if (ai == 0.0) { + d_in3[i].re = 0.0; + d_in3[i].im = -(ar / d_in3_re_tmp); + } else { + d_in3[i].re = ai / d_in3_re_tmp; + d_in3[i].im = -(ar / d_in3_re_tmp); + } + } else { + real_T brm; + brm = std::abs(c_in3_re_tmp); + in3_re_tmp = std::abs(d_in3_re_tmp); + if (brm > in3_re_tmp) { + b_in3_re_tmp = d_in3_re_tmp / c_in3_re_tmp; + in3_re_tmp = c_in3_re_tmp + b_in3_re_tmp * d_in3_re_tmp; + d_in3[i].re = (ar + b_in3_re_tmp * ai) / in3_re_tmp; + d_in3[i].im = (ai - b_in3_re_tmp * ar) / in3_re_tmp; + } else if (in3_re_tmp == brm) { + if (c_in3_re_tmp > 0.0) { + b_in3_re_tmp = 0.5; + } else { + b_in3_re_tmp = -0.5; + } + + if (d_in3_re_tmp > 0.0) { + in3_re_tmp = 0.5; + } else { + in3_re_tmp = -0.5; + } + + d_in3[i].re = (ar * b_in3_re_tmp + ai * in3_re_tmp) / brm; + d_in3[i].im = (ai * b_in3_re_tmp - ar * in3_re_tmp) / brm; + } else { + b_in3_re_tmp = c_in3_re_tmp / d_in3_re_tmp; + in3_re_tmp = d_in3_re_tmp + b_in3_re_tmp * c_in3_re_tmp; + d_in3[i].re = (b_in3_re_tmp * ar + ai) / in3_re_tmp; + d_in3[i].im = (b_in3_re_tmp * ai - ar) / in3_re_tmp; + } + } + } + + in1.set_size(1, d_in3.size(1)); + loop_ub = d_in3.size(1); + for (i = 0; i < loop_ub; i++) { + creal_T varargin_1; + creal_T varargout_1; + varargin_1 = d_in3[i]; + varargout_1.re = varargin_1.re * varargin_1.re - varargin_1.im * + varargin_1.im; + in3_re_tmp = varargin_1.re * varargin_1.im; + varargout_1.im = in3_re_tmp + in3_re_tmp; + in1[i] = varargout_1; + } + } + + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 1U> &in3, const ::coder::array &in4) + { + ::coder::array b_in1; + int32_T i; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_1_0; + int32_T stride_2_0; + if (in4.size(0) == 1) { + if (in3.size(0) == 1) { + i = in1.size(0); + } else { + i = in3.size(0); + } + } else { + i = in4.size(0); + } + + b_in1.set_size(i); + stride_0_0 = (in1.size(0) != 1); + stride_1_0 = (in3.size(0) != 1); + stride_2_0 = (in4.size(0) != 1); + if (in4.size(0) == 1) { + if (in3.size(0) == 1) { + loop_ub = in1.size(0); + } else { + loop_ub = in3.size(0); + } + } else { + loop_ub = in4.size(0); + } + + for (i = 0; i < loop_ub; i++) { + b_in1[i] = (in1[i * stride_0_0] - in3[i * stride_1_0]) / in4[i * + stride_2_0]; + } + + in1.set_size(b_in1.size(0)); + loop_ub = b_in1.size(0); + for (i = 0; i < loop_ub; i++) { + in1[i] = b_in1[i]; + } + + loop_ub = in1.size(0); + for (i = 0; i < loop_ub; i++) { + real_T varargin_1; + varargin_1 = in1[i]; + in1[i] = varargin_1 * varargin_1; + } + } + + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in3, int32_T in4, int32_T in5, const :: + coder::array &in6, int32_T in7, int32_T in8, + const ::coder::array &in9) + { + ::coder::array b_in3; + int32_T aux_0_1; + int32_T aux_1_1; + int32_T aux_2_1; + int32_T b_loop_ub; + int32_T i; + int32_T i1; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_0_1; + int32_T stride_1_0; + int32_T stride_1_1; + int32_T stride_2_0; + int32_T stride_2_1; + if (in9.size(0) == 1) { + if (in7 + 1 == 1) { + i = in4 + 1; + } else { + i = in7 + 1; + } + } else { + i = in9.size(0); + } + + if (in9.size(1) == 1) { + if (in8 + 1 == 1) { + i1 = in5 + 1; + } else { + i1 = in8 + 1; + } + } else { + i1 = in9.size(1); + } + + b_in3.set_size(i, i1); + stride_0_0 = (in4 + 1 != 1); + stride_0_1 = (in5 + 1 != 1); + stride_1_0 = (in7 + 1 != 1); + stride_1_1 = (in8 + 1 != 1); + stride_2_0 = (in9.size(0) != 1); + stride_2_1 = (in9.size(1) != 1); + aux_0_1 = 0; + aux_1_1 = 0; + aux_2_1 = 0; + if (in9.size(1) == 1) { + if (in8 + 1 == 1) { + loop_ub = in5 + 1; + } else { + loop_ub = in8 + 1; + } + } else { + loop_ub = in9.size(1); + } + + for (i = 0; i < loop_ub; i++) { + i1 = in9.size(0); + if (i1 == 1) { + if (in7 + 1 == 1) { + b_loop_ub = in4 + 1; + } else { + b_loop_ub = in7 + 1; + } + } else { + b_loop_ub = i1; + } + + for (i1 = 0; i1 < b_loop_ub; i1++) { + b_in3[i1 + b_in3.size(0) * i] = (in3[i1 * stride_0_0 + in3.size(0) * + aux_0_1] - in6[i1 * stride_1_0 + in6.size(0) * aux_1_1]) / in9[i1 * + stride_2_0 + in9.size(0) * aux_2_1]; + } + + aux_2_1 += stride_2_1; + aux_1_1 += stride_1_1; + aux_0_1 += stride_0_1; + } + + in1.set_size(b_in3.size(0), b_in3.size(1)); + loop_ub = b_in3.size(1); + for (i = 0; i < loop_ub; i++) { + b_loop_ub = b_in3.size(0); + for (i1 = 0; i1 < b_loop_ub; i1++) { + real_T varargin_1; + varargin_1 = b_in3[i1 + b_in3.size(0) * i]; + in1[i1 + in1.size(0) * i] = rt_powd_snf(varargin_1, 2.0); + } + } + } + + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in3, const ::coder::array &in4) + { + ::coder::array b_in3; + int32_T i; + int32_T loop_ub; + int32_T stride_0_0; + int32_T stride_1_0; + int32_T stride_2_0; + if (in3.size(0) == 1) { + if (in4.size(0) == 1) { + i = in3.size(0); + } else { + i = in4.size(0); + } + } else { + i = in3.size(0); + } + + b_in3.set_size(i); + stride_0_0 = (in3.size(0) != 1); + stride_1_0 = (in4.size(0) != 1); + stride_2_0 = (in3.size(0) != 1); + if (in3.size(0) == 1) { + if (in4.size(0) == 1) { + loop_ub = in3.size(0); + } else { + loop_ub = in4.size(0); + } + } else { + loop_ub = in3.size(0); + } + + for (i = 0; i < loop_ub; i++) { + b_in3[i] = (in3[i * stride_0_0 + in3.size(0)] - in4[i * stride_1_0 + + in4.size(0)]) / in3[i * stride_2_0 + in3.size(0) * 2]; + } + + in1.set_size(b_in3.size(0)); + loop_ub = b_in3.size(0); + for (i = 0; i < loop_ub; i++) { + real_T varargin_1; + varargin_1 = b_in3[i]; + in1[i] = varargin_1 * varargin_1; + } + } +} + +// End of code generation (unsafeSxfun.cpp) diff --git a/cpp/RAT/unsafeSxfun.h b/cpp/RAT/unsafeSxfun.h new file mode 100644 index 00000000..e16458a4 --- /dev/null +++ b/cpp/RAT/unsafeSxfun.h @@ -0,0 +1,38 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// unsafeSxfun.h +// +// Code generation for function 'unsafeSxfun' +// +#ifndef UNSAFESXFUN_H +#define UNSAFESXFUN_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in3, const ::coder::array &in4, + int32_T in5, const ::coder::array &in6, + const ::coder::array &in7); + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 1U> &in3, const ::coder::array &in4); + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in3, int32_T in4, int32_T in5, const :: + coder::array &in6, int32_T in7, int32_T in8, + const ::coder::array &in9); + void binary_expand_op(::coder::array &in1, const ::coder::array< + real_T, 2U> &in3, const ::coder::array &in4); +} + +#endif + +// End of code generation (unsafeSxfun.h) diff --git a/cpp/RAT/useConstantDim.cpp b/cpp/RAT/useConstantDim.cpp new file mode 100644 index 00000000..cd168815 --- /dev/null +++ b/cpp/RAT/useConstantDim.cpp @@ -0,0 +1,63 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// useConstantDim.cpp +// +// Code generation for function 'useConstantDim' +// + +// Include files +#include "useConstantDim.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + void useConstantDim(::coder::array &varargin_2, int32_T + varargin_3) + { + int32_T subsb_idx_1; + if (varargin_3 == 1) { + if ((varargin_2.size(0) != 0) && (varargin_2.size(1) != 0)) { + int32_T i; + i = varargin_2.size(1); + for (int32_T k{0}; k < i; k++) { + int32_T i1; + i1 = varargin_2.size(0); + if (i1 - 2 >= 0) { + subsb_idx_1 = k + 1; + } + + for (int32_T b_k{0}; b_k <= i1 - 2; b_k++) { + varargin_2[(b_k + varargin_2.size(0) * (subsb_idx_1 - 1)) + 1] = + varargin_2[b_k + varargin_2.size(0) * k] + varargin_2[(b_k + + varargin_2.size(0) * (subsb_idx_1 - 1)) + 1]; + } + } + } + } else if ((varargin_2.size(0) != 0) && (varargin_2.size(1) != 0)) { + int32_T i; + i = varargin_2.size(1); + for (int32_T k{0}; k <= i - 2; k++) { + int32_T i1; + i1 = varargin_2.size(0); + for (int32_T b_k{0}; b_k < i1; b_k++) { + varargin_2[b_k + varargin_2.size(0) * (k + 1)] = varargin_2[b_k + + varargin_2.size(0) * k] + varargin_2[b_k + varargin_2.size(0) * + (k + 1)]; + } + } + } + } + } + } +} + +// End of code generation (useConstantDim.cpp) diff --git a/cpp/RAT/useConstantDim.h b/cpp/RAT/useConstantDim.h new file mode 100644 index 00000000..c9d5d1bd --- /dev/null +++ b/cpp/RAT/useConstantDim.h @@ -0,0 +1,34 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// useConstantDim.h +// +// Code generation for function 'useConstantDim' +// +#ifndef USECONSTANTDIM_H +#define USECONSTANTDIM_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + void useConstantDim(::coder::array &varargin_2, int32_T + varargin_3); + } + } +} + +#endif + +// End of code generation (useConstantDim.h) diff --git a/cpp/RAT/vAllOrAny.cpp b/cpp/RAT/vAllOrAny.cpp new file mode 100644 index 00000000..07c4218e --- /dev/null +++ b/cpp/RAT/vAllOrAny.cpp @@ -0,0 +1,93 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// vAllOrAny.cpp +// +// Code generation for function 'vAllOrAny' +// + +// Include files +#include "vAllOrAny.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + static void genloops(const ::coder::array &x, boolean_T *p, + int32_T varargin_1, int32_T varargin_2); + } + } +} + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + static void genloops(const ::coder::array &x, boolean_T *p, + int32_T varargin_1, int32_T varargin_2) + { + if ((*p) || std::isnan(x[(varargin_1 + x.size(0) * (varargin_2 - 1)) - 1])) + { + *p = true; + } else { + *p = false; + } + } + + void b_genloops(const ::coder::array &x, boolean_T *p, int32_T + varargin_1, int32_T varargin_2) + { + if (*p) { + real_T b_x; + b_x = x[(varargin_1 + x.size(0) * (varargin_2 - 1)) - 1]; + if ((!std::isinf(b_x)) && (!std::isnan(b_x))) { + *p = true; + } else { + *p = false; + } + } else { + *p = false; + } + } + + void c_genloops(const real_T x_data[], boolean_T *p) + { + if ((*p) || std::isnan(x_data[0])) { + *p = true; + } else { + *p = false; + } + } + + boolean_T vAllOrAny(const ::coder::array &x) + { + int32_T i; + boolean_T p; + p = false; + i = x.size(1); + for (int32_T k{0}; k < i; k++) { + int32_T i1; + i1 = x.size(0); + for (int32_T b_k{0}; b_k < i1; b_k++) { + genloops(x, &p, b_k + 1, k + 1); + } + } + + return p; + } + } + } +} + +// End of code generation (vAllOrAny.cpp) diff --git a/cpp/RAT/vAllOrAny.h b/cpp/RAT/vAllOrAny.h new file mode 100644 index 00000000..20f79b0a --- /dev/null +++ b/cpp/RAT/vAllOrAny.h @@ -0,0 +1,36 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// vAllOrAny.h +// +// Code generation for function 'vAllOrAny' +// +#ifndef VALLORANY_H +#define VALLORANY_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + void b_genloops(const ::coder::array &x, boolean_T *p, int32_T + varargin_1, int32_T varargin_2); + void c_genloops(const real_T x_data[], boolean_T *p); + boolean_T vAllOrAny(const ::coder::array &x); + } + } +} + +#endif + +// End of code generation (vAllOrAny.h) diff --git a/cpp/RAT/validate_print_arguments.cpp b/cpp/RAT/validate_print_arguments.cpp new file mode 100644 index 00000000..f6474505 --- /dev/null +++ b/cpp/RAT/validate_print_arguments.cpp @@ -0,0 +1,44 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// validate_print_arguments.cpp +// +// Code generation for function 'validate_print_arguments' +// + +// Include files +#include "validate_print_arguments.h" +#include "rt_nonfinite.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + void validate_print_arguments(real_T varargin_1, real_T varargin_2, real_T + varargin_3, real_T varargin_4, real_T varargin_5, real_T + validatedArguments[5]) + { + validatedArguments[0] = varargin_1; + validatedArguments[1] = varargin_2; + validatedArguments[2] = varargin_3; + validatedArguments[3] = varargin_4; + validatedArguments[4] = varargin_5; + } + + void validate_print_arguments(int32_T varargin_1, int32_T varargin_2, + int32_T varargin_3, int32_T validatedArguments[3]) + { + validatedArguments[0] = varargin_1; + validatedArguments[1] = varargin_2; + validatedArguments[2] = varargin_3; + } + } + } +} + +// End of code generation (validate_print_arguments.cpp) diff --git a/cpp/RAT/validate_print_arguments.h b/cpp/RAT/validate_print_arguments.h new file mode 100644 index 00000000..62db5460 --- /dev/null +++ b/cpp/RAT/validate_print_arguments.h @@ -0,0 +1,36 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// validate_print_arguments.h +// +// Code generation for function 'validate_print_arguments' +// +#ifndef VALIDATE_PRINT_ARGUMENTS_H +#define VALIDATE_PRINT_ARGUMENTS_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + void validate_print_arguments(real_T varargin_1, real_T varargin_2, real_T + varargin_3, real_T varargin_4, real_T varargin_5, real_T + validatedArguments[5]); + void validate_print_arguments(int32_T varargin_1, int32_T varargin_2, + int32_T varargin_3, int32_T validatedArguments[3]); + } + } +} + +#endif + +// End of code generation (validate_print_arguments.h) diff --git a/cpp/RAT/var.cpp b/cpp/RAT/var.cpp new file mode 100644 index 00000000..57c5b905 --- /dev/null +++ b/cpp/RAT/var.cpp @@ -0,0 +1,58 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// var.cpp +// +// Code generation for function 'var' +// + +// Include files +#include "var.h" +#include "rt_nonfinite.h" +#include "varstd.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + void var(const ::coder::array &x, ::coder::array &y) + { + ::coder::array xv; + int32_T hi; + int32_T loop_ub; + int32_T nx; + int32_T outsize_idx_0; + y.set_size(1, x.size(1)); + hi = x.size(1); + for (int32_T k{0}; k < hi; k++) { + y[k] = 0.0; + } + + hi = x.size(1); + if (x.size(1) - 1 >= 0) { + nx = x.size(0); + outsize_idx_0 = x.size(0); + loop_ub = x.size(0); + } + + for (int32_T b_k{0}; b_k < hi; b_k++) { + xv.set_size(outsize_idx_0); + for (int32_T k{0}; k < loop_ub; k++) { + xv[k] = 0.0; + } + + for (int32_T k{0}; k < nx; k++) { + xv[k] = x[k + x.size(0) * b_k]; + } + + y[b_k] = b_varstd_anonFcn3(x.size(0), xv); + } + } + } +} + +// End of code generation (var.cpp) diff --git a/cpp/RAT/var.h b/cpp/RAT/var.h new file mode 100644 index 00000000..baf60459 --- /dev/null +++ b/cpp/RAT/var.h @@ -0,0 +1,30 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// var.h +// +// Code generation for function 'var' +// +#ifndef VAR_H +#define VAR_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + void var(const ::coder::array &x, ::coder::array &y); + } +} + +#endif + +// End of code generation (var.h) diff --git a/cpp/RAT/varstd.cpp b/cpp/RAT/varstd.cpp new file mode 100644 index 00000000..153eff88 --- /dev/null +++ b/cpp/RAT/varstd.cpp @@ -0,0 +1,80 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// varstd.cpp +// +// Code generation for function 'varstd' +// + +// Include files +#include "varstd.h" +#include "combineVectorElements.h" +#include "rt_nonfinite.h" +#include "xnrm2.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + real_T b_varstd_anonFcn3(int32_T n, const ::coder::array &x) + { + real_T varargout_1; + if (n == 0) { + varargout_1 = rtNaN; + } else if (n == 1) { + if ((!std::isinf(x[0])) && (!std::isnan(x[0]))) { + varargout_1 = 0.0; + } else { + varargout_1 = rtNaN; + } + } else { + real_T xbar; + xbar = b_combineVectorElements(x, n) / static_cast(n); + varargout_1 = 0.0; + for (int32_T k{0}; k < n; k++) { + real_T t; + t = x[k] - xbar; + varargout_1 += t * t; + } + + varargout_1 /= static_cast(n - 1); + } + + return varargout_1; + } + + real_T varstd_anonFcn3(int32_T n, const ::coder::array &x) + { + ::coder::array absdiff; + real_T varargout_1; + if (n == 0) { + varargout_1 = rtNaN; + } else if (n == 1) { + if ((!std::isinf(x[0])) && (!std::isnan(x[0]))) { + varargout_1 = 0.0; + } else { + varargout_1 = rtNaN; + } + } else { + real_T xbar; + xbar = b_combineVectorElements(x, n) / static_cast(n); + absdiff.set_size(x.size(0)); + for (int32_T k{0}; k < n; k++) { + absdiff[k] = std::abs(x[k] - xbar); + } + + varargout_1 = internal::blas::xnrm2(n, absdiff) / std::sqrt(static_cast< + real_T>(n - 1)); + } + + return varargout_1; + } + } +} + +// End of code generation (varstd.cpp) diff --git a/cpp/RAT/varstd.h b/cpp/RAT/varstd.h new file mode 100644 index 00000000..c7036f84 --- /dev/null +++ b/cpp/RAT/varstd.h @@ -0,0 +1,31 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// varstd.h +// +// Code generation for function 'varstd' +// +#ifndef VARSTD_H +#define VARSTD_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + real_T b_varstd_anonFcn3(int32_T n, const ::coder::array &x); + real_T varstd_anonFcn3(int32_T n, const ::coder::array &x); + } +} + +#endif + +// End of code generation (varstd.h) diff --git a/cpp/RAT/xdhseqr.cpp b/cpp/RAT/xdhseqr.cpp new file mode 100644 index 00000000..e4b1ddd0 --- /dev/null +++ b/cpp/RAT/xdhseqr.cpp @@ -0,0 +1,388 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xdhseqr.cpp +// +// Code generation for function 'xdhseqr' +// + +// Include files +#include "xdhseqr.h" +#include "rt_nonfinite.h" +#include "xdlanv2.h" +#include "xrot.h" +#include "xzlarfg.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + int32_T eml_dlahqr(::coder::array &h, ::coder::array &z) + { + real_T aa; + real_T ab; + real_T ba; + real_T bb; + real_T d; + real_T rt1r; + real_T rt2r; + real_T s; + real_T tst; + int32_T info; + int32_T ldh; + int32_T ldz; + int32_T n; + n = h.size(0); + ldh = h.size(0); + ldz = z.size(0); + info = 0; + if ((n != 0) && (n != 1)) { + real_T v[3]; + real_T SMLNUM; + int32_T i; + int32_T itmax; + int32_T kdefl; + boolean_T exitg1; + v[0] = 0.0; + v[1] = 0.0; + v[2] = 0.0; + for (int32_T j{0}; j <= n - 4; j++) { + h[(j + h.size(0) * j) + 2] = 0.0; + h[(j + h.size(0) * j) + 3] = 0.0; + } + + if (n - 2 >= 1) { + h[(n + h.size(0) * (n - 3)) - 1] = 0.0; + } + + if (n <= 10) { + itmax = 10; + } else { + itmax = n; + } + + itmax *= 30; + kdefl = 0; + SMLNUM = 2.2250738585072014E-308 * (static_cast(n) / + 2.2204460492503131E-16); + i = n - 1; + exitg1 = false; + while ((!exitg1) && (i + 1 >= 1)) { + int32_T L; + int32_T its; + int32_T nr; + boolean_T exitg2; + boolean_T goto150; + L = 1; + goto150 = false; + its = 0; + exitg2 = false; + while ((!exitg2) && (its <= itmax)) { + int32_T k; + boolean_T exitg3; + k = i; + exitg3 = false; + while ((!exitg3) && (k + 1 > L)) { + ba = std::abs(h[k + h.size(0) * (k - 1)]); + if (ba <= SMLNUM) { + exitg3 = true; + } else { + bb = std::abs(h[k + h.size(0) * k]); + tst = std::abs(h[(k + h.size(0) * (k - 1)) - 1]) + bb; + if (tst == 0.0) { + if (k - 1 >= 1) { + tst = std::abs(h[(k + h.size(0) * (k - 2)) - 1]); + } + + if (k + 2 <= n) { + tst += std::abs(h[(k + h.size(0) * k) + 1]); + } + } + + if (ba <= 2.2204460492503131E-16 * tst) { + tst = std::abs(h[(k + h.size(0) * k) - 1]); + if (ba > tst) { + ab = ba; + ba = tst; + } else { + ab = tst; + } + + tst = std::abs(h[(k + h.size(0) * (k - 1)) - 1] - h[k + + h.size(0) * k]); + if (bb > tst) { + aa = bb; + bb = tst; + } else { + aa = tst; + } + + s = aa + ab; + if (ba * (ab / s) <= std::fmax(SMLNUM, + 2.2204460492503131E-16 * (bb * (aa / s)))) { + exitg3 = true; + } else { + k--; + } + } else { + k--; + } + } + } + + L = k + 1; + if (k + 1 > 1) { + h[k + h.size(0) * (k - 1)] = 0.0; + } + + if (k + 1 >= i) { + goto150 = true; + exitg2 = true; + } else { + int32_T m; + kdefl++; + if (kdefl - kdefl / 20 * 20 == 0) { + s = std::abs(h[i + h.size(0) * (i - 1)]) + std::abs(h[(i + + h.size(0) * (i - 2)) - 1]); + tst = 0.75 * s + h[i + h.size(0) * i]; + aa = -0.4375 * s; + ab = s; + bb = tst; + } else if (kdefl - kdefl / 10 * 10 == 0) { + s = std::abs(h[(k + h.size(0) * k) + 1]) + std::abs(h[(k + + h.size(0) * (k + 1)) + 2]); + tst = 0.75 * s + h[k + h.size(0) * k]; + aa = -0.4375 * s; + ab = s; + bb = tst; + } else { + tst = h[(i + h.size(0) * (i - 1)) - 1]; + ab = h[i + h.size(0) * (i - 1)]; + aa = h[(i + h.size(0) * i) - 1]; + bb = h[i + h.size(0) * i]; + } + + s = ((std::abs(tst) + std::abs(aa)) + std::abs(ab)) + std::abs + (bb); + if (s == 0.0) { + rt1r = 0.0; + ab = 0.0; + rt2r = 0.0; + aa = 0.0; + } else { + tst /= s; + ab /= s; + aa /= s; + bb /= s; + ba = (tst + bb) / 2.0; + tst = (tst - ba) * (bb - ba) - aa * ab; + ab = std::sqrt(std::abs(tst)); + if (tst >= 0.0) { + rt1r = ba * s; + rt2r = rt1r; + ab *= s; + aa = -ab; + } else { + rt1r = ba + ab; + rt2r = ba - ab; + if (std::abs(rt1r - bb) <= std::abs(rt2r - bb)) { + rt1r *= s; + rt2r = rt1r; + } else { + rt2r *= s; + rt1r = rt2r; + } + + ab = 0.0; + aa = 0.0; + } + } + + m = i - 1; + exitg3 = false; + while ((!exitg3) && (m >= k + 1)) { + tst = h[m + h.size(0) * (m - 1)]; + ba = h[(m + h.size(0) * (m - 1)) - 1]; + bb = ba - rt2r; + s = (std::abs(bb) + std::abs(aa)) + std::abs(tst); + tst /= s; + v[0] = (tst * h[(m + h.size(0) * m) - 1] + (ba - rt1r) * (bb + / s)) - ab * (aa / s); + v[1] = tst * (((ba + h[m + h.size(0) * m]) - rt1r) - rt2r); + v[2] = tst * h[(m + h.size(0) * m) + 1]; + s = (std::abs(v[0]) + std::abs(v[1])) + std::abs(v[2]); + v[0] /= s; + v[1] /= s; + v[2] /= s; + if ((m == k + 1) || (std::abs(h[(m + h.size(0) * (m - 2)) - + 1]) * (std::abs(v[1]) + std::abs(v[2])) <= + 2.2204460492503131E-16 * std::abs(v[0]) + * ((std::abs(h[(m + h.size(0) * (m - 2)) + - 2]) + std::abs(ba)) + std::abs(h[m + h.size(0) * m])))) + { + exitg3 = true; + } else { + m--; + } + } + + for (int32_T b_k{m}; b_k <= i; b_k++) { + nr = (i - b_k) + 2; + if (nr >= 3) { + nr = 3; + } + + if (b_k > m) { + int32_T hoffset; + hoffset = (b_k + ldh * (b_k - 2)) - 1; + for (int32_T j{0}; j < nr; j++) { + v[j] = h[j + hoffset]; + } + } + + tst = v[0]; + rt2r = xzlarfg(nr, &tst, v); + v[0] = tst; + if (b_k > m) { + h[(b_k + h.size(0) * (b_k - 2)) - 1] = tst; + h[b_k + h.size(0) * (b_k - 2)] = 0.0; + if (b_k < i) { + h[(b_k + h.size(0) * (b_k - 2)) + 1] = 0.0; + } + } else if (m > k + 1) { + h[(b_k + h.size(0) * (b_k - 2)) - 1] = h[(b_k + h.size(0) * + (b_k - 2)) - 1] * (1.0 - rt2r); + } + + rt1r = v[1]; + tst = rt2r * v[1]; + if (nr == 3) { + s = v[2]; + aa = rt2r * v[2]; + for (int32_T j{b_k}; j <= n; j++) { + d = h[(b_k + h.size(0) * (j - 1)) - 1]; + ba = h[b_k + h.size(0) * (j - 1)]; + bb = h[(b_k + h.size(0) * (j - 1)) + 1]; + ab = (d + rt1r * ba) + s * bb; + d -= ab * rt2r; + h[(b_k + h.size(0) * (j - 1)) - 1] = d; + ba -= ab * tst; + h[b_k + h.size(0) * (j - 1)] = ba; + bb -= ab * aa; + h[(b_k + h.size(0) * (j - 1)) + 1] = bb; + } + + if (b_k + 3 <= i + 1) { + nr = b_k + 2; + } else { + nr = i; + } + + for (int32_T j{0}; j <= nr; j++) { + d = h[j + h.size(0) * (b_k - 1)]; + ba = h[j + h.size(0) * b_k]; + bb = h[j + h.size(0) * (b_k + 1)]; + ab = (d + rt1r * ba) + s * bb; + d -= ab * rt2r; + h[j + h.size(0) * (b_k - 1)] = d; + ba -= ab * tst; + h[j + h.size(0) * b_k] = ba; + bb -= ab * aa; + h[j + h.size(0) * (b_k + 1)] = bb; + } + + for (int32_T j{0}; j < n; j++) { + d = z[j + z.size(0) * (b_k - 1)]; + ba = z[j + z.size(0) * b_k]; + bb = z[j + z.size(0) * (b_k + 1)]; + ab = (d + rt1r * ba) + s * bb; + d -= ab * rt2r; + z[j + z.size(0) * (b_k - 1)] = d; + ba -= ab * tst; + z[j + z.size(0) * b_k] = ba; + bb -= ab * aa; + z[j + z.size(0) * (b_k + 1)] = bb; + } + } else if (nr == 2) { + for (int32_T j{b_k}; j <= n; j++) { + s = h[(b_k + h.size(0) * (j - 1)) - 1]; + d = h[b_k + h.size(0) * (j - 1)]; + ab = s + rt1r * d; + s -= ab * rt2r; + h[(b_k + h.size(0) * (j - 1)) - 1] = s; + d -= ab * tst; + h[b_k + h.size(0) * (j - 1)] = d; + } + + for (int32_T j{0}; j <= i; j++) { + s = h[j + h.size(0) * (b_k - 1)]; + d = h[j + h.size(0) * b_k]; + ab = s + rt1r * d; + s -= ab * rt2r; + h[j + h.size(0) * (b_k - 1)] = s; + d -= ab * tst; + h[j + h.size(0) * b_k] = d; + } + + for (int32_T j{0}; j < n; j++) { + s = z[j + z.size(0) * (b_k - 1)]; + d = z[j + z.size(0) * b_k]; + ab = s + rt1r * d; + s -= ab * rt2r; + z[j + z.size(0) * (b_k - 1)] = s; + d -= ab * tst; + z[j + z.size(0) * b_k] = d; + } + } + } + + its++; + } + } + + if (!goto150) { + info = i + 1; + exitg1 = true; + } else { + if ((L != i + 1) && (L == i)) { + rt1r = h[(i + h.size(0) * i) - 1]; + s = h[i + h.size(0) * (i - 1)]; + d = h[i + h.size(0) * i]; + xdlanv2(&h[(i + h.size(0) * (i - 1)) - 1], &rt1r, &s, &d, &tst, + &ab, &aa, &ba, &bb, &rt2r); + h[(i + h.size(0) * i) - 1] = rt1r; + h[i + h.size(0) * (i - 1)] = s; + h[i + h.size(0) * i] = d; + if (n > i + 1) { + nr = i + (i + 1) * ldh; + blas::xrot((n - i) - 1, h, nr, ldh, nr + 1, ldh, bb, rt2r); + } + + blas::xrot(i - 1, h, (i - 1) * ldh + 1, i * ldh + 1, bb, rt2r); + blas::xrot(n, z, (i - 1) * ldz + 1, i * ldz + 1, bb, rt2r); + } + + kdefl = 0; + i = L - 2; + } + } + } + + return info; + } + } + } + } +} + +// End of code generation (xdhseqr.cpp) diff --git a/cpp/RAT/xdhseqr.h b/cpp/RAT/xdhseqr.h new file mode 100644 index 00000000..e6d74ed0 --- /dev/null +++ b/cpp/RAT/xdhseqr.h @@ -0,0 +1,37 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xdhseqr.h +// +// Code generation for function 'xdhseqr' +// +#ifndef XDHSEQR_H +#define XDHSEQR_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + int32_T eml_dlahqr(::coder::array &h, ::coder::array &z); + } + } + } +} + +#endif + +// End of code generation (xdhseqr.h) diff --git a/cpp/RAT/xdlanv2.cpp b/cpp/RAT/xdlanv2.cpp new file mode 100644 index 00000000..82e0c692 --- /dev/null +++ b/cpp/RAT/xdlanv2.cpp @@ -0,0 +1,179 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xdlanv2.cpp +// +// Code generation for function 'xdlanv2' +// + +// Include files +#include "xdlanv2.h" +#include "RATMain_rtwutil.h" +#include "rt_nonfinite.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + void xdlanv2(real_T *a, real_T *b, real_T *c, real_T *d, real_T *rt1r, + real_T *rt1i, real_T *rt2r, real_T *rt2i, real_T *cs, + real_T *sn) + { + if (*c == 0.0) { + *cs = 1.0; + *sn = 0.0; + } else if (*b == 0.0) { + real_T temp; + *cs = 0.0; + *sn = 1.0; + temp = *d; + *d = *a; + *a = temp; + *b = -*c; + *c = 0.0; + } else { + real_T temp; + temp = *a - *d; + if ((temp == 0.0) && ((*b < 0.0) != (*c < 0.0))) { + *cs = 1.0; + *sn = 0.0; + } else { + real_T bcmax; + real_T bcmis; + real_T p; + real_T scale; + real_T z; + int32_T count; + int32_T i; + p = 0.5 * temp; + bcmis = std::abs(*b); + scale = std::abs(*c); + bcmax = std::fmax(bcmis, scale); + if (!(*b < 0.0)) { + count = 1; + } else { + count = -1; + } + + if (!(*c < 0.0)) { + i = 1; + } else { + i = -1; + } + + bcmis = std::fmin(bcmis, scale) * static_cast(count) * + static_cast(i); + scale = std::fmax(std::abs(p), bcmax); + z = p / scale * p + bcmax / scale * bcmis; + if (z >= 8.8817841970012523E-16) { + real_T tau; + *a = std::sqrt(scale) * std::sqrt(z); + if (p < 0.0) { + *a = -*a; + } + + z = p + *a; + *a = *d + z; + *d -= bcmax / z * bcmis; + tau = rt_hypotd_snf(*c, z); + *cs = z / tau; + *sn = *c / tau; + *b -= *c; + *c = 0.0; + } else { + real_T tau; + bcmis = *b + *c; + scale = std::fmax(std::abs(temp), std::abs(bcmis)); + count = 0; + while ((scale >= 7.4428285367870146E+137) && (count <= 20)) { + bcmis *= 1.3435752215134178E-138; + temp *= 1.3435752215134178E-138; + scale = std::fmax(std::abs(temp), std::abs(bcmis)); + count++; + } + + while ((scale <= 1.3435752215134178E-138) && (count <= 20)) { + bcmis *= 7.4428285367870146E+137; + temp *= 7.4428285367870146E+137; + scale = std::fmax(std::abs(temp), std::abs(bcmis)); + count++; + } + + tau = rt_hypotd_snf(bcmis, temp); + *cs = std::sqrt(0.5 * (std::abs(bcmis) / tau + 1.0)); + if (!(bcmis < 0.0)) { + count = 1; + } else { + count = -1; + } + + *sn = -(0.5 * temp / (tau * *cs)) * static_cast(count); + bcmax = *a * *cs + *b * *sn; + scale = -*a * *sn + *b * *cs; + z = *c * *cs + *d * *sn; + bcmis = -*c * *sn + *d * *cs; + *b = scale * *cs + bcmis * *sn; + *c = -bcmax * *sn + z * *cs; + temp = 0.5 * ((bcmax * *cs + z * *sn) + (-scale * *sn + bcmis * * + cs)); + *a = temp; + *d = temp; + if (*c != 0.0) { + if (*b != 0.0) { + if ((*b < 0.0) == (*c < 0.0)) { + bcmis = std::sqrt(std::abs(*b)); + scale = std::sqrt(std::abs(*c)); + *a = bcmis * scale; + if (!(*c < 0.0)) { + p = *a; + } else { + p = -*a; + } + + tau = 1.0 / std::sqrt(std::abs(*b + *c)); + *a = temp + p; + *d = temp - p; + *b -= *c; + *c = 0.0; + bcmax = bcmis * tau; + bcmis = scale * tau; + temp = *cs * bcmax - *sn * bcmis; + *sn = *cs * bcmis + *sn * bcmax; + *cs = temp; + } + } else { + *b = -*c; + *c = 0.0; + temp = *cs; + *cs = -*sn; + *sn = temp; + } + } + } + } + } + + *rt1r = *a; + *rt2r = *d; + if (*c == 0.0) { + *rt1i = 0.0; + *rt2i = 0.0; + } else { + *rt1i = std::sqrt(std::abs(*b)) * std::sqrt(std::abs(*c)); + *rt2i = -*rt1i; + } + } + } + } + } +} + +// End of code generation (xdlanv2.cpp) diff --git a/cpp/RAT/xdlanv2.h b/cpp/RAT/xdlanv2.h new file mode 100644 index 00000000..a27ccefd --- /dev/null +++ b/cpp/RAT/xdlanv2.h @@ -0,0 +1,37 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xdlanv2.h +// +// Code generation for function 'xdlanv2' +// +#ifndef XDLANV2_H +#define XDLANV2_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + void xdlanv2(real_T *a, real_T *b, real_T *c, real_T *d, real_T *rt1r, + real_T *rt1i, real_T *rt2r, real_T *rt2i, real_T *cs, + real_T *sn); + } + } + } +} + +#endif + +// End of code generation (xdlanv2.h) diff --git a/cpp/RAT/xgehrd.cpp b/cpp/RAT/xgehrd.cpp new file mode 100644 index 00000000..1b585568 --- /dev/null +++ b/cpp/RAT/xgehrd.cpp @@ -0,0 +1,78 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xgehrd.cpp +// +// Code generation for function 'xgehrd' +// + +// Include files +#include "xgehrd.h" +#include "rt_nonfinite.h" +#include "xzlarf.h" +#include "xzlarfg.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace lapack + { + void xgehrd(::coder::array &a, ::coder::array + &tau) + { + ::coder::array work; + real_T alpha1; + int32_T i; + int32_T n; + int32_T unnamed_idx_0; + n = a.size(0); + if (a.size(0) < 1) { + i = 0; + } else { + i = a.size(0) - 1; + } + + tau.set_size(i); + unnamed_idx_0 = a.size(0); + work.set_size(unnamed_idx_0); + for (i = 0; i < unnamed_idx_0; i++) { + work[i] = 0.0; + } + + i = a.size(0); + for (int32_T b_i{0}; b_i <= i - 2; b_i++) { + real_T d; + int32_T i1; + int32_T in; + in = (b_i + 1) * n; + alpha1 = a[(b_i + a.size(0) * b_i) + 1]; + unnamed_idx_0 = b_i + 3; + if (unnamed_idx_0 > n) { + unnamed_idx_0 = n; + } + + d = reflapack::xzlarfg((n - b_i) - 1, &alpha1, a, unnamed_idx_0 + + b_i * n); + tau[b_i] = d; + a[(b_i + a.size(0) * b_i) + 1] = 1.0; + unnamed_idx_0 = (n - b_i) - 1; + i1 = (b_i + b_i * n) + 2; + reflapack::b_xzlarf(n, unnamed_idx_0, i1, d, a, in + 1, n, work); + reflapack::c_xzlarf(unnamed_idx_0, unnamed_idx_0, i1, d, a, (b_i + + in) + 2, n, work); + a[(b_i + a.size(0) * b_i) + 1] = alpha1; + } + } + } + } + } +} + +// End of code generation (xgehrd.cpp) diff --git a/cpp/RAT/xgehrd.h b/cpp/RAT/xgehrd.h new file mode 100644 index 00000000..4303f942 --- /dev/null +++ b/cpp/RAT/xgehrd.h @@ -0,0 +1,37 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xgehrd.h +// +// Code generation for function 'xgehrd' +// +#ifndef XGEHRD_H +#define XGEHRD_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace lapack + { + void xgehrd(::coder::array &a, ::coder::array + &tau); + } + } + } +} + +#endif + +// End of code generation (xgehrd.h) diff --git a/cpp/RAT/xgemm.cpp b/cpp/RAT/xgemm.cpp new file mode 100644 index 00000000..81e24dcd --- /dev/null +++ b/cpp/RAT/xgemm.cpp @@ -0,0 +1,84 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xgemm.cpp +// +// Code generation for function 'xgemm' +// + +// Include files +#include "xgemm.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace blas + { + void xgemm(int32_T m, int32_T n, int32_T k, real_T alpha1, const ::coder:: + array &A, int32_T lda, const ::coder::array< + real_T, 2U> &B, int32_T ldb, ::coder::array &C, + int32_T ldc) + { + if ((m != 0) && (n != 0)) { + int32_T br; + int32_T i; + int32_T i1; + int32_T lastColC; + lastColC = ldc * (n - 1); + for (int32_T cr{0}; ldc < 0 ? cr >= lastColC : cr <= lastColC; cr += + ldc) { + i = cr + 1; + i1 = cr + m; + for (int32_T ic{i}; ic <= i1; ic++) { + C[ic - 1] = 0.0; + } + } + + br = -1; + for (int32_T cr{0}; ldc < 0 ? cr >= lastColC : cr <= lastColC; cr += + ldc) { + int32_T ar; + ar = -1; + i = cr + 1; + i1 = cr + m; + for (int32_T ic{i}; ic <= i1; ic++) { + real_T temp; + temp = 0.0; + for (int32_T w{0}; w < k; w++) { + temp += A[(w + ar) + 1] * B[(w + br) + 1]; + } + + C[ic - 1] = C[ic - 1] + alpha1 * temp; + ar += lda; + } + + br += ldb; + } + } + } + + real_T xgemm(int32_T k, real_T alpha1, const ::coder::array + &A, const ::coder::array &B) + { + real_T temp; + temp = 0.0; + for (int32_T w{0}; w < k; w++) { + temp += A[w] * B[w]; + } + + return alpha1 * temp; + } + } + } + } +} + +// End of code generation (xgemm.cpp) diff --git a/cpp/RAT/xgemm.h b/cpp/RAT/xgemm.h new file mode 100644 index 00000000..13a5cbce --- /dev/null +++ b/cpp/RAT/xgemm.h @@ -0,0 +1,41 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xgemm.h +// +// Code generation for function 'xgemm' +// +#ifndef XGEMM_H +#define XGEMM_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace blas + { + void xgemm(int32_T m, int32_T n, int32_T k, real_T alpha1, const ::coder:: + array &A, int32_T lda, const ::coder::array< + real_T, 2U> &B, int32_T ldb, ::coder::array &C, + int32_T ldc); + real_T xgemm(int32_T k, real_T alpha1, const ::coder::array + &A, const ::coder::array &B); + } + } + } +} + +#endif + +// End of code generation (xgemm.h) diff --git a/cpp/RAT/xgemv.cpp b/cpp/RAT/xgemv.cpp new file mode 100644 index 00000000..ebd8e6dc --- /dev/null +++ b/cpp/RAT/xgemv.cpp @@ -0,0 +1,125 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xgemv.cpp +// +// Code generation for function 'xgemv' +// + +// Include files +#include "xgemv.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace blas + { + void b_xgemv(int32_T m, int32_T n, const ::coder::array &A, + int32_T ia0, int32_T lda, const ::coder::array + &x, int32_T ix0, ::coder::array &y) + { + if (m != 0) { + int32_T i; + int32_T ix; + for (ix = 0; ix < m; ix++) { + y[ix] = 0.0; + } + + ix = ix0; + i = ia0 + lda * (n - 1); + for (int32_T iac{ia0}; lda < 0 ? iac >= i : iac <= i; iac += lda) { + int32_T i1; + i1 = (iac + m) - 1; + for (int32_T ia{iac}; ia <= i1; ia++) { + int32_T i2; + i2 = ia - iac; + y[i2] = y[i2] + A[ia - 1] * x[ix - 1]; + } + + ix++; + } + } + } + + void c_xgemv(int32_T m, int32_T n, const ::coder::array &A, + int32_T ia0, int32_T lda, const ::coder::array + &x, int32_T ix0, ::coder::array &y) + { + ::coder::array b_y; + int32_T i; + int32_T loop_ub; + b_y.set_size(y.size(0)); + loop_ub = y.size(0); + for (i = 0; i < loop_ub; i++) { + b_y[i] = y[i]; + } + + if (n != 0) { + int32_T iy; + for (iy = 0; iy < n; iy++) { + b_y[iy] = 0.0; + } + + iy = 0; + i = ia0 + lda * (n - 1); + for (int32_T iac{ia0}; lda < 0 ? iac >= i : iac <= i; iac += lda) { + real_T c; + c = 0.0; + loop_ub = (iac + m) - 1; + for (int32_T ia{iac}; ia <= loop_ub; ia++) { + c += A[ia - 1] * x[((ix0 + ia) - iac) - 1]; + } + + b_y[iy] = b_y[iy] + c; + iy++; + } + } + + y.set_size(b_y.size(0)); + loop_ub = b_y.size(0); + for (i = 0; i < loop_ub; i++) { + y[i] = b_y[i]; + } + } + + void xgemv(int32_T m, int32_T n, const ::coder::array &A, + int32_T ia0, int32_T lda, const ::coder::array &x, + int32_T ix0, ::coder::array &y) + { + if (n != 0) { + int32_T i; + int32_T iy; + for (iy = 0; iy < n; iy++) { + y[iy] = 0.0; + } + + iy = 0; + i = ia0 + lda * (n - 1); + for (int32_T iac{ia0}; lda < 0 ? iac >= i : iac <= i; iac += lda) { + real_T c; + int32_T i1; + c = 0.0; + i1 = (iac + m) - 1; + for (int32_T ia{iac}; ia <= i1; ia++) { + c += A[ia - 1] * x[((ix0 + ia) - iac) - 1]; + } + + y[iy] = y[iy] + c; + iy++; + } + } + } + } + } + } +} + +// End of code generation (xgemv.cpp) diff --git a/cpp/RAT/xgemv.h b/cpp/RAT/xgemv.h new file mode 100644 index 00000000..c781e106 --- /dev/null +++ b/cpp/RAT/xgemv.h @@ -0,0 +1,44 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xgemv.h +// +// Code generation for function 'xgemv' +// +#ifndef XGEMV_H +#define XGEMV_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace blas + { + void b_xgemv(int32_T m, int32_T n, const ::coder::array &A, + int32_T ia0, int32_T lda, const ::coder::array + &x, int32_T ix0, ::coder::array &y); + void c_xgemv(int32_T m, int32_T n, const ::coder::array &A, + int32_T ia0, int32_T lda, const ::coder::array + &x, int32_T ix0, ::coder::array &y); + void xgemv(int32_T m, int32_T n, const ::coder::array &A, + int32_T ia0, int32_T lda, const ::coder::array &x, + int32_T ix0, ::coder::array &y); + } + } + } +} + +#endif + +// End of code generation (xgemv.h) diff --git a/cpp/RAT/xgeqp3.cpp b/cpp/RAT/xgeqp3.cpp new file mode 100644 index 00000000..ea093131 --- /dev/null +++ b/cpp/RAT/xgeqp3.cpp @@ -0,0 +1,89 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xgeqp3.cpp +// +// Code generation for function 'xgeqp3' +// + +// Include files +#include "xgeqp3.h" +#include "rt_nonfinite.h" +#include "xzgeqp3.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace lapack + { + void xgeqp3(::coder::array &A, ::coder::array + &tau, ::coder::array &jpvt) + { + int32_T k; + int32_T minmana; + int32_T n; + boolean_T guard1; + n = A.size(1) - 1; + k = A.size(0); + minmana = A.size(1); + if (k <= minmana) { + minmana = k; + } + + tau.set_size(minmana); + for (k = 0; k < minmana; k++) { + tau[k] = 0.0; + } + + guard1 = false; + if ((A.size(0) == 0) || (A.size(1) == 0)) { + guard1 = true; + } else { + k = A.size(0); + minmana = A.size(1); + if (k <= minmana) { + minmana = k; + } + + if (minmana < 1) { + guard1 = true; + } else { + minmana = A.size(1); + jpvt.set_size(1, minmana); + for (k = 0; k < minmana; k++) { + jpvt[k] = 0; + } + + for (k = 0; k <= n; k++) { + jpvt[k] = k + 1; + } + + reflapack::qrpf(A, A.size(0), A.size(1), tau, jpvt); + } + } + + if (guard1) { + minmana = A.size(1); + jpvt.set_size(1, minmana); + for (k = 0; k < minmana; k++) { + jpvt[k] = 0; + } + + for (minmana = 0; minmana <= n; minmana++) { + jpvt[minmana] = minmana + 1; + } + } + } + } + } + } +} + +// End of code generation (xgeqp3.cpp) diff --git a/cpp/RAT/xgeqp3.h b/cpp/RAT/xgeqp3.h new file mode 100644 index 00000000..be9d901c --- /dev/null +++ b/cpp/RAT/xgeqp3.h @@ -0,0 +1,37 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xgeqp3.h +// +// Code generation for function 'xgeqp3' +// +#ifndef XGEQP3_H +#define XGEQP3_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace lapack + { + void xgeqp3(::coder::array &A, ::coder::array + &tau, ::coder::array &jpvt); + } + } + } +} + +#endif + +// End of code generation (xgeqp3.h) diff --git a/cpp/RAT/xgerc.cpp b/cpp/RAT/xgerc.cpp new file mode 100644 index 00000000..12da5e30 --- /dev/null +++ b/cpp/RAT/xgerc.cpp @@ -0,0 +1,76 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xgerc.cpp +// +// Code generation for function 'xgerc' +// + +// Include files +#include "xgerc.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace blas + { + void xgerc(int32_T m, int32_T n, real_T alpha1, const ::coder::array< + real_T, 1U> &x, int32_T iy0, ::coder::array &A, + int32_T ia0, int32_T lda) + { + if (!(alpha1 == 0.0)) { + int32_T jA; + jA = ia0; + for (int32_T j{0}; j < n; j++) { + int32_T i; + i = (iy0 + j) - 1; + if (A[i] != 0.0) { + real_T temp; + temp = A[i] * alpha1; + i = m + jA; + for (int32_T ijA{jA}; ijA < i; ijA++) { + A[ijA - 1] = A[ijA - 1] + x[ijA - jA] * temp; + } + } + + jA += lda; + } + } + } + + void xgerc(int32_T m, int32_T n, real_T alpha1, int32_T ix0, const :: + coder::array &y, ::coder::array &A, + int32_T ia0, int32_T lda) + { + if (!(alpha1 == 0.0)) { + int32_T jA; + jA = ia0; + for (int32_T j{0}; j < n; j++) { + if (y[j] != 0.0) { + real_T temp; + int32_T i; + temp = y[j] * alpha1; + i = m + jA; + for (int32_T ijA{jA}; ijA < i; ijA++) { + A[ijA - 1] = A[ijA - 1] + A[((ix0 + ijA) - jA) - 1] * temp; + } + } + + jA += lda; + } + } + } + } + } + } +} + +// End of code generation (xgerc.cpp) diff --git a/cpp/RAT/xgerc.h b/cpp/RAT/xgerc.h new file mode 100644 index 00000000..5f9b904b --- /dev/null +++ b/cpp/RAT/xgerc.h @@ -0,0 +1,41 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xgerc.h +// +// Code generation for function 'xgerc' +// +#ifndef XGERC_H +#define XGERC_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace blas + { + void xgerc(int32_T m, int32_T n, real_T alpha1, const ::coder::array< + real_T, 1U> &x, int32_T iy0, ::coder::array &A, + int32_T ia0, int32_T lda); + void xgerc(int32_T m, int32_T n, real_T alpha1, int32_T ix0, const :: + coder::array &y, ::coder::array &A, + int32_T ia0, int32_T lda); + } + } + } +} + +#endif + +// End of code generation (xgerc.h) diff --git a/cpp/RAT/xgeru.cpp b/cpp/RAT/xgeru.cpp new file mode 100644 index 00000000..1398374b --- /dev/null +++ b/cpp/RAT/xgeru.cpp @@ -0,0 +1,50 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xgeru.cpp +// +// Code generation for function 'xgeru' +// + +// Include files +#include "xgeru.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace blas + { + void xgeru(int32_T m, int32_T n, int32_T ix0, int32_T iy0, int32_T incy, + ::coder::array &A, int32_T ia0, int32_T lda) + { + int32_T jA; + jA = ia0; + for (int32_T j{0}; j < n; j++) { + real_T yjy; + int32_T yjy_tmp; + yjy_tmp = (iy0 + j * incy) - 1; + yjy = A[yjy_tmp]; + if (A[yjy_tmp] != 0.0) { + yjy_tmp = m + jA; + for (int32_T ijA{jA}; ijA < yjy_tmp; ijA++) { + A[ijA - 1] = A[ijA - 1] + A[((ix0 + ijA) - jA) - 1] * -yjy; + } + } + + jA += lda; + } + } + } + } + } +} + +// End of code generation (xgeru.cpp) diff --git a/cpp/RAT/xgeru.h b/cpp/RAT/xgeru.h new file mode 100644 index 00000000..8e8addc6 --- /dev/null +++ b/cpp/RAT/xgeru.h @@ -0,0 +1,37 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xgeru.h +// +// Code generation for function 'xgeru' +// +#ifndef XGERU_H +#define XGERU_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace blas + { + void xgeru(int32_T m, int32_T n, int32_T ix0, int32_T iy0, int32_T incy, + ::coder::array &A, int32_T ia0, int32_T lda); + } + } + } +} + +#endif + +// End of code generation (xgeru.h) diff --git a/cpp/RAT/xgetrf.cpp b/cpp/RAT/xgetrf.cpp new file mode 100644 index 00000000..17f0358c --- /dev/null +++ b/cpp/RAT/xgetrf.cpp @@ -0,0 +1,172 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xgetrf.cpp +// +// Code generation for function 'xgetrf' +// + +// Include files +#include "xgetrf.h" +#include "colon.h" +#include "ixamax.h" +#include "rt_nonfinite.h" +#include "xgeru.h" +#include "xswap.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace lapack + { + void xgetrf(int32_T m, int32_T n, ::coder::array &A, int32_T + lda) + { + if ((m >= 1) && (n >= 1)) { + int32_T u0; + u0 = m - 1; + if (u0 > n) { + u0 = n; + } + + for (int32_T j{0}; j < u0; j++) { + int32_T b_tmp; + int32_T jp1j; + int32_T jpiv_offset; + int32_T mmj; + mmj = m - j; + b_tmp = j * (lda + 1); + jp1j = b_tmp + 2; + jpiv_offset = blas::ixamax(mmj, A, b_tmp + 1) - 1; + if (A[b_tmp + jpiv_offset] != 0.0) { + if (blas::ixamax(mmj, A, b_tmp + 1) - 1 != 0) { + blas::xswap(n, A, j + 1, lda, (j + jpiv_offset) + 1, lda); + } + + jpiv_offset = b_tmp + mmj; + for (int32_T i{jp1j}; i <= jpiv_offset; i++) { + A[i - 1] = A[i - 1] / A[b_tmp]; + } + } + + jpiv_offset = b_tmp + lda; + blas::xgeru(mmj - 1, (n - j) - 1, b_tmp + 2, jpiv_offset + 1, lda, + A, jpiv_offset + 2, lda); + } + } + } + + void xgetrf(int32_T m, int32_T n, ::coder::array &A, int32_T + lda, ::coder::array &ipiv) + { + int32_T y; + if (m <= n) { + y = m; + } else { + y = n; + } + + eml_integer_colon_dispatcher(y, ipiv); + if ((m >= 1) && (n >= 1)) { + int32_T u0; + u0 = m - 1; + if (u0 > n) { + u0 = n; + } + + for (int32_T j{0}; j < u0; j++) { + int32_T b_tmp; + int32_T jp1j; + int32_T jpiv_offset; + int32_T mmj; + mmj = m - j; + b_tmp = j * (lda + 1); + jp1j = b_tmp + 2; + y = blas::ixamax(mmj, A, b_tmp + 1); + jpiv_offset = blas::ixamax(mmj, A, b_tmp + 1); + if (A[(b_tmp + jpiv_offset) - 1] != 0.0) { + if (y - 1 != 0) { + ipiv[j] = j + y; + blas::xswap(n, A, j + 1, lda, j + jpiv_offset, lda); + } + + y = b_tmp + mmj; + for (jpiv_offset = jp1j; jpiv_offset <= y; jpiv_offset++) { + A[jpiv_offset - 1] = A[jpiv_offset - 1] / A[b_tmp]; + } + } + + y = b_tmp + lda; + blas::xgeru(mmj - 1, (n - j) - 1, b_tmp + 2, y + 1, lda, A, y + 2, + lda); + } + } + } + + void xgetrf(int32_T m, int32_T n, ::coder::array &A, int32_T + lda, ::coder::array &ipiv, int32_T *info) + { + int32_T y; + if (m <= n) { + y = m; + } else { + y = n; + } + + eml_integer_colon_dispatcher(y, ipiv); + *info = 0; + if ((m >= 1) && (n >= 1)) { + int32_T u0; + u0 = m - 1; + if (u0 > n) { + u0 = n; + } + + for (int32_T j{0}; j < u0; j++) { + int32_T b_tmp; + int32_T jp1j; + int32_T jpiv_offset; + int32_T mmj; + mmj = m - j; + b_tmp = j * (lda + 1); + jp1j = b_tmp + 2; + y = blas::ixamax(mmj, A, b_tmp + 1); + jpiv_offset = blas::ixamax(mmj, A, b_tmp + 1) - 1; + if (A[b_tmp + jpiv_offset] != 0.0) { + if (y - 1 != 0) { + ipiv[j] = j + y; + blas::xswap(n, A, j + 1, lda, (j + jpiv_offset) + 1, lda); + } + + y = b_tmp + mmj; + for (jpiv_offset = jp1j; jpiv_offset <= y; jpiv_offset++) { + A[jpiv_offset - 1] = A[jpiv_offset - 1] / A[b_tmp]; + } + } else { + *info = j + 1; + } + + y = b_tmp + lda; + blas::xgeru(mmj - 1, (n - j) - 1, b_tmp + 2, y + 1, lda, A, y + 2, + lda); + } + + if ((*info == 0) && (m <= n) && (!(A[(m + A.size(0) * (m - 1)) - 1] + != 0.0))) { + *info = m; + } + } + } + } + } + } +} + +// End of code generation (xgetrf.cpp) diff --git a/cpp/RAT/xgetrf.h b/cpp/RAT/xgetrf.h new file mode 100644 index 00000000..79d06dde --- /dev/null +++ b/cpp/RAT/xgetrf.h @@ -0,0 +1,41 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xgetrf.h +// +// Code generation for function 'xgetrf' +// +#ifndef XGETRF_H +#define XGETRF_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace lapack + { + void xgetrf(int32_T m, int32_T n, ::coder::array &A, int32_T + lda); + void xgetrf(int32_T m, int32_T n, ::coder::array &A, int32_T + lda, ::coder::array &ipiv); + void xgetrf(int32_T m, int32_T n, ::coder::array &A, int32_T + lda, ::coder::array &ipiv, int32_T *info); + } + } + } +} + +#endif + +// End of code generation (xgetrf.h) diff --git a/cpp/RAT/xnrm2.cpp b/cpp/RAT/xnrm2.cpp new file mode 100644 index 00000000..08777e8e --- /dev/null +++ b/cpp/RAT/xnrm2.cpp @@ -0,0 +1,235 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xnrm2.cpp +// +// Code generation for function 'xnrm2' +// + +// Include files +#include "xnrm2.h" +#include "RATMain_rtwutil.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace blas + { + real_T b_xnrm2(int32_T n, const ::coder::array &x) + { + real_T y; + y = 0.0; + if (n >= 1) { + if (n == 1) { + y = std::abs(x[1]); + } else { + real_T scale; + int32_T kend; + scale = 3.3121686421112381E-170; + kend = n + 1; + for (int32_T k{2}; k <= kend; k++) { + real_T absxk; + absxk = std::abs(x[k - 1]); + if (absxk > scale) { + real_T t; + t = scale / absxk; + y = y * t * t + 1.0; + scale = absxk; + } else { + real_T t; + t = absxk / scale; + y += t * t; + } + } + + y = scale * std::sqrt(y); + } + } + + return y; + } + + real_T xnrm2(int32_T n, const ::coder::array &x) + { + real_T y; + y = 0.0; + if (n >= 1) { + if (n == 1) { + y = std::abs(x[0]); + } else { + real_T scale; + scale = 3.3121686421112381E-170; + for (int32_T k{0}; k < n; k++) { + real_T absxk; + absxk = std::abs(x[k]); + if (absxk > scale) { + real_T t; + t = scale / absxk; + y = y * t * t + 1.0; + scale = absxk; + } else { + real_T t; + t = absxk / scale; + y += t * t; + } + } + + y = scale * std::sqrt(y); + } + } + + return y; + } + + real_T xnrm2(int32_T n, const ::coder::array &x, int32_T + ix0) + { + real_T y; + y = 0.0; + if (n == 1) { + y = rt_hypotd_snf(x[ix0 - 1].re, x[ix0 - 1].im); + } else { + real_T scale; + int32_T kend; + scale = 3.3121686421112381E-170; + kend = (ix0 + n) - 1; + for (int32_T k{ix0}; k <= kend; k++) { + real_T absxk; + real_T t; + absxk = std::abs(x[k - 1].re); + if (absxk > scale) { + t = scale / absxk; + y = y * t * t + 1.0; + scale = absxk; + } else { + t = absxk / scale; + y += t * t; + } + + absxk = std::abs(x[k - 1].im); + if (absxk > scale) { + t = scale / absxk; + y = y * t * t + 1.0; + scale = absxk; + } else { + t = absxk / scale; + y += t * t; + } + } + + y = scale * std::sqrt(y); + } + + return y; + } + + real_T xnrm2(int32_T n, const ::coder::array &x, int32_T ix0) + { + real_T y; + y = 0.0; + if (n >= 1) { + if (n == 1) { + y = std::abs(x[ix0 - 1]); + } else { + real_T scale; + int32_T kend; + scale = 3.3121686421112381E-170; + kend = (ix0 + n) - 1; + for (int32_T k{ix0}; k <= kend; k++) { + real_T absxk; + absxk = std::abs(x[k - 1]); + if (absxk > scale) { + real_T t; + t = scale / absxk; + y = y * t * t + 1.0; + scale = absxk; + } else { + real_T t; + t = absxk / scale; + y += t * t; + } + } + + y = scale * std::sqrt(y); + } + } + + return y; + } + + real_T xnrm2(int32_T n, const real_T x[3]) + { + real_T y; + y = 0.0; + if (n >= 1) { + if (n == 1) { + y = std::abs(x[1]); + } else { + real_T absxk; + real_T scale; + real_T t; + scale = 3.3121686421112381E-170; + absxk = std::abs(x[1]); + if (absxk > 3.3121686421112381E-170) { + y = 1.0; + scale = absxk; + } else { + t = absxk / 3.3121686421112381E-170; + y = t * t; + } + + absxk = std::abs(x[2]); + if (absxk > scale) { + t = scale / absxk; + y = y * t * t + 1.0; + scale = absxk; + } else { + t = absxk / scale; + y += t * t; + } + + y = scale * std::sqrt(y); + } + } + + return y; + } + + real_T xnrm2(int32_T n, const ::coder::array &x) + { + real_T scale; + real_T y; + y = 0.0; + scale = 3.3121686421112381E-170; + for (int32_T k{0}; k < n; k++) { + real_T absxk; + absxk = std::abs(x[k]); + if (absxk > scale) { + real_T t; + t = scale / absxk; + y = y * t * t + 1.0; + scale = absxk; + } else { + real_T t; + t = absxk / scale; + y += t * t; + } + } + + return scale * std::sqrt(y); + } + } + } + } +} + +// End of code generation (xnrm2.cpp) diff --git a/cpp/RAT/xnrm2.h b/cpp/RAT/xnrm2.h new file mode 100644 index 00000000..054b891a --- /dev/null +++ b/cpp/RAT/xnrm2.h @@ -0,0 +1,42 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xnrm2.h +// +// Code generation for function 'xnrm2' +// +#ifndef XNRM2_H +#define XNRM2_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace blas + { + real_T b_xnrm2(int32_T n, const ::coder::array &x); + real_T xnrm2(int32_T n, const ::coder::array &x); + real_T xnrm2(int32_T n, const ::coder::array &x, int32_T + ix0); + real_T xnrm2(int32_T n, const ::coder::array &x, int32_T ix0); + real_T xnrm2(int32_T n, const real_T x[3]); + real_T xnrm2(int32_T n, const ::coder::array &x); + } + } + } +} + +#endif + +// End of code generation (xnrm2.h) diff --git a/cpp/RAT/xrot.cpp b/cpp/RAT/xrot.cpp new file mode 100644 index 00000000..a468b02d --- /dev/null +++ b/cpp/RAT/xrot.cpp @@ -0,0 +1,63 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xrot.cpp +// +// Code generation for function 'xrot' +// + +// Include files +#include "xrot.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace blas + { + void xrot(int32_T n, ::coder::array &x, int32_T ix0, int32_T + incx, int32_T iy0, int32_T incy, real_T c, real_T s) + { + if (n >= 1) { + for (int32_T k{0}; k < n; k++) { + real_T temp; + int32_T b_temp_tmp; + int32_T temp_tmp; + temp_tmp = (iy0 + k * incx) - 1; + b_temp_tmp = (ix0 + k * incy) - 1; + temp = c * x[b_temp_tmp] + s * x[temp_tmp]; + x[temp_tmp] = c * x[temp_tmp] - s * x[b_temp_tmp]; + x[b_temp_tmp] = temp; + } + } + } + + void xrot(int32_T n, ::coder::array &x, int32_T ix0, int32_T + iy0, real_T c, real_T s) + { + if (n >= 1) { + for (int32_T k{0}; k < n; k++) { + real_T temp; + int32_T b_temp_tmp; + int32_T temp_tmp; + temp_tmp = (iy0 + k) - 1; + b_temp_tmp = (ix0 + k) - 1; + temp = c * x[b_temp_tmp] + s * x[temp_tmp]; + x[temp_tmp] = c * x[temp_tmp] - s * x[b_temp_tmp]; + x[b_temp_tmp] = temp; + } + } + } + } + } + } +} + +// End of code generation (xrot.cpp) diff --git a/cpp/RAT/xrot.h b/cpp/RAT/xrot.h new file mode 100644 index 00000000..65a233d0 --- /dev/null +++ b/cpp/RAT/xrot.h @@ -0,0 +1,39 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xrot.h +// +// Code generation for function 'xrot' +// +#ifndef XROT_H +#define XROT_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace blas + { + void xrot(int32_T n, ::coder::array &x, int32_T ix0, int32_T + incx, int32_T iy0, int32_T incy, real_T c, real_T s); + void xrot(int32_T n, ::coder::array &x, int32_T ix0, int32_T + iy0, real_T c, real_T s); + } + } + } +} + +#endif + +// End of code generation (xrot.h) diff --git a/cpp/RAT/xswap.cpp b/cpp/RAT/xswap.cpp new file mode 100644 index 00000000..3064ff68 --- /dev/null +++ b/cpp/RAT/xswap.cpp @@ -0,0 +1,59 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xswap.cpp +// +// Code generation for function 'xswap' +// + +// Include files +#include "xswap.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace blas + { + void xswap(int32_T n, ::coder::array &x, int32_T ix0, + int32_T iy0) + { + for (int32_T k{0}; k < n; k++) { + real_T temp; + int32_T i; + int32_T temp_tmp; + temp_tmp = (ix0 + k) - 1; + temp = x[temp_tmp]; + i = (iy0 + k) - 1; + x[temp_tmp] = x[i]; + x[i] = temp; + } + } + + void xswap(int32_T n, ::coder::array &x, int32_T ix0, + int32_T incx, int32_T iy0, int32_T incy) + { + for (int32_T k{0}; k < n; k++) { + real_T temp; + int32_T i; + int32_T temp_tmp; + temp_tmp = (ix0 + k * incx) - 1; + temp = x[temp_tmp]; + i = (iy0 + k * incy) - 1; + x[temp_tmp] = x[i]; + x[i] = temp; + } + } + } + } + } +} + +// End of code generation (xswap.cpp) diff --git a/cpp/RAT/xswap.h b/cpp/RAT/xswap.h new file mode 100644 index 00000000..d63fe545 --- /dev/null +++ b/cpp/RAT/xswap.h @@ -0,0 +1,39 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xswap.h +// +// Code generation for function 'xswap' +// +#ifndef XSWAP_H +#define XSWAP_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace blas + { + void xswap(int32_T n, ::coder::array &x, int32_T ix0, + int32_T iy0); + void xswap(int32_T n, ::coder::array &x, int32_T ix0, + int32_T incx, int32_T iy0, int32_T incy); + } + } + } +} + +#endif + +// End of code generation (xswap.h) diff --git a/cpp/RAT/xtrsm.cpp b/cpp/RAT/xtrsm.cpp new file mode 100644 index 00000000..05d348aa --- /dev/null +++ b/cpp/RAT/xtrsm.cpp @@ -0,0 +1,89 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xtrsm.cpp +// +// Code generation for function 'xtrsm' +// + +// Include files +#include "xtrsm.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace blas + { + void b_xtrsm(int32_T m, int32_T n, const ::coder::array &A, + int32_T lda, ::coder::array &B, int32_T ldb) + { + if ((n != 0) && ((B.size(0) != 0) && (B.size(1) != 0))) { + for (int32_T j{n}; j >= 1; j--) { + int32_T i; + int32_T jAcol; + int32_T jBcol; + jBcol = ldb * (j - 1); + jAcol = lda * (j - 1) - 1; + i = j + 1; + for (int32_T k{i}; k <= n; k++) { + int32_T i1; + int32_T kBcol; + kBcol = ldb * (k - 1); + i1 = k + jAcol; + if (A[i1] != 0.0) { + int32_T i2; + i2 = static_cast(m); + for (int32_T b_i{0}; b_i < i2; b_i++) { + B[jBcol] = B[jBcol] - A[i1] * B[kBcol]; + } + } + } + } + } + } + + void xtrsm(int32_T m, int32_T n, const ::coder::array &A, + int32_T lda, ::coder::array &B, int32_T ldb) + { + if ((n != 0) && ((B.size(0) != 0) && (B.size(1) != 0))) { + int32_T i; + i = static_cast(m); + for (int32_T j{0}; j < n; j++) { + real_T temp; + int32_T jAcol; + int32_T jBcol; + jBcol = ldb * j; + jAcol = lda * j; + for (int32_T k{0}; k < j; k++) { + int32_T i1; + int32_T kBcol; + kBcol = ldb * k; + i1 = k + jAcol; + if (A[i1] != 0.0) { + for (int32_T b_i{0}; b_i < i; b_i++) { + B[jBcol] = B[jBcol] - A[i1] * B[kBcol]; + } + } + } + + temp = 1.0 / A[j + jAcol]; + for (int32_T b_i{0}; b_i < i; b_i++) { + B[jBcol] = temp * B[jBcol]; + } + } + } + } + } + } + } +} + +// End of code generation (xtrsm.cpp) diff --git a/cpp/RAT/xtrsm.h b/cpp/RAT/xtrsm.h new file mode 100644 index 00000000..b05294b1 --- /dev/null +++ b/cpp/RAT/xtrsm.h @@ -0,0 +1,39 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xtrsm.h +// +// Code generation for function 'xtrsm' +// +#ifndef XTRSM_H +#define XTRSM_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace blas + { + void b_xtrsm(int32_T m, int32_T n, const ::coder::array &A, + int32_T lda, ::coder::array &B, int32_T ldb); + void xtrsm(int32_T m, int32_T n, const ::coder::array &A, + int32_T lda, ::coder::array &B, int32_T ldb); + } + } + } +} + +#endif + +// End of code generation (xtrsm.h) diff --git a/cpp/RAT/xtrsv.cpp b/cpp/RAT/xtrsv.cpp new file mode 100644 index 00000000..ed4e49b1 --- /dev/null +++ b/cpp/RAT/xtrsv.cpp @@ -0,0 +1,102 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xtrsv.cpp +// +// Code generation for function 'xtrsv' +// + +// Include files +#include "xtrsv.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace blas + { + void b_xtrsv(int32_T n, const ::coder::array &A, int32_T lda, + ::coder::array &x) + { + if ((A.size(0) != 0) && (A.size(1) != 0)) { + for (int32_T j{n}; j >= 1; j--) { + int32_T jjA; + jjA = (j + (j - 1) * lda) - 1; + x[j - 1] = x[j - 1] / A[jjA]; + for (int32_T i{0}; i <= j - 2; i++) { + int32_T ix; + ix = (j - i) - 2; + x[ix] = x[ix] - x[j - 1] * A[(jjA - i) - 1]; + } + } + } + } + + void c_xtrsv(int32_T n, const ::coder::array &A, int32_T lda, + ::coder::array &x) + { + if ((A.size(0) != 0) && (A.size(1) != 0)) { + for (int32_T j{0}; j < n; j++) { + real_T temp; + int32_T jA; + jA = j * lda; + temp = x[j]; + for (int32_T i{0}; i < j; i++) { + temp -= A[jA + i] * x[i]; + } + + x[j] = temp / A[jA + j]; + } + } + } + + void d_xtrsv(int32_T n, const ::coder::array &A, int32_T lda, + ::coder::array &x) + { + if ((A.size(0) != 0) && (A.size(1) != 0)) { + for (int32_T j{n}; j >= 1; j--) { + real_T temp; + int32_T i; + int32_T jA; + jA = (j - 1) * lda; + temp = x[j - 1]; + i = j + 1; + for (int32_T b_i{n}; b_i >= i; b_i--) { + temp -= A[(jA + b_i) - 1] * x[b_i - 1]; + } + + x[j - 1] = temp; + } + } + } + + void xtrsv(int32_T n, const ::coder::array &A, int32_T lda, :: + coder::array &x) + { + if ((A.size(0) != 0) && (A.size(1) != 0)) { + for (int32_T j{0}; j < n; j++) { + int32_T i; + int32_T jjA; + jjA = j + j * lda; + i = n - j; + for (int32_T b_i{0}; b_i <= i - 2; b_i++) { + int32_T ix; + ix = (j + b_i) + 1; + x[ix] = x[ix] - x[j] * A[(jjA + b_i) + 1]; + } + } + } + } + } + } + } +} + +// End of code generation (xtrsv.cpp) diff --git a/cpp/RAT/xtrsv.h b/cpp/RAT/xtrsv.h new file mode 100644 index 00000000..f63320e8 --- /dev/null +++ b/cpp/RAT/xtrsv.h @@ -0,0 +1,43 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xtrsv.h +// +// Code generation for function 'xtrsv' +// +#ifndef XTRSV_H +#define XTRSV_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace blas + { + void b_xtrsv(int32_T n, const ::coder::array &A, int32_T lda, + ::coder::array &x); + void c_xtrsv(int32_T n, const ::coder::array &A, int32_T lda, + ::coder::array &x); + void d_xtrsv(int32_T n, const ::coder::array &A, int32_T lda, + ::coder::array &x); + void xtrsv(int32_T n, const ::coder::array &A, int32_T lda, :: + coder::array &x); + } + } + } +} + +#endif + +// End of code generation (xtrsv.h) diff --git a/cpp/RAT/xungorghr.cpp b/cpp/RAT/xungorghr.cpp new file mode 100644 index 00000000..d00065fc --- /dev/null +++ b/cpp/RAT/xungorghr.cpp @@ -0,0 +1,74 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xungorghr.cpp +// +// Code generation for function 'xungorghr' +// + +// Include files +#include "xungorghr.h" +#include "rt_nonfinite.h" +#include "xzungqr.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace lapack + { + void xungorghr(int32_T n, int32_T ihi, ::coder::array &A, + int32_T lda, const ::coder::array &tau) + { + if (n != 0) { + int32_T b_i; + int32_T ia; + for (int32_T j{ihi}; j >= 2; j--) { + int32_T iajm1; + ia = (j - 1) * lda - 1; + for (int32_T i{0}; i <= j - 2; i++) { + A[(ia + i) + 1] = 0.0; + } + + iajm1 = ia - lda; + b_i = j + 1; + for (int32_T i{b_i}; i <= ihi; i++) { + A[ia + i] = A[iajm1 + i]; + } + + b_i = ihi + 1; + for (int32_T i{b_i}; i <= n; i++) { + A[ia + i] = 0.0; + } + } + + for (int32_T i{0}; i < n; i++) { + A[i] = 0.0; + } + + A[0] = 1.0; + b_i = ihi + 1; + for (int32_T j{b_i}; j <= n; j++) { + ia = (j - 1) * lda; + for (int32_T i{0}; i < n; i++) { + A[ia + i] = 0.0; + } + + A[(ia + j) - 1] = 1.0; + } + + reflapack::xzungqr(ihi - 1, ihi - 1, ihi - 1, A, lda + 2, lda, tau); + } + } + } + } + } +} + +// End of code generation (xungorghr.cpp) diff --git a/cpp/RAT/xungorghr.h b/cpp/RAT/xungorghr.h new file mode 100644 index 00000000..687d951b --- /dev/null +++ b/cpp/RAT/xungorghr.h @@ -0,0 +1,37 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xungorghr.h +// +// Code generation for function 'xungorghr' +// +#ifndef XUNGORGHR_H +#define XUNGORGHR_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace lapack + { + void xungorghr(int32_T n, int32_T ihi, ::coder::array &A, + int32_T lda, const ::coder::array &tau); + } + } + } +} + +#endif + +// End of code generation (xungorghr.h) diff --git a/cpp/RAT/xunormqr.cpp b/cpp/RAT/xunormqr.cpp new file mode 100644 index 00000000..f986b78a --- /dev/null +++ b/cpp/RAT/xunormqr.cpp @@ -0,0 +1,102 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xunormqr.cpp +// +// Code generation for function 'xunormqr' +// + +// Include files +#include "xunormqr.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace lapack + { + void xunormqr(const ::coder::array &Q, ::coder::array &C, const ::coder::array &tau) + { + int32_T m; + int32_T mn; + int32_T nb; + int32_T u0; + m = Q.size(0); + nb = C.size(1); + u0 = Q.size(0); + mn = Q.size(1); + if (u0 <= mn) { + mn = u0; + } + + for (int32_T j{0}; j < mn; j++) { + if (tau[j] != 0.0) { + for (int32_T k{0}; k < nb; k++) { + real_T wj; + wj = C[j]; + u0 = j + 2; + for (int32_T i{u0}; i <= m; i++) { + wj += Q[(i + Q.size(0) * j) - 1] * C[i - 1]; + } + + wj *= tau[j]; + if (wj != 0.0) { + C[j] = C[j] - wj; + for (int32_T i{u0}; i <= m; i++) { + C[i - 1] = C[i - 1] - Q[(i + Q.size(0) * j) - 1] * wj; + } + } + } + } + } + } + + void xunormqr(const ::coder::array &Q, ::coder::array &C, const real_T tau_data[]) + { + int32_T i; + int32_T m; + int32_T nb; + m = Q.size(0); + nb = C.size(1); + if (Q.size(0) < 1) { + i = -1; + } else { + i = 0; + } + + for (int32_T j{0}; j <= i; j++) { + if (tau_data[0] != 0.0) { + for (int32_T k{0}; k < nb; k++) { + real_T wj; + wj = C[C.size(0) * k]; + for (int32_T b_i{2}; b_i <= m; b_i++) { + wj += Q[b_i - 1] * C[(b_i + C.size(0) * k) - 1]; + } + + wj *= tau_data[0]; + if (wj != 0.0) { + C[C.size(0) * k] = C[C.size(0) * k] - wj; + for (int32_T b_i{2}; b_i <= m; b_i++) { + C[(b_i + C.size(0) * k) - 1] = C[(b_i + C.size(0) * k) - 1] + - Q[b_i - 1] * wj; + } + } + } + } + } + } + } + } + } +} + +// End of code generation (xunormqr.cpp) diff --git a/cpp/RAT/xunormqr.h b/cpp/RAT/xunormqr.h new file mode 100644 index 00000000..340e1313 --- /dev/null +++ b/cpp/RAT/xunormqr.h @@ -0,0 +1,39 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xunormqr.h +// +// Code generation for function 'xunormqr' +// +#ifndef XUNORMQR_H +#define XUNORMQR_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace lapack + { + void xunormqr(const ::coder::array &Q, ::coder::array &C, const ::coder::array &tau); + void xunormqr(const ::coder::array &Q, ::coder::array &C, const real_T tau_data[]); + } + } + } +} + +#endif + +// End of code generation (xunormqr.h) diff --git a/cpp/RAT/xzgeev.cpp b/cpp/RAT/xzgeev.cpp new file mode 100644 index 00000000..4fda97f3 --- /dev/null +++ b/cpp/RAT/xzgeev.cpp @@ -0,0 +1,83 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzgeev.cpp +// +// Code generation for function 'xzgeev' +// + +// Include files +#include "xzgeev.h" +#include "RATMain_data.h" +#include "rt_nonfinite.h" +#include "xnrm2.h" +#include "xzggev.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + void xzgeev(const ::coder::array &A, int32_T *info, ::coder:: + array &alpha1, ::coder::array + &beta1, ::coder::array &V) + { + ::coder::array At; + int32_T i; + int32_T lastcol; + int32_T n; + At.set_size(A.size(0), A.size(1)); + n = A.size(1); + for (i = 0; i < n; i++) { + lastcol = A.size(0); + for (int32_T coltop{0}; coltop < lastcol; coltop++) { + At[coltop + At.size(0) * i].re = A[coltop + A.size(0) * i]; + At[coltop + At.size(0) * i].im = 0.0; + } + } + + xzggev(At, info, alpha1, beta1, V); + n = A.size(0); + if (A.size(0) > 0) { + lastcol = (A.size(0) - 1) * A.size(0) + 1; + for (int32_T coltop{1}; n < 0 ? coltop >= lastcol : coltop <= + lastcol; coltop += n) { + real_T colnorm; + colnorm = blas::xnrm2(n, V, coltop); + i = (coltop + n) - 1; + for (int32_T j{coltop}; j <= i; j++) { + real_T ai; + real_T im; + real_T re; + im = V[j - 1].re; + ai = V[j - 1].im; + if (ai == 0.0) { + re = im / colnorm; + im = 0.0; + } else if (im == 0.0) { + re = 0.0; + im = ai / colnorm; + } else { + re = im / colnorm; + im = ai / colnorm; + } + + V[j - 1].re = re; + V[j - 1].im = im; + } + } + } + } + } + } + } +} + +// End of code generation (xzgeev.cpp) diff --git a/cpp/RAT/xzgeev.h b/cpp/RAT/xzgeev.h new file mode 100644 index 00000000..8e4fdee0 --- /dev/null +++ b/cpp/RAT/xzgeev.h @@ -0,0 +1,38 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzgeev.h +// +// Code generation for function 'xzgeev' +// +#ifndef XZGEEV_H +#define XZGEEV_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + void xzgeev(const ::coder::array &A, int32_T *info, ::coder:: + array &alpha1, ::coder::array + &beta1, ::coder::array &V); + } + } + } +} + +#endif + +// End of code generation (xzgeev.h) diff --git a/cpp/RAT/xzgeqp3.cpp b/cpp/RAT/xzgeqp3.cpp new file mode 100644 index 00000000..363ddca7 --- /dev/null +++ b/cpp/RAT/xzgeqp3.cpp @@ -0,0 +1,220 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzgeqp3.cpp +// +// Code generation for function 'xzgeqp3' +// + +// Include files +#include "xzgeqp3.h" +#include "ixamax.h" +#include "rt_nonfinite.h" +#include "xnrm2.h" +#include "xswap.h" +#include "xzlarf.h" +#include "xzlarfg.h" +#include "coder_array.h" +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + static int32_T qrpf(::coder::array &A, int32_T m, real_T + tau_data[]); + } + } + } +} + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + static int32_T qrpf(::coder::array &A, int32_T m, real_T + tau_data[]) + { + real_T atmp; + int32_T jpvt; + int32_T y; + jpvt = 1; + if (m <= 1) { + y = m; + } else { + y = 1; + } + + y = static_cast(y); + for (int32_T i{0}; i < y; i++) { + if (m > 1) { + atmp = A[0]; + tau_data[0] = xzlarfg(m, &atmp, A); + A[0] = atmp; + } else { + tau_data[0] = 0.0; + } + } + + return jpvt; + } + + void qrpf(::coder::array &A, int32_T m, int32_T n, ::coder:: + array &tau, ::coder::array &jpvt) + { + ::coder::array vn1; + ::coder::array vn2; + ::coder::array work; + real_T d; + real_T temp1; + int32_T itemp; + int32_T j; + int32_T ma; + int32_T minmn; + ma = A.size(0); + if (m <= n) { + minmn = m; + } else { + minmn = n; + } + + itemp = A.size(1); + work.set_size(itemp); + for (j = 0; j < itemp; j++) { + work[j] = 0.0; + } + + itemp = A.size(1); + vn1.set_size(itemp); + for (j = 0; j < itemp; j++) { + vn1[j] = 0.0; + } + + itemp = A.size(1); + vn2.set_size(itemp); + for (j = 0; j < itemp; j++) { + vn2[j] = 0.0; + } + + for (j = 0; j < n; j++) { + d = blas::xnrm2(m, A, j * ma + 1); + vn1[j] = d; + vn2[j] = d; + } + + for (int32_T i{0}; i < minmn; i++) { + int32_T ii; + int32_T ip1; + int32_T mmi; + int32_T nmi; + int32_T pvt; + ip1 = i + 2; + j = i * ma; + ii = j + i; + nmi = n - i; + mmi = m - i; + pvt = (i + blas::ixamax(nmi, vn1, i + 1)) - 1; + if (pvt + 1 != i + 1) { + blas::xswap(m, A, pvt * ma + 1, j + 1); + itemp = jpvt[pvt]; + jpvt[pvt] = jpvt[i]; + jpvt[i] = itemp; + vn1[pvt] = vn1[i]; + vn2[pvt] = vn2[i]; + } + + if (i + 1 < m) { + temp1 = A[ii]; + d = xzlarfg(mmi, &temp1, A, ii + 2); + tau[i] = d; + A[ii] = temp1; + } else { + d = 0.0; + tau[i] = 0.0; + } + + if (i + 1 < n) { + temp1 = A[ii]; + A[ii] = 1.0; + xzlarf(mmi, nmi - 1, ii + 1, d, A, (ii + ma) + 1, ma, work); + A[ii] = temp1; + } + + for (j = ip1; j <= n; j++) { + itemp = i + (j - 1) * ma; + d = vn1[j - 1]; + if (d != 0.0) { + real_T temp2; + temp1 = std::abs(A[itemp]) / d; + temp1 = 1.0 - temp1 * temp1; + if (temp1 < 0.0) { + temp1 = 0.0; + } + + temp2 = d / vn2[j - 1]; + temp2 = temp1 * (temp2 * temp2); + if (temp2 <= 1.4901161193847656E-8) { + if (i + 1 < m) { + d = blas::xnrm2(mmi - 1, A, itemp + 2); + vn1[j - 1] = d; + vn2[j - 1] = d; + } else { + vn1[j - 1] = 0.0; + vn2[j - 1] = 0.0; + } + } else { + vn1[j - 1] = d * std::sqrt(temp1); + } + } + } + } + } + + void xzgeqp3(::coder::array &A, int32_T m, real_T tau_data[], + int32_T *tau_size, int32_T *jpvt) + { + *tau_size = A.size(0); + if (*tau_size > 1) { + *tau_size = 1; + } + + if (*tau_size - 1 >= 0) { + tau_data[0] = 0.0; + } + + if (A.size(0) == 0) { + *jpvt = 1; + } else { + int32_T y; + if (m <= 1) { + y = m; + } else { + y = 1; + } + + if (y < 1) { + *jpvt = 1; + } else { + qrpf(A, m, tau_data); + *jpvt = 1; + } + } + } + } + } + } +} + +// End of code generation (xzgeqp3.cpp) diff --git a/cpp/RAT/xzgeqp3.h b/cpp/RAT/xzgeqp3.h new file mode 100644 index 00000000..aad7bd63 --- /dev/null +++ b/cpp/RAT/xzgeqp3.h @@ -0,0 +1,39 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzgeqp3.h +// +// Code generation for function 'xzgeqp3' +// +#ifndef XZGEQP3_H +#define XZGEQP3_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + void qrpf(::coder::array &A, int32_T m, int32_T n, ::coder:: + array &tau, ::coder::array &jpvt); + void xzgeqp3(::coder::array &A, int32_T m, real_T tau_data[], + int32_T *tau_size, int32_T *jpvt); + } + } + } +} + +#endif + +// End of code generation (xzgeqp3.h) diff --git a/cpp/RAT/xzggbak.cpp b/cpp/RAT/xzggbak.cpp new file mode 100644 index 00000000..f8825d9b --- /dev/null +++ b/cpp/RAT/xzggbak.cpp @@ -0,0 +1,72 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzggbak.cpp +// +// Code generation for function 'xzggbak' +// + +// Include files +#include "xzggbak.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + void xzggbak(::coder::array &V, int32_T ilo, int32_T ihi, + const ::coder::array &rscale) + { + real_T tmp_im; + real_T tmp_re; + int32_T k; + int32_T m; + int32_T n; + n = V.size(0); + m = V.size(1) - 1; + if (ilo > 1) { + for (int32_T i{ilo - 2}; i + 1 >= 1; i--) { + k = rscale[i] - 1; + if (rscale[i] != i + 1) { + for (int32_T j{0}; j <= m; j++) { + tmp_re = V[i + V.size(0) * j].re; + tmp_im = V[i + V.size(0) * j].im; + V[i + V.size(0) * j] = V[k + V.size(0) * j]; + V[k + V.size(0) * j].re = tmp_re; + V[k + V.size(0) * j].im = tmp_im; + } + } + } + } + + if (ihi < V.size(0)) { + k = ihi + 1; + for (int32_T i{k}; i <= n; i++) { + int32_T b_i; + b_i = rscale[i - 1]; + if (b_i != i) { + for (int32_T j{0}; j <= m; j++) { + tmp_re = V[(i + V.size(0) * j) - 1].re; + tmp_im = V[(i + V.size(0) * j) - 1].im; + V[(i + V.size(0) * j) - 1] = V[(b_i + V.size(0) * j) - 1]; + V[(b_i + V.size(0) * j) - 1].re = tmp_re; + V[(b_i + V.size(0) * j) - 1].im = tmp_im; + } + } + } + } + } + } + } + } +} + +// End of code generation (xzggbak.cpp) diff --git a/cpp/RAT/xzggbak.h b/cpp/RAT/xzggbak.h new file mode 100644 index 00000000..db7f8a4d --- /dev/null +++ b/cpp/RAT/xzggbak.h @@ -0,0 +1,37 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzggbak.h +// +// Code generation for function 'xzggbak' +// +#ifndef XZGGBAK_H +#define XZGGBAK_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + void xzggbak(::coder::array &V, int32_T ilo, int32_T ihi, + const ::coder::array &rscale); + } + } + } +} + +#endif + +// End of code generation (xzggbak.h) diff --git a/cpp/RAT/xzggbal.cpp b/cpp/RAT/xzggbal.cpp new file mode 100644 index 00000000..0c1338c1 --- /dev/null +++ b/cpp/RAT/xzggbal.cpp @@ -0,0 +1,202 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzggbal.cpp +// +// Code generation for function 'xzggbal' +// + +// Include files +#include "xzggbal.h" +#include "rt_nonfinite.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + void xzggbal(::coder::array &A, int32_T *ilo, int32_T *ihi, + ::coder::array &rscale) + { + int32_T ii; + int32_T nzcount; + nzcount = A.size(0); + rscale.set_size(nzcount); + for (ii = 0; ii < nzcount; ii++) { + rscale[ii] = 1; + } + + *ilo = 1; + *ihi = A.size(0); + if (A.size(0) <= 1) { + *ihi = 1; + } else { + real_T atmp_im; + real_T atmp_re; + int32_T exitg2; + int32_T i; + int32_T j; + int32_T jj; + boolean_T exitg3; + boolean_T exitg4; + boolean_T found; + do { + exitg2 = 0; + i = 0; + j = 0; + found = false; + ii = *ihi; + exitg3 = false; + while ((!exitg3) && (ii > 0)) { + nzcount = 0; + i = ii; + j = *ihi; + jj = 0; + exitg4 = false; + while ((!exitg4) && (jj <= *ihi - 1)) { + if ((A[(ii + A.size(0) * jj) - 1].re != 0.0) || (A[(ii + + A.size(0) * jj) - 1].im != 0.0) || (ii == jj + 1)) { + if (nzcount == 0) { + j = jj + 1; + nzcount = 1; + jj++; + } else { + nzcount = 2; + exitg4 = true; + } + } else { + jj++; + } + } + + if (nzcount < 2) { + found = true; + exitg3 = true; + } else { + ii--; + } + } + + if (!found) { + exitg2 = 2; + } else { + nzcount = A.size(0); + if (i != *ihi) { + for (ii = 1; ii <= nzcount; ii++) { + atmp_re = A[(i + A.size(0) * (ii - 1)) - 1].re; + atmp_im = A[(i + A.size(0) * (ii - 1)) - 1].im; + A[(i + A.size(0) * (ii - 1)) - 1] = A[(*ihi + A.size(0) * + (ii - 1)) - 1]; + A[(*ihi + A.size(0) * (ii - 1)) - 1].re = atmp_re; + A[(*ihi + A.size(0) * (ii - 1)) - 1].im = atmp_im; + } + } + + if (j != *ihi) { + for (ii = 0; ii < *ihi; ii++) { + atmp_re = A[ii + A.size(0) * (j - 1)].re; + atmp_im = A[ii + A.size(0) * (j - 1)].im; + A[ii + A.size(0) * (j - 1)] = A[ii + A.size(0) * (*ihi - 1)]; + A[ii + A.size(0) * (*ihi - 1)].re = atmp_re; + A[ii + A.size(0) * (*ihi - 1)].im = atmp_im; + } + } + + rscale[*ihi - 1] = j; + (*ihi)--; + if (*ihi == 1) { + rscale[0] = 1; + exitg2 = 1; + } + } + } while (exitg2 == 0); + + if (exitg2 != 1) { + int32_T exitg1; + do { + exitg1 = 0; + i = 0; + j = 0; + found = false; + jj = *ilo; + exitg3 = false; + while ((!exitg3) && (jj <= *ihi)) { + nzcount = 0; + i = *ihi; + j = jj; + ii = *ilo; + exitg4 = false; + while ((!exitg4) && (ii <= *ihi)) { + if ((A[(ii + A.size(0) * (jj - 1)) - 1].re != 0.0) || (A[(ii + + A.size(0) * (jj - 1)) - 1].im != 0.0) || (ii == jj)) + { + if (nzcount == 0) { + i = ii; + nzcount = 1; + ii++; + } else { + nzcount = 2; + exitg4 = true; + } + } else { + ii++; + } + } + + if (nzcount < 2) { + found = true; + exitg3 = true; + } else { + jj++; + } + } + + if (!found) { + exitg1 = 1; + } else { + nzcount = A.size(0); + if (i != *ilo) { + for (ii = *ilo; ii <= nzcount; ii++) { + atmp_re = A[(i + A.size(0) * (ii - 1)) - 1].re; + atmp_im = A[(i + A.size(0) * (ii - 1)) - 1].im; + A[(i + A.size(0) * (ii - 1)) - 1] = A[(*ilo + A.size(0) * + (ii - 1)) - 1]; + A[(*ilo + A.size(0) * (ii - 1)) - 1].re = atmp_re; + A[(*ilo + A.size(0) * (ii - 1)) - 1].im = atmp_im; + } + } + + if (j != *ilo) { + for (ii = 0; ii < *ihi; ii++) { + atmp_re = A[ii + A.size(0) * (j - 1)].re; + atmp_im = A[ii + A.size(0) * (j - 1)].im; + A[ii + A.size(0) * (j - 1)] = A[ii + A.size(0) * (*ilo - 1)]; + A[ii + A.size(0) * (*ilo - 1)].re = atmp_re; + A[ii + A.size(0) * (*ilo - 1)].im = atmp_im; + } + } + + rscale[*ilo - 1] = j; + (*ilo)++; + if (*ilo == *ihi) { + rscale[*ilo - 1] = *ilo; + exitg1 = 1; + } + } + } while (exitg1 == 0); + } + } + } + } + } + } +} + +// End of code generation (xzggbal.cpp) diff --git a/cpp/RAT/xzggbal.h b/cpp/RAT/xzggbal.h new file mode 100644 index 00000000..75b9ae89 --- /dev/null +++ b/cpp/RAT/xzggbal.h @@ -0,0 +1,37 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzggbal.h +// +// Code generation for function 'xzggbal' +// +#ifndef XZGGBAL_H +#define XZGGBAL_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + void xzggbal(::coder::array &A, int32_T *ilo, int32_T *ihi, + ::coder::array &rscale); + } + } + } +} + +#endif + +// End of code generation (xzggbal.h) diff --git a/cpp/RAT/xzggev.cpp b/cpp/RAT/xzggev.cpp new file mode 100644 index 00000000..cb15c0de --- /dev/null +++ b/cpp/RAT/xzggev.cpp @@ -0,0 +1,153 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzggev.cpp +// +// Code generation for function 'xzggev' +// + +// Include files +#include "xzggev.h" +#include "rt_nonfinite.h" +#include "xzggbak.h" +#include "xzggbal.h" +#include "xzgghrd.h" +#include "xzhgeqz.h" +#include "xzlangeM.h" +#include "xzlascl.h" +#include "xztgevc.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + void xzggev(::coder::array &A, int32_T *info, ::coder:: + array &alpha1, ::coder::array + &beta1, ::coder::array &V) + { + ::coder::array rscale; + int32_T ihi; + int32_T ilo; + int32_T n; + *info = 0; + n = A.size(0) - 1; + ilo = A.size(0); + alpha1.set_size(ilo); + for (int32_T i{0}; i < ilo; i++) { + alpha1[i].re = 0.0; + alpha1[i].im = 0.0; + } + + ilo = A.size(0); + beta1.set_size(ilo); + for (int32_T i{0}; i < ilo; i++) { + beta1[i].re = 0.0; + beta1[i].im = 0.0; + } + + ilo = A.size(0); + ihi = A.size(0); + V.set_size(ilo, ihi); + for (int32_T i{0}; i < ihi; i++) { + for (int32_T i1{0}; i1 < ilo; i1++) { + V[i1 + V.size(0) * i].re = 0.0; + V[i1 + V.size(0) * i].im = 0.0; + } + } + + if ((A.size(0) != 0) && (A.size(1) != 0)) { + real_T anrm; + anrm = xzlangeM(A); + if (std::isinf(anrm) || std::isnan(anrm)) { + ilo = A.size(0); + alpha1.set_size(ilo); + for (int32_T i{0}; i < ilo; i++) { + alpha1[i].re = rtNaN; + alpha1[i].im = 0.0; + } + + ilo = A.size(0); + beta1.set_size(ilo); + for (int32_T i{0}; i < ilo; i++) { + beta1[i].re = rtNaN; + beta1[i].im = 0.0; + } + + ilo = A.size(0); + ihi = A.size(0); + V.set_size(ilo, ihi); + for (int32_T i{0}; i < ihi; i++) { + for (int32_T i1{0}; i1 < ilo; i1++) { + V[i1 + V.size(0) * i].re = rtNaN; + V[i1 + V.size(0) * i].im = 0.0; + } + } + } else { + real_T anrmto; + boolean_T ilascl; + ilascl = false; + anrmto = anrm; + if ((anrm > 0.0) && (anrm < 6.7178761075670888E-139)) { + anrmto = 6.7178761075670888E-139; + ilascl = true; + xzlascl(anrm, anrmto, A); + } else if (anrm > 1.4885657073574029E+138) { + anrmto = 1.4885657073574029E+138; + ilascl = true; + xzlascl(anrm, anrmto, A); + } + + xzggbal(A, &ilo, &ihi, rscale); + xzgghrd(ilo, ihi, A, V); + xzhgeqz(A, ilo, ihi, V, info, alpha1, beta1); + if (*info == 0) { + xztgevc(A, V); + xzggbak(V, ilo, ihi, rscale); + for (ilo = 0; ilo <= n; ilo++) { + real_T vtemp; + vtemp = std::abs(V[V.size(0) * ilo].re) + std::abs(V[V.size(0) + * ilo].im); + if (n + 1 > 1) { + for (ihi = 0; ihi < n; ihi++) { + real_T y; + y = std::abs(V[(ihi + V.size(0) * ilo) + 1].re) + std::abs + (V[(ihi + V.size(0) * ilo) + 1].im); + if (y > vtemp) { + vtemp = y; + } + } + } + + if (vtemp >= 6.7178761075670888E-139) { + vtemp = 1.0 / vtemp; + for (ihi = 0; ihi <= n; ihi++) { + V[ihi + V.size(0) * ilo].re = vtemp * V[ihi + V.size(0) * + ilo].re; + V[ihi + V.size(0) * ilo].im = vtemp * V[ihi + V.size(0) * + ilo].im; + } + } + } + + if (ilascl) { + xzlascl(anrmto, anrm, alpha1); + } + } + } + } + } + } + } + } +} + +// End of code generation (xzggev.cpp) diff --git a/cpp/RAT/xzggev.h b/cpp/RAT/xzggev.h new file mode 100644 index 00000000..02de1130 --- /dev/null +++ b/cpp/RAT/xzggev.h @@ -0,0 +1,38 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzggev.h +// +// Code generation for function 'xzggev' +// +#ifndef XZGGEV_H +#define XZGGEV_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + void xzggev(::coder::array &A, int32_T *info, ::coder:: + array &alpha1, ::coder::array + &beta1, ::coder::array &V); + } + } + } +} + +#endif + +// End of code generation (xzggev.h) diff --git a/cpp/RAT/xzgghrd.cpp b/cpp/RAT/xzgghrd.cpp new file mode 100644 index 00000000..58163c82 --- /dev/null +++ b/cpp/RAT/xzgghrd.cpp @@ -0,0 +1,125 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzgghrd.cpp +// +// Code generation for function 'xzgghrd' +// + +// Include files +#include "xzgghrd.h" +#include "eye.h" +#include "rt_nonfinite.h" +#include "xzlartg.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + void xzgghrd(int32_T ilo, int32_T ihi, ::coder::array &A, :: + coder::array &Z) + { + ::coder::array b_A; + creal_T s; + real_T c; + int32_T n; + n = A.size(0); + eye(A.size(0), Z); + if ((A.size(0) > 1) && (ihi >= ilo + 2)) { + for (int32_T jcol{ilo - 1}; jcol + 1 < ihi - 1; jcol++) { + int32_T jcolp1; + jcolp1 = jcol + 2; + for (int32_T jrow{ihi - 1}; jrow + 1 > jcol + 2; jrow--) { + real_T b_s_re_tmp; + real_T s_re_tmp; + real_T stemp_im_tmp; + real_T stemp_re_tmp; + int32_T j; + int32_T loop_ub; + xzlartg(A[(jrow + A.size(0) * jcol) - 1], A[jrow + A.size(0) * + jcol], &c, &s, &A[(jrow + A.size(0) * jcol) - 1]); + A[jrow + A.size(0) * jcol].re = 0.0; + A[jrow + A.size(0) * jcol].im = 0.0; + for (j = jcolp1; j <= n; j++) { + s_re_tmp = A[jrow + A.size(0) * (j - 1)].im; + b_s_re_tmp = A[jrow + A.size(0) * (j - 1)].re; + stemp_re_tmp = A[(jrow + A.size(0) * (j - 1)) - 1].re; + stemp_im_tmp = A[(jrow + A.size(0) * (j - 1)) - 1].im; + A[jrow + A.size(0) * (j - 1)].re = c * b_s_re_tmp - (s.re * + stemp_re_tmp + s.im * stemp_im_tmp); + A[jrow + A.size(0) * (j - 1)].im = c * A[jrow + A.size(0) * (j + - 1)].im - (s.re * stemp_im_tmp - s.im * stemp_re_tmp); + A[(jrow + A.size(0) * (j - 1)) - 1].re = c * stemp_re_tmp + + (s.re * b_s_re_tmp - s.im * s_re_tmp); + A[(jrow + A.size(0) * (j - 1)) - 1].im = c * stemp_im_tmp + + (s.re * s_re_tmp + s.im * b_s_re_tmp); + } + + s.re = -s.re; + s.im = -s.im; + for (j = 1; j <= ihi; j++) { + s_re_tmp = A[(j + A.size(0) * (jrow - 1)) - 1].im; + b_s_re_tmp = A[(j + A.size(0) * (jrow - 1)) - 1].re; + stemp_re_tmp = A[(j + A.size(0) * jrow) - 1].re; + stemp_im_tmp = A[(j + A.size(0) * jrow) - 1].im; + A[(j + A.size(0) * (jrow - 1)) - 1].re = c * b_s_re_tmp - + (s.re * stemp_re_tmp + s.im * stemp_im_tmp); + A[(j + A.size(0) * (jrow - 1)) - 1].im = c * A[(j + A.size(0) * + (jrow - 1)) - 1].im - (s.re * stemp_im_tmp - s.im * + stemp_re_tmp); + A[(j + A.size(0) * jrow) - 1].re = c * stemp_re_tmp + (s.re * + b_s_re_tmp - s.im * s_re_tmp); + A[(j + A.size(0) * jrow) - 1].im = c * stemp_im_tmp + (s.re * + s_re_tmp + s.im * b_s_re_tmp); + } + + b_A.set_size(Z.size(0), Z.size(1)); + j = Z.size(1); + for (int32_T i{0}; i < j; i++) { + loop_ub = Z.size(0); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + b_A[i1 + b_A.size(0) * i] = Z[i1 + Z.size(0) * i]; + } + } + + for (j = 1; j <= n; j++) { + s_re_tmp = b_A[(j + b_A.size(0) * (jrow - 1)) - 1].im; + b_s_re_tmp = b_A[(j + b_A.size(0) * (jrow - 1)) - 1].re; + stemp_re_tmp = b_A[(j + b_A.size(0) * jrow) - 1].re; + stemp_im_tmp = b_A[(j + b_A.size(0) * jrow) - 1].im; + b_A[(j + b_A.size(0) * (jrow - 1)) - 1].re = c * b_s_re_tmp - + (s.re * stemp_re_tmp + s.im * stemp_im_tmp); + b_A[(j + b_A.size(0) * (jrow - 1)) - 1].im = c * s_re_tmp - + (s.re * stemp_im_tmp - s.im * stemp_re_tmp); + b_A[(j + b_A.size(0) * jrow) - 1].re = c * stemp_re_tmp + + (s.re * b_s_re_tmp - s.im * s_re_tmp); + b_A[(j + b_A.size(0) * jrow) - 1].im = c * stemp_im_tmp + + (s.re * s_re_tmp + s.im * b_s_re_tmp); + } + + Z.set_size(b_A.size(0), b_A.size(1)); + j = b_A.size(1); + for (int32_T i{0}; i < j; i++) { + loop_ub = b_A.size(0); + for (int32_T i1{0}; i1 < loop_ub; i1++) { + Z[i1 + Z.size(0) * i] = b_A[i1 + b_A.size(0) * i]; + } + } + } + } + } + } + } + } + } +} + +// End of code generation (xzgghrd.cpp) diff --git a/cpp/RAT/xzgghrd.h b/cpp/RAT/xzgghrd.h new file mode 100644 index 00000000..edeb9227 --- /dev/null +++ b/cpp/RAT/xzgghrd.h @@ -0,0 +1,37 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzgghrd.h +// +// Code generation for function 'xzgghrd' +// +#ifndef XZGGHRD_H +#define XZGGHRD_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + void xzgghrd(int32_T ilo, int32_T ihi, ::coder::array &A, :: + coder::array &Z); + } + } + } +} + +#endif + +// End of code generation (xzgghrd.h) diff --git a/cpp/RAT/xzhgeqz.cpp b/cpp/RAT/xzhgeqz.cpp new file mode 100644 index 00000000..97b6a6a0 --- /dev/null +++ b/cpp/RAT/xzhgeqz.cpp @@ -0,0 +1,654 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzhgeqz.cpp +// +// Code generation for function 'xzhgeqz' +// + +// Include files +#include "xzhgeqz.h" +#include "RATMain_data.h" +#include "rt_nonfinite.h" +#include "sqrt.h" +#include "xzlanhs.h" +#include "xzlartg.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + void xzhgeqz(::coder::array &A, int32_T ilo, int32_T ihi, :: + coder::array &Z, int32_T *info, ::coder::array< + creal_T, 1U> &alpha1, ::coder::array &beta1) + { + ::coder::array b_A; + creal_T ctemp; + creal_T stemp; + creal_T y; + real_T anorm; + real_T ascale; + real_T b_atol; + real_T bscale; + real_T eshift_im; + real_T eshift_re; + real_T temp; + real_T tempr; + int32_T i; + int32_T ilast; + int32_T j; + int32_T jm1; + int32_T jp1; + int32_T n; + boolean_T compz; + boolean_T failed; + boolean_T guard1; + boolean_T guard2; + *info = 0; + compz = ((Z.size(0) != 0) && (Z.size(1) != 0)); + if ((A.size(0) == 1) && (A.size(1) == 1)) { + ihi = 1; + } + + n = A.size(0); + jm1 = A.size(0); + alpha1.set_size(jm1); + for (i = 0; i < jm1; i++) { + alpha1[i].re = 0.0; + alpha1[i].im = 0.0; + } + + jm1 = A.size(0); + beta1.set_size(jm1); + for (i = 0; i < jm1; i++) { + beta1[i].re = 1.0; + beta1[i].im = 0.0; + } + + eshift_re = 0.0; + eshift_im = 0.0; + ctemp.re = 0.0; + ctemp.im = 0.0; + anorm = xzlanhs(A, ilo, ihi); + tempr = 2.2204460492503131E-16 * anorm; + b_atol = 2.2250738585072014E-308; + if (tempr > 2.2250738585072014E-308) { + b_atol = tempr; + } + + tempr = 2.2250738585072014E-308; + if (anorm > 2.2250738585072014E-308) { + tempr = anorm; + } + + ascale = 1.0 / tempr; + bscale = 1.0 / std::sqrt(static_cast(A.size(0))); + failed = true; + i = ihi + 1; + for (j = i; j <= n; j++) { + alpha1[j - 1] = A[(j + A.size(0) * (j - 1)) - 1]; + } + + guard1 = false; + guard2 = false; + if (ihi >= ilo) { + int32_T ifirst; + int32_T ifrstm; + int32_T iiter; + int32_T ilastm; + int32_T ilastm1; + int32_T istart; + int32_T jiter; + boolean_T goto60; + boolean_T goto70; + boolean_T goto90; + ifirst = ilo; + istart = ilo; + ilast = ihi - 1; + ilastm1 = ihi - 2; + if (compz) { + ifrstm = 1; + ilastm = n; + } else { + ifrstm = ilo; + ilastm = ihi; + } + + iiter = 0; + goto60 = false; + goto70 = false; + goto90 = false; + jiter = 0; + int32_T exitg1; + do { + exitg1 = 0; + if (jiter <= 30 * ((ihi - ilo) + 1) - 1) { + boolean_T b_guard1; + boolean_T exitg2; + b_guard1 = false; + if (ilast + 1 == ilo) { + goto60 = true; + b_guard1 = true; + } else if (std::abs(A[ilast + A.size(0) * ilastm1].re) + std:: + abs(A[ilast + A.size(0) * ilastm1].im) <= std::fmax + (2.2250738585072014E-308, 2.2204460492503131E-16 * + ((std::abs(A[ilast + A.size(0) * ilast].re) + std:: + abs(A[ilast + A.size(0) * ilast].im)) + (std::abs + (A[ilastm1 + A.size(0) * ilastm1].re) + std::abs + (A[ilastm1 + A.size(0) * ilastm1].im))))) { + A[ilast + A.size(0) * ilastm1].re = 0.0; + A[ilast + A.size(0) * ilastm1].im = 0.0; + goto60 = true; + b_guard1 = true; + } else { + boolean_T guard3; + j = ilastm1; + guard3 = false; + exitg2 = false; + while ((!exitg2) && (j + 1 >= ilo)) { + if (j + 1 == ilo) { + guard3 = true; + exitg2 = true; + } else if (std::abs(A[j + A.size(0) * (j - 1)].re) + std:: + abs(A[j + A.size(0) * (j - 1)].im) <= std::fmax + (2.2250738585072014E-308, 2.2204460492503131E-16 * + ((std::abs(A[j + A.size(0) * j].re) + std::abs + (A[j + A.size(0) * j].im)) + (std::abs(A[(j + + A.size(0) * (j - 1)) - 1].re) + std::abs(A[(j + A.size(0) + * (j - 1)) - 1].im))))) { + A[j + A.size(0) * (j - 1)].re = 0.0; + A[j + A.size(0) * (j - 1)].im = 0.0; + guard3 = true; + exitg2 = true; + } else { + j--; + guard3 = false; + } + } + + if (guard3) { + ifirst = j + 1; + goto70 = true; + } + + if (goto70) { + b_guard1 = true; + } else { + jm1 = alpha1.size(0); + alpha1.set_size(jm1); + for (i = 0; i < jm1; i++) { + alpha1[i].re = rtNaN; + alpha1[i].im = 0.0; + } + + jm1 = beta1.size(0); + beta1.set_size(jm1); + for (i = 0; i < jm1; i++) { + beta1[i].re = rtNaN; + beta1[i].im = 0.0; + } + + if (compz) { + jm1 = Z.size(0); + jp1 = Z.size(1); + Z.set_size(jm1, jp1); + for (i = 0; i < jp1; i++) { + for (int32_T i1{0}; i1 < jm1; i1++) { + Z[i1 + Z.size(0) * i].re = rtNaN; + Z[i1 + Z.size(0) * i].im = 0.0; + } + } + } + + *info = 1; + exitg1 = 1; + } + } + + if (b_guard1) { + if (goto60) { + goto60 = false; + alpha1[ilast] = A[ilast + A.size(0) * ilast]; + ilast = ilastm1; + ilastm1--; + if (ilast + 1 < ilo) { + failed = false; + guard2 = true; + exitg1 = 1; + } else { + iiter = 0; + eshift_re = 0.0; + eshift_im = 0.0; + if (!compz) { + ilastm = ilast + 1; + if (ifrstm > ilast + 1) { + ifrstm = ilo; + } + } + + jiter++; + } + } else { + if (goto70) { + real_T ad22_im; + real_T ad22_re; + real_T temp2; + real_T y_im_tmp; + goto70 = false; + iiter++; + if (!compz) { + ifrstm = ifirst; + } + + if (iiter - iiter / 10 * 10 != 0) { + tempr = ascale * A[ilast + A.size(0) * ilast].re; + anorm = ascale * A[ilast + A.size(0) * ilast].im; + if (anorm == 0.0) { + ad22_re = tempr / bscale; + ad22_im = 0.0; + } else if (tempr == 0.0) { + ad22_re = 0.0; + ad22_im = anorm / bscale; + } else { + ad22_re = tempr / bscale; + ad22_im = anorm / bscale; + } + + tempr = ascale * A[ilastm1 + A.size(0) * ilast].re; + anorm = ascale * A[ilastm1 + A.size(0) * ilast].im; + if (anorm == 0.0) { + stemp.re = tempr / bscale; + stemp.im = 0.0; + } else if (tempr == 0.0) { + stemp.re = 0.0; + stemp.im = anorm / bscale; + } else { + stemp.re = tempr / bscale; + stemp.im = anorm / bscale; + } + + scalar::d_sqrt(&stemp); + tempr = ascale * A[ilast + A.size(0) * ilastm1].re; + anorm = ascale * A[ilast + A.size(0) * ilastm1].im; + if (anorm == 0.0) { + y.re = tempr / bscale; + y.im = 0.0; + } else if (tempr == 0.0) { + y.re = 0.0; + y.im = anorm / bscale; + } else { + y.re = tempr / bscale; + y.im = anorm / bscale; + } + + scalar::d_sqrt(&y); + ctemp.re = stemp.re * y.re - stemp.im * y.im; + ctemp.im = stemp.re * y.im + stemp.im * y.re; + if ((ctemp.re != 0.0) || (ctemp.im != 0.0)) { + real_T x_im; + real_T x_re; + tempr = ascale * A[ilastm1 + A.size(0) * ilastm1].re; + anorm = ascale * A[ilastm1 + A.size(0) * ilastm1].im; + if (anorm == 0.0) { + tempr /= bscale; + anorm = 0.0; + } else if (tempr == 0.0) { + tempr = 0.0; + anorm /= bscale; + } else { + tempr /= bscale; + anorm /= bscale; + } + + x_re = 0.5 * (tempr - ad22_re); + x_im = 0.5 * (anorm - ad22_im); + temp2 = std::abs(x_re) + std::abs(x_im); + temp = std::fmax(std::abs(ctemp.re) + std::abs + (ctemp.im), temp2); + if (x_im == 0.0) { + stemp.re = x_re / temp; + stemp.im = 0.0; + } else if (x_re == 0.0) { + stemp.re = 0.0; + stemp.im = x_im / temp; + } else { + stemp.re = x_re / temp; + stemp.im = x_im / temp; + } + + if (ctemp.im == 0.0) { + y.re = ctemp.re / temp; + y.im = 0.0; + } else if (ctemp.re == 0.0) { + y.re = 0.0; + y.im = ctemp.im / temp; + } else { + y.re = ctemp.re / temp; + y.im = ctemp.im / temp; + } + + anorm = stemp.re * stemp.re - stemp.im * stemp.im; + tempr = stemp.re * stemp.im; + y_im_tmp = y.re * y.im; + stemp.re = anorm + (y.re * y.re - y.im * y.im); + stemp.im = (tempr + tempr) + (y_im_tmp + y_im_tmp); + scalar::d_sqrt(&stemp); + y.re = temp * stemp.re; + y.im = temp * stemp.im; + if (temp2 > 0.0) { + if (x_im == 0.0) { + tempr = x_re / temp2; + anorm = 0.0; + } else { + if (x_re == 0.0) { + tempr = 0.0; + } else { + tempr = x_re / temp2; + } + + anorm = x_im / temp2; + } + + if (tempr * y.re + anorm * y.im < 0.0) { + y.re = -y.re; + y.im = -y.im; + } + } + + tempr = x_re + y.re; + temp = x_im + y.im; + if (temp == 0.0) { + if (ctemp.im == 0.0) { + y_im_tmp = ctemp.re / tempr; + tempr = 0.0; + } else if (ctemp.re == 0.0) { + y_im_tmp = 0.0; + tempr = ctemp.im / tempr; + } else { + y_im_tmp = ctemp.re / tempr; + tempr = ctemp.im / tempr; + } + } else if (tempr == 0.0) { + if (ctemp.re == 0.0) { + y_im_tmp = ctemp.im / temp; + tempr = 0.0; + } else if (ctemp.im == 0.0) { + y_im_tmp = 0.0; + tempr = -(ctemp.re / temp); + } else { + y_im_tmp = ctemp.im / temp; + tempr = -(ctemp.re / temp); + } + } else { + temp2 = std::abs(tempr); + anorm = std::abs(temp); + if (temp2 > anorm) { + anorm = temp / tempr; + tempr += anorm * temp; + y_im_tmp = (ctemp.re + anorm * ctemp.im) / tempr; + tempr = (ctemp.im - anorm * ctemp.re) / tempr; + } else if (anorm == temp2) { + if (tempr > 0.0) { + tempr = 0.5; + } else { + tempr = -0.5; + } + + if (temp > 0.0) { + anorm = 0.5; + } else { + anorm = -0.5; + } + + y_im_tmp = (ctemp.re * tempr + ctemp.im * anorm) / + temp2; + tempr = (ctemp.im * tempr - ctemp.re * anorm) / + temp2; + } else { + anorm = tempr / temp; + tempr = temp + anorm * tempr; + y_im_tmp = (anorm * ctemp.re + ctemp.im) / tempr; + tempr = (anorm * ctemp.im - ctemp.re) / tempr; + } + } + + ad22_re -= ctemp.re * y_im_tmp - ctemp.im * tempr; + ad22_im -= ctemp.re * tempr + ctemp.im * y_im_tmp; + } + } else { + if (iiter - iiter / 20 * 20 == 0) { + tempr = ascale * A[ilast + A.size(0) * ilast].re; + anorm = ascale * A[ilast + A.size(0) * ilast].im; + if (anorm == 0.0) { + tempr /= bscale; + anorm = 0.0; + } else if (tempr == 0.0) { + tempr = 0.0; + anorm /= bscale; + } else { + tempr /= bscale; + anorm /= bscale; + } + + eshift_re += tempr; + eshift_im += anorm; + } else { + tempr = ascale * A[ilast + A.size(0) * ilastm1].re; + anorm = ascale * A[ilast + A.size(0) * ilastm1].im; + if (anorm == 0.0) { + tempr /= bscale; + anorm = 0.0; + } else if (tempr == 0.0) { + tempr = 0.0; + anorm /= bscale; + } else { + tempr /= bscale; + anorm /= bscale; + } + + eshift_re += tempr; + eshift_im += anorm; + } + + ad22_re = eshift_re; + ad22_im = eshift_im; + } + + j = ilastm1; + jp1 = ilastm1 + 1; + exitg2 = false; + while ((!exitg2) && (j + 1 > ifirst)) { + istart = j + 1; + ctemp.re = ascale * A[j + A.size(0) * j].re - ad22_re * + bscale; + ctemp.im = ascale * A[j + A.size(0) * j].im - ad22_im * + bscale; + temp = std::abs(ctemp.re) + std::abs(ctemp.im); + temp2 = ascale * (std::abs(A[jp1 + A.size(0) * j].re) + + std::abs(A[jp1 + A.size(0) * j].im)); + tempr = temp; + if (temp2 > temp) { + tempr = temp2; + } + + if ((tempr < 1.0) && (tempr != 0.0)) { + temp /= tempr; + temp2 /= tempr; + } + + if ((std::abs(A[j + A.size(0) * (j - 1)].re) + std::abs + (A[j + A.size(0) * (j - 1)].im)) * temp2 <= temp * + b_atol) { + goto90 = true; + exitg2 = true; + } else { + jp1 = j; + j--; + } + } + + if (!goto90) { + istart = ifirst; + ctemp.re = ascale * A[(ifirst + A.size(0) * (ifirst - 1)) + - 1].re - ad22_re * bscale; + ctemp.im = ascale * A[(ifirst + A.size(0) * (ifirst - 1)) + - 1].im - ad22_im * bscale; + } + + goto90 = false; + stemp.re = ascale * A[istart + A.size(0) * (istart - 1)]. + re; + stemp.im = ascale * A[istart + A.size(0) * (istart - 1)]. + im; + xzlartg(ctemp, stemp, &temp, &y); + j = istart; + jm1 = istart - 2; + while (j < ilast + 1) { + if (j > istart) { + xzlartg(A[(j + A.size(0) * jm1) - 1], A[j + A.size(0) * + jm1], &temp, &y, &A[(j + A.size(0) * jm1) - 1]); + A[j + A.size(0) * jm1].re = 0.0; + A[j + A.size(0) * jm1].im = 0.0; + } + + for (jp1 = j; jp1 <= ilastm; jp1++) { + anorm = A[j + A.size(0) * (jp1 - 1)].im; + tempr = A[j + A.size(0) * (jp1 - 1)].re; + temp2 = A[(j + A.size(0) * (jp1 - 1)) - 1].re; + stemp.re = temp * temp2 + (y.re * tempr - y.im * anorm); + y_im_tmp = A[(j + A.size(0) * (jp1 - 1)) - 1].im; + stemp.im = temp * y_im_tmp + (y.re * anorm + y.im * + tempr); + A[j + A.size(0) * (jp1 - 1)].re = temp * tempr - (y.re + * temp2 + y.im * y_im_tmp); + A[j + A.size(0) * (jp1 - 1)].im = temp * A[j + A.size + (0) * (jp1 - 1)].im - (y.re * y_im_tmp - y.im * + temp2); + A[(j + A.size(0) * (jp1 - 1)) - 1] = stemp; + } + + y.re = -y.re; + y.im = -y.im; + jp1 = j; + if (ilast + 1 < j + 2) { + jp1 = ilast - 1; + } + + for (jm1 = ifrstm; jm1 <= jp1 + 2; jm1++) { + anorm = A[(jm1 + A.size(0) * (j - 1)) - 1].im; + tempr = A[(jm1 + A.size(0) * (j - 1)) - 1].re; + temp2 = A[(jm1 + A.size(0) * j) - 1].re; + stemp.re = temp * temp2 + (y.re * tempr - y.im * anorm); + stemp.im = temp * A[(jm1 + A.size(0) * j) - 1].im + + (y.re * anorm + y.im * tempr); + tempr = A[(jm1 + A.size(0) * j) - 1].im; + anorm = A[(jm1 + A.size(0) * j) - 1].re; + A[(jm1 + A.size(0) * (j - 1)) - 1].re = temp * A[(jm1 + + A.size(0) * (j - 1)) - 1].re - (y.re * temp2 + + y.im * tempr); + A[(jm1 + A.size(0) * (j - 1)) - 1].im = temp * A[(jm1 + + A.size(0) * (j - 1)) - 1].im - (y.re * tempr - + y.im * anorm); + A[(jm1 + A.size(0) * j) - 1] = stemp; + } + + if (compz) { + b_A.set_size(Z.size(0), Z.size(1)); + jp1 = Z.size(1); + for (i = 0; i < jp1; i++) { + jm1 = Z.size(0); + for (int32_T i1{0}; i1 < jm1; i1++) { + b_A[i1 + b_A.size(0) * i] = Z[i1 + Z.size(0) * i]; + } + } + + for (jm1 = 1; jm1 <= n; jm1++) { + anorm = b_A[(jm1 + b_A.size(0) * (j - 1)) - 1].im; + tempr = b_A[(jm1 + b_A.size(0) * (j - 1)) - 1].re; + temp2 = b_A[(jm1 + b_A.size(0) * j) - 1].re; + stemp.re = temp * temp2 + (y.re * tempr - y.im * + anorm); + y_im_tmp = b_A[(jm1 + b_A.size(0) * j) - 1].im; + stemp.im = temp * y_im_tmp + (y.re * anorm + y.im * + tempr); + b_A[(jm1 + b_A.size(0) * (j - 1)) - 1].re = temp * + tempr - (y.re * temp2 + y.im * y_im_tmp); + b_A[(jm1 + b_A.size(0) * (j - 1)) - 1].im = temp * + anorm - (y.re * y_im_tmp - y.im * temp2); + b_A[(jm1 + b_A.size(0) * j) - 1] = stemp; + } + + Z.set_size(b_A.size(0), b_A.size(1)); + jp1 = b_A.size(1); + for (i = 0; i < jp1; i++) { + jm1 = b_A.size(0); + for (int32_T i1{0}; i1 < jm1; i1++) { + Z[i1 + Z.size(0) * i] = b_A[i1 + b_A.size(0) * i]; + } + } + } + + jm1 = j - 1; + j++; + } + } + + jiter++; + } + } + } else { + guard2 = true; + exitg1 = 1; + } + } while (exitg1 == 0); + } else { + guard1 = true; + } + + if (guard2) { + if (failed) { + *info = ilast + 1; + for (jm1 = 0; jm1 <= ilast; jm1++) { + alpha1[jm1].re = rtNaN; + alpha1[jm1].im = 0.0; + beta1[jm1].re = rtNaN; + beta1[jm1].im = 0.0; + } + + if (compz) { + jm1 = Z.size(0); + jp1 = Z.size(1); + Z.set_size(jm1, jp1); + for (i = 0; i < jp1; i++) { + for (int32_T i1{0}; i1 < jm1; i1++) { + Z[i1 + Z.size(0) * i].re = rtNaN; + Z[i1 + Z.size(0) * i].im = 0.0; + } + } + } + } else { + guard1 = true; + } + } + + if (guard1) { + for (j = 0; j <= ilo - 2; j++) { + alpha1[j] = A[j + A.size(0) * j]; + } + } + } + } + } + } +} + +// End of code generation (xzhgeqz.cpp) diff --git a/cpp/RAT/xzhgeqz.h b/cpp/RAT/xzhgeqz.h new file mode 100644 index 00000000..53d9519d --- /dev/null +++ b/cpp/RAT/xzhgeqz.h @@ -0,0 +1,38 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzhgeqz.h +// +// Code generation for function 'xzhgeqz' +// +#ifndef XZHGEQZ_H +#define XZHGEQZ_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + void xzhgeqz(::coder::array &A, int32_T ilo, int32_T ihi, :: + coder::array &Z, int32_T *info, ::coder::array< + creal_T, 1U> &alpha1, ::coder::array &beta1); + } + } + } +} + +#endif + +// End of code generation (xzhgeqz.h) diff --git a/cpp/RAT/xzlangeM.cpp b/cpp/RAT/xzlangeM.cpp new file mode 100644 index 00000000..c93c43aa --- /dev/null +++ b/cpp/RAT/xzlangeM.cpp @@ -0,0 +1,63 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzlangeM.cpp +// +// Code generation for function 'xzlangeM' +// + +// Include files +#include "xzlangeM.h" +#include "RATMain_rtwutil.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + real_T xzlangeM(const ::coder::array &x) + { + real_T y; + boolean_T b; + boolean_T b1; + y = 0.0; + b = (x.size(0) == 0); + b1 = (x.size(1) == 0); + if ((!b) && (!b1)) { + int32_T k; + boolean_T exitg1; + k = 0; + exitg1 = false; + while ((!exitg1) && (k <= x.size(0) * x.size(1) - 1)) { + real_T absxk; + absxk = rt_hypotd_snf(x[k].re, x[k].im); + if (std::isnan(absxk)) { + y = rtNaN; + exitg1 = true; + } else { + if (absxk > y) { + y = absxk; + } + + k++; + } + } + } + + return y; + } + } + } + } +} + +// End of code generation (xzlangeM.cpp) diff --git a/cpp/RAT/xzlangeM.h b/cpp/RAT/xzlangeM.h new file mode 100644 index 00000000..0128c89a --- /dev/null +++ b/cpp/RAT/xzlangeM.h @@ -0,0 +1,36 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzlangeM.h +// +// Code generation for function 'xzlangeM' +// +#ifndef XZLANGEM_H +#define XZLANGEM_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + real_T xzlangeM(const ::coder::array &x); + } + } + } +} + +#endif + +// End of code generation (xzlangeM.h) diff --git a/cpp/RAT/xzlanhs.cpp b/cpp/RAT/xzlanhs.cpp new file mode 100644 index 00000000..db5838d1 --- /dev/null +++ b/cpp/RAT/xzlanhs.cpp @@ -0,0 +1,96 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzlanhs.cpp +// +// Code generation for function 'xzlanhs' +// + +// Include files +#include "xzlanhs.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + real_T xzlanhs(const ::coder::array &A, int32_T ilo, + int32_T ihi) + { + real_T f; + f = 0.0; + if (ilo <= ihi) { + real_T scale; + real_T ssq; + int32_T nm1; + scale = 3.3121686421112381E-170; + ssq = 0.0; + nm1 = ihi - ilo; + for (int32_T j{0}; j <= nm1; j++) { + real_T absxk; + real_T colscale; + real_T colssq; + int32_T col; + int32_T u0; + colscale = 3.3121686421112381E-170; + colssq = 0.0; + col = (ilo + j) - 1; + u0 = j + 1; + if (u0 > nm1) { + u0 = nm1; + } + + u0 += ilo; + for (int32_T row{ilo}; row <= u0; row++) { + real_T t; + absxk = std::abs(A[(row + A.size(0) * col) - 1].re); + if (absxk > colscale) { + t = colscale / absxk; + colssq = colssq * t * t + 1.0; + colscale = absxk; + } else { + t = absxk / colscale; + colssq += t * t; + } + + absxk = std::abs(A[(row + A.size(0) * col) - 1].im); + if (absxk > colscale) { + t = colscale / absxk; + colssq = colssq * t * t + 1.0; + colscale = absxk; + } else { + t = absxk / colscale; + colssq += t * t; + } + } + + if (scale >= colscale) { + absxk = colscale / scale; + ssq += absxk * absxk * colssq; + } else { + absxk = scale / colscale; + ssq = colssq + absxk * absxk * ssq; + scale = colscale; + } + } + + f = scale * std::sqrt(ssq); + } + + return f; + } + } + } + } +} + +// End of code generation (xzlanhs.cpp) diff --git a/cpp/RAT/xzlanhs.h b/cpp/RAT/xzlanhs.h new file mode 100644 index 00000000..9628bf23 --- /dev/null +++ b/cpp/RAT/xzlanhs.h @@ -0,0 +1,37 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzlanhs.h +// +// Code generation for function 'xzlanhs' +// +#ifndef XZLANHS_H +#define XZLANHS_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + real_T xzlanhs(const ::coder::array &A, int32_T ilo, + int32_T ihi); + } + } + } +} + +#endif + +// End of code generation (xzlanhs.h) diff --git a/cpp/RAT/xzlarf.cpp b/cpp/RAT/xzlarf.cpp new file mode 100644 index 00000000..ef2fab20 --- /dev/null +++ b/cpp/RAT/xzlarf.cpp @@ -0,0 +1,198 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzlarf.cpp +// +// Code generation for function 'xzlarf' +// + +// Include files +#include "xzlarf.h" +#include "rt_nonfinite.h" +#include "xgemv.h" +#include "xgerc.h" +#include "coder_array.h" + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + static int32_T ilazlc(int32_T m, int32_T n, const ::coder::array &A, int32_T ia0, int32_T lda); + static int32_T ilazlr(int32_T m, int32_T n, const ::coder::array &A, int32_T ia0, int32_T lda); + } + } + } +} + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + static int32_T ilazlc(int32_T m, int32_T n, const ::coder::array &A, int32_T ia0, int32_T lda) + { + int32_T j; + boolean_T exitg2; + j = n; + exitg2 = false; + while ((!exitg2) && (j > 0)) { + int32_T coltop; + int32_T exitg1; + int32_T ia; + coltop = ia0 + (j - 1) * lda; + ia = coltop; + do { + exitg1 = 0; + if (ia <= (coltop + m) - 1) { + if (A[ia - 1] != 0.0) { + exitg1 = 1; + } else { + ia++; + } + } else { + j--; + exitg1 = 2; + } + } while (exitg1 == 0); + + if (exitg1 == 1) { + exitg2 = true; + } + } + + return j; + } + + static int32_T ilazlr(int32_T m, int32_T n, const ::coder::array &A, int32_T ia0, int32_T lda) + { + int32_T i; + boolean_T exitg2; + i = m; + exitg2 = false; + while ((!exitg2) && (i > 0)) { + int32_T exitg1; + int32_T rowleft; + int32_T rowright; + rowleft = (ia0 + i) - 1; + rowright = rowleft + (n - 1) * lda; + do { + exitg1 = 0; + if (((lda > 0) && (rowleft <= rowright)) || ((lda < 0) && (rowleft + >= rowright))) { + if (A[rowleft - 1] != 0.0) { + exitg1 = 1; + } else { + rowleft += lda; + } + } else { + i--; + exitg1 = 2; + } + } while (exitg1 == 0); + + if (exitg1 == 1) { + exitg2 = true; + } + } + + return i; + } + + void b_xzlarf(int32_T m, int32_T n, int32_T iv0, real_T tau, ::coder:: + array &C, int32_T ic0, int32_T ldc, ::coder:: + array &work) + { + int32_T lastc; + int32_T lastv; + if (tau != 0.0) { + lastv = n; + lastc = iv0 + n; + while ((lastv > 0) && (C[lastc - 2] == 0.0)) { + lastv--; + lastc--; + } + + lastc = ilazlr(m, lastv, C, ic0, ldc); + } else { + lastv = 0; + lastc = 0; + } + + if (lastv > 0) { + blas::b_xgemv(lastc, lastv, C, ic0, ldc, C, iv0, work); + blas::xgerc(lastc, lastv, -tau, work, iv0, C, ic0, ldc); + } + } + + void c_xzlarf(int32_T m, int32_T n, int32_T iv0, real_T tau, ::coder:: + array &C, int32_T ic0, int32_T ldc, ::coder:: + array &work) + { + int32_T lastc; + int32_T lastv; + if (tau != 0.0) { + lastv = m; + lastc = iv0 + m; + while ((lastv > 0) && (C[lastc - 2] == 0.0)) { + lastv--; + lastc--; + } + + lastc = ilazlc(lastv, n, C, ic0, ldc); + } else { + lastv = 0; + lastc = 0; + } + + if (lastv > 0) { + blas::c_xgemv(lastv, lastc, C, ic0, ldc, C, iv0, work); + blas::xgerc(lastv, lastc, -tau, iv0, work, C, ic0, ldc); + } + } + + void xzlarf(int32_T m, int32_T n, int32_T iv0, real_T tau, ::coder:: + array &C, int32_T ic0, int32_T ldc, ::coder:: + array &work) + { + int32_T lastc; + int32_T lastv; + if (tau != 0.0) { + lastv = m; + lastc = iv0 + m; + while ((lastv > 0) && (C[lastc - 2] == 0.0)) { + lastv--; + lastc--; + } + + lastc = ilazlc(lastv, n, C, ic0, ldc); + } else { + lastv = 0; + lastc = 0; + } + + if (lastv > 0) { + blas::xgemv(lastv, lastc, C, ic0, ldc, C, iv0, work); + blas::xgerc(lastv, lastc, -tau, iv0, work, C, ic0, ldc); + } + } + } + } + } +} + +// End of code generation (xzlarf.cpp) diff --git a/cpp/RAT/xzlarf.h b/cpp/RAT/xzlarf.h new file mode 100644 index 00000000..feaff388 --- /dev/null +++ b/cpp/RAT/xzlarf.h @@ -0,0 +1,44 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzlarf.h +// +// Code generation for function 'xzlarf' +// +#ifndef XZLARF_H +#define XZLARF_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + void b_xzlarf(int32_T m, int32_T n, int32_T iv0, real_T tau, ::coder:: + array &C, int32_T ic0, int32_T ldc, ::coder:: + array &work); + void c_xzlarf(int32_T m, int32_T n, int32_T iv0, real_T tau, ::coder:: + array &C, int32_T ic0, int32_T ldc, ::coder:: + array &work); + void xzlarf(int32_T m, int32_T n, int32_T iv0, real_T tau, ::coder:: + array &C, int32_T ic0, int32_T ldc, ::coder:: + array &work); + } + } + } +} + +#endif + +// End of code generation (xzlarf.h) diff --git a/cpp/RAT/xzlarfg.cpp b/cpp/RAT/xzlarfg.cpp new file mode 100644 index 00000000..378304eb --- /dev/null +++ b/cpp/RAT/xzlarfg.cpp @@ -0,0 +1,214 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzlarfg.cpp +// +// Code generation for function 'xzlarfg' +// + +// Include files +#include "xzlarfg.h" +#include "RATMain_rtwutil.h" +#include "rt_nonfinite.h" +#include "xnrm2.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + real_T xzlarfg(int32_T n, real_T *alpha1, ::coder::array &x) + { + real_T tau; + tau = 0.0; + if (n > 0) { + real_T xnorm; + xnorm = blas::b_xnrm2(n - 1, x); + if (xnorm != 0.0) { + real_T beta1; + beta1 = rt_hypotd_snf(*alpha1, xnorm); + if (*alpha1 >= 0.0) { + beta1 = -beta1; + } + + if (std::abs(beta1) < 1.0020841800044864E-292) { + int32_T knt; + knt = 0; + do { + knt++; + for (int32_T k{2}; k <= n; k++) { + x[k - 1] = 9.9792015476736E+291 * x[k - 1]; + } + + beta1 *= 9.9792015476736E+291; + *alpha1 *= 9.9792015476736E+291; + } while ((std::abs(beta1) < 1.0020841800044864E-292) && (knt < + 20)); + + beta1 = rt_hypotd_snf(*alpha1, blas::b_xnrm2(n - 1, x)); + if (*alpha1 >= 0.0) { + beta1 = -beta1; + } + + tau = (beta1 - *alpha1) / beta1; + xnorm = 1.0 / (*alpha1 - beta1); + for (int32_T k{2}; k <= n; k++) { + x[k - 1] = xnorm * x[k - 1]; + } + + for (int32_T k{0}; k < knt; k++) { + beta1 *= 1.0020841800044864E-292; + } + + *alpha1 = beta1; + } else { + tau = (beta1 - *alpha1) / beta1; + xnorm = 1.0 / (*alpha1 - beta1); + for (int32_T k{2}; k <= n; k++) { + x[k - 1] = xnorm * x[k - 1]; + } + + *alpha1 = beta1; + } + } + } + + return tau; + } + + real_T xzlarfg(int32_T n, real_T *alpha1, ::coder::array &x, + int32_T ix0) + { + real_T tau; + tau = 0.0; + if (n > 0) { + real_T xnorm; + xnorm = blas::xnrm2(n - 1, x, ix0); + if (xnorm != 0.0) { + real_T beta1; + beta1 = rt_hypotd_snf(*alpha1, xnorm); + if (*alpha1 >= 0.0) { + beta1 = -beta1; + } + + if (std::abs(beta1) < 1.0020841800044864E-292) { + int32_T i; + int32_T knt; + knt = 0; + i = (ix0 + n) - 2; + do { + knt++; + for (int32_T k{ix0}; k <= i; k++) { + x[k - 1] = 9.9792015476736E+291 * x[k - 1]; + } + + beta1 *= 9.9792015476736E+291; + *alpha1 *= 9.9792015476736E+291; + } while ((std::abs(beta1) < 1.0020841800044864E-292) && (knt < + 20)); + + beta1 = rt_hypotd_snf(*alpha1, blas::xnrm2(n - 1, x, ix0)); + if (*alpha1 >= 0.0) { + beta1 = -beta1; + } + + tau = (beta1 - *alpha1) / beta1; + xnorm = 1.0 / (*alpha1 - beta1); + for (int32_T k{ix0}; k <= i; k++) { + x[k - 1] = xnorm * x[k - 1]; + } + + for (int32_T k{0}; k < knt; k++) { + beta1 *= 1.0020841800044864E-292; + } + + *alpha1 = beta1; + } else { + int32_T i; + tau = (beta1 - *alpha1) / beta1; + xnorm = 1.0 / (*alpha1 - beta1); + i = (ix0 + n) - 2; + for (int32_T k{ix0}; k <= i; k++) { + x[k - 1] = xnorm * x[k - 1]; + } + + *alpha1 = beta1; + } + } + } + + return tau; + } + + real_T xzlarfg(int32_T n, real_T *alpha1, real_T x[3]) + { + real_T tau; + tau = 0.0; + if (n > 0) { + real_T xnorm; + xnorm = blas::xnrm2(n - 1, x); + if (xnorm != 0.0) { + real_T beta1; + beta1 = rt_hypotd_snf(*alpha1, xnorm); + if (*alpha1 >= 0.0) { + beta1 = -beta1; + } + + if (std::abs(beta1) < 1.0020841800044864E-292) { + int32_T knt; + knt = 0; + do { + knt++; + for (int32_T k{2}; k <= n; k++) { + x[k - 1] *= 9.9792015476736E+291; + } + + beta1 *= 9.9792015476736E+291; + *alpha1 *= 9.9792015476736E+291; + } while ((std::abs(beta1) < 1.0020841800044864E-292) && (knt < + 20)); + + beta1 = rt_hypotd_snf(*alpha1, blas::xnrm2(n - 1, x)); + if (*alpha1 >= 0.0) { + beta1 = -beta1; + } + + tau = (beta1 - *alpha1) / beta1; + xnorm = 1.0 / (*alpha1 - beta1); + for (int32_T k{2}; k <= n; k++) { + x[k - 1] *= xnorm; + } + + for (int32_T k{0}; k < knt; k++) { + beta1 *= 1.0020841800044864E-292; + } + + *alpha1 = beta1; + } else { + tau = (beta1 - *alpha1) / beta1; + xnorm = 1.0 / (*alpha1 - beta1); + for (int32_T k{2}; k <= n; k++) { + x[k - 1] *= xnorm; + } + + *alpha1 = beta1; + } + } + } + + return tau; + } + } + } + } +} + +// End of code generation (xzlarfg.cpp) diff --git a/cpp/RAT/xzlarfg.h b/cpp/RAT/xzlarfg.h new file mode 100644 index 00000000..02267ebf --- /dev/null +++ b/cpp/RAT/xzlarfg.h @@ -0,0 +1,39 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzlarfg.h +// +// Code generation for function 'xzlarfg' +// +#ifndef XZLARFG_H +#define XZLARFG_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + real_T xzlarfg(int32_T n, real_T *alpha1, ::coder::array &x); + real_T xzlarfg(int32_T n, real_T *alpha1, ::coder::array &x, + int32_T ix0); + real_T xzlarfg(int32_T n, real_T *alpha1, real_T x[3]); + } + } + } +} + +#endif + +// End of code generation (xzlarfg.h) diff --git a/cpp/RAT/xzlartg.cpp b/cpp/RAT/xzlartg.cpp new file mode 100644 index 00000000..225797ae --- /dev/null +++ b/cpp/RAT/xzlartg.cpp @@ -0,0 +1,282 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzlartg.cpp +// +// Code generation for function 'xzlartg' +// + +// Include files +#include "xzlartg.h" +#include "RATMain_rtwutil.h" +#include "rt_nonfinite.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + void xzlartg(const creal_T f, const creal_T g, real_T *cs, creal_T *sn) + { + real_T f2; + real_T fs_im; + real_T fs_re; + real_T gs_im; + real_T gs_re; + real_T scale; + real_T scale_tmp; + int32_T count; + boolean_T guard1; + scale_tmp = std::abs(f.re); + f2 = std::abs(f.im); + if (f2 > scale_tmp) { + scale_tmp = f2; + } + + f2 = std::abs(g.re); + scale = std::abs(g.im); + if (scale > f2) { + f2 = scale; + } + + scale = scale_tmp; + if (f2 > scale_tmp) { + scale = f2; + } + + fs_re = f.re; + fs_im = f.im; + gs_re = g.re; + gs_im = g.im; + count = 0; + guard1 = false; + if (scale >= 7.4428285367870146E+137) { + do { + count++; + fs_re *= 1.3435752215134178E-138; + fs_im *= 1.3435752215134178E-138; + gs_re *= 1.3435752215134178E-138; + gs_im *= 1.3435752215134178E-138; + scale *= 1.3435752215134178E-138; + } while ((scale >= 7.4428285367870146E+137) && (count < 20)); + + guard1 = true; + } else if (scale <= 1.3435752215134178E-138) { + if (((g.re == 0.0) && (g.im == 0.0)) || (std::isnan(g.re) || std:: + isnan(g.im))) { + *cs = 1.0; + sn->re = 0.0; + sn->im = 0.0; + } else { + do { + fs_re *= 7.4428285367870146E+137; + fs_im *= 7.4428285367870146E+137; + gs_re *= 7.4428285367870146E+137; + gs_im *= 7.4428285367870146E+137; + scale *= 7.4428285367870146E+137; + } while (!!(scale <= 1.3435752215134178E-138)); + + guard1 = true; + } + } else { + guard1 = true; + } + + if (guard1) { + real_T g2; + f2 = fs_re * fs_re + fs_im * fs_im; + g2 = gs_re * gs_re + gs_im * gs_im; + scale = g2; + if (g2 < 1.0) { + scale = 1.0; + } + + if (f2 <= scale * 2.0041683600089728E-292) { + if ((f.re == 0.0) && (f.im == 0.0)) { + *cs = 0.0; + g2 = rt_hypotd_snf(gs_re, gs_im); + sn->re = gs_re / g2; + sn->im = -gs_im / g2; + } else { + real_T g2s; + g2s = std::sqrt(g2); + *cs = rt_hypotd_snf(fs_re, fs_im) / g2s; + if (scale_tmp > 1.0) { + g2 = rt_hypotd_snf(f.re, f.im); + fs_re = f.re / g2; + fs_im = f.im / g2; + } else { + f2 = 7.4428285367870146E+137 * f.re; + scale = 7.4428285367870146E+137 * f.im; + g2 = rt_hypotd_snf(f2, scale); + fs_re = f2 / g2; + fs_im = scale / g2; + } + + gs_re /= g2s; + gs_im = -gs_im / g2s; + sn->re = fs_re * gs_re - fs_im * gs_im; + sn->im = fs_re * gs_im + fs_im * gs_re; + } + } else { + scale = std::sqrt(g2 / f2 + 1.0); + *cs = 1.0 / scale; + g2 += f2; + fs_re = scale * fs_re / g2; + fs_im = scale * fs_im / g2; + sn->re = fs_re * gs_re - fs_im * -gs_im; + sn->im = fs_re * -gs_im + fs_im * gs_re; + } + } + } + + void xzlartg(const creal_T f, const creal_T g, real_T *cs, creal_T *sn, + creal_T *r) + { + real_T f2s; + real_T fs_im; + real_T fs_re; + real_T gs_im; + real_T gs_re; + real_T scale; + real_T scale_tmp; + int32_T count; + int8_T rescaledir; + boolean_T guard1; + scale_tmp = std::abs(f.re); + f2s = std::abs(f.im); + if (f2s > scale_tmp) { + scale_tmp = f2s; + } + + f2s = std::abs(g.re); + scale = std::abs(g.im); + if (scale > f2s) { + f2s = scale; + } + + scale = scale_tmp; + if (f2s > scale_tmp) { + scale = f2s; + } + + fs_re = f.re; + fs_im = f.im; + gs_re = g.re; + gs_im = g.im; + count = -1; + rescaledir = 0; + guard1 = false; + if (scale >= 7.4428285367870146E+137) { + do { + count++; + fs_re *= 1.3435752215134178E-138; + fs_im *= 1.3435752215134178E-138; + gs_re *= 1.3435752215134178E-138; + gs_im *= 1.3435752215134178E-138; + scale *= 1.3435752215134178E-138; + } while ((scale >= 7.4428285367870146E+137) && (count + 1 < 20)); + + rescaledir = 1; + guard1 = true; + } else if (scale <= 1.3435752215134178E-138) { + if (((g.re == 0.0) && (g.im == 0.0)) || (std::isnan(g.re) || std:: + isnan(g.im))) { + *cs = 1.0; + sn->re = 0.0; + sn->im = 0.0; + *r = f; + } else { + do { + count++; + fs_re *= 7.4428285367870146E+137; + fs_im *= 7.4428285367870146E+137; + gs_re *= 7.4428285367870146E+137; + gs_im *= 7.4428285367870146E+137; + scale *= 7.4428285367870146E+137; + } while (!!(scale <= 1.3435752215134178E-138)); + + rescaledir = -1; + guard1 = true; + } + } else { + guard1 = true; + } + + if (guard1) { + real_T f2; + real_T g2; + f2 = fs_re * fs_re + fs_im * fs_im; + g2 = gs_re * gs_re + gs_im * gs_im; + scale = g2; + if (g2 < 1.0) { + scale = 1.0; + } + + if (f2 <= scale * 2.0041683600089728E-292) { + if ((f.re == 0.0) && (f.im == 0.0)) { + *cs = 0.0; + r->re = rt_hypotd_snf(g.re, g.im); + r->im = 0.0; + f2 = rt_hypotd_snf(gs_re, gs_im); + sn->re = gs_re / f2; + sn->im = -gs_im / f2; + } else { + g2 = std::sqrt(g2); + *cs = rt_hypotd_snf(fs_re, fs_im) / g2; + if (scale_tmp > 1.0) { + f2 = rt_hypotd_snf(f.re, f.im); + fs_re = f.re / f2; + fs_im = f.im / f2; + } else { + scale = 7.4428285367870146E+137 * f.re; + f2s = 7.4428285367870146E+137 * f.im; + f2 = rt_hypotd_snf(scale, f2s); + fs_re = scale / f2; + fs_im = f2s / f2; + } + + gs_re /= g2; + gs_im = -gs_im / g2; + sn->re = fs_re * gs_re - fs_im * gs_im; + sn->im = fs_re * gs_im + fs_im * gs_re; + r->re = *cs * f.re + (sn->re * g.re - sn->im * g.im); + r->im = *cs * f.im + (sn->re * g.im + sn->im * g.re); + } + } else { + f2s = std::sqrt(g2 / f2 + 1.0); + r->re = f2s * fs_re; + r->im = f2s * fs_im; + *cs = 1.0 / f2s; + f2 += g2; + f2s = r->re / f2; + scale = r->im / f2; + sn->re = f2s * gs_re - scale * -gs_im; + sn->im = f2s * -gs_im + scale * gs_re; + if (rescaledir > 0) { + for (int32_T i{0}; i <= count; i++) { + r->re *= 7.4428285367870146E+137; + r->im *= 7.4428285367870146E+137; + } + } else if (rescaledir < 0) { + for (int32_T i{0}; i <= count; i++) { + r->re *= 1.3435752215134178E-138; + r->im *= 1.3435752215134178E-138; + } + } + } + } + } + } + } + } +} + +// End of code generation (xzlartg.cpp) diff --git a/cpp/RAT/xzlartg.h b/cpp/RAT/xzlartg.h new file mode 100644 index 00000000..cefbef82 --- /dev/null +++ b/cpp/RAT/xzlartg.h @@ -0,0 +1,37 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzlartg.h +// +// Code generation for function 'xzlartg' +// +#ifndef XZLARTG_H +#define XZLARTG_H + +// Include files +#include "rtwtypes.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + void xzlartg(const creal_T f, const creal_T g, real_T *cs, creal_T *sn); + void xzlartg(const creal_T f, const creal_T g, real_T *cs, creal_T *sn, + creal_T *r); + } + } + } +} + +#endif + +// End of code generation (xzlartg.h) diff --git a/cpp/RAT/xzlascl.cpp b/cpp/RAT/xzlascl.cpp new file mode 100644 index 00000000..43ff0991 --- /dev/null +++ b/cpp/RAT/xzlascl.cpp @@ -0,0 +1,102 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzlascl.cpp +// +// Code generation for function 'xzlascl' +// + +// Include files +#include "xzlascl.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + void xzlascl(real_T cfrom, real_T cto, ::coder::array &A) + { + real_T cfromc; + real_T ctoc; + boolean_T notdone; + cfromc = cfrom; + ctoc = cto; + notdone = true; + while (notdone) { + real_T a; + real_T cfrom1; + real_T cto1; + int32_T loop_ub; + cfrom1 = cfromc * 2.0041683600089728E-292; + cto1 = ctoc / 4.9896007738368E+291; + if ((std::abs(cfrom1) > std::abs(ctoc)) && (ctoc != 0.0)) { + a = 2.0041683600089728E-292; + cfromc = cfrom1; + } else if (std::abs(cto1) > std::abs(cfromc)) { + a = 4.9896007738368E+291; + ctoc = cto1; + } else { + a = ctoc / cfromc; + notdone = false; + } + + loop_ub = A.size(0); + for (int32_T i{0}; i < loop_ub; i++) { + A[i].re = a * A[i].re; + A[i].im = a * A[i].im; + } + } + } + + void xzlascl(real_T cfrom, real_T cto, ::coder::array &A) + { + real_T cfromc; + real_T ctoc; + boolean_T notdone; + cfromc = cfrom; + ctoc = cto; + notdone = true; + while (notdone) { + real_T a; + real_T cfrom1; + real_T cto1; + int32_T loop_ub; + cfrom1 = cfromc * 2.0041683600089728E-292; + cto1 = ctoc / 4.9896007738368E+291; + if ((std::abs(cfrom1) > std::abs(ctoc)) && (ctoc != 0.0)) { + a = 2.0041683600089728E-292; + cfromc = cfrom1; + } else if (std::abs(cto1) > std::abs(cfromc)) { + a = 4.9896007738368E+291; + ctoc = cto1; + } else { + a = ctoc / cfromc; + notdone = false; + } + + loop_ub = A.size(1); + for (int32_T i{0}; i < loop_ub; i++) { + int32_T b_loop_ub; + b_loop_ub = A.size(0); + for (int32_T i1{0}; i1 < b_loop_ub; i1++) { + A[i1 + A.size(0) * i].re = a * A[i1 + A.size(0) * i].re; + A[i1 + A.size(0) * i].im = a * A[i1 + A.size(0) * i].im; + } + } + } + } + } + } + } +} + +// End of code generation (xzlascl.cpp) diff --git a/cpp/RAT/xzlascl.h b/cpp/RAT/xzlascl.h new file mode 100644 index 00000000..e394a31a --- /dev/null +++ b/cpp/RAT/xzlascl.h @@ -0,0 +1,37 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzlascl.h +// +// Code generation for function 'xzlascl' +// +#ifndef XZLASCL_H +#define XZLASCL_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + void xzlascl(real_T cfrom, real_T cto, ::coder::array &A); + void xzlascl(real_T cfrom, real_T cto, ::coder::array &A); + } + } + } +} + +#endif + +// End of code generation (xzlascl.h) diff --git a/cpp/RAT/xztgevc.cpp b/cpp/RAT/xztgevc.cpp new file mode 100644 index 00000000..750f16c7 --- /dev/null +++ b/cpp/RAT/xztgevc.cpp @@ -0,0 +1,338 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xztgevc.cpp +// +// Code generation for function 'xztgevc' +// + +// Include files +#include "xztgevc.h" +#include "RATMain_data.h" +#include "rt_nonfinite.h" +#include "coder_array.h" +#include + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + void xztgevc(const ::coder::array &A, ::coder::array< + creal_T, 2U> &V) + { + ::coder::array work1; + ::coder::array work2; + ::coder::array rworka; + real_T BIG; + real_T BIGNUM; + real_T NSAFMIN; + real_T SMALL; + real_T anorm; + real_T ascale; + real_T x; + real_T y; + int32_T b_i; + int32_T i; + int32_T n; + n = A.size(0); + work1.set_size(A.size(0)); + i = A.size(0); + for (b_i = 0; b_i < i; b_i++) { + work1[b_i].re = 0.0; + work1[b_i].im = 0.0; + } + + work2.set_size(A.size(0)); + i = A.size(0); + for (b_i = 0; b_i < i; b_i++) { + work2[b_i].re = 0.0; + work2[b_i].im = 0.0; + } + + NSAFMIN = 2.2250738585072014E-308 * static_cast(A.size(0)); + SMALL = NSAFMIN / 2.2204460492503131E-16; + BIG = 1.0 / SMALL; + BIGNUM = 1.0 / NSAFMIN; + rworka.set_size(A.size(0)); + i = A.size(0); + for (b_i = 0; b_i < i; b_i++) { + rworka[b_i] = 0.0; + } + + anorm = std::abs(A[0].re) + std::abs(A[0].im); + for (int32_T j{2}; j <= n; j++) { + for (i = 0; i <= j - 2; i++) { + rworka[j - 1] = rworka[j - 1] + (std::abs(A[i + A.size(0) * (j - 1)] + .re) + std::abs(A[i + A.size(0) * (j - 1)].im)); + } + + y = rworka[j - 1] + (std::abs(A[(j + A.size(0) * (j - 1)) - 1].re) + + std::abs(A[(j + A.size(0) * (j - 1)) - 1].im)); + if (y > anorm) { + anorm = y; + } + } + + x = anorm; + if (anorm < 2.2250738585072014E-308) { + x = 2.2250738585072014E-308; + } + + ascale = 1.0 / x; + for (int32_T je{n}; je >= 1; je--) { + real_T acoeff; + real_T dmin; + real_T salpha_im; + real_T salpha_re; + real_T scale; + real_T temp; + boolean_T lscalea; + boolean_T lscaleb; + NSAFMIN = A[(je + A.size(0) * (je - 1)) - 1].re; + y = A[(je + A.size(0) * (je - 1)) - 1].im; + x = (std::abs(NSAFMIN) + std::abs(y)) * ascale; + if (x < 1.0) { + x = 1.0; + } + + temp = 1.0 / x; + salpha_re = ascale * (temp * NSAFMIN); + salpha_im = ascale * (temp * y); + acoeff = temp * ascale; + if ((temp >= 2.2250738585072014E-308) && (acoeff < SMALL)) { + lscalea = true; + } else { + lscalea = false; + } + + NSAFMIN = std::abs(salpha_re) + std::abs(salpha_im); + if ((NSAFMIN >= 2.2250738585072014E-308) && (NSAFMIN < SMALL)) { + lscaleb = true; + } else { + lscaleb = false; + } + + scale = 1.0; + if (lscalea) { + x = anorm; + if (BIG < anorm) { + x = BIG; + } + + scale = SMALL / temp * x; + } + + if (lscaleb) { + y = SMALL / NSAFMIN; + if (y > scale) { + scale = y; + } + } + + if (lscalea || lscaleb) { + x = acoeff; + if (acoeff < 1.0) { + x = 1.0; + } + + if (NSAFMIN > x) { + x = NSAFMIN; + } + + y = 1.0 / (2.2250738585072014E-308 * x); + if (y < scale) { + scale = y; + } + + if (lscalea) { + acoeff = ascale * (scale * temp); + } else { + acoeff *= scale; + } + + salpha_re *= scale; + salpha_im *= scale; + } + + for (int32_T jr{0}; jr < n; jr++) { + work1[jr].re = 0.0; + work1[jr].im = 0.0; + } + + work1[je - 1].re = 1.0; + work1[je - 1].im = 0.0; + dmin = 2.2204460492503131E-16 * acoeff * anorm; + y = 2.2204460492503131E-16 * (std::abs(salpha_re) + std::abs + (salpha_im)); + if (y > dmin) { + dmin = y; + } + + if (dmin < 2.2250738585072014E-308) { + dmin = 2.2250738585072014E-308; + } + + for (int32_T jr{0}; jr <= je - 2; jr++) { + work1[jr].re = acoeff * A[jr + A.size(0) * (je - 1)].re; + work1[jr].im = acoeff * A[jr + A.size(0) * (je - 1)].im; + } + + work1[je - 1].re = 1.0; + work1[je - 1].im = 0.0; + b_i = je - 1; + for (int32_T j{b_i}; j >= 1; j--) { + real_T brm; + real_T d_im; + real_T d_re; + d_re = acoeff * A[(j + A.size(0) * (j - 1)) - 1].re - salpha_re; + d_im = acoeff * A[(j + A.size(0) * (j - 1)) - 1].im - salpha_im; + if (std::abs(d_re) + std::abs(d_im) <= dmin) { + d_re = dmin; + d_im = 0.0; + } + + brm = std::abs(d_re); + y = std::abs(d_im); + NSAFMIN = brm + y; + if (NSAFMIN < 1.0) { + scale = std::abs(work1[j - 1].re) + std::abs(work1[j - 1].im); + if (scale >= BIGNUM * NSAFMIN) { + temp = 1.0 / scale; + for (int32_T jr{0}; jr < je; jr++) { + work1[jr].re = temp * work1[jr].re; + work1[jr].im = temp * work1[jr].im; + } + } + } + + NSAFMIN = work1[j - 1].re; + x = -work1[j - 1].re; + scale = work1[j - 1].im; + temp = -work1[j - 1].im; + if (d_im == 0.0) { + if (-scale == 0.0) { + y = -NSAFMIN / d_re; + NSAFMIN = 0.0; + } else if (-NSAFMIN == 0.0) { + y = 0.0; + NSAFMIN = -scale / d_re; + } else { + y = -NSAFMIN / d_re; + NSAFMIN = -scale / d_re; + } + } else if (d_re == 0.0) { + if (-NSAFMIN == 0.0) { + y = -scale / d_im; + NSAFMIN = 0.0; + } else if (-scale == 0.0) { + y = 0.0; + NSAFMIN = -(-NSAFMIN / d_im); + } else { + y = -scale / d_im; + NSAFMIN = -(-NSAFMIN / d_im); + } + } else if (brm > y) { + scale = d_im / d_re; + NSAFMIN = d_re + scale * d_im; + y = (x + scale * temp) / NSAFMIN; + NSAFMIN = (temp - scale * x) / NSAFMIN; + } else if (y == brm) { + if (d_re > 0.0) { + scale = 0.5; + } else { + scale = -0.5; + } + + if (d_im > 0.0) { + NSAFMIN = 0.5; + } else { + NSAFMIN = -0.5; + } + + y = (x * scale + temp * NSAFMIN) / brm; + NSAFMIN = (temp * scale - x * NSAFMIN) / brm; + } else { + scale = d_re / d_im; + NSAFMIN = d_im + scale * d_re; + y = (scale * x + temp) / NSAFMIN; + NSAFMIN = (scale * temp - x) / NSAFMIN; + } + + work1[j - 1].re = y; + work1[j - 1].im = NSAFMIN; + if (j > 1) { + NSAFMIN = std::abs(y) + std::abs(NSAFMIN); + if (NSAFMIN > 1.0) { + temp = 1.0 / NSAFMIN; + if (acoeff * rworka[j - 1] >= BIGNUM * temp) { + for (int32_T jr{0}; jr < je; jr++) { + work1[jr].re = temp * work1[jr].re; + work1[jr].im = temp * work1[jr].im; + } + } + } + + d_re = acoeff * work1[j - 1].re; + d_im = acoeff * work1[j - 1].im; + for (int32_T jr{0}; jr <= j - 2; jr++) { + NSAFMIN = A[jr + A.size(0) * (j - 1)].im; + x = A[jr + A.size(0) * (j - 1)].re; + work1[jr].re = work1[jr].re + (d_re * x - d_im * NSAFMIN); + work1[jr].im = work1[jr].im + (d_re * NSAFMIN + d_im * x); + } + } + } + + for (int32_T jr{0}; jr < n; jr++) { + work2[jr].re = 0.0; + work2[jr].im = 0.0; + } + + for (i = 0; i < je; i++) { + for (int32_T jr{0}; jr < n; jr++) { + NSAFMIN = V[jr + V.size(0) * i].re; + y = work1[i].im; + scale = V[jr + V.size(0) * i].im; + x = work1[i].re; + work2[jr].re = work2[jr].re + (NSAFMIN * x - scale * y); + work2[jr].im = work2[jr].im + (NSAFMIN * y + scale * x); + } + } + + NSAFMIN = std::abs(work2[0].re) + std::abs(work2[0].im); + if (n > 1) { + for (int32_T jr{2}; jr <= n; jr++) { + y = std::abs(work2[jr - 1].re) + std::abs(work2[jr - 1].im); + if (y > NSAFMIN) { + NSAFMIN = y; + } + } + } + + if (NSAFMIN > 2.2250738585072014E-308) { + temp = 1.0 / NSAFMIN; + for (int32_T jr{0}; jr < n; jr++) { + V[jr + V.size(0) * (je - 1)].re = temp * work2[jr].re; + V[jr + V.size(0) * (je - 1)].im = temp * work2[jr].im; + } + } else { + for (int32_T jr{0}; jr < n; jr++) { + V[jr + V.size(0) * (je - 1)].re = 0.0; + V[jr + V.size(0) * (je - 1)].im = 0.0; + } + } + } + } + } + } + } +} + +// End of code generation (xztgevc.cpp) diff --git a/cpp/RAT/xztgevc.h b/cpp/RAT/xztgevc.h new file mode 100644 index 00000000..af942c9c --- /dev/null +++ b/cpp/RAT/xztgevc.h @@ -0,0 +1,37 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xztgevc.h +// +// Code generation for function 'xztgevc' +// +#ifndef XZTGEVC_H +#define XZTGEVC_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + void xztgevc(const ::coder::array &A, ::coder::array< + creal_T, 2U> &V); + } + } + } +} + +#endif + +// End of code generation (xztgevc.h) diff --git a/cpp/RAT/xzungqr.cpp b/cpp/RAT/xzungqr.cpp new file mode 100644 index 00000000..280f49f4 --- /dev/null +++ b/cpp/RAT/xzungqr.cpp @@ -0,0 +1,86 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzungqr.cpp +// +// Code generation for function 'xzungqr' +// + +// Include files +#include "xzungqr.h" +#include "rt_nonfinite.h" +#include "xzlarf.h" +#include "coder_array.h" + +// Function Definitions +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + void xzungqr(int32_T m, int32_T n, int32_T k, ::coder::array + &A, int32_T ia0, int32_T lda, const ::coder::array &tau) + { + ::coder::array work; + if (n >= 1) { + int32_T i; + int32_T ia; + int32_T iaii; + int32_T itau; + i = n - 1; + for (int32_T j{k}; j <= i; j++) { + ia = (ia0 + j * lda) - 1; + iaii = m - 1; + for (int32_T b_i{0}; b_i <= iaii; b_i++) { + A[ia + b_i] = 0.0; + } + + A[ia + j] = 1.0; + } + + uint32_T unnamed_idx_0; + itau = k - 1; + unnamed_idx_0 = static_cast(A.size(1)); + work.set_size(static_cast(unnamed_idx_0)); + ia = static_cast(unnamed_idx_0); + for (i = 0; i < ia; i++) { + work[i] = 0.0; + } + + for (int32_T b_i{k}; b_i >= 1; b_i--) { + iaii = ((ia0 + b_i) + (b_i - 1) * lda) - 1; + if (b_i < n) { + A[iaii - 1] = 1.0; + c_xzlarf((m - b_i) + 1, n - b_i, iaii, tau[itau], A, iaii + lda, + lda, work); + } + + if (b_i < m) { + ia = iaii + 1; + i = (iaii + m) - b_i; + for (int32_T j{ia}; j <= i; j++) { + A[j - 1] = -tau[itau] * A[j - 1]; + } + } + + A[iaii - 1] = 1.0 - tau[itau]; + for (int32_T j{0}; j <= b_i - 2; j++) { + A[(iaii - j) - 2] = 0.0; + } + + itau--; + } + } + } + } + } + } +} + +// End of code generation (xzungqr.cpp) diff --git a/cpp/RAT/xzungqr.h b/cpp/RAT/xzungqr.h new file mode 100644 index 00000000..16f17d79 --- /dev/null +++ b/cpp/RAT/xzungqr.h @@ -0,0 +1,38 @@ +// +// Non-Degree Granting Education License -- for use at non-degree +// granting, nonprofit, education, and research organizations only. Not +// for commercial or industrial use. +// +// xzungqr.h +// +// Code generation for function 'xzungqr' +// +#ifndef XZUNGQR_H +#define XZUNGQR_H + +// Include files +#include "rtwtypes.h" +#include "coder_array.h" +#include +#include + +// Function Declarations +namespace RAT +{ + namespace coder + { + namespace internal + { + namespace reflapack + { + void xzungqr(int32_T m, int32_T n, int32_T k, ::coder::array + &A, int32_T ia0, int32_T lda, const ::coder::array &tau); + } + } + } +} + +#endif + +// End of code generation (xzungqr.h) diff --git a/cpp/includes/defines.h b/cpp/includes/defines.h deleted file mode 100644 index 097ad0eb..00000000 --- a/cpp/includes/defines.h +++ /dev/null @@ -1,679 +0,0 @@ -#ifndef RAT_DEFINES_H -#define RAT_DEFINES_H - -#include -#include -#include - -namespace py = pybind11; - -const std::string docsProgressEventData = R"(The Python binding for the C++ progressEventData struct. -The progress event shows the percentage completion for the calculation. This can be emitted by -the DREAM algorithm only. - -Parameters ----------- -message : str - The title text for the event. -percent : float - The percentage of the calculation completed (as a number between 0 and 1) -)"; - -struct ProgressEventData -{ - std::string message; - double percent; -}; - -const std::string docsPlotEventData = R"(The Python binding for the C++ plotEventData struct. -The plot event data contains intermediate results from the calculation. This can be emitted -by the Simplex and DE algorithms only. - -Parameters ----------- -reflectivity : list - The reflectivity curves for each contrast, with the same range as the data - (``data_range`` in the contrast's ``Data`` object) -shiftedData : list - The data with scalefactors and background corrections applied. -sldProfiles : list - The SLD profiles for each contrast. -resampledLayers : list - If resampling is used, the SLD for each contrast after resampling has been performed. -subRoughs : np.ndarray[np.float] - The substrate roughness values for each contrast. -resample : np.ndarray[np.float] - An array containing whether each contrast was resampled. -dataPresent : np.ndarray[np.float] - Non-zero values indicates if data is present for the contrast. -modelType : str - The model type for the project. -contrastNames : list - The names of all contrasts in the project. -)"; - -struct PlotEventData -{ - py::list reflectivity; - py::list shiftedData; - py::list sldProfiles; - py::list resampledLayers; - py::array_t subRoughs; - py::array_t resample; - py::array_t dataPresent; - std::string modelType; - py::list contrastNames; -}; - - -const std::string docsPredictionIntervals = R"(The Python binding for the C++ predictionIntervals struct. -The Bayesian prediction intervals for 95% and 65% confidence. - -For ``reflectivity`` and ``sld``, each list item is an array -with five rows. The rows represent: - -- 0: the 5th percentile; -- 1: the 35th percentile; -- 2: the mean value of the interval; -- 3: the 65th percentile; -- 4: the 95th percentile. - -Parameters ----------- -reflectivity : list - The prediction interval data for reflectivity of each contrast. -sld : list - The prediction interval data for SLD of each contrast. -sampleChi : np.ndarray[np.float] - The value of sumChi at each point of the Markov chain. -)"; - -struct PredictionIntervals -{ - py::list reflectivity; - py::list sld; - py::array_t sampleChi; -}; - -const std::string docsConfidenceIntervals = R"(The Python binding for the C++ confidenceIntervals struct. -The 65% and 95% confidence intervals for the best fit results. - -Parameters ----------- -percentile95 : np.ndarray[np.float] - The 95% confidence intervals for each fit parameter. -percentile65 : np.ndarray[np.float] - The 65% confidence intervals for each fit parameter. -mean : np.ndarray[np.float] - The mean values for each fit parameter. -)"; - -struct ConfidenceIntervals -{ - py::array_t percentile95; - py::array_t percentile65; - py::array_t mean; -}; - -const std::string docsNestedSamplerOutput = R"(The Python binding for the C++ nestedSamplerOutput struct. -The output information from the Nested Sampler (ns). - -Parameters ----------- -logZ : float - The natural logarithm of the evidence Z for the parameter values. -logZErr : float - The estimated uncertainty in the final value of logZ. -nestSamples : np.ndarray[np.float] - ``NestedSamplerOutput.nestSamples[i, j]`` represents the values - sampled at iteration ``i``, where this value is: - - - the value sampled for parameter ``j``, for ``j`` in ``0:nParams``, - - the minimum log-likelihood for ``j = nParams + 1``. - -postSamples : np.ndarray[np.float] - The posterior values at the points sampled in ``NestedSamplerOutput.nestSamples``. -)"; - -struct NestedSamplerOutput -{ - real_T logZ; - real_T logZErr; - py::array_t nestSamples; - py::array_t postSamples; -}; - -const std::string docsDreamParams = R"(The Python binding for the C++ dreamParams struct. -The parameters used by the inner DREAM algorithm. - -Parameters ----------- -nParams : float - The number of parameters used by the algorithm. -nChains : float - The number of MCMC chains used by the algorithm. -nGenerations : float - The number of DE generations calculated per iteration. -parallel : bool - Whether the algorithm should run chains in parallel. -CPU : float - The number of processor cores used for parallel chains. -jumpProbability : float - A probability range for the size of jumps when performing subspace sampling. -pUnitGamma : float - The probability that the scaling-down factor of jumps will be ignored - and a larger jump will be taken for one iteration. -nCR : float - The number of crossovers performed each iteration. -delta : float - The number of chain mutation pairs proposed each iteration. -steps : float - The number of MCMC steps to perform between conversion checks. -zeta : float - The ergodicity of the algorithm. -outlier : str - What test should be used to detect outliers. -adaptPCR : bool - Whether the crossover probability for differential evolution should be - adapted by the algorithm as it runs. -thinning : float - The thinning rate of each Markov chain (to reduce memory intensity) -epsilon : float - The cutoff threshold for Approximate Bayesian Computation (if used) -ABC : bool - Whether Approximate Bayesian Computation is used. -IO : bool - Whether the algorithm should perform IO writes of the model in parallel. -storeOutput : bool - Whether output model simulations are performed. -R : np.np.ndarray[np.float] - An array where row ``i`` is the list of chains - with which chain ``i`` can mutate. -)"; - -struct DreamParams -{ - real_T nParams; - real_T nChains; - real_T nGenerations; - boolean_T parallel; - real_T CPU; - real_T jumpProbability; - real_T pUnitGamma; - real_T nCR; - real_T delta; - real_T steps; - real_T zeta; - std::string outlier; - boolean_T adaptPCR; - real_T thinning; - real_T epsilon; - boolean_T ABC; - boolean_T IO; - boolean_T storeOutput; - py::array_t R; -}; - -const std::string docsDreamOutput = R"(The Python binding for the C++ DreamOutput struct. -The diagnostic output information from DREAM. - -Parameters ----------- -allChains : np.ndarray[np.float] - An ``nGenerations`` x ``nParams + 2`` x ``nChains`` size array, - where ``chain_k = DreamOutput.allChains[:, :, k]`` - is the data of chain ``k`` in the final iteration; - for generation i of the final iteration, ``chain_k[i, j]`` represents: - - - the sampled value of parameter ``j`` for ``j in 0:nParams``; - - the associated log-prior for those sampled values for ``j = nParams + 1``; - - the associated log-likelihood for those sampled values for ``j = nParams + 2``. - -outlierChains : np.ndarray[np.float] - A two-column array where ``DreamOutput.AR[i, 1]`` is the index of a chain - and ``DreamOutput.AR[i, 0]`` is the length of that chain when it was removed - for being an outlier. -runtime : float - The runtime of the DREAM algorithm in seconds. -iteration : float - The number of iterations performed. -AR : np.ndarray[np.float] - A two-column array where ``DreamOutput.AR[i, 0]`` is an iteration number - and ``DreamOutput.AR[i, 1]`` is the average acceptance rate of chain step - proposals for that iteration. -R_stat : np.ndarray[np.float] - An array where ``DreamOutput.R_stat[i, 0]`` is an iteration number and - ``DreamOutput.R_stat[i, j]`` is the convergence statistic for parameter ``j`` - at that iteration (where chains are indexed 1 to ``nParams`` inclusive). -CR : np.ndarray[np.float] - A four-column array where ``DreamOutput.CR[i, 0]`` is an iteration number, - ``and DreamOutput.CR[i, j]`` is the selection probability of the ``j``'th crossover - value for that iteration. -)"; - -struct DreamOutput -{ - py::array_t allChains; - py::array_t outlierChains; - real_T runtime; - real_T iteration; - py::array_t AR; - py::array_t R_stat; - py::array_t CR; -}; - -const std::string docsOutputBayesResult = R"(The Python binding for the C++ bayesResults struct. -The results of a Bayesian RAT calculation. - -Parameters ----------- -predictionIntervals : RATapi.rat_core.PredictionIntervals - The prediction intervals. -confidenceIntervals : RATapi.rat_core.ConfidenceIntervals - The 65% and 95% confidence intervals for the best fit results. -dreamParams : RATapi.rat_core.DreamParams - The parameters used by DREAM, if relevant. -dreamOutput : RATapi.rat_core.DreamOutput - The output from DREAM if DREAM was used. -nestedSamplerOutput : RATapi.rat_core.NestedSamplerOutput - The output from nested sampling if ns was used. -chain : np.ndarray - The MCMC chains for each parameter. - The ``i``'th column of the array contains the chain for parameter ``fitNames[i]``. -)"; - -struct OutputBayesResult -{ - PredictionIntervals predictionIntervals; - ConfidenceIntervals confidenceIntervals; - DreamParams dreamParams; - DreamOutput dreamOutput; - NestedSamplerOutput nestedSamplerOutput; - py::array_t chain; -}; - -const std::string docsCalculation = R"(The Python binding for the C++ calculationResult struct. -The goodness of fit from the Abeles calculation. - -Parameters ----------- -chiValues : np.ndarray[np.float] - The chi-squared value for each contrast. -sumChi : float - The sum of the chiValues array. -)"; - -struct Calculation -{ - py::array_t chiValues; - real_T sumChi; -}; - -const std::string docsContrastParams = R"(The Python binding for the C++ contrastParams struct. -The experimental parameters for each contrast. - -Parameters ----------- -scalefactors : np.ndarray[np.float] - The scalefactor values for each contrast. -bulkIn : np.ndarray[np.float] - The bulk in values for each contrast. -bulkOut : np.ndarray[np.float] - The bulk out values for each contrast. -subRoughs : np.ndarray[np.float] - The substrate roughness values for each contrast. -resample : np.ndarray[np.float] - An array containing whether each contrast was resampled. -)"; - -struct ContrastParams -{ - py::array_t scalefactors; - py::array_t bulkIn; - py::array_t bulkOut; - py::array_t subRoughs; - py::array_t resample; -}; - -const std::string docsOutputResult = R"(The C++ result struct of a RAT calculation. - -Parameters ----------- -reflectivity : list - The reflectivity curves for each contrast, with the same range as the data - (``data_range`` in the contrast's ``Data`` object) -simulation : list - The reflectivity curves for each contrast, which can be a wider range to allow extrapolation - (``simulation_range`` in the contrast's ``Data`` object). -shiftedData : list - The data with scalefactors and background corrections applied. -backgrounds : list - The background for each contrast defined over the simulation range. -resolutions : list - The resolution for each contrast defined over the simulation range. -sldProfiles : list - The SLD profiles for each contrast. -layers : list - The array of layer parameter values for each contrast. -resampledLayers : list - If resampling is used, the array of layer parameter values for each contrast after resampling has been performed. -calculationResults : RATapi.rat_core.Calculation - The chi-squared fit results from the final calculation and fit. -contrastParams : RATapi.rat_core.ContrastParams - The experimental parameters for the contrasts. -fitParams : np.ndarray[np.float] - The best fit value of the parameter with name ``fitNames[i]``. -fitNames : list[str] - The names of the fit parameters, where ``fitNames[i]`` is the name - of the parameter with value given in ``fitParams[i]``. -)"; - -struct OutputResult { - py::list reflectivity; - py::list simulation; - py::list shiftedData; - py::list backgrounds; - py::list resolutions; - py::list sldProfiles; - py::list layers; - py::list resampledLayers; - Calculation calculationResults {}; - ContrastParams contrastParams {}; - py::array_t fitParams; - py::list fitNames; -}; - -const std::string docsNameStore = R"(The Python binding for the C++ names struct which -contains names of all parameters in the project. - -Parameters ----------- -params : list - Names of params in the problem definition. -backgroundParams : list - Names of backgroundParams in the problem definition. -scalefactors : list - Names of scalefactors in the problem definition. -bulkIns : list - Names of bulkIns in the problem definition. -bulkName: list - Names of bulkOuts in the problem definition. -resolutionParams : list - Names of resolutionParams in the problem definition. -domainRatios : list - Names of domainRatios in the problem definition. -)"; - -struct NameStore { - py::list params; - py::list backgroundParams; - py::list scalefactors; - py::list bulkIns; - py::list bulkOuts; - py::list resolutionParams; - py::list domainRatios; - py::list contrasts; -}; - - -const std::string docsChecks = R"(The Python binding for the C++ checks struct which contains -flags indicating which parameters should be fitted in the project. - -For each attribute, if index ``i`` is non-zero, then parameter ``i`` in that attribute is fitted, e.g. if ``Checks.scalefactors = [0.0, 1.0, 1.0]``, then the second and third scalefactors are fitted and the first is not. - -Parameters ----------- -params : np.ndarray[np.float] - Non-zero values indicates which params is fitted. -backgroundParams : np.ndarray[np.float] - Non-zero values indicates which backgroundParams is fitted. -scalefactors : np.ndarray[np.float] - Non-zero values indicates which scalefactors is fitted. -bulkIns : np.ndarray[np.float] - Non-zero values indicates which bulkIns is fitted. -bulkOuts : np.ndarray[np.float] - Non-zero values indicates which bulkOuts is fitted. -resolutionParams : np.ndarray[np.float] - Non-zero values indicates which resolutionParams is fitted. -domainRatios : np.ndarray[np.float] - Non-zero values indicates which domainRatios is fitted. -)"; - -struct Checks { - py::array_t params; - py::array_t backgroundParams; - py::array_t scalefactors; - py::array_t bulkIns; - py::array_t bulkOuts; - py::array_t resolutionParams; - py::array_t domainRatios; -}; - -const std::string docsProblemDefinition = R"(The Python binding for the C++ problem struct. - -Parameters ----------- -TF : str - The target function for the calculation which can be 'normal' or 'domains'. -resample : np.ndarray[np.float] - If ``resample[i]`` is non-zero, then contrast ``i`` will be resampled. -data : list - Data for each contrast. -dataPresent : np.ndarray[np.float] - If ``dataPresent[i]`` is non-zero, then contrast ``i`` has experimental data. -dataLimits : list - Data limits for each contrast. -simulationLimits : list; - Simulation for each contrast. -numberOfContrasts : int - Number of contrasts. -geometry : str - The geometry to use which can be 'air/substrate' or 'substrate/liquid' -useImaginary : bool - Indicates whether imaginary component is used for the SLD value in layers, i.e. - absorption is set to True for the project. -repeatLayers : list - Information about repeating layers for each contrast. This is currently not being used. -contrastBackgroundParams : list - Indices of backgroundParams used for each contrast -contrastBackgroundTypes : list - Background type for each contrast. -contrastBackgroundActions : list - Background action for each contrast. -contrastScalefactors : np.ndarray[np.float] - Indices of scalefactors used for each contrast. -contrastBulkIns : np.ndarray[np.float] - Indices of BulkIns used for each contrast. -contrastBulkOuts : np.ndarray[np.float] - Indices of BulkIns used for each contrast. -contrastResolutionParams : list - Indices of resolutionParams used for each contrast -contrastResolutionTypes : list - Resolution type for each contrast. -backgroundParams : np.ndarray[np.float] - Background parameter values. -scalefactors : np.ndarray[np.float] - Scalefactors values. -bulkIns : np.ndarray[np.float] - BulkIn values. -bulkOuts : np.ndarray[np.float] - BulkOut values. -resolutionParams : np.ndarray[np.float] - Resolution parameter values. -params : np.ndarray[np.float] - Parameter values. -numberOfLayers : int - Number of layers. -contrastLayers : list - Indices of layers added to the model of each contrast. -layersDetails : list - Indices of parameters in each layer. -customFiles : object - Iterable with custom file functions -modelType : str - The layer model type which can be 'standard layers', 'custom layers', or 'custom xy'. -contrastCustomFiles : np.ndarray[np.float] - Indices of CustomFiles used for each domain contrast -contrastDomainRatios : np.ndarray[np.float] - Indices of DomainRatios used for each domain contrast -domainRatios : np.ndarray[np.float] - Domain ratio values -numberOfDomainContrasts : int - Number of domain contrasts. -domainContrastLayers : list - Indices of layers added to the model of each domain contrast. -fitParams : np.ndarray[np.float] - Values of fitted parameters. -fitLimits : np.ndarray[np.float] - Limits of fitted parameters. -priorNames : list - Parameter names for for all parameters in the problem definition. -priorValues : np.ndarray[np.float] - Prior type, mu, and sigma for all parameters in the problem definition. -names : RATapi.rat_core.NameStore - Names of all parameters. -checks : RATapi.rat_core.Checks - Flags indicating which parameters should be fitted. -)"; - -struct ProblemDefinition { - std::string TF {}; - py::array_t resample; - py::list data; - py::array_t dataPresent; - py::list dataLimits; - py::list simulationLimits; - real_T numberOfContrasts; - std::string geometry {}; - boolean_T useImaginary {}; - py::list repeatLayers; - py::list contrastBackgroundParams; - py::list contrastBackgroundTypes; - py::list contrastBackgroundActions; - py::array_t contrastScalefactors; - py::array_t contrastBulkIns; - py::array_t contrastBulkOuts; - py::list contrastResolutionParams; - py::list contrastResolutionTypes; - py::array_t backgroundParams; - py::array_t scalefactors; - py::array_t bulkIns; - py::array_t bulkOuts; - py::array_t resolutionParams; - py::array_t params; - real_T numberOfLayers {}; - py::list contrastLayers; - py::list layersDetails; - py::object customFiles; - std::string modelType {}; - py::array_t contrastCustomFiles; - py::array_t contrastDomainRatios; - py::array_t domainRatios; - real_T numberOfDomainContrasts {}; - py::list domainContrastLayers; - py::array_t fitParams; - py::array_t fitLimits; - py::list priorNames; - py::array_t priorValues; - NameStore names; - Checks checks {}; -}; - - -const std::string docsControl = R"(The Python binding for the C++ controls struct. - -Parameters ----------- -parallel : str - How the calculation should be parallelised (This uses the Parallel Computing Toolbox). Can be 'single', 'contrasts' or 'points'. -procedure : str - Which procedure RAT should execute. Can be 'calculate', 'simplex', 'de', 'ns', or 'dream'. -numSimulationPoints : int - The number of points used for a reflectivity simulation where no data is present. -resampleMinAngle : float - The upper threshold on the angle between three sampled points for resampling, in units of radians over pi. -resampleNPoints : int - The number of initial points to use for resampling. -display : str - How much RAT should print to the terminal. Can be 'off', 'iter', 'notify', or 'final'. -IPCFilePath : str - The path of the inter process communication file. -updateFreq : int - [SIMPLEX, DE] Number of iterations between printing progress updates to the terminal. -updatePlotFreq : int - [SIMPLEX, DE] Number of iterations between updates to live plots. -xTolerance : float - [SIMPLEX] The termination tolerance for step size. -funcTolerance : float - [SIMPLEX] The termination tolerance for change in chi-squared. -maxFuncEvals : int - [SIMPLEX] The maximum number of function evaluations before the algorithm terminates. -maxIterations : int - [SIMPLEX] The maximum number of iterations before the algorithm terminates. -populationSize : int - [DE] The number of candidate solutions that exist at any time. -fWeight : float - [DE] The step size for how different mutations are to their parents. -crossoverProbability : float - [DE] The probability of exchange of parameters between individuals at any iteration. -strategy : int - [DE] The algorithm used to generate new candidates. -targetValue : float - [DE] The value of chi-squared at which the algorithm will terminate. -numGenerations : int - [DE] The maximum number of iterations before the algorithm terminates. -nLive : int - [NS] The number of points to sample. -nMCMC : int - [NS] If non-zero, an MCMC process with ``nMCMC`` chains will be used instead of MultiNest. -propScale : float - [NS] A scaling factor for the ellipsoid generated by MultiNest. -nsTolerance : float - [NS] The tolerance threshold for when the algorithm should terminate. -nSamples : int - [DREAM] The number of samples in the initial population for each chain. -nChains : int - [DREAM] The number of Markov chains to use in the algorithm. -jumpProbability : float - [DREAM] The probability range for the size of jumps in sampling. Larger values mean more variable jumps. -pUnitGamma : float - [DREAM] The probability that the scaling-down factor of jumps will be ignored and a larger jump will be taken. -boundHandling : str - [DREAM] How steps past the space boundaries should be handled. Can be 'off', 'reflect', 'bound', or 'fold'. -adaptPCR : bool - [DREAM] Whether the crossover probability for differential evolution should be adapted during the run. -)"; - -struct Control { - std::string parallel {}; - std::string procedure {}; - std::string display {}; - real_T xTolerance {}; - real_T funcTolerance {}; - real_T maxFuncEvals {}; - real_T maxIterations {}; - real_T populationSize {}; - real_T fWeight {}; - real_T crossoverProbability {}; - real_T targetValue {}; - real_T numGenerations {}; - real_T strategy {}; - real_T nLive {}; - real_T nMCMC {}; - real_T propScale {}; - real_T nsTolerance {}; - real_T numSimulationPoints {}; - real_T resampleMinAngle {}; - real_T resampleNPoints {}; - real_T updateFreq {}; - real_T updatePlotFreq {}; - real_T nSamples {}; - real_T nChains {}; - real_T jumpProbability {}; - real_T pUnitGamma {}; - std::string boundHandling {}; - boolean_T adaptPCR; - std::string IPCFilePath {}; -}; - -#endif // RAT_DEFINES_H \ No newline at end of file diff --git a/cpp/includes/functions.h b/cpp/includes/functions.h deleted file mode 100644 index 3ced72fe..00000000 --- a/cpp/includes/functions.h +++ /dev/null @@ -1,500 +0,0 @@ -#ifndef RAT_FUNCTIONS_H -#define RAT_FUNCTIONS_H - -#include -#include -#include -#include -#include "../RAT/classHandle.hpp" - -namespace py = pybind11; - -template -auto customCaller(std::string identifier, Function f, Args&& ... args) -> decltype((*f)(std::forward(args)...)) -{ - try - { - return (*f)(std::forward(args)...); - } - catch(const std::runtime_error& re) - { - std::string errorMsg; - size_t start_pos = std::string(re.what()).find("$id"); - if(start_pos == std::string::npos) - { - errorMsg = std::string("Error occurred when setting ") + identifier + ". " + re.what(); - } - else - { - errorMsg = re.what(); - errorMsg.replace(start_pos, 3, identifier); - } - - throw std::runtime_error(errorMsg); - } -} - -class Library: public CallbackInterface -{ - public: - - py::function function; - - Library(const py::function function){ - this->function = function; - }; - - - void setOutput(py::tuple& result, std::vector& output, double *outputSize) - { - int nRows = 0, idx = 0; - for (py::handle rowHandle : result[0]) - { - py::list rows = py::cast(rowHandle); - for (py::handle value : rows) - { - output.push_back(py::cast(value)); - idx++; - } - nRows++; - } - - outputSize[0] = nRows; - outputSize[1] = (nRows == 0) ? 0 : idx / nRows; - } - - // Backgrounds - void invoke(std::vector& xdata, std::vector& params, std::vector& output) - { - auto f = py::cast>(this->function); - auto result = f(py::cast(xdata), py::cast(params)); - for (py::handle rowHandle : result) - { - if (py::isinstance(rowHandle)) - output.push_back(py::cast(py::cast(rowHandle)[0])); - else - output.push_back(py::cast(rowHandle)); - - } - }; - - // Domain overload - void invoke(std::vector& params, std::vector& bulkIn, std::vector& bulkOut, - int contrast, int domainNumber, std::vector& output, double *outputSize, double *roughness) - { - auto f = py::cast>(this->function); - auto result = f(py::cast(params), py::cast(bulkIn), py::cast(bulkOut), contrast, domainNumber); - *roughness = py::cast(result[1]); - setOutput(result, output, outputSize); - }; - - // Non-Domain overload - void invoke(std::vector& params, std::vector& bulkIn, std::vector& bulkOut, - int contrast, std::vector& output, double *outputSize, double *roughness) - { - auto f = py::cast>(this->function); - auto result = f(py::cast(params), py::cast(bulkIn), py::cast(bulkOut), contrast); - *roughness = py::cast(result[1]); - setOutput(result, output, outputSize); - }; -}; - - -void stringToRatBoundedArray(std::string value, char_T result_data[], int32_T result_size[2]) -{ - result_size[0] = 1; - result_size[1] = value.length(); - - for (int32_T idx1{0}; idx1 < value.length(); idx1++) { - result_data[idx1] = value[idx1]; - } -} - -void stringToRatCharArray(std::string value, coder::array& result) -{ - result.set_size(1, value.length()); - - for (int32_T idx{0}; idx < value.length(); idx++) { - result[idx] = value[idx]; - } -} - -void stringFromRatBoundedArray(const char_T array_data[], const int32_T array_size[2], std::string& result) -{ - result.resize(array_size[1]); - memcpy(&result[0], array_data, array_size[1]); -} - - -coder::array pyArrayToRatRowArray1d(py::array_t value) -{ - coder::array result; - - py::buffer_info buffer_info = value.request(); - - if (buffer_info.size == 0) - return result; - - if (buffer_info.ndim != 1) - throw std::runtime_error("Expects a 1D numeric array"); - - result.set_size(1, buffer_info.shape[0]); - for (int32_T idx0{0}; idx0 < buffer_info.shape[0]; idx0++) { - result[idx0] = value.at(idx0); - } - - return result; -} - -coder::bounded_array pyArrayToRatBoundedArray(py::array_t value) -{ - coder::bounded_array result {}; - - py::buffer_info buffer_info = value.request(); - - if (buffer_info.size == 0) - return result; - - if (buffer_info.ndim != 1) - throw std::runtime_error("Expects a 1D numeric array"); - - result.size[0] = 1; - result.size[1] = buffer_info.shape[0]; - for (int32_T idx0{0}; idx0 < buffer_info.shape[0]; idx0++) { - result.data[idx0] = value.at(idx0); - } - - return result; -} - -coder::bounded_array pyArrayToRatBoundedArray3(py::array_t value) -{ - coder::bounded_array result {}; - - py::buffer_info buffer_info = value.request(); - - if (buffer_info.size == 0) - return result; - - if (buffer_info.ndim != 1) - throw std::runtime_error("Expects a 1D numeric array"); - - result.size[0] = 1; - result.size[1] = buffer_info.shape[0]; - for (int32_T idx0{0}; idx0 < buffer_info.shape[0]; idx0++) { - result.data[idx0] = value.at(idx0); - } - - return result; -} - -coder::array pyArrayToRatArray2d(py::array_t value) -{ - coder::array result; - - py::buffer_info buffer_info = value.request(); - - if (buffer_info.size == 0) - return result; - - if (buffer_info.ndim != 2) - throw std::runtime_error("Expects a 2D numeric array"); - - result.set_size(buffer_info.shape[0], buffer_info.shape[1]); - - int32_T idx {0}; - for (int32_T idx0{0}; idx0 < buffer_info.shape[0]; idx0++) { - for (int32_T idx1{0}; idx1 < buffer_info.shape[1]; idx1++) { - idx = idx0 + result.size(0) * idx1; - result[idx] = value.at(idx0, idx1); - } - } - - return result; -} - -coder::array pyListToRatCellWrap1(py::list values) -{ - coder::array result; - result.set_size(1, values.size()); - int32_T idx {0}; - for (py::handle array: values) - { - py::array_t casted_array = py::cast(array); - result[idx].f1 = customCaller("$id[" + std::to_string(idx) +"]", pyArrayToRatArray2d, casted_array); - idx++; - } - - return result; -} - -coder::array pyListToRatCellWrap2(py::list values) -{ - coder::array result; - result.set_size(1, values.size()); - int32_T idx {0}; - for (py::handle array: values) - { - py::array_t casted_array = py::cast(array); - if (casted_array.size() != 2) - throw std::runtime_error("Expects a 2D list where each row contains exactly 2 numbers"); - result[idx].f1[0] = casted_array.at(0); - result[idx].f1[1] = casted_array.at(1); - idx++; - } - - return result; -} - - -coder::array pyListToRatCellWrap3(py::list values) -{ - coder::array result; - result.set_size(1, values.size()); - int32_T idx {0}; - for (py::handle array: values) - { - py::array_t casted_array = py::cast(array); - result[idx].f1 = customCaller("$id[" + std::to_string(idx) +"]", pyArrayToRatBoundedArray3, casted_array); - idx++; - } - - return result; -} - -coder::array pyListToRatCellWrap4(py::list values) -{ - coder::array result; - result.set_size(1, values.size()); - int32_T idx {0}; - for (py::handle array: values) - { - py::array_t casted_array = py::cast(array); - result[idx].f1 = customCaller("$id[" + std::to_string(idx) +"]", pyArrayToRatBoundedArray3, casted_array); - idx++; - } - - return result; -} - -coder::array pyListToRatCellWrap5(py::list values) -{ - coder::array result; - result.set_size(1, values.size()); - int32_T idx {0}; - for (py::handle array: values) - { - py::array_t casted_array = py::cast(array); - result[idx].f1 = customCaller("$id[" + std::to_string(idx) +"]", pyArrayToRatRowArray1d, casted_array); - idx++; - } - - return result; -} - -coder::array pyListToRatCellWrap6(py::list values) -{ - coder::array result; - result.set_size(1, values.size()); - int32_T idx {0}; - for (py::handle array: values) - { - py::array_t casted_array = py::cast(array); - result[idx].f1 = customCaller("$id[" + std::to_string(idx) +"]", pyArrayToRatBoundedArray, casted_array); - idx++; - } - - return result; -} - -coder::array pyListToRatCellWrap01d(py::list values) -{ - coder::array result; - result.set_size(values.size()); - int32_T idx {0}; - for (py::handle array: values) - { - if (py::isinstance(array)) { - std::string name = py::cast(array); - stringToRatBoundedArray(name, result[idx].f1.data, result[idx].f1.size); - idx++; - } - else - throw std::runtime_error("Expects a 1D list of strings"); - } - - return result; -} - -coder::array pyListToRatCellWrap02d(py::list values) -{ - coder::array result; - result.set_size(1, values.size()); - int32_T idx {0}; - for (py::handle array: values) - { - if (py::isinstance(array)) { - std::string name = py::cast(array); - stringToRatBoundedArray(name, result[idx].f1.data, result[idx].f1.size); - idx++; - } - else - throw std::runtime_error("Expects a 1D list of strings"); - } - - return result; -} - -coder::array py_function_array_to_rat_cell_wrap_0(py::object values) -{ - auto handles = py::cast(values); - coder::array result; - result.set_size(1, handles.size()); - int32_T idx {0}; - for (py::handle array: handles) - { - auto func = py::cast(array); - std::string func_ptr = convertPtr2String(new Library(func)); - stringToRatBoundedArray(func_ptr, result[idx].f1.data, result[idx].f1.size); - idx++; - } - - return result; -} -template -py::array_t pyArrayFromRatArray1d(T array, bool isCol=true) -{ - auto size = isCol ? array.size(1) : array.size(0); - auto result_array = py::array_t(size); - std::memcpy(result_array.request().ptr, array.data(), result_array.nbytes()); - - return result_array; -} - -py::array_t pyArrayFromRatArray2d(coder::array array) -{ - auto result_array = py::array_t({array.size(0), array.size(1)}); - std::memcpy(result_array.request().ptr, array.data(), result_array.nbytes()); - - return result_array; -} - -py::list pyListFromRatCellWrap01d(coder::array values) -{ - py::list result; - for (int32_T idx0{0}; idx0 < values.size(0); idx0++) { - std::string tmp; - stringFromRatBoundedArray(values[idx0].f1.data, values[idx0].f1.size, tmp); - result.append(tmp); - } - - return result; -} - -py::list pyListFromRatCellWrap02d(coder::array values) -{ - py::list result; - for (int32_T idx0{0}; idx0 < values.size(1); idx0++) { - std::string tmp; - stringFromRatBoundedArray(values[idx0].f1.data, values[idx0].f1.size, tmp); - result.append(tmp); - } - - return result; -} - -py::list pyListFromRatCellWrap2(coder::array values) -{ - py::list result; - - for (int32_T idx0{0}; idx0 < values.size(1); idx0++) { - py::list inner = py::make_tuple(values[idx0].f1[0], values[idx0].f1[1]); - result.append(inner); - } - - return result; -} - -template -py::list pyList1DFromRatCellWrap2D(const T& values) -{ - py::list result; - - for (int32_T idx0{0}; idx0 < values.size(1); idx0++) { - result.append(pyArrayFromRatArray2d(values[idx0].f1)); - } - - return result; -} - -template -py::list pyList1DFromRatCellWrap1D(const T& values) -{ - py::list result; - - for (int32_T idx0{0}; idx0 < values.size(0); idx0++) { - result.append(pyArrayFromRatArray2d(values[idx0].f1)); - } - - return result; -} - -template -py::list pyList2dFromRatCellWrap(const T& values) -{ - py::list result; - int32_T idx {0}; - for (int32_T idx0{0}; idx0 < values.size(0); idx0++) { - py::list inner; - for (int32_T idx1{0}; idx1 < values.size(1); idx1++) { - idx = idx0 + values.size(0) * idx1; - inner.append(pyArrayFromRatArray2d(values[idx].f1)); - } - result.append(inner); - } - - return result; -} - -template -py::list pyListFromBoundedCellWrap(const T& values) -{ - py::list result; - - for (int32_T idx0{0}; idx0 < values.size(1); idx0++) { - auto array = py::array_t({values[idx0].f1.size[0]}); - std::memcpy(array.request().ptr, values[idx0].f1.data, array.nbytes()); - - result.append(array); - } - - return result; -} - -template -py::array_t pyArray1dFromBoundedArray(const T& array) -{ - auto result_array = py::array_t({array.size[0]}); - std::memcpy(result_array.request().ptr, array.data, result_array.nbytes()); - - return result_array; -} - -template -py::array_t pyArray2dFromBoundedArray(const T& array) -{ - auto result_array = py::array_t({array.size[0], array.size[1]}); - std::memcpy(result_array.request().ptr, array.data, result_array.nbytes()); - - return result_array; -} - -py::array_t pyArrayFromRatArray3d(coder::array array) -{ - auto result_array = py::array_t({array.size(0), array.size(1), array.size(2)}); - std::memcpy(result_array.request().ptr, array.data(), result_array.nbytes()); - - return result_array; -} - -#endif // RAT_FUNCTIONS_H \ No newline at end of file diff --git a/cpp/rat.cpp b/cpp/rat.cpp index 957ba4fa..20e60d24 100644 --- a/cpp/rat.cpp +++ b/cpp/rat.cpp @@ -16,16 +16,63 @@ setup_pybind11(cfg) #include "RAT/RATMain_initialize.h" #include "RAT/RATMain_terminate.h" #include "RAT/RATMain_types.h" -#include "RAT/makeSLDProfile.h" +#include "RAT/classHandle.hpp" #include "RAT/dylib.hpp" #include "RAT/events/eventManager.h" -#include "includes/defines.h" -#include "includes/functions.h" namespace py = pybind11; const int DEFAULT_DOMAIN = -1; -const int DEFAULT_NREPEATS = 1; + +class Library: public CallbackInterface +{ + public: + + py::function function; + + Library(const py::function function){ + this->function = function; + }; + + + void setOutput(py::tuple& result, std::vector& output, double *outputSize) + { + int nRows = 0, idx = 0; + for (py::handle rowHandle : result[0]) + { + py::list rows = py::cast(rowHandle); + for (py::handle value : rows) + { + output.push_back(py::cast(value)); + idx++; + } + nRows++; + } + + outputSize[0] = nRows; + outputSize[1] = (nRows == 0) ? 0 : idx / nRows; + } + + // Domain overload + void invoke(std::vector& params, std::vector& bulkIn, std::vector& bulkOut, + int contrast, int domainNumber, std::vector& output, double *outputSize, double *roughness) + { + auto f = py::cast>(this->function); + auto result = f(py::cast(params), py::cast(bulkIn), py::cast(bulkOut), contrast, domainNumber); + *roughness = py::cast(result[1]); + setOutput(result, output, outputSize); + }; + + // Non-Domain overload + void invoke(std::vector& params, std::vector& bulkIn, std::vector& bulkOut, + int contrast, std::vector& output, double *outputSize, double *roughness) + { + auto f = py::cast>(this->function); + auto result = f(py::cast(params), py::cast(bulkIn), py::cast(bulkOut), contrast); + *roughness = py::cast(result[1]); + setOutput(result, output, outputSize); + }; +}; class DylibEngine { @@ -39,28 +86,13 @@ class DylibEngine this->library = std::unique_ptr(new dylib(libName)); if (!library) { - std::cerr << "dynamic library failed to load" << std::endl; + std::cerr << "dynamic libray failed to load" << std::endl; return; } }; ~DylibEngine(){}; - py::list invoke(std::vector& xdata, std::vector& params) - { - try{ - std::vector output; - - auto func = library->get_function&, std::vector&, std::vector&)>(functionName); - func(xdata, params, output); - - return py::cast(output); - - }catch (const dylib::symbol_error &) { - throw std::runtime_error("failed to get dynamic library symbol for " + functionName); - } - }; - py::tuple invoke(std::vector& params, std::vector& bulkIn, std::vector& bulkOut, int contrast, int domain=DEFAULT_DOMAIN) { try{ @@ -92,11 +124,24 @@ class DylibEngine return py::make_tuple(output, roughness); }catch (const dylib::symbol_error &) { - throw std::runtime_error("failed to get dynamic library symbol for " + functionName); + throw std::runtime_error("failed to get dynamic libray symbol for ***functionName"); } }; }; + +struct PlotEventData +{ + py::list reflectivity; + py::list shiftedData; + py::list sldProfiles; + py::list allLayers; + py::array_t ssubs; + py::array_t resample; + py::array_t dataPresent; + std::string modelType; +}; + class EventBridge { public: @@ -109,32 +154,26 @@ class EventBridge this->library = std::unique_ptr(new dylib(std::getenv("RAT_PATH"), filename.c_str())); if (!library) { - std::cerr << "event manager dynamic library failed to load" << std::endl; + std::cerr << "event manager dynamic libray failed to load" << std::endl; return; } this->callback = callback; }; py::list unpackDataToCell(int rows, int cols, double* data, double* nData, - double* data2, double* nData2, bool isOutput2D=false) + double* data2, double* nData2, int dataCol) { py::list allResults; - int dims[2] = {0, 0}; + int dims[2] = {0, dataCol}; int offset = 0; for (int i = 0; i < rows; i++){ - dims[0] = (int)nData[2*i]; - dims[1] = (int)nData[2*i+1]; + py::list rowList; + dims[0] = (int)nData[i] / dataCol; auto result = py::array_t({dims[0], dims[1]}); std::memcpy(result.request().ptr, data + offset, result.nbytes()); offset += result.size(); - if (isOutput2D){ - py::list rowList; - rowList.append(result); - allResults.append(rowList); - } - else{ - allResults.append(result); - } + rowList.append(result); + allResults.append(rowList); } if (data2 != NULL && nData2 != NULL) @@ -142,8 +181,7 @@ class EventBridge // This is used to unpack the domains data into the second column offset = 0; for ( int i = 0; i < rows; i++){ - dims[0] = (int)nData2[2*i]; - dims[1] = (int)nData2[2*i+1]; + dims[0] = (int)nData2[i] / dataCol; auto result = py::array_t({dims[0], dims[1]}); std::memcpy(result.request().ptr, data2 + offset, result.nbytes()); offset += result.size(); @@ -160,21 +198,14 @@ class EventBridge if (event.type == EventTypes::Message) { messageEvent* mEvent = (messageEvent*)&event; this->callback(event.type, mEvent->msg); - } else if (event.type == EventTypes::Progress){ - progressEvent* pEvent = (progressEvent*)&event; - ProgressEventData eventData; - - eventData.message = pEvent->msg; - eventData.percent = pEvent->percent; - this->callback(event.type, eventData); } else if (event.type == EventTypes::Plot){ plotEvent* pEvent = (plotEvent*)&event; PlotEventData eventData; eventData.modelType = std::string(pEvent->data->modelType); - eventData.subRoughs = py::array_t(pEvent->data->nContrast); - std::memcpy(eventData.subRoughs.request().ptr, pEvent->data->subRoughs, eventData.subRoughs.nbytes()); + eventData.ssubs = py::array_t(pEvent->data->nContrast); + std::memcpy(eventData.ssubs.request().ptr, pEvent->data->ssubs, eventData.ssubs.nbytes()); eventData.resample = py::array_t(pEvent->data->nContrast); std::memcpy(eventData.resample.request().ptr, pEvent->data->resample, eventData.resample.nbytes()); @@ -183,25 +214,18 @@ class EventBridge std::memcpy(eventData.dataPresent.request().ptr, pEvent->data->dataPresent, eventData.dataPresent.nbytes()); eventData.reflectivity = unpackDataToCell(pEvent->data->nContrast, 1, - pEvent->data->reflect, pEvent->data->nReflect, NULL, NULL); + pEvent->data->reflect, pEvent->data->nReflect, NULL, NULL, 2); eventData.shiftedData = unpackDataToCell(pEvent->data->nContrast, 1, - pEvent->data->shiftedData, pEvent->data->nShiftedData, NULL, NULL); + pEvent->data->shiftedData, pEvent->data->nShiftedData, NULL, NULL, 3); eventData.sldProfiles = unpackDataToCell(pEvent->data->nContrast, (pEvent->data->nSldProfiles2 == NULL) ? 1 : 2, pEvent->data->sldProfiles, pEvent->data->nSldProfiles, - pEvent->data->sldProfiles2, pEvent->data->nSldProfiles2, true); - - eventData.resampledLayers = unpackDataToCell(pEvent->data->nContrast, (pEvent->data->nLayers2 == NULL) ? 1 : 2, - pEvent->data->layers, pEvent->data->nLayers, - pEvent->data->layers2, pEvent->data->nLayers2, true); - - int offset = 0; - for (int i = 0; i < pEvent->data->nContrast; i++){ - eventData.contrastNames.append(std::string(pEvent->data->contrastNames + offset, - pEvent->data->nContrastNames[i])); - offset += pEvent->data->nContrastNames[i]; - } + pEvent->data->sldProfiles2, pEvent->data->nSldProfiles2, 2); + + eventData.allLayers = unpackDataToCell(pEvent->data->nContrast, (pEvent->data->nLayers2 == NULL) ? 1 : 2, + pEvent->data->layers, pEvent->data->nLayers, + pEvent->data->layers2, pEvent->data->nLayers, 2); this->callback(event.type, eventData); } }; @@ -221,420 +245,955 @@ class EventBridge }; }; -RAT::b_ParamNames createParamNamesStruct(const NameStore& names) +struct Predlims +{ + py::list refPredInts; + py::list sldPredInts; + py::list refXdata; + py::list sldXdata; + py::array_t sampleChi; +}; + +struct BestFitsMean { - RAT::b_ParamNames names_struct; - names_struct.params = customCaller("NameStore.params", pyListToRatCellWrap02d, names.params); - names_struct.backgroundParams = customCaller("NameStore.backgroundParams", pyListToRatCellWrap02d, names.backgroundParams); - names_struct.scalefactors = customCaller("NameStore.scalefactors", pyListToRatCellWrap02d, names.scalefactors); - names_struct.bulkIns = customCaller("NameStore.bulkIns", pyListToRatCellWrap02d, names.bulkIns); - names_struct.bulkOuts = customCaller("NameStore.bulkOuts", pyListToRatCellWrap02d, names.bulkOuts); - names_struct.resolutionParams = customCaller("NameStore.resolutionParams", pyListToRatCellWrap02d, names.resolutionParams); - names_struct.domainRatios = customCaller("NameStore.domainRatios", pyListToRatCellWrap02d, names.domainRatios); - names_struct.contrasts = customCaller("NameStore.contrasts", pyListToRatCellWrap02d, names.contrasts); + py::list ref; + py::list sld; + real_T chi; + py::list data; +}; + +struct ParConfInts +{ + py::array_t par95; + py::array_t par65; + py::array_t mean; +}; + +struct NestOutput +{ + real_T logZ; + py::array_t nestSamples; + py::array_t postSamples; +}; + +struct DREAMPars +{ + real_T d; + real_T N; + real_T T; + boolean_T parallel; + real_T CPU; + real_T lambda; + real_T pUnitGamma; + real_T nCR; + real_T delta; + real_T steps; + real_T zeta; + std::string outlier; + boolean_T adaptPCR; + real_T thinning; + real_T epsilon; + boolean_T ABC; + boolean_T IO; + boolean_T modout; + boolean_T restart; + boolean_T save; + py::array_t R; +}; + +struct MeasInfo +{ + real_T Y; + real_T N; +}; + +struct DreamOutput +{ + py::array_t outlier; + real_T runtime; + DREAMPars DREAMPar; + MeasInfo Meas_info; + real_T iteration; + real_T iloc; + real_T fx; + py::array_t AR; + py::array_t R_stat; + py::array_t CR; +}; + +struct BayesOutput +{ + py::array_t allChains; + DreamOutput dreamOutput; + NestOutput nestOutput; +}; + +struct BayesResults +{ + BestFitsMean bestFitsMean; + Predlims predlims; + ParConfInts parConfInts; + py::array_t bestPars; + BayesOutput bayesRes; + py::array_t chain; +}; + +struct Priors +{ + py::list param; + py::list backgroundParam; + py::list resolutionParam; + py::list bulkIn; + py::list bulkOut; + py::list qzshift; + py::list scalefactor; + py::list domainRatio; + py::list priorNames; + py::array_t priorValues; +}; + +struct Checks { + py::array_t fitParam; + py::array_t fitBackgroundParam; + py::array_t fitQzshift; + py::array_t fitScalefactor; + py::array_t fitBulkIn; + py::array_t fitBulkOut; + py::array_t fitResolutionParam; + py::array_t fitDomainRatio; +}; + +struct Calculation +{ + py::array_t allChis; + real_T sumChi; +}; + +struct ContrastParams +{ + py::array_t ssubs; + py::array_t backgroundParams; + py::array_t qzshifts; + py::array_t scalefactors; + py::array_t bulkIn; + py::array_t bulkOut; + py::array_t resolutionParams; + Calculation calculations {}; + py::array_t allSubRough; + py::array_t resample; +}; + +struct OutputResult { + py::list f1; + py::list f2; + py::list f3; + py::list f4; + py::list f5; + py::list f6; +}; + +struct Limits { + py::array_t param; + py::array_t backgroundParam; + py::array_t scalefactor; + py::array_t qzshift; + py::array_t bulkIn; + py::array_t bulkOut; + py::array_t resolutionParam; + py::array_t domainRatio; +}; + +struct Cells { + py::list f1; + py::list f2; + py::list f3; + py::list f4; + py::list f5; + py::list f6; + py::list f7; + py::list f8; + py::list f9; + py::list f10; + py::list f11; + py::list f12; + py::list f13; + py::list f14; + py::list f15; + py::list f16; + py::list f17; + py::list f18; + py::list f19; + py::list f20; +}; + +struct ProblemDefinition { + py::array_t contrastBackgrounds; + py::array_t contrastBackgroundsType; + std::string TF {}; + py::array_t resample; + py::array_t dataPresent; + py::array_t oilChiDataPresent; + real_T numberOfContrasts; + std::string geometry {}; + bool useImaginary {}; + py::array_t contrastQzshifts; + py::array_t contrastScalefactors; + py::array_t contrastBulkIns; + py::array_t contrastBulkOuts; + py::array_t contrastResolutions; + py::array_t backgroundParams; + py::array_t qzshifts; + py::array_t scalefactors; + py::array_t bulkIn; + py::array_t bulkOut; + py::array_t resolutionParams; + py::array_t params; + real_T numberOfLayers {}; + std::string modelType {}; + py::array_t contrastCustomFiles; + py::array_t contrastDomainRatios; + py::array_t domainRatio; + real_T numberOfDomainContrasts {}; + py::array_t fitParams; + py::array_t otherParams; + py::array_t fitLimits; + py::array_t otherLimits; +}; + +struct Control { + std::string parallel {}; + std::string procedure {}; + std::string display {}; + real_T tolX {}; + real_T tolFun {}; + real_T maxFunEvals {}; + real_T maxIter {}; + real_T populationSize {}; + real_T fWeight {}; + real_T crossoverProbability {}; + real_T targetValue {}; + real_T numGenerations {}; + real_T strategy {}; + real_T Nlive {}; + real_T Nmcmc {}; + real_T propScale {}; + real_T nsTolerance {}; + boolean_T calcSldDuringFit {}; + py::array_t resamPars; + real_T updateFreq {}; + real_T updatePlotFreq {}; + real_T nSamples {}; + real_T nChains {}; + real_T jumpProbability {}; + real_T pUnitGamma {}; + std::string boundHandling {}; + boolean_T adaptPCR; + Checks checks {}; +}; + + +void stringToRatArray(std::string value, char_T result_data[], int32_T result_size[2]) +{ + result_size[0] = 1; + result_size[1] = value.length(); + + for (int32_T idx1{0}; idx1 < value.length(); idx1++) { + result_data[idx1] = value[idx1]; + } +} + +void stringToRatCharArray(std::string value, coder::array& result) +{ + result.set_size(1, value.length()); + + for (int32_T idx{0}; idx < value.length(); idx++) { + result[idx] = value[idx]; + } +} + +coder::array pyArrayToRatArray1d(py::array_t value) +{ + coder::array result; + + py::buffer_info buffer_info = value.request(); + + if (buffer_info.size == 0) + return result; - return names_struct; + if (buffer_info.ndim != 1) + throw std::runtime_error("Number of dimensions must be 1"); + + result.set_size(1, buffer_info.shape[0]); + for (int32_T idx0{0}; idx0 < buffer_info.shape[0]; idx0++) { + result[idx0] = value.at(idx0); + } + + return result; } -RAT::CheckFlags createCheckFlagsStruct(const Checks& checks) +coder::bounded_array pyArrayToRatBoundedArray(py::array_t value) { - RAT::CheckFlags checks_struct; - checks_struct.params = customCaller("Checks.params", pyArrayToRatRowArray1d, checks.params); - checks_struct.backgroundParams = customCaller("Checks.backgroundParams", pyArrayToRatRowArray1d, checks.backgroundParams); - checks_struct.scalefactors = customCaller("Checks.scalefactors", pyArrayToRatRowArray1d, checks.scalefactors); - checks_struct.bulkIns = customCaller("Checks.bulkIns", pyArrayToRatRowArray1d, checks.bulkIns); - checks_struct.bulkOuts = customCaller("Checks.bulkOuts", pyArrayToRatRowArray1d, checks.bulkOuts); - checks_struct.resolutionParams = customCaller("Checks.resolutionParams", pyArrayToRatRowArray1d, checks.resolutionParams); - checks_struct.domainRatios = customCaller("Checks.domainRatios", pyArrayToRatRowArray1d, checks.domainRatios); + coder::bounded_array result {}; + + py::buffer_info buffer_info = value.request(); - return checks_struct; + if (buffer_info.size == 0) + return result; + + if (buffer_info.ndim != 1) + throw std::runtime_error("Number of dimensions must be 1"); + + result.size[0] = 1; + result.size[1] = buffer_info.shape[0]; + for (int32_T idx0{0}; idx0 < buffer_info.shape[0]; idx0++) { + result.data[idx0] = value.at(idx0); + } + + return result; } -RAT::b_ProblemDefinition createProblemDefinitionStruct(const ProblemDefinition& problem) +coder::array pyArrayToRatArray2d(py::array_t value) { - RAT::b_ProblemDefinition problem_struct; + coder::array result; + + py::buffer_info buffer_info = value.request(); + + if (buffer_info.size == 0) + return result; + + if (buffer_info.ndim != 2) + throw std::runtime_error("Number of dimensions must be 2"); + + result.set_size(buffer_info.shape[0], buffer_info.shape[1]); + + int32_T idx {0}; + for (int32_T idx0{0}; idx0 < buffer_info.shape[0]; idx0++) { + for (int32_T idx1{0}; idx1 < buffer_info.shape[1]; idx1++) { + idx = idx0 + result.size(0) * idx1; + result[idx] = value.at(idx0, idx1); + } + } + + return result; +} + +coder::array pyListToUnboundedCell0(py::list values) +{ + coder::array result; + result.set_size(values.size()); + int32_T idx {0}; + for (py::handle list: values) + { + py::list value = py::cast(list); + if (py::len(list) != 4) + throw std::runtime_error("Number of dimensions for each row must be 4"); + stringToRatCharArray(value[0].cast(), result[idx].f1); + stringToRatCharArray(value[1].cast(), result[idx].f2); + result[idx].f3 = value[2].cast(); + result[idx].f4 = value[3].cast(); + idx++; + } + + return result; +} + +coder::array pyListToUnboundedCell1(py::list values) +{ + coder::array result; + result.set_size(values.size()); + int32_T idx {0}; + for (py::handle list: values) + { + std::string value = py::cast(list); + //TODO: validate dimension + stringToRatCharArray(value, result[idx].f1); + idx++; + } + + return result; +} + +RAT::struct0_T createStruct0(const ProblemDefinition& problem) +{ + RAT::struct0_T problem_struct; - stringToRatBoundedArray(problem.TF, problem_struct.TF.data, problem_struct.TF.size); - problem_struct.resample = customCaller("Problem.resample", pyArrayToRatRowArray1d, problem.resample); - problem_struct.data = customCaller("Problem.data", pyListToRatCellWrap1, problem.data); - problem_struct.dataPresent = customCaller("Problem.dataPresent", pyArrayToRatRowArray1d, problem.dataPresent); - problem_struct.dataLimits = customCaller("Problem.dataLimits", pyListToRatCellWrap2, problem.dataLimits); - problem_struct.simulationLimits = customCaller("Problem.simulationLimits", pyListToRatCellWrap2, problem.simulationLimits); - problem_struct.numberOfContrasts = problem.numberOfContrasts; - stringToRatBoundedArray(problem.geometry, problem_struct.geometry.data, problem_struct.geometry.size); problem_struct.useImaginary = problem.useImaginary; - problem_struct.repeatLayers = customCaller("Problem.repeatLayers", pyArrayToRatRowArray1d, problem.repeatLayers); - problem_struct.contrastBackgroundParams = customCaller("Problem.contrastBackgroundParams", pyListToRatCellWrap3, problem.contrastBackgroundParams); - problem_struct.contrastBackgroundTypes = customCaller("Problem.contrastBackgroundTypes", pyListToRatCellWrap02d, problem.contrastBackgroundTypes); - problem_struct.contrastBackgroundActions = customCaller("Problem.contrastBackgroundActions", pyListToRatCellWrap02d, problem.contrastBackgroundActions); - problem_struct.contrastScalefactors = customCaller("Problem.contrastScalefactors", pyArrayToRatRowArray1d, problem.contrastScalefactors); - problem_struct.contrastBulkIns = customCaller("Problem.contrastBulkIns", pyArrayToRatRowArray1d, problem.contrastBulkIns); - problem_struct.contrastBulkOuts = customCaller("Problem.contrastBulkOuts", pyArrayToRatRowArray1d, problem.contrastBulkOuts); - problem_struct.contrastResolutionParams = customCaller("Problem.contrastResolutionParams", pyListToRatCellWrap4, problem.contrastResolutionParams); - problem_struct.contrastResolutionTypes = customCaller("Problem.contrastResolutionTypes", pyListToRatCellWrap02d, problem.contrastResolutionTypes); - problem_struct.backgroundParams = customCaller("Problem.backgroundParams", pyArrayToRatRowArray1d, problem.backgroundParams); - problem_struct.scalefactors = customCaller("Problem.scalefactors", pyArrayToRatRowArray1d, problem.scalefactors); - problem_struct.bulkIns = customCaller("Problem.bulkIns", pyArrayToRatRowArray1d, problem.bulkIns); - problem_struct.bulkOuts = customCaller("Problem.bulkOuts", pyArrayToRatRowArray1d, problem.bulkOuts); - problem_struct.resolutionParams = customCaller("Problem.resolutionParams", pyArrayToRatRowArray1d, problem.resolutionParams); - problem_struct.params = customCaller("Problem.params", pyArrayToRatRowArray1d, problem.params); + problem_struct.numberOfLayers = problem.numberOfLayers; - problem_struct.contrastLayers = customCaller("Problem.contrastLayers", pyListToRatCellWrap5, problem.contrastLayers); - problem_struct.layersDetails = customCaller("Problem.layersDetails", pyListToRatCellWrap6, problem.layersDetails); - problem_struct.customFiles = customCaller("Problem.customFiles", py_function_array_to_rat_cell_wrap_0, problem.customFiles); - stringToRatBoundedArray(problem.modelType, problem_struct.modelType.data, problem_struct.modelType.size); - problem_struct.contrastCustomFiles = customCaller("Problem.contrastCustomFiles", pyArrayToRatRowArray1d, problem.contrastCustomFiles); - problem_struct.contrastDomainRatios = customCaller("Problem.contrastDomainRatios", pyArrayToRatRowArray1d, problem.contrastDomainRatios); - problem_struct.domainRatios = customCaller("Problem.domainRatios", pyArrayToRatRowArray1d, problem.domainRatios); problem_struct.numberOfDomainContrasts = problem.numberOfDomainContrasts; - problem_struct.domainContrastLayers = customCaller("Problem.domainContrastLayers", pyListToRatCellWrap5, problem.domainContrastLayers); - problem_struct.fitParams = customCaller("Problem.fitParams", pyArrayToRatRowArray1d, problem.fitParams); - problem_struct.fitLimits = customCaller("Problem.fitLimits", pyArrayToRatArray2d, problem.fitLimits); - problem_struct.priorNames = customCaller("Problem.priorNames", pyListToRatCellWrap01d, problem.priorNames); - problem_struct.priorValues = customCaller("Problem.priorValues", pyArrayToRatArray2d, problem.priorValues); - - problem_struct.names = createParamNamesStruct(problem.names); - problem_struct.checks = createCheckFlagsStruct(problem.checks); + problem_struct.numberOfContrasts = problem.numberOfContrasts; + stringToRatArray(problem.modelType, problem_struct.modelType.data, problem_struct.modelType.size); + stringToRatArray(problem.geometry, problem_struct.geometry.data, problem_struct.geometry.size); + stringToRatArray(problem.TF, problem_struct.TF.data, problem_struct.TF.size); + + problem_struct.contrastBackgrounds = pyArrayToRatArray1d(problem.contrastBackgrounds); + problem_struct.contrastBackgroundsType = pyArrayToRatArray1d(problem.contrastBackgroundsType); + problem_struct.resample = pyArrayToRatArray1d(problem.resample); + problem_struct.dataPresent = pyArrayToRatArray1d(problem.dataPresent); + problem_struct.oilChiDataPresent = pyArrayToRatArray1d(problem.oilChiDataPresent); + problem_struct.contrastQzshifts = pyArrayToRatArray1d(problem.contrastQzshifts); + problem_struct.contrastScalefactors = pyArrayToRatArray1d(problem.contrastScalefactors); + problem_struct.contrastBulkIns = pyArrayToRatArray1d(problem.contrastBulkIns); + problem_struct.contrastBulkOuts = pyArrayToRatArray1d(problem.contrastBulkOuts); + problem_struct.contrastResolutions = pyArrayToRatArray1d(problem.contrastResolutions); + problem_struct.backgroundParams = pyArrayToRatArray1d(problem.backgroundParams); + problem_struct.qzshifts = pyArrayToRatArray1d(problem.qzshifts); + problem_struct.scalefactors = pyArrayToRatArray1d(problem.scalefactors); + problem_struct.bulkIn = pyArrayToRatArray1d(problem.bulkIn); + problem_struct.bulkOut = pyArrayToRatArray1d(problem.bulkOut); + problem_struct.resolutionParams = pyArrayToRatArray1d(problem.resolutionParams); + problem_struct.params = pyArrayToRatArray1d(problem.params); + + problem_struct.contrastCustomFiles = pyArrayToRatArray1d(problem.contrastCustomFiles); + problem_struct.contrastDomainRatios = pyArrayToRatArray1d(problem.contrastDomainRatios); + problem_struct.domainRatio = pyArrayToRatArray1d(problem.domainRatio); + + problem_struct.fitParams = pyArrayToRatArray1d(problem.fitParams); + problem_struct.otherParams = pyArrayToRatArray1d(problem.otherParams); + problem_struct.fitLimits = pyArrayToRatArray2d(problem.fitLimits); + problem_struct.otherLimits = pyArrayToRatArray2d(problem.otherLimits); return problem_struct; } +RAT::struct1_T createStruct1(const Limits& limits) +{ + RAT::struct1_T limits_struct; + limits_struct.param = pyArrayToRatArray2d(limits.param); + limits_struct.backgroundParam = pyArrayToRatArray2d(limits.backgroundParam); + limits_struct.qzshift = pyArrayToRatArray2d(limits.qzshift); + limits_struct.scalefactor = pyArrayToRatArray2d(limits.scalefactor); + limits_struct.bulkIn = pyArrayToRatArray2d(limits.bulkIn); + limits_struct.bulkOut = pyArrayToRatArray2d(limits.bulkOut); + limits_struct.resolutionParam = pyArrayToRatArray2d(limits.resolutionParam); + limits_struct.domainRatio = pyArrayToRatArray2d(limits.domainRatio); + + return limits_struct; +} + +RAT::struct3_T createStruct3(const Checks& checks) +{ + RAT::struct3_T checks_struct; + checks_struct.fitParam = pyArrayToRatArray1d(checks.fitParam); + checks_struct.fitBackgroundParam = pyArrayToRatArray1d(checks.fitBackgroundParam); + checks_struct.fitQzshift = pyArrayToRatArray1d(checks.fitQzshift); + checks_struct.fitScalefactor = pyArrayToRatArray1d(checks.fitScalefactor); + checks_struct.fitBulkIn = pyArrayToRatArray1d(checks.fitBulkIn); + checks_struct.fitBulkOut = pyArrayToRatArray1d(checks.fitBulkOut); + checks_struct.fitResolutionParam = pyArrayToRatArray1d(checks.fitResolutionParam); + checks_struct.fitDomainRatio = pyArrayToRatArray1d(checks.fitDomainRatio); + + return checks_struct; +} + +RAT::struct4_T createStruct4(const Priors& priors) +{ + RAT::struct4_T priors_struct; + priors_struct.param = pyListToUnboundedCell0(priors.param); + priors_struct.backgroundParam = pyListToUnboundedCell0(priors.backgroundParam); + priors_struct.resolutionParam = pyListToUnboundedCell0(priors.resolutionParam); + priors_struct.qzshift = pyListToUnboundedCell0(priors.qzshift); + priors_struct.scalefactor = pyListToUnboundedCell0(priors.scalefactor); + priors_struct.bulkIn = pyListToUnboundedCell0(priors.bulkIn); + priors_struct.bulkOut = pyListToUnboundedCell0(priors.bulkOut); + priors_struct.domainRatio = pyListToUnboundedCell0(priors.domainRatio); + priors_struct.priorNames = pyListToUnboundedCell1(priors.priorNames); + priors_struct.priorValues = pyArrayToRatArray2d(priors.priorValues); + + return priors_struct; +} + +coder::array pyListToRatCellWrap2(py::list values) +{ + coder::array result; + result.set_size(1, values.size()); + int32_T idx {0}; + for (py::handle array: values) + { + py::array_t casted_array = py::cast(array); + result[idx].f1[0] = casted_array.at(0); + result[idx].f1[1] = casted_array.at(1); + idx++; + } + + return result; +} + +coder::array pyListToRatCellWrap3(py::list values) +{ + coder::array result; + result.set_size(1, values.size()); + int32_T idx {0}; + for (py::handle array: values) + { + py::array_t casted_array = py::cast(array); + result[idx].f1 = pyArrayToRatArray2d(casted_array); + idx++; + } + + return result; +} + +coder::array pyListToRatCellWrap4(py::list values) +{ + coder::array result; + result.set_size(1, values.size()); + int32_T idx {0}; + for (py::handle array: values) + { + py::array_t casted_array = py::cast(array); + result[idx].f1 = pyArrayToRatArray1d(casted_array); + idx++; + } + + return result; +} -RAT::Controls createControlsStruct(const Control& control) +coder::array pyListToRatCellWrap5(py::list values) { - RAT::Controls control_struct; - control_struct.funcTolerance = control.funcTolerance; - control_struct.maxFuncEvals = control.maxFuncEvals; - control_struct.maxIterations = control.maxIterations; + coder::array result; + result.set_size(values.size()); + int32_T idx {0}; + for (py::handle array: values) + { + py::array_t casted_array = py::cast(array); + result[idx].f1 = pyArrayToRatBoundedArray(casted_array); + idx++; + } + + return result; +} + +coder::array pyListToRatCellWrap6(py::list values) +{ + coder::array result; + result.set_size(1, values.size()); + int32_T idx {0}; + for (py::handle array: values) + { + std::string name = py::cast(array); + stringToRatArray(name, result[idx].f1.data, result[idx].f1.size); + idx++; + } + + return result; +} + +coder::array py_function_array_to_rat_cell_wrap_6(py::list values) +{ + coder::array result; + result.set_size(1, values.size()); + int32_T idx {0}; + for (py::handle array: values) + { + auto func = py::cast(array); + std::string func_ptr = convertPtr2String(new Library(func)); + stringToRatArray(func_ptr, result[idx].f1.data, result[idx].f1.size); + idx++; + } + + return result; +} + +RAT::cell_7 createCell7(const Cells& cells) +{ + RAT::cell_7 cells_struct; + cells_struct.f1 = pyListToRatCellWrap2(cells.f1); + cells_struct.f2 = pyListToRatCellWrap3(cells.f2); + cells_struct.f3 = pyListToRatCellWrap2(cells.f3); + cells_struct.f4 = pyListToRatCellWrap2(cells.f4); + cells_struct.f5 = pyListToRatCellWrap4(cells.f5); + cells_struct.f6 = pyListToRatCellWrap5(cells.f6); + cells_struct.f7 = pyListToRatCellWrap6(cells.f7); + cells_struct.f8 = pyListToRatCellWrap6(cells.f8); + cells_struct.f9 = pyListToRatCellWrap6(cells.f9); + cells_struct.f10 = pyListToRatCellWrap6(cells.f10); + cells_struct.f11 = pyListToRatCellWrap6(cells.f11); + cells_struct.f12 = pyListToRatCellWrap6(cells.f12); + cells_struct.f13 = pyListToRatCellWrap6(cells.f13); + cells_struct.f14 = py_function_array_to_rat_cell_wrap_6(cells.f14); + cells_struct.f15 = pyListToRatCellWrap6(cells.f15); + cells_struct.f16 = pyListToRatCellWrap6(cells.f16); + cells_struct.f17 = pyListToRatCellWrap3(cells.f17); + cells_struct.f18 = pyListToRatCellWrap2(cells.f18); + cells_struct.f19 = pyListToRatCellWrap4(cells.f19); + cells_struct.f20 = pyListToRatCellWrap6(cells.f20); + + return cells_struct; +} + +RAT::struct2_T createStruct2T(const Control& control) +{ + RAT::struct2_T control_struct; + control_struct.tolFun = control.tolFun; + control_struct.maxFunEvals = control.maxFunEvals; + control_struct.maxIter = control.maxIter; control_struct.populationSize = control.populationSize; control_struct.fWeight = control.fWeight; control_struct.crossoverProbability = control.crossoverProbability; control_struct.targetValue = control.targetValue; control_struct.numGenerations = control.numGenerations; control_struct.strategy = control.strategy; - control_struct.nLive = control.nLive; - control_struct.nMCMC = control.nMCMC; + control_struct.Nlive = control.Nlive; + control_struct.Nmcmc = control.Nmcmc; control_struct.propScale = control.propScale; control_struct.nsTolerance = control.nsTolerance; - control_struct.numSimulationPoints = control.numSimulationPoints; + control_struct.calcSldDuringFit = control.calcSldDuringFit; control_struct.updateFreq = control.updateFreq; control_struct.updatePlotFreq = control.updatePlotFreq; control_struct.nSamples = control.nSamples; control_struct.nChains = control.nChains; control_struct.jumpProbability = control.jumpProbability; control_struct.pUnitGamma = control.pUnitGamma; - stringToRatBoundedArray(control.parallel, control_struct.parallel.data, control_struct.parallel.size); - stringToRatBoundedArray(control.procedure, control_struct.procedure.data, control_struct.procedure.size); - stringToRatBoundedArray(control.display, control_struct.display.data, control_struct.display.size); - control_struct.xTolerance = control.xTolerance; - control_struct.resampleMinAngle = control.resampleMinAngle; - control_struct.resampleNPoints = control.resampleNPoints; - stringToRatBoundedArray(control.boundHandling, control_struct.boundHandling.data, control_struct.boundHandling.size); + stringToRatArray(control.parallel, control_struct.parallel.data, control_struct.parallel.size); + stringToRatArray(control.procedure, control_struct.procedure.data, control_struct.procedure.size); + stringToRatArray(control.display, control_struct.display.data, control_struct.display.size); + control_struct.tolX = control.tolX; + control_struct.resamPars[0] = control.resamPars.at(0); + control_struct.resamPars[1] = control.resamPars.at(1); + stringToRatArray(control.boundHandling, control_struct.boundHandling.data, control_struct.boundHandling.size); control_struct.adaptPCR = control.adaptPCR; - control_struct.calcSLD = false; - stringToRatBoundedArray(control.IPCFilePath, control_struct.IPCFilePath.data, control_struct.IPCFilePath.size); + control_struct.checks = createStruct3(control.checks); return control_struct; } -OutputResult OutputResultFromStruct(const RAT::Results result) +py::array_t pyArrayFromRatArray1d(coder::array array) { - // Copy problem to output - OutputResult output_result; - for (int32_T idx0{0}; idx0 < result.reflectivity.size(0); idx0++) { - auto tmp = result.reflectivity[idx0]; - auto array = py::array_t({tmp.f1.size(0), tmp.f1.size(1)}); - std::memcpy(array.request().ptr, tmp.f1.data(), array.nbytes()); - output_result.reflectivity.append(array); - } + auto size = (array.size(0) > 1) ? array.size(0) : array.size(1); + auto result_array = py::array_t(size); + std::memcpy(result_array.request().ptr, array.data(), result_array.nbytes()); - for (int32_T idx0{0}; idx0 < result.simulation.size(0); idx0++) { - auto tmp = result.simulation[idx0]; - auto array = py::array_t({tmp.f1.size(0), tmp.f1.size(1)}); - std::memcpy(array.request().ptr, tmp.f1.data(), array.nbytes()); - output_result.simulation.append(array); - } + return result_array; +} + +py::array_t pyArrayFromRatArray2d(coder::array array) +{ + auto result_array = py::array_t({array.size(0), array.size(1)}); + std::memcpy(result_array.request().ptr, array.data(), result_array.nbytes()); + + return result_array; +} - for (int32_T idx0{0}; idx0 < result.shiftedData.size(0); idx0++) { - auto tmp = result.shiftedData[idx0]; - auto array = py::array_t({tmp.f1.size(0), tmp.f1.size(1)}); - std::memcpy(array.request().ptr, tmp.f1.data(), array.nbytes()); - output_result.shiftedData.append(array); +py::list resultArrayToList(const RAT::cell_wrap_9 results[]) +{ + py::list outer_list_1; + for (int32_T idx0{0}; idx0 < results[0].f1.size(0); idx0++) { + py::list inner_list; + for (int32_T idx1{0}; idx1 < results[0].f1.size(1); idx1++) { + auto tmp = results[0].f1[idx0 + results[0].f1.size(0) * idx1]; + auto array = py::array_t({tmp.f1.size(0), tmp.f1.size(1)}); + std::memcpy(array.request().ptr, tmp.f1.data(), array.nbytes()); + inner_list.append(array); + } + outer_list_1.append(inner_list); } - for (int32_T idx0{0}; idx0 < result.backgrounds.size(0); idx0++) { - auto tmp = result.backgrounds[idx0]; - auto array = py::array_t({tmp.f1.size(0), tmp.f1.size(1)}); - std::memcpy(array.request().ptr, tmp.f1.data(), array.nbytes()); - output_result.backgrounds.append(array); + py::list outer_list_2; + for (int32_T idx0{0}; idx0 < results[1].f1.size(0); idx0++) { + py::list inner_list; + for (int32_T idx1{0}; idx1 < results[1].f1.size(1); idx1++) { + auto tmp = results[1].f1[idx0 + results[1].f1.size(0) * idx1]; + auto array = py::array_t({tmp.f1.size(0), tmp.f1.size(1)}); + std::memcpy(array.request().ptr, tmp.f1.data(), array.nbytes()); + inner_list.append(array); + } + outer_list_2.append(inner_list); } - for (int32_T idx0{0}; idx0 < result.resolutions.size(0); idx0++) { - auto tmp = result.resolutions[idx0]; - auto array = py::array_t({tmp.f1.size(0), tmp.f1.size(1)}); - std::memcpy(array.request().ptr, tmp.f1.data(), array.nbytes()); - output_result.resolutions.append(array); + py::list outer_list_3; + for (int32_T idx0{0}; idx0 < results[2].f1.size(0); idx0++) { + py::list inner_list; + for (int32_T idx1{0}; idx1 < results[2].f1.size(1); idx1++) { + auto tmp = results[2].f1[idx0 + results[2].f1.size(0) * idx1]; + auto array = py::array_t({tmp.f1.size(0), tmp.f1.size(1)}); + std::memcpy(array.request().ptr, tmp.f1.data(), array.nbytes()); + inner_list.append(array); + } + outer_list_3.append(inner_list); } - for (int32_T idx0{0}; idx0 < result.sldProfiles.size(0); idx0++) { + py::list outer_list_4; + for (int32_T idx0{0}; idx0 < results[3].f1.size(0); idx0++) { py::list inner_list; - for (int32_T idx1{0}; idx1 < result.sldProfiles.size(1); idx1++) { - auto tmp = result.sldProfiles[idx0 + result.sldProfiles.size(0) * idx1]; + for (int32_T idx1{0}; idx1 < results[3].f1.size(1); idx1++) { + auto tmp = results[3].f1[idx0 + results[3].f1.size(0) * idx1]; auto array = py::array_t({tmp.f1.size(0), tmp.f1.size(1)}); std::memcpy(array.request().ptr, tmp.f1.data(), array.nbytes()); inner_list.append(array); } - output_result.sldProfiles.append(inner_list); + outer_list_4.append(inner_list); } - for (int32_T idx0{0}; idx0 < result.layers.size(0); idx0++) { + py::list outer_list_5; + for (int32_T idx0{0}; idx0 < results[4].f1.size(0); idx0++) { py::list inner_list; - for (int32_T idx1{0}; idx1 < result.layers.size(1); idx1++) { - auto tmp = result.layers[idx0 + result.layers.size(0) * idx1]; + for (int32_T idx1{0}; idx1 < results[4].f1.size(1); idx1++) { + auto tmp = results[4].f1[idx0 + results[4].f1.size(0) * idx1]; auto array = py::array_t({tmp.f1.size(0), tmp.f1.size(1)}); std::memcpy(array.request().ptr, tmp.f1.data(), array.nbytes()); inner_list.append(array); } - output_result.layers.append(inner_list); + outer_list_5.append(inner_list); } - for (int32_T idx0{0}; idx0 < result.resampledLayers.size(0); idx0++) { + py::list outer_list_6; + for (int32_T idx0{0}; idx0 < results[5].f1.size(0); idx0++) { py::list inner_list; - for (int32_T idx1{0}; idx1 < result.resampledLayers.size(1); idx1++) { - auto tmp = result.resampledLayers[idx0 + result.resampledLayers.size(0) * idx1]; + for (int32_T idx1{0}; idx1 < results[5].f1.size(1); idx1++) { + auto tmp = results[5].f1[idx0 + results[5].f1.size(0) * idx1]; auto array = py::array_t({tmp.f1.size(0), tmp.f1.size(1)}); std::memcpy(array.request().ptr, tmp.f1.data(), array.nbytes()); inner_list.append(array); } - output_result.resampledLayers.append(inner_list); + outer_list_6.append(inner_list); } + py::list output_result; + output_result.append(outer_list_1); + output_result.append(outer_list_2); + output_result.append(outer_list_3); + output_result.append(outer_list_4); + output_result.append(outer_list_5); + output_result.append(outer_list_6); - for (int32_T idx0{0}; idx0 < result.fitNames.size(0); idx0++) { - auto tmp = result.fitNames[idx0]; - std::string str(tmp.f1.data(), tmp.f1.size(1)); - output_result.fitNames.append(str); - } + return output_result; +} - output_result.fitParams = py::array_t(result.fitParams.size(1)); - auto buffer = output_result.fitParams.request(); - std::memcpy(buffer.ptr, result.fitParams.data(), output_result.fitParams.size()*sizeof(real_T)); +ContrastParams contrastParamsFromStruct5T(const RAT::struct5_T problem) +{ + // Copy problem to output + ContrastParams output_problem; + output_problem.ssubs = py::array_t(problem.ssubs.size(0)); + auto buffer = output_problem.ssubs.request(); + std::memcpy(buffer.ptr, problem.ssubs.data(), output_problem.ssubs.size()*sizeof(real_T)); - output_result.contrastParams.scalefactors = py::array_t(result.contrastParams.scalefactors.size(0)); - buffer = output_result.contrastParams.scalefactors.request(); - std::memcpy(buffer.ptr, result.contrastParams.scalefactors.data(), output_result.contrastParams.scalefactors.size()*sizeof(real_T)); + output_problem.backgroundParams = py::array_t(problem.backgroundParams.size(0)); + buffer = output_problem.backgroundParams.request(); + std::memcpy(buffer.ptr, problem.backgroundParams.data(), output_problem.backgroundParams.size()*sizeof(real_T)); - output_result.contrastParams.bulkIn = py::array_t(result.contrastParams.bulkIn.size(0)); - buffer = output_result.contrastParams.bulkIn.request(); - std::memcpy(buffer.ptr, result.contrastParams.bulkIn.data(), output_result.contrastParams.bulkIn.size()*sizeof(real_T)); + output_problem.qzshifts = py::array_t(problem.qzshifts.size(0)); + buffer = output_problem.qzshifts.request(); + std::memcpy(buffer.ptr, problem.qzshifts.data(), output_problem.qzshifts.size()*sizeof(real_T)); - output_result.contrastParams.bulkOut = py::array_t(result.contrastParams.bulkOut.size(0)); - buffer = output_result.contrastParams.bulkOut.request(); - std::memcpy(buffer.ptr, result.contrastParams.bulkOut.data(), output_result.contrastParams.bulkOut.size()*sizeof(real_T)); + output_problem.scalefactors = py::array_t(problem.scalefactors.size(0)); + buffer = output_problem.scalefactors.request(); + std::memcpy(buffer.ptr, problem.scalefactors.data(), output_problem.scalefactors.size()*sizeof(real_T)); - output_result.calculationResults.sumChi = result.calculationResults.sumChi; - output_result.calculationResults.chiValues = py::array_t(result.calculationResults.chiValues.size(0)); - buffer = output_result.calculationResults.chiValues.request(); - std::memcpy(buffer.ptr, result.calculationResults.chiValues.data(), output_result.calculationResults.chiValues.size()*sizeof(real_T)); + output_problem.bulkIn = py::array_t(problem.bulkIn.size(0)); + buffer = output_problem.bulkIn.request(); + std::memcpy(buffer.ptr, problem.bulkIn.data(), output_problem.bulkIn.size()*sizeof(real_T)); - output_result.contrastParams.subRoughs = py::array_t(result.contrastParams.subRoughs.size(0)); - buffer = output_result.contrastParams.subRoughs.request(); - std::memcpy(buffer.ptr, result.contrastParams.subRoughs.data(), output_result.contrastParams.subRoughs.size()*sizeof(real_T)); + output_problem.bulkOut = py::array_t(problem.bulkOut.size(0)); + buffer = output_problem.bulkOut.request(); + std::memcpy(buffer.ptr, problem.bulkOut.data(), output_problem.bulkOut.size()*sizeof(real_T)); - output_result.contrastParams.resample = py::array_t(result.contrastParams.resample.size(1)); - buffer = output_result.contrastParams.resample.request(); - std::memcpy(buffer.ptr, result.contrastParams.resample.data(), output_result.contrastParams.resample.size()*sizeof(real_T)); + output_problem.resolutionParams = py::array_t(problem.resolutionParams.size(0)); + buffer = output_problem.resolutionParams.request(); + std::memcpy(buffer.ptr, problem.resolutionParams.data(), output_problem.resolutionParams.size()*sizeof(real_T)); - return output_result; + output_problem.calculations.sumChi = problem.calculations.sumChi; + output_problem.calculations.allChis = py::array_t(problem.calculations.allChis.size(0)); + buffer = output_problem.calculations.allChis.request(); + std::memcpy(buffer.ptr, problem.calculations.allChis.data(), output_problem.calculations.allChis.size()*sizeof(real_T)); + + output_problem.allSubRough = py::array_t(problem.allSubRough.size(0)); + buffer = output_problem.allSubRough.request(); + std::memcpy(buffer.ptr, problem.allSubRough.data(), output_problem.allSubRough.size()*sizeof(real_T)); + + output_problem.resample = py::array_t(problem.resample.size(1)); + buffer = output_problem.resample.request(); + std::memcpy(buffer.ptr, problem.resample.data(), output_problem.resample.size()*sizeof(real_T)); + + return output_problem; } -ProblemDefinition problemDefinitionFromStruct(const RAT::b_ProblemDefinition problem) +ProblemDefinition problemDefinitionFromStruct0T(const RAT::struct0_T problem) { ProblemDefinition problem_def; - stringFromRatBoundedArray(problem.TF.data, problem.TF.size, problem_def.TF); - problem_def.resample = pyArrayFromRatArray1d>(problem.resample); - problem_def.data = pyList1DFromRatCellWrap2D>(problem.data); - problem_def.dataPresent = pyArrayFromRatArray1d>(problem.dataPresent); - problem_def.dataLimits = pyListFromRatCellWrap2(problem.dataLimits); - problem_def.simulationLimits = pyListFromRatCellWrap2(problem.simulationLimits); - problem_def.numberOfContrasts = problem.numberOfContrasts; - stringFromRatBoundedArray(problem.geometry.data, problem.geometry.size, problem_def.geometry); - problem_def.useImaginary = problem.useImaginary; - problem_def.repeatLayers = pyArrayFromRatArray1d>(problem.repeatLayers); - problem_def.contrastBackgroundParams = pyListFromBoundedCellWrap>(problem.contrastBackgroundParams); - problem_def.contrastBackgroundTypes = pyListFromRatCellWrap02d(problem.contrastBackgroundTypes); - problem_def.contrastBackgroundActions = pyListFromRatCellWrap02d(problem.contrastBackgroundActions); - problem_def.contrastScalefactors = pyArrayFromRatArray1d>(problem.contrastScalefactors); - problem_def.contrastBulkIns = pyArrayFromRatArray1d>(problem.contrastBulkIns); - problem_def.contrastBulkOuts = pyArrayFromRatArray1d>(problem.contrastBulkOuts); - problem_def.contrastResolutionParams = pyListFromBoundedCellWrap>(problem.contrastResolutionParams); - problem_def.contrastResolutionTypes = pyListFromRatCellWrap02d(problem.contrastResolutionTypes); - problem_def.backgroundParams = pyArrayFromRatArray1d>(problem.backgroundParams); - problem_def.scalefactors = pyArrayFromRatArray1d>(problem.scalefactors); - problem_def.bulkIns = pyArrayFromRatArray1d>(problem.bulkIns); - problem_def.bulkOuts = pyArrayFromRatArray1d>(problem.bulkOuts); - problem_def.resolutionParams = pyArrayFromRatArray1d>(problem.resolutionParams); - problem_def.params = pyArrayFromRatArray1d>(problem.params); + problem_def.useImaginary = problem.useImaginary; + problem_def.numberOfLayers = problem.numberOfLayers; - problem_def.contrastLayers = pyList1DFromRatCellWrap2D>(problem.contrastLayers); - problem_def.layersDetails = pyListFromBoundedCellWrap>(problem.layersDetails); - // problem_def.customFiles is not set here since the object has been converted to function handles - stringFromRatBoundedArray(problem.modelType.data, problem.modelType.size, problem_def.modelType); - problem_def.contrastCustomFiles = pyArrayFromRatArray1d>(problem.contrastCustomFiles); - problem_def.contrastDomainRatios = pyArrayFromRatArray1d>(problem.contrastDomainRatios); - problem_def.domainRatios = pyArrayFromRatArray1d>(problem.domainRatios); problem_def.numberOfDomainContrasts = problem.numberOfDomainContrasts; - problem_def.domainContrastLayers = pyList1DFromRatCellWrap2D>(problem.domainContrastLayers); - problem_def.fitParams = pyArrayFromRatArray1d>(problem.fitParams); - problem_def.fitLimits = pyArrayFromRatArray2d(problem.fitLimits); - problem_def.priorNames = pyListFromRatCellWrap01d(problem.priorNames); - problem_def.priorValues = pyArrayFromRatArray2d(problem.priorValues); - - problem_def.names.params = pyListFromRatCellWrap02d(problem.names.params); - problem_def.names.backgroundParams = pyListFromRatCellWrap02d(problem.names.backgroundParams); - problem_def.names.scalefactors = pyListFromRatCellWrap02d(problem.names.scalefactors); - problem_def.names.bulkIns = pyListFromRatCellWrap02d(problem.names.bulkIns); - problem_def.names.bulkOuts = pyListFromRatCellWrap02d(problem.names.bulkOuts); - problem_def.names.resolutionParams = pyListFromRatCellWrap02d(problem.names.resolutionParams); - problem_def.names.domainRatios = pyListFromRatCellWrap02d(problem.names.domainRatios); - problem_def.names.contrasts = pyListFromRatCellWrap02d(problem.names.contrasts); + problem_def.numberOfContrasts = problem.numberOfContrasts; + + problem_def.modelType.resize(problem.modelType.size[1]); + memcpy(&problem_def.modelType[0], problem.modelType.data, problem.modelType.size[1]); + problem_def.geometry.resize(problem.geometry.size[1]); + memcpy(&problem_def.geometry[0], problem.geometry.data, problem.geometry.size[1]); + problem_def.TF.resize(problem.TF.size[1]); + memcpy(&problem_def.TF[0], problem.TF.data, problem.TF.size[1]); - problem_def.checks.params = pyArrayFromRatArray1d>(problem.checks.params); - problem_def.checks.backgroundParams = pyArrayFromRatArray1d>(problem.checks.backgroundParams); - problem_def.checks.scalefactors = pyArrayFromRatArray1d>(problem.checks.scalefactors); - problem_def.checks.bulkIns = pyArrayFromRatArray1d>(problem.checks.bulkIns); - problem_def.checks.bulkOuts = pyArrayFromRatArray1d>(problem.checks.bulkOuts); - problem_def.checks.resolutionParams = pyArrayFromRatArray1d>(problem.checks.resolutionParams); - problem_def.checks.domainRatios = pyArrayFromRatArray1d>(problem.checks.domainRatios); + problem_def.contrastBackgrounds = pyArrayFromRatArray1d(problem.contrastBackgrounds); + problem_def.contrastBackgroundsType = pyArrayFromRatArray1d(problem.contrastBackgroundsType); + problem_def.resample = pyArrayFromRatArray1d(problem.resample); + problem_def.dataPresent = pyArrayFromRatArray1d(problem.dataPresent); + problem_def.oilChiDataPresent = pyArrayFromRatArray1d(problem.oilChiDataPresent); + problem_def.contrastQzshifts = pyArrayFromRatArray1d(problem.contrastQzshifts); + problem_def.contrastScalefactors = pyArrayFromRatArray1d(problem.contrastScalefactors); + problem_def.contrastBulkIns = pyArrayFromRatArray1d(problem.contrastBulkIns); + problem_def.contrastBulkOuts = pyArrayFromRatArray1d(problem.contrastBulkOuts); + problem_def.contrastResolutions = pyArrayFromRatArray1d(problem.contrastResolutions); + problem_def.backgroundParams = pyArrayFromRatArray1d(problem.backgroundParams); + problem_def.qzshifts = pyArrayFromRatArray1d(problem.qzshifts); + problem_def.scalefactors = pyArrayFromRatArray1d(problem.scalefactors); + problem_def.bulkIn = pyArrayFromRatArray1d(problem.bulkIn); + problem_def.bulkOut = pyArrayFromRatArray1d(problem.bulkOut); + problem_def.resolutionParams = pyArrayFromRatArray1d(problem.resolutionParams); + problem_def.params = pyArrayFromRatArray1d(problem.params); + + problem_def.contrastCustomFiles = pyArrayFromRatArray1d(problem.contrastCustomFiles); + problem_def.contrastDomainRatios = pyArrayFromRatArray1d(problem.contrastDomainRatios); + problem_def.domainRatio = pyArrayFromRatArray1d(problem.domainRatio); + + problem_def.fitParams = pyArrayFromRatArray1d(problem.fitParams); + problem_def.otherParams = pyArrayFromRatArray1d(problem.otherParams); + problem_def.fitLimits = pyArrayFromRatArray2d(problem.fitLimits); + problem_def.otherLimits = pyArrayFromRatArray2d(problem.otherLimits); return problem_def; } -OutputBayesResult OutputBayesResultsFromStruct(const RAT::BayesResults results) +py::list pyList1DFromRatCellWrap8(const coder::array& values) { - OutputBayesResult bayesResults; + py::list result; + + for (int32_T idx0{0}; idx0 < values.size(0); idx0++) { + result.append(pyArrayFromRatArray2d(values[idx0].f1)); + } - bayesResults.chain = pyArrayFromRatArray2d(results.chain); + return result; +} - bayesResults.predictionIntervals.reflectivity = pyList1DFromRatCellWrap1D>(results.predictionIntervals.reflectivity); - bayesResults.predictionIntervals.sld = pyList2dFromRatCellWrap>(results.predictionIntervals.sld); - bayesResults.predictionIntervals.sampleChi = pyArray1dFromBoundedArray>(results.predictionIntervals.sampleChi); - - bayesResults.confidenceIntervals.percentile95 = pyArrayFromRatArray2d(results.confidenceIntervals.percentile95); - bayesResults.confidenceIntervals.percentile65 = pyArrayFromRatArray2d(results.confidenceIntervals.percentile65); - bayesResults.confidenceIntervals.mean = pyArrayFromRatArray2d(results.confidenceIntervals.mean); - - bayesResults.nestedSamplerOutput.logZ = results.nestedSamplerOutput.logZ; - bayesResults.nestedSamplerOutput.logZErr = results.nestedSamplerOutput.logZErr; - bayesResults.nestedSamplerOutput.nestSamples = pyArrayFromRatArray2d(results.nestedSamplerOutput.nestSamples); - bayesResults.nestedSamplerOutput.postSamples = pyArrayFromRatArray2d(results.nestedSamplerOutput.postSamples); - - bayesResults.dreamOutput.allChains = pyArrayFromRatArray3d(results.dreamOutput.allChains); - bayesResults.dreamOutput.outlierChains = pyArray2dFromBoundedArray>(results.dreamOutput.outlierChains); - bayesResults.dreamOutput.runtime = results.dreamOutput.runtime; - bayesResults.dreamOutput.iteration = results.dreamOutput.iteration; - bayesResults.dreamOutput.R_stat = pyArrayFromRatArray2d(results.dreamOutput.R_stat); - bayesResults.dreamOutput.CR = pyArrayFromRatArray2d(results.dreamOutput.CR); - bayesResults.dreamOutput.AR = pyArray2dFromBoundedArray>(results.dreamOutput.AR); - - bayesResults.dreamParams.nParams = results.dreamParams.nParams; - bayesResults.dreamParams.nChains = results.dreamParams.nChains; - bayesResults.dreamParams.nGenerations = results.dreamParams.nGenerations; - bayesResults.dreamParams.parallel = results.dreamParams.parallel; - bayesResults.dreamParams.CPU = results.dreamParams.CPU; - bayesResults.dreamParams.jumpProbability = results.dreamParams.jumpProbability; - bayesResults.dreamParams.pUnitGamma = results.dreamParams.pUnitGamma; - bayesResults.dreamParams.nCR = results.dreamParams.nCR; - bayesResults.dreamParams.delta = results.dreamParams.delta; - bayesResults.dreamParams.steps = results.dreamParams.steps; - bayesResults.dreamParams.zeta = results.dreamParams.zeta; - bayesResults.dreamParams.outlier = std::string(results.dreamParams.outlier, 3); - bayesResults.dreamParams.adaptPCR = results.dreamParams.adaptPCR; - bayesResults.dreamParams.thinning = results.dreamParams.thinning; - bayesResults.dreamParams.epsilon = results.dreamParams.epsilon; - bayesResults.dreamParams.ABC = results.dreamParams.ABC; - bayesResults.dreamParams.IO = results.dreamParams.IO; - bayesResults.dreamParams.storeOutput = results.dreamParams.storeOutput; - bayesResults.dreamParams.R = pyArrayFromRatArray2d(results.dreamParams.R); +py::list pyList2dFromRatCellWrap8(const coder::array& values) +{ + py::list result; + int32_T idx {0}; + for (int32_T idx0{0}; idx0 < values.size(0); idx0++) { + py::list inner; + for (int32_T idx1{0}; idx1 < values.size(1); idx1++) { + idx = idx0 + values.size(0) * idx1; + inner.append(pyArrayFromRatArray2d(values[idx].f1)); + } + result.append(inner); + } - return bayesResults; + return result; } -const std::string docsRATMain = R"(Entry point for the main reflectivity computation. - -Parameters ----------- -problem_def : Rat.rat_core.ProblemDefinition - The project input for the RAT calculation. -control : RATapi.rat_core.Control - The controls object for the RAT calculation. - -Returns -------- -out_problem_def : Rat.rat_core.ProblemDefinition - The project input with the updated fit values. -results : Rat.rat_core.OutputResult - The results from a RAT calculation. -bayes_result : Rat.rat_core.OutputBayesResult - The extra results if RAT calculation is Bayesian. -)"; - -py::tuple RATMain(const ProblemDefinition& problem_def, const Control& control) +template +py::array_t pyArray1dFromBoundedArray(const T& array) { - RAT::b_ProblemDefinition problem_def_struct = createProblemDefinitionStruct(problem_def); - RAT::Controls control_struct = createControlsStruct(control); - // Output - RAT::Results results; - RAT::BayesResults bayesResults; - // Call the entry-point - RAT::RATMain(&problem_def_struct, &control_struct, &results, &bayesResults); - // Copy result to output - auto out_problem_def = problemDefinitionFromStruct(problem_def_struct); - out_problem_def.customFiles = problem_def.customFiles.attr("copy")(); - return py::make_tuple(out_problem_def, - OutputResultFromStruct(results), - OutputBayesResultsFromStruct(bayesResults)); + auto result_array = py::array_t({array.size[0]}); + std::memcpy(result_array.request().ptr, array.data, result_array.nbytes()); + + return result_array; +} + +template +py::array_t pyArray2dFromBoundedArray(const T& array) +{ + auto result_array = py::array_t({array.size[0], array.size[1]}); + std::memcpy(result_array.request().ptr, array.data, result_array.nbytes()); + + return result_array; } -const std::string docsMakeSLDProfile = R"(Creates the profiles for the SLD plots - -Parameters ----------- -bulk_in : float - Bulk in value for contrast. -bulk_out : float - Bulk out value for contrast. -layers : np.ndarray[np.float] - Array of parameters for each layer in the contrast. -ssub : float - Substrate roughness. -number_of_repeats : int, default: 1 - Number of times the layers are repeated. - -Returns -------- -sld_profile : np.ndarray[np.float] - Computed SLD profile -)"; - -py::array_t makeSLDProfile(real_T bulk_in, - real_T bulk_out, - const py::array_t &layers, - real_T ssub, - int number_of_repeats=DEFAULT_NREPEATS) +py::array_t pyArrayFromRatArray3d(coder::array array) { - coder::array out; - coder::array layers_array = pyArrayToRatArray2d(layers); - RAT::makeSLDProfile(bulk_in, - bulk_out, - layers_array, - ssub, - number_of_repeats, - out); - - return pyArrayFromRatArray2d(out); + auto result_array = py::array_t({array.size(0), array.size(1), array.size(2)}); + std::memcpy(result_array.request().ptr, array.data(), result_array.nbytes()); + + return result_array; +} + +BayesResults bayesResultsFromStruct7T(const RAT::struct7_T results) +{ + BayesResults bayesResults; + + bayesResults.bestPars = pyArrayFromRatArray2d(results.bestPars); + bayesResults.chain = pyArrayFromRatArray2d(results.chain); + + bayesResults.bestFitsMean.ref = pyList1DFromRatCellWrap8(results.bestFitsMean.ref); + bayesResults.bestFitsMean.sld = pyList2dFromRatCellWrap8(results.bestFitsMean.sld); + bayesResults.bestFitsMean.chi = results.bestFitsMean.chi; + bayesResults.bestFitsMean.data = pyList1DFromRatCellWrap8(results.bestFitsMean.data); + + bayesResults.predlims.refPredInts = pyList1DFromRatCellWrap8(results.predlims.refPredInts); + bayesResults.predlims.sldPredInts = pyList2dFromRatCellWrap8(results.predlims.sldPredInts); + bayesResults.predlims.refXdata = pyList1DFromRatCellWrap8(results.predlims.refXdata); + bayesResults.predlims.sldXdata = pyList2dFromRatCellWrap8(results.predlims.sldXdata); + bayesResults.predlims.sampleChi = pyArray1dFromBoundedArray>(results.predlims.sampleChi); + + bayesResults.parConfInts.par95 = pyArrayFromRatArray2d(results.parConfInts.par95); + bayesResults.parConfInts.par65 = pyArrayFromRatArray2d(results.parConfInts.par65); + bayesResults.parConfInts.mean = pyArrayFromRatArray2d(results.parConfInts.mean); + + bayesResults.bayesRes.allChains = pyArrayFromRatArray3d(results.bayesRes.allChains); + + bayesResults.bayesRes.nestOutput.logZ = results.bayesRes.nestOutput.LogZ; + bayesResults.bayesRes.nestOutput.nestSamples = pyArrayFromRatArray2d(results.bayesRes.nestOutput.nestSamples); + bayesResults.bayesRes.nestOutput.postSamples = pyArrayFromRatArray2d(results.bayesRes.nestOutput.postSamples); + + bayesResults.bayesRes.dreamOutput.runtime = results.bayesRes.dreamOutput.RunTime; + bayesResults.bayesRes.dreamOutput.iteration = results.bayesRes.dreamOutput.iteration; + bayesResults.bayesRes.dreamOutput.iloc = results.bayesRes.dreamOutput.iloc; + bayesResults.bayesRes.dreamOutput.fx = results.bayesRes.dreamOutput.fx; + bayesResults.bayesRes.dreamOutput.R_stat = pyArrayFromRatArray2d(results.bayesRes.dreamOutput.R_stat); + bayesResults.bayesRes.dreamOutput.CR = pyArrayFromRatArray2d(results.bayesRes.dreamOutput.CR); + bayesResults.bayesRes.dreamOutput.AR = pyArray2dFromBoundedArray>(results.bayesRes.dreamOutput.AR); + bayesResults.bayesRes.dreamOutput.outlier = pyArray2dFromBoundedArray>(results.bayesRes.dreamOutput.outlier); + + bayesResults.bayesRes.dreamOutput.Meas_info.Y = results.bayesRes.dreamOutput.Meas_info.Y; + bayesResults.bayesRes.dreamOutput.Meas_info.N = results.bayesRes.dreamOutput.Meas_info.N; + + bayesResults.bayesRes.dreamOutput.DREAMPar.d = results.bayesRes.dreamOutput.DREAMPar.d; + bayesResults.bayesRes.dreamOutput.DREAMPar.N = results.bayesRes.dreamOutput.DREAMPar.N; + bayesResults.bayesRes.dreamOutput.DREAMPar.T = results.bayesRes.dreamOutput.DREAMPar.T; + bayesResults.bayesRes.dreamOutput.DREAMPar.parallel = results.bayesRes.dreamOutput.DREAMPar.parallel; + bayesResults.bayesRes.dreamOutput.DREAMPar.CPU = results.bayesRes.dreamOutput.DREAMPar.CPU; + bayesResults.bayesRes.dreamOutput.DREAMPar.lambda = results.bayesRes.dreamOutput.DREAMPar.lambda; + bayesResults.bayesRes.dreamOutput.DREAMPar.pUnitGamma = results.bayesRes.dreamOutput.DREAMPar.pUnitGamma; + bayesResults.bayesRes.dreamOutput.DREAMPar.nCR = results.bayesRes.dreamOutput.DREAMPar.nCR; + bayesResults.bayesRes.dreamOutput.DREAMPar.delta = results.bayesRes.dreamOutput.DREAMPar.delta; + bayesResults.bayesRes.dreamOutput.DREAMPar.steps = results.bayesRes.dreamOutput.DREAMPar.steps; + bayesResults.bayesRes.dreamOutput.DREAMPar.zeta = results.bayesRes.dreamOutput.DREAMPar.zeta; + bayesResults.bayesRes.dreamOutput.DREAMPar.outlier = std::string(results.bayesRes.dreamOutput.DREAMPar.outlier); + bayesResults.bayesRes.dreamOutput.DREAMPar.adaptPCR = results.bayesRes.dreamOutput.DREAMPar.adaptPCR; + bayesResults.bayesRes.dreamOutput.DREAMPar.thinning = results.bayesRes.dreamOutput.DREAMPar.thinning; + bayesResults.bayesRes.dreamOutput.DREAMPar.epsilon = results.bayesRes.dreamOutput.DREAMPar.epsilon; + bayesResults.bayesRes.dreamOutput.DREAMPar.ABC = results.bayesRes.dreamOutput.DREAMPar.ABC; + bayesResults.bayesRes.dreamOutput.DREAMPar.IO = results.bayesRes.dreamOutput.DREAMPar.IO; + bayesResults.bayesRes.dreamOutput.DREAMPar.modout = results.bayesRes.dreamOutput.DREAMPar.modout; + bayesResults.bayesRes.dreamOutput.DREAMPar.restart = results.bayesRes.dreamOutput.DREAMPar.restart; + bayesResults.bayesRes.dreamOutput.DREAMPar.save = results.bayesRes.dreamOutput.DREAMPar.save; + bayesResults.bayesRes.dreamOutput.DREAMPar.R = pyArrayFromRatArray2d(results.bayesRes.dreamOutput.DREAMPar.R); + + return bayesResults; +} + +py::tuple RATMain(const ProblemDefinition& problem_def, const Cells& cells, const Limits& limits, const Control& control, + const Priors& priors) +{ + RAT::struct0_T problem_def_struct = createStruct0(problem_def); + RAT::cell_7 cells_struct = createCell7(cells); + RAT::struct1_T limits_struct = createStruct1(limits); + RAT::struct2_T control_struct = createStruct2T(control); + RAT::struct4_T priors_struct = createStruct4(priors); + + RAT::cell_wrap_9 results[6]; + RAT::struct5_T problem; + RAT::struct7_T bayesResults; + + // Call the entry-point + RAT::RATMain(&problem_def_struct, &cells_struct, &limits_struct, &control_struct, + &priors_struct, &problem, results, &bayesResults); + // Copy result to output + return py::make_tuple(problemDefinitionFromStruct0T(problem_def_struct), + contrastParamsFromStruct5T(problem), + resultArrayToList(results), bayesResultsFromStruct7T(bayesResults)); } class Module @@ -650,12 +1209,8 @@ class Module } }; -template -using overload_cast_ = pybind11::detail::overload_cast_impl; - PYBIND11_MODULE(rat_core, m) { static Module module; - py::class_(m, "EventBridge") .def(py::init()) .def("register", &EventBridge::registerEvent) @@ -663,256 +1218,215 @@ PYBIND11_MODULE(rat_core, m) { py::enum_(m, "EventTypes") .value("Message", EventTypes::Message) - .value("Plot", EventTypes::Plot) - .value("Progress", EventTypes::Progress); + .value("Plot", EventTypes::Plot); py::class_(m, "DylibEngine") .def(py::init()) - .def("invoke", overload_cast_&, std::vector&, - std::vector&, int, int>()(&DylibEngine::invoke), - py::arg("params"), py::arg("bulkIn"), - py::arg("bulkOut"), py::arg("contrast"), - py::arg("domain") = DEFAULT_DOMAIN) - .def("invoke", overload_cast_&, - std::vector&>()(&DylibEngine::invoke), py::arg("xdata"), py::arg("param")); - - py::class_(m, "PredictionIntervals", docsPredictionIntervals.c_str()) + .def("invoke", &DylibEngine::invoke, py::arg("params"), py::arg("bulkIn"), + py::arg("bulkOut"), py::arg("contrast"), + py::arg("domain") = DEFAULT_DOMAIN); + + py::class_(m, "Predlims") .def(py::init<>()) - .def_readwrite("reflectivity", &PredictionIntervals::reflectivity) - .def_readwrite("sld", &PredictionIntervals::sld) - .def_readwrite("sampleChi", &PredictionIntervals::sampleChi); + .def_readwrite("refPredInts", &Predlims::refPredInts) + .def_readwrite("sldPredInts", &Predlims::sldPredInts) + .def_readwrite("refXdata", &Predlims::refXdata) + .def_readwrite("sldXdata", &Predlims::sldXdata) + .def_readwrite("sampleChi", &Predlims::sampleChi); - py::class_(m, "PlotEventData", docsPlotEventData.c_str()) + py::class_(m, "PlotEventData") .def(py::init<>()) .def_readwrite("reflectivity", &PlotEventData::reflectivity) .def_readwrite("shiftedData", &PlotEventData::shiftedData) .def_readwrite("sldProfiles", &PlotEventData::sldProfiles) - .def_readwrite("resampledLayers", &PlotEventData::resampledLayers) - .def_readwrite("subRoughs", &PlotEventData::subRoughs) + .def_readwrite("allLayers", &PlotEventData::allLayers) + .def_readwrite("ssubs", &PlotEventData::ssubs) .def_readwrite("resample", &PlotEventData::resample) .def_readwrite("dataPresent", &PlotEventData::dataPresent) - .def_readwrite("modelType", &PlotEventData::modelType) - .def_readwrite("contrastNames", &PlotEventData::contrastNames) - .def(py::pickle( - [](const PlotEventData &evt) { // __getstate__ - /* Return a tuple that fully encodes the state of the object */ - return py::make_tuple(evt.reflectivity, evt.shiftedData, evt.sldProfiles, evt.resampledLayers, evt.subRoughs, evt.resample, - evt.dataPresent, evt.modelType, evt.contrastNames); - }, - [](py::tuple t) { // __setstate__ - if (t.size() != 9) - throw std::runtime_error("Encountered invalid state unpickling PlotEventData object!"); - - /* Create a new C++ instance */ - PlotEventData evt; - - evt.reflectivity = t[0].cast(); - evt.shiftedData = t[1].cast(); - evt.sldProfiles = t[2].cast(); - evt.resampledLayers = t[3].cast(); - evt.subRoughs = t[4].cast>(); - evt.resample = t[5].cast>(); - evt.dataPresent = t[6].cast>(); - evt.modelType = t[7].cast(); - evt.contrastNames = t[8].cast(); - - return evt; - })); - - py::class_(m, "ProgressEventData", docsProgressEventData.c_str()) + .def_readwrite("modelType", &PlotEventData::modelType); + + py::class_(m, "BestFitsMean") + .def(py::init<>()) + .def_readwrite("ref", &BestFitsMean::ref) + .def_readwrite("sld", &BestFitsMean::sld) + .def_readwrite("chi", &BestFitsMean::chi) + .def_readwrite("data", &BestFitsMean::data); + + py::class_(m, "ParConfInts") .def(py::init<>()) - .def_readwrite("message", &ProgressEventData::message) - .def_readwrite("percent", &ProgressEventData::percent) - .def(py::pickle( - [](const ProgressEventData &evt) { // __getstate__ - /* Return a tuple that fully encodes the state of the object */ - return py::make_tuple(evt.message, evt.percent); - }, - [](py::tuple t) { // __setstate__ - if (t.size() != 2) - throw std::runtime_error("Encountered invalid state unpickling ProgressEventData object!"); - - /* Create a new C++ instance */ - ProgressEventData evt; - - evt.message = t[0].cast(); - evt.percent = t[1].cast(); - - return evt; - })); - - py::class_(m, "ConfidenceIntervals", docsConfidenceIntervals.c_str()) + .def_readwrite("par95", &ParConfInts::par95) + .def_readwrite("par65", &ParConfInts::par65) + .def_readwrite("mean", &ParConfInts::mean); + + py::class_(m, "MeasInfo") .def(py::init<>()) - .def_readwrite("percentile95", &ConfidenceIntervals::percentile95) - .def_readwrite("percentile65", &ConfidenceIntervals::percentile65) - .def_readwrite("mean", &ConfidenceIntervals::mean); + .def_readwrite("Y", &MeasInfo::Y) + .def_readwrite("N", &MeasInfo::N); - py::class_(m, "DreamParams") + py::class_(m, "DREAMPars") .def(py::init<>()) - .def_readwrite("nParams", &DreamParams::nParams) - .def_readwrite("nChains", &DreamParams::nChains) - .def_readwrite("nGenerations", &DreamParams::nGenerations) - .def_readwrite("parallel", &DreamParams::parallel) - .def_readwrite("CPU", &DreamParams::CPU) - .def_readwrite("jumpProbability", &DreamParams::jumpProbability) - .def_readwrite("pUnitGamma", &DreamParams::pUnitGamma) - .def_readwrite("nCR", &DreamParams::nCR) - .def_readwrite("delta", &DreamParams::delta) - .def_readwrite("steps", &DreamParams::steps) - .def_readwrite("zeta", &DreamParams::zeta) - .def_readwrite("outlier", &DreamParams::outlier) - .def_readwrite("adaptPCR", &DreamParams::adaptPCR) - .def_readwrite("thinning", &DreamParams::thinning) - .def_readwrite("epsilon", &DreamParams::epsilon) - .def_readwrite("ABC", &DreamParams::ABC) - .def_readwrite("IO", &DreamParams::IO) - .def_readwrite("storeOutput", &DreamParams::storeOutput) - .def_readwrite("R", &DreamParams::R); - - py::class_(m, "NestedSamplerOutput", docsNestedSamplerOutput.c_str()) + .def_readwrite("d", &DREAMPars::d) + .def_readwrite("N", &DREAMPars::N) + .def_readwrite("T", &DREAMPars::T) + .def_readwrite("parallel", &DREAMPars::parallel) + .def_readwrite("CPU", &DREAMPars::CPU) + .def_readwrite("lambda_", &DREAMPars::lambda) + .def_readwrite("pUnitGamma", &DREAMPars::pUnitGamma) + .def_readwrite("nCR", &DREAMPars::nCR) + .def_readwrite("delta", &DREAMPars::delta) + .def_readwrite("steps", &DREAMPars::steps) + .def_readwrite("zeta", &DREAMPars::zeta) + .def_readwrite("outlier", &DREAMPars::outlier) + .def_readwrite("adaptPCR", &DREAMPars::adaptPCR) + .def_readwrite("thinning", &DREAMPars::thinning) + .def_readwrite("epsilon", &DREAMPars::epsilon) + .def_readwrite("ABC", &DREAMPars::ABC) + .def_readwrite("IO", &DREAMPars::IO) + .def_readwrite("modout", &DREAMPars::modout) + .def_readwrite("restart", &DREAMPars::restart) + .def_readwrite("save", &DREAMPars::save) + .def_readwrite("R", &DREAMPars::R); + + py::class_(m, "NestOutput") .def(py::init<>()) - .def_readwrite("logZ", &NestedSamplerOutput::logZ) - .def_readwrite("logZErr", &NestedSamplerOutput::logZErr) - .def_readwrite("nestSamples", &NestedSamplerOutput::nestSamples) - .def_readwrite("postSamples", &NestedSamplerOutput::postSamples); + .def_readwrite("logZ", &NestOutput::logZ) + .def_readwrite("nestSamples", &NestOutput::nestSamples) + .def_readwrite("postSamples", &NestOutput::postSamples); - py::class_(m, "DreamOutput", docsDreamOutput.c_str()) + py::class_(m, "DreamOutput") .def(py::init<>()) - .def_readwrite("allChains", &DreamOutput::allChains) - .def_readwrite("outlierChains", &DreamOutput::outlierChains) + .def_readwrite("outlier", &DreamOutput::outlier) .def_readwrite("runtime", &DreamOutput::runtime) + .def_readwrite("DREAMPar", &DreamOutput::DREAMPar) + .def_readwrite("Meas_info", &DreamOutput::Meas_info) .def_readwrite("iteration", &DreamOutput::iteration) + .def_readwrite("iloc", &DreamOutput::iloc) + .def_readwrite("fx", &DreamOutput::fx) .def_readwrite("AR", &DreamOutput::AR) .def_readwrite("R_stat", &DreamOutput::R_stat) .def_readwrite("CR", &DreamOutput::CR); - py::class_(m, "OutputBayesResult", docsOutputBayesResult.c_str()) + py::class_(m, "BayesOutput") .def(py::init<>()) - .def_readwrite("predictionIntervals", &OutputBayesResult::predictionIntervals) - .def_readwrite("confidenceIntervals", &OutputBayesResult::confidenceIntervals) - .def_readwrite("dreamParams", &OutputBayesResult::dreamParams) - .def_readwrite("dreamOutput", &OutputBayesResult::dreamOutput) - .def_readwrite("nestedSamplerOutput", &OutputBayesResult::nestedSamplerOutput) - .def_readwrite("chain", &OutputBayesResult::chain); - - py::class_(m, "Calculation", docsCalculation.c_str()) + .def_readwrite("allChains", &BayesOutput::allChains) + .def_readwrite("dreamOutput", &BayesOutput::dreamOutput) + .def_readwrite("nestOutput", &BayesOutput::nestOutput); + + py::class_(m, "BayesResults") + .def(py::init<>()) + .def_readwrite("bestFitsMean", &BayesResults::bestFitsMean) + .def_readwrite("predlims", &BayesResults::predlims) + .def_readwrite("parConfInts", &BayesResults::parConfInts) + .def_readwrite("bestPars", &BayesResults::bestPars) + .def_readwrite("bayesRes", &BayesResults::bayesRes) + .def_readwrite("chain", &BayesResults::chain); + + py::class_(m, "Calculation") .def(py::init<>()) - .def_readwrite("chiValues", &Calculation::chiValues) + .def_readwrite("allChis", &Calculation::allChis) .def_readwrite("sumChi", &Calculation::sumChi); - py::class_(m, "ContrastParams", docsContrastParams.c_str()) + py::class_(m, "ContrastParams") .def(py::init<>()) + .def_readwrite("ssubs", &ContrastParams::ssubs) + .def_readwrite("backgroundParams", &ContrastParams::backgroundParams) + .def_readwrite("qzshifts", &ContrastParams::qzshifts) .def_readwrite("scalefactors", &ContrastParams::scalefactors) .def_readwrite("bulkIn", &ContrastParams::bulkIn) .def_readwrite("bulkOut", &ContrastParams::bulkOut) - .def_readwrite("subRoughs", &ContrastParams::subRoughs) + .def_readwrite("resolutionParams", &ContrastParams::resolutionParams) + .def_readwrite("calculations", &ContrastParams::calculations) + .def_readwrite("allSubRough", &ContrastParams::allSubRough) .def_readwrite("resample", &ContrastParams::resample); - - py::class_(m, "OutputResult", docsOutputResult.c_str()) + + py::class_(m, "OutputResult") .def(py::init<>()) - .def_readwrite("reflectivity", &OutputResult::reflectivity) - .def_readwrite("simulation", &OutputResult::simulation) - .def_readwrite("shiftedData", &OutputResult::shiftedData) - .def_readwrite("backgrounds", &OutputResult::backgrounds) - .def_readwrite("resolutions", &OutputResult::resolutions) - .def_readwrite("sldProfiles", &OutputResult::sldProfiles) - .def_readwrite("layers", &OutputResult::layers) - .def_readwrite("resampledLayers", &OutputResult::resampledLayers) - .def_readwrite("calculationResults", &OutputResult::calculationResults) - .def_readwrite("contrastParams", &OutputResult::contrastParams) - .def_readwrite("fitParams", &OutputResult::fitParams) - .def_readwrite("fitNames", &OutputResult::fitNames); - - py::class_(m, "NameStore", docsNameStore.c_str()) + .def_readwrite("f1", &OutputResult::f1) + .def_readwrite("f2", &OutputResult::f2) + .def_readwrite("f3", &OutputResult::f3) + .def_readwrite("f4", &OutputResult::f4) + .def_readwrite("f5", &OutputResult::f5) + .def_readwrite("f6", &OutputResult::f6); + + py::class_(m, "Checks") .def(py::init<>()) - .def_readwrite("params", &NameStore::params) - .def_readwrite("backgroundParams", &NameStore::backgroundParams) - .def_readwrite("scalefactors", &NameStore::scalefactors) - .def_readwrite("bulkIns", &NameStore::bulkIns) - .def_readwrite("bulkOuts", &NameStore::bulkOuts) - .def_readwrite("resolutionParams", &NameStore::resolutionParams) - .def_readwrite("domainRatios", &NameStore::domainRatios) - .def_readwrite("contrasts", &NameStore::contrasts) - .def(py::pickle( - [](const NameStore &names) { // __getstate__ - /* Return a tuple that fully encodes the state of the object */ - return py::make_tuple(names.params, names.backgroundParams, names.scalefactors, names.bulkIns, names.bulkOuts, names.resolutionParams, - names.domainRatios, names.contrasts); - }, - [](py::tuple t) { // __setstate__ - if (t.size() != 8) - throw std::runtime_error("Encountered invalid state unpickling NameStore object!"); - - /* Create a new C++ instance */ - NameStore names; - - names.params = t[0].cast(); - names.backgroundParams = t[1].cast(); - names.scalefactors = t[2].cast(); - names.bulkIns = t[3].cast(); - names.bulkOuts = t[4].cast(); - names.resolutionParams = t[5].cast(); - names.domainRatios = t[6].cast(); - names.contrasts = t[7].cast(); - - return names; - })); - - py::class_(m, "Checks", docsChecks.c_str()) + .def_readwrite("fitParam", &Checks::fitParam) + .def_readwrite("fitBackgroundParam", &Checks::fitBackgroundParam) + .def_readwrite("fitQzshift", &Checks::fitQzshift) + .def_readwrite("fitScalefactor", &Checks::fitScalefactor) + .def_readwrite("fitBulkIn", &Checks::fitBulkIn) + .def_readwrite("fitBulkOut", &Checks::fitBulkOut) + .def_readwrite("fitResolutionParam", &Checks::fitResolutionParam) + .def_readwrite("fitDomainRatio", &Checks::fitDomainRatio); + + py::class_(m, "Limits") .def(py::init<>()) - .def_readwrite("params", &Checks::params) - .def_readwrite("backgroundParams", &Checks::backgroundParams) - .def_readwrite("scalefactors", &Checks::scalefactors) - .def_readwrite("bulkIns", &Checks::bulkIns) - .def_readwrite("bulkOuts", &Checks::bulkOuts) - .def_readwrite("resolutionParams", &Checks::resolutionParams) - .def_readwrite("domainRatios", &Checks::domainRatios) - .def(py::pickle( - [](const Checks &chk) { // __getstate__ - /* Return a tuple that fully encodes the state of the object */ - return py::make_tuple(chk.params, chk.backgroundParams, chk.scalefactors, chk.bulkIns, chk.bulkOuts, - chk.resolutionParams, chk.domainRatios); - }, - [](py::tuple t) { // __setstate__ - if (t.size() != 7) - throw std::runtime_error("Encountered invalid state unpickling Checks object!"); - - /* Create a new C++ instance */ - Checks chk; - - chk.params = t[0].cast>(); - chk.backgroundParams = t[1].cast>(); - chk.scalefactors = t[2].cast>(); - chk.bulkIns = t[3].cast>(); - chk.bulkOuts = t[4].cast>(); - chk.resolutionParams = t[5].cast>(); - chk.domainRatios = t[6].cast>(); - - return chk; - })); - - py::class_(m, "Control", docsControl.c_str()) + .def_readwrite("param", &Limits::param) + .def_readwrite("backgroundParam", &Limits::backgroundParam) + .def_readwrite("qzshift", &Limits::qzshift) + .def_readwrite("scalefactor", &Limits::scalefactor) + .def_readwrite("bulkIn", &Limits::bulkIn) + .def_readwrite("bulkOut", &Limits::bulkOut) + .def_readwrite("resolutionParam", &Limits::resolutionParam) + .def_readwrite("domainRatio", &Limits::domainRatio); + + py::class_(m, "Priors") + .def(py::init<>()) + .def_readwrite("param", &Priors::param) + .def_readwrite("backgroundParam", &Priors::backgroundParam) + .def_readwrite("qzshift", &Priors::qzshift) + .def_readwrite("scalefactor", &Priors::scalefactor) + .def_readwrite("bulkIn", &Priors::bulkIn) + .def_readwrite("bulkOut", &Priors::bulkOut) + .def_readwrite("resolutionParam", &Priors::resolutionParam) + .def_readwrite("domainRatio", &Priors::domainRatio) + .def_readwrite("priorNames", &Priors::priorNames) + .def_readwrite("priorValues", &Priors::priorValues); + + py::class_(m, "Cells") + .def(py::init<>()) + .def_readwrite("f1", &Cells::f1) + .def_readwrite("f2", &Cells::f2) + .def_readwrite("f3", &Cells::f3) + .def_readwrite("f4", &Cells::f4) + .def_readwrite("f5", &Cells::f5) + .def_readwrite("f6", &Cells::f6) + .def_readwrite("f7", &Cells::f7) + .def_readwrite("f8", &Cells::f8) + .def_readwrite("f9", &Cells::f9) + .def_readwrite("f10", &Cells::f10) + .def_readwrite("f11", &Cells::f11) + .def_readwrite("f12", &Cells::f12) + .def_readwrite("f13", &Cells::f13) + .def_readwrite("f14", &Cells::f14) + .def_readwrite("f15", &Cells::f15) + .def_readwrite("f16", &Cells::f16) + .def_readwrite("f17", &Cells::f17) + .def_readwrite("f18", &Cells::f18) + .def_readwrite("f19", &Cells::f19) + .def_readwrite("f20", &Cells::f20); + + py::class_(m, "Control") .def(py::init<>()) .def_readwrite("parallel", &Control::parallel) .def_readwrite("procedure", &Control::procedure) .def_readwrite("display", &Control::display) - .def_readwrite("xTolerance", &Control::xTolerance) - .def_readwrite("funcTolerance", &Control::funcTolerance) - .def_readwrite("maxFuncEvals", &Control::maxFuncEvals) - .def_readwrite("maxIterations", &Control::maxIterations) + .def_readwrite("tolX", &Control::tolX) + .def_readwrite("tolFun", &Control::tolFun) + .def_readwrite("maxFunEvals", &Control::maxFunEvals) + .def_readwrite("maxIter", &Control::maxIter) .def_readwrite("populationSize", &Control::populationSize) .def_readwrite("fWeight", &Control::fWeight) .def_readwrite("crossoverProbability", &Control::crossoverProbability) .def_readwrite("targetValue", &Control::targetValue) .def_readwrite("numGenerations", &Control::numGenerations) .def_readwrite("strategy", &Control::strategy) - .def_readwrite("nLive", &Control::nLive) - .def_readwrite("nMCMC", &Control::nMCMC) + .def_readwrite("Nlive", &Control::Nlive) + .def_readwrite("Nmcmc", &Control::Nmcmc) .def_readwrite("propScale", &Control::propScale) .def_readwrite("nsTolerance", &Control::nsTolerance) - .def_readwrite("numSimulationPoints", &Control::numSimulationPoints) - .def_readwrite("resampleMinAngle", &Control::resampleMinAngle) - .def_readwrite("resampleNPoints", &Control::resampleNPoints) + .def_readwrite("calcSldDuringFit", &Control::calcSldDuringFit) + .def_readwrite("resamPars", &Control::resamPars) .def_readwrite("updateFreq", &Control::updateFreq) .def_readwrite("updatePlotFreq", &Control::updatePlotFreq) .def_readwrite("nSamples", &Control::nSamples) @@ -921,183 +1435,41 @@ PYBIND11_MODULE(rat_core, m) { .def_readwrite("pUnitGamma", &Control::pUnitGamma) .def_readwrite("boundHandling", &Control::boundHandling) .def_readwrite("adaptPCR", &Control::adaptPCR) - .def_readwrite("IPCFilePath", &Control::IPCFilePath) - .def(py::pickle( - [](const Control &ctrl) { // __getstate__ - /* Return a tuple that fully encodes the state of the object */ - return py::make_tuple(ctrl.parallel, ctrl.procedure, ctrl.display, ctrl.xTolerance, ctrl.funcTolerance, - ctrl.maxFuncEvals, ctrl.maxIterations, ctrl.populationSize, ctrl.fWeight, ctrl.crossoverProbability, - ctrl.targetValue, ctrl.numGenerations, ctrl.strategy, ctrl.nLive, ctrl.nMCMC, ctrl.propScale, - ctrl.nsTolerance, ctrl.numSimulationPoints, ctrl.resampleMinAngle, ctrl.resampleNPoints, - ctrl.updateFreq, ctrl.updatePlotFreq, ctrl.nSamples, ctrl.nChains, ctrl.jumpProbability, - ctrl.pUnitGamma, ctrl.boundHandling, ctrl.adaptPCR, ctrl.IPCFilePath); - }, - [](py::tuple t) { // __setstate__ - if (t.size() != 29) - throw std::runtime_error("Encountered invalid state unpickling ProblemDefinition object!"); - - /* Create a new C++ instance */ - Control ctrl; - - ctrl.parallel = t[0].cast(); - ctrl.procedure = t[1].cast(); - ctrl.display = t[2].cast(); - ctrl.xTolerance = t[3].cast(); - ctrl.funcTolerance = t[4].cast(); - ctrl.maxFuncEvals = t[5].cast(); - ctrl.maxIterations = t[6].cast(); - ctrl.populationSize = t[7].cast(); - ctrl.fWeight = t[8].cast(); - ctrl.crossoverProbability = t[9].cast(); - ctrl.targetValue = t[10].cast(); - ctrl.numGenerations = t[11].cast(); - ctrl.strategy = t[12].cast(); - ctrl.nLive = t[13].cast(); - ctrl.nMCMC = t[14].cast(); - ctrl.propScale = t[15].cast(); - ctrl.nsTolerance = t[16].cast(); - ctrl.numSimulationPoints = t[17].cast(); - ctrl.resampleMinAngle = t[18].cast(); - ctrl.resampleNPoints = t[19].cast(); - ctrl.updateFreq = t[20].cast(); - ctrl.updatePlotFreq = t[21].cast(); - ctrl.nSamples = t[22].cast(); - ctrl.nChains = t[23].cast(); - ctrl.jumpProbability = t[24].cast(); - ctrl.pUnitGamma = t[25].cast(); - ctrl.boundHandling = t[26].cast(); - ctrl.adaptPCR = t[27].cast(); - ctrl.IPCFilePath = t[28].cast(); - - return ctrl; - })); - - py::class_(m, "ProblemDefinition", docsProblemDefinition.c_str()) + .def_readwrite("checks", &Control::checks); + + py::class_(m, "ProblemDefinition") .def(py::init<>()) + .def_readwrite("contrastBackgrounds", &ProblemDefinition::contrastBackgrounds) + .def_readwrite("contrastBackgroundsType", &ProblemDefinition::contrastBackgroundsType) .def_readwrite("TF", &ProblemDefinition::TF) .def_readwrite("resample", &ProblemDefinition::resample) - .def_readwrite("data", &ProblemDefinition::data) .def_readwrite("dataPresent", &ProblemDefinition::dataPresent) - .def_readwrite("dataLimits", &ProblemDefinition::dataLimits) - .def_readwrite("simulationLimits", &ProblemDefinition::simulationLimits) + .def_readwrite("oilChiDataPresent", &ProblemDefinition::oilChiDataPresent) .def_readwrite("numberOfContrasts", &ProblemDefinition::numberOfContrasts) .def_readwrite("geometry", &ProblemDefinition::geometry) - .def_readwrite("useImaginary", &ProblemDefinition::useImaginary) - .def_readwrite("repeatLayers", &ProblemDefinition::repeatLayers) - .def_readwrite("contrastBackgroundParams", &ProblemDefinition::contrastBackgroundParams) - .def_readwrite("contrastBackgroundTypes", &ProblemDefinition::contrastBackgroundTypes) - .def_readwrite("contrastBackgroundActions", &ProblemDefinition::contrastBackgroundActions) + .def_readwrite("useImaginary", &ProblemDefinition::useImaginary) + .def_readwrite("contrastQzshifts", &ProblemDefinition::contrastQzshifts) .def_readwrite("contrastScalefactors", &ProblemDefinition::contrastScalefactors) .def_readwrite("contrastBulkIns", &ProblemDefinition::contrastBulkIns) .def_readwrite("contrastBulkOuts", &ProblemDefinition::contrastBulkOuts) - .def_readwrite("contrastResolutionParams", &ProblemDefinition::contrastResolutionParams) - .def_readwrite("contrastResolutionTypes", &ProblemDefinition::contrastResolutionTypes) + .def_readwrite("contrastResolutions", &ProblemDefinition::contrastResolutions) .def_readwrite("backgroundParams", &ProblemDefinition::backgroundParams) + .def_readwrite("qzshifts", &ProblemDefinition::qzshifts) .def_readwrite("scalefactors", &ProblemDefinition::scalefactors) - .def_readwrite("bulkIns", &ProblemDefinition::bulkIns) - .def_readwrite("bulkOuts", &ProblemDefinition::bulkOuts) + .def_readwrite("bulkIn", &ProblemDefinition::bulkIn) + .def_readwrite("bulkOut", &ProblemDefinition::bulkOut) .def_readwrite("resolutionParams", &ProblemDefinition::resolutionParams) .def_readwrite("params", &ProblemDefinition::params) .def_readwrite("numberOfLayers", &ProblemDefinition::numberOfLayers) - .def_readwrite("contrastLayers", &ProblemDefinition::contrastLayers) - .def_readwrite("layersDetails", &ProblemDefinition::layersDetails) - .def_readwrite("customFiles", &ProblemDefinition::customFiles) .def_readwrite("modelType", &ProblemDefinition::modelType) .def_readwrite("contrastCustomFiles", &ProblemDefinition::contrastCustomFiles) .def_readwrite("contrastDomainRatios", &ProblemDefinition::contrastDomainRatios) - .def_readwrite("domainRatios", &ProblemDefinition::domainRatios) + .def_readwrite("domainRatio", &ProblemDefinition::domainRatio) .def_readwrite("numberOfDomainContrasts", &ProblemDefinition::numberOfDomainContrasts) - .def_readwrite("domainContrastLayers", &ProblemDefinition::domainContrastLayers) .def_readwrite("fitParams", &ProblemDefinition::fitParams) + .def_readwrite("otherParams", &ProblemDefinition::otherParams) .def_readwrite("fitLimits", &ProblemDefinition::fitLimits) - .def_readwrite("priorNames", &ProblemDefinition::priorNames) - .def_readwrite("priorValues", &ProblemDefinition::priorValues) - .def_readwrite("names", &ProblemDefinition::names) - .def_readwrite("checks", &ProblemDefinition::checks) - .def(py::pickle( - [](const ProblemDefinition &p) { // __getstate__ - /* Return a tuple that fully encodes the state of the object */ - return py::make_tuple(p.TF, p.resample, p.data, p.dataPresent, p.dataLimits, p.simulationLimits, - p.numberOfContrasts, p.geometry, p.useImaginary, p.repeatLayers, - p.contrastBackgroundParams, p.contrastBackgroundTypes, p.contrastBackgroundActions, - p.contrastScalefactors, p.contrastBulkIns, p.contrastBulkOuts, p.contrastResolutionParams, - p.contrastResolutionTypes, p.backgroundParams, p.scalefactors, p.bulkIns, p.bulkOuts, - p.resolutionParams, p.params, p.numberOfLayers, p.contrastLayers, p.layersDetails, - p.customFiles, p.modelType, p.contrastCustomFiles, p.contrastDomainRatios, p.domainRatios, - p.numberOfDomainContrasts, p.domainContrastLayers, p.fitParams, p.fitLimits, p.priorNames, p.priorValues, - p.names.params, p.names.backgroundParams, p.names.scalefactors, p.names.bulkIns, - p.names.bulkOuts, p.names.resolutionParams, p.names.domainRatios, p.names.contrasts, - p.checks.params, p.checks.backgroundParams, p.checks.scalefactors, - p.checks.bulkIns, p.checks.bulkOuts, p.checks.resolutionParams, p.checks.domainRatios); - }, - [](py::tuple t) { // __setstate__ - if (t.size() != 53) - throw std::runtime_error("Encountered invalid state unpickling ProblemDefinition object!"); - - /* Create a new C++ instance */ - ProblemDefinition p; - - p.TF = t[0].cast(); - p.resample = t[1].cast>(); - p.data = t[2].cast(); - p.dataPresent = t[3].cast>(); - p.dataLimits = t[4].cast(); - p.simulationLimits = t[5].cast(); - p.numberOfContrasts = t[6].cast(); - p.geometry = t[7].cast(); - p.useImaginary = t[8].cast(); - p.repeatLayers = t[9].cast>(); - p.contrastBackgroundParams = t[10].cast(); - p.contrastBackgroundTypes = t[11].cast(); - p.contrastBackgroundActions = t[12].cast(); - p.contrastScalefactors = t[13].cast>(); - p.contrastBulkIns = t[14].cast>(); - p.contrastBulkOuts = t[15].cast>(); - p.contrastResolutionParams = t[16].cast(); - p.contrastResolutionTypes = t[17].cast(); - p.backgroundParams = t[18].cast>(); - p.scalefactors = t[19].cast>(); - p.bulkIns = t[20].cast>(); - p.bulkOuts = t[21].cast>(); - p.resolutionParams = t[22].cast>(); - p.params = t[23].cast>(); - p.numberOfLayers = t[24].cast(); - p.contrastLayers = t[25].cast(); - p.layersDetails = t[26].cast(); - p.customFiles = t[27].cast(); - p.modelType = t[28].cast(); - p.contrastCustomFiles = t[29].cast>(); - p.contrastDomainRatios = t[30].cast>(); - p.domainRatios = t[31].cast>(); - p.numberOfDomainContrasts = t[32].cast(); - p.domainContrastLayers = t[33].cast(); - p.fitParams = t[34].cast>(); - p.fitLimits = t[35].cast>(); - p.priorNames = t[36].cast(); - p.priorValues = t[37].cast>(); - - p.names.params = t[38].cast(); - p.names.backgroundParams = t[39].cast(); - p.names.scalefactors = t[40].cast(); - p.names.bulkIns = t[41].cast(); - p.names.bulkOuts = t[42].cast(); - p.names.resolutionParams = t[43].cast(); - p.names.domainRatios = t[44].cast(); - p.names.contrasts = t[45].cast(); - - p.checks.params = t[46].cast>(); - p.checks.backgroundParams = t[47].cast>(); - p.checks.scalefactors = t[48].cast>(); - p.checks.bulkIns = t[49].cast>(); - p.checks.bulkOuts = t[50].cast>(); - p.checks.resolutionParams = t[51].cast>(); - p.checks.domainRatios = t[52].cast>(); - - return p; - })); - - m.def("RATMain", &RATMain, docsRATMain.c_str(), py::arg("problem_def"), py::arg("control")); - - m.def("makeSLDProfile", &makeSLDProfile, docsMakeSLDProfile.c_str(), - py::arg("bulk_in"), py::arg("bulk_out"), py::arg("layers"), py::arg("ssub"), py::arg("number_of_repeats") = DEFAULT_NREPEATS); + .def_readwrite("otherLimits", &ProblemDefinition::otherLimits); + + m.def("RATMain", &RATMain, "A demo for Python RAT"); } diff --git a/data/dspc_bilayer/data1.csv b/data/dspc_bilayer/data1.csv new file mode 100644 index 00000000..69e6272f --- /dev/null +++ b/data/dspc_bilayer/data1.csv @@ -0,0 +1,82 @@ +0.011403,0.10063,0.0019003 +0.011973,0.11082,0.001883 +0.012572,0.10766,0.0016413 +0.013201,0.10652,0.0014669 +0.013861,0.090118,0.0011774 +0.014554,0.034255,0.00048888 +0.015281,0.017209,0.00026267 +0.016045,0.010465,0.00017551 +0.016848,0.0070455,0.00013083 +0.01769,0.0045958,9.72E-05 +0.018575,0.0034925,8.09E-05 +0.019503,0.002451,6.45E-05 +0.020479,0.0017544,5.13E-05 +0.021502,0.0013384,4.27E-05 +0.022578,0.0010447,3.59E-05 +0.023706,0.00076523,2.93E-05 +0.024892,0.00064257,2.62E-05 +0.026136,0.00050024,1.37E-05 +0.027443,0.00039982,1.16E-05 +0.028815,0.00034301,1.01E-05 +0.030256,0.00027746,8.58E-06 +0.031769,0.00026396,8.28E-06 +0.033357,0.00023596,7.89E-06 +0.035025,0.0002028,1.00E-05 +0.036777,0.00018591,4.94E-06 +0.038615,0.00015427,4.31E-06 +0.040546,0.00014273,3.96E-06 +0.042573,0.00012868,3.66E-06 +0.044702,0.00011002,3.26E-06 +0.046937,9.11E-05,2.82E-06 +0.049284,9.12E-05,2.72E-06 +0.051748,7.63E-05,2.37E-06 +0.054336,6.67E-05,2.14E-06 +0.057052,6.46E-05,2.46E-06 +0.059905,6.10E-05,1.32E-06 +0.0629,6.31E-05,1.29E-06 +0.066045,6.07E-05,1.18E-06 +0.069348,6.00E-05,1.11E-06 +0.072815,6.10E-05,1.10E-06 +0.076456,5.68E-05,1.04E-06 +0.080279,5.88E-05,1.56E-06 +0.084292,5.41E-05,9.53E-07 +0.088507,4.70E-05,8.44E-07 +0.092932,4.26E-05,7.71E-07 +0.097579,3.27E-05,6.53E-07 +0.10246,2.54E-05,5.46E-07 +0.10758,1.71E-05,4.22E-07 +0.11296,1.22E-05,3.41E-07 +0.11861,7.82E-06,2.59E-07 +0.12454,5.09E-06,2.02E-07 +0.13077,4.16E-06,1.76E-07 +0.1373,3.63E-06,1.62E-07 +0.14417,3.35E-06,1.51E-07 +0.15138,2.73E-06,1.32E-07 +0.15895,1.82E-06,1.07E-07 +0.16689,1.22E-06,8.76E-08 +0.17524,4.93E-07,5.67E-08 +0.184,2.40E-07,4.13E-08 +0.1932,3.38E-07,5.32E-08 +0.20286,3.20E-07,5.50E-08 +0.213,4.19E-07,6.85E-08 +0.22365,3.15E-07,6.34E-08 +0.23484,2.32E-07,5.60E-08 +0.24658,3.34E-07,6.84E-08 +0.25891,3.99E-07,8.21E-08 +0.27185,2.51E-07,6.27E-08 +0.28544,2.25E-07,6.33E-08 +0.29972,2.09E-07,6.06E-08 +0.3147,2.09E-07,6.14E-08 +0.33044,3.34E-07,7.72E-08 +0.34696,1.84E-07,6.05E-08 +0.36431,2.35E-07,6.62E-08 +0.38252,2.12E-07,6.31E-08 +0.40165,2.47E-07,6.66E-08 +0.42173,2.02E-07,6.24E-08 +0.44282,2.46E-07,6.91E-08 +0.46496,1.99E-07,6.08E-08 +0.48821,2.86E-07,7.39E-08 +0.51262,1.95E-07,6.18E-08 +0.53825,2.88E-07,7.54E-08 +0.56516,2.38E-07,7.06E-08 +0.59342,2.18E-07,6.69E-08 diff --git a/data/dspc_bilayer/data2.csv b/data/dspc_bilayer/data2.csv new file mode 100644 index 00000000..57709af5 --- /dev/null +++ b/data/dspc_bilayer/data2.csv @@ -0,0 +1,82 @@ +0.011403,0.0018074,0.00010983 +0.011973,0.0014774,9.06E-05 +0.012572,0.001325,7.70E-05 +0.013201,0.0012216,6.64E-05 +0.013861,0.0010077,5.58E-05 +0.014554,0.0010266,5.14E-05 +0.015281,0.00091489,4.52E-05 +0.016045,0.00080921,4.00E-05 +0.016848,0.00061576,3.35E-05 +0.01769,0.00060308,3.16E-05 +0.018575,0.00046074,2.68E-05 +0.019503,0.00040453,2.44E-05 +0.020479,0.00036496,2.20E-05 +0.021502,0.00032468,2.00E-05 +0.022578,0.0002479,1.66E-05 +0.023706,0.00027709,1.70E-05 +0.024892,0.00021141,1.44E-05 +0.026136,0.00017034,7.51E-06 +0.027443,0.00015127,6.71E-06 +0.028815,0.00013632,5.95E-06 +0.030256,0.00011151,5.25E-06 +0.031769,9.58E-05,4.77E-06 +0.033357,7.59E-05,4.22E-06 +0.035025,6.92E-05,6.20E-06 +0.036777,5.27E-05,2.39E-06 +0.038615,3.92E-05,1.98E-06 +0.040546,2.94E-05,1.64E-06 +0.042573,2.23E-05,1.39E-06 +0.044702,1.47E-05,1.09E-06 +0.046937,8.20E-06,7.77E-07 +0.049284,6.49E-06,6.66E-07 +0.051748,3.09E-06,4.36E-07 +0.054336,2.60E-06,3.89E-07 +0.057052,2.73E-06,5.00E-07 +0.059905,4.36E-06,3.20E-07 +0.0629,5.49E-06,3.45E-07 +0.066045,7.29E-06,3.70E-07 +0.069348,8.91E-06,3.89E-07 +0.072815,1.06E-05,4.19E-07 +0.076456,1.24E-05,4.42E-07 +0.080279,1.46E-05,7.02E-07 +0.084292,1.48E-05,4.56E-07 +0.088507,1.40E-05,4.24E-07 +0.092932,1.16E-05,3.73E-07 +0.097579,1.06E-05,3.48E-07 +0.10246,7.77E-06,2.85E-07 +0.10758,6.43E-06,2.46E-07 +0.11296,4.95E-06,2.07E-07 +0.11861,2.90E-06,1.51E-07 +0.12454,1.98E-06,1.21E-07 +0.13077,1.18E-06,9.06E-08 +0.1373,9.56E-07,8.03E-08 +0.14417,9.92E-07,7.95E-08 +0.15138,8.10E-07,6.93E-08 +0.15895,7.82E-07,6.76E-08 +0.16689,6.04E-07,5.99E-08 +0.17524,4.86E-07,5.49E-08 +0.184,4.14E-07,5.29E-08 +0.1932,4.38E-07,5.92E-08 +0.20286,3.00E-07,5.16E-08 +0.213,4.95E-07,7.11E-08 +0.22365,2.80E-07,5.78E-08 +0.23484,2.39E-07,5.49E-08 +0.24658,2.18E-07,5.37E-08 +0.25891,2.57E-07,6.37E-08 +0.27185,5.80E-07,9.35E-08 +0.28544,3.27E-07,7.46E-08 +0.29972,3.05E-07,7.16E-08 +0.3147,3.36E-07,7.63E-08 +0.33044,3.86E-07,8.11E-08 +0.34696,2.94E-07,7.29E-08 +0.36431,3.03E-07,7.30E-08 +0.38252,4.10E-07,8.57E-08 +0.40165,4.06E-07,8.34E-08 +0.42173,5.31E-07,9.75E-08 +0.44282,4.95E-07,9.56E-08 +0.46496,3.54E-07,7.87E-08 +0.48821,3.56E-07,8.00E-08 +0.51262,3.76E-07,8.34E-08 +0.53825,5.89E-07,1.05E-07 +0.56516,3.26E-07,7.97E-08 +0.59342,3.07E-07,7.71E-08 diff --git a/ratapi/examples/data/c_PLP0016596.dat b/data/dspc_custom/data1.csv similarity index 100% rename from ratapi/examples/data/c_PLP0016596.dat rename to data/dspc_custom/data1.csv diff --git a/ratapi/examples/data/c_PLP0016601.dat b/data/dspc_custom/data2.csv similarity index 100% rename from ratapi/examples/data/c_PLP0016601.dat rename to data/dspc_custom/data2.csv diff --git a/ratapi/examples/data/c_PLP0016607.dat b/data/dspc_custom/data3.csv similarity index 100% rename from ratapi/examples/data/c_PLP0016607.dat rename to data/dspc_custom/data3.csv diff --git a/examples/DSPC_bilayer_example.py b/examples/DSPC_bilayer_example.py new file mode 100644 index 00000000..9debc19c --- /dev/null +++ b/examples/DSPC_bilayer_example.py @@ -0,0 +1,204 @@ +import numpy as np +from rat import rat_core + +if __name__ == '__main__': + + control = rat_core.Control() + problem = rat_core.ProblemDefinition() + limits = rat_core.Limits() + cells = rat_core.Cells() + priors = rat_core.Priors() + + #------------------------------------------------------------------------------------ + # Control + control.procedure = 'calculate' + control.parallel = 'single' + control.display = 'iter' + control.calcSldDuringFit = False + control.resamPars = [0.9000, 50] + + # control.procedure = 'simplex' + # control.tolX = 1e-6 + # control.tolFun = 1e-6 + # control.maxFunEvals = 10000 + # control.maxIter = 1 + # control.updateFreq = -1 + # control.updatePlotFreq = 1 + + # control.procedure = 'dream' + # control.nSamples = 100 + # control.nChains = 10 + # control.jumpProbability = 0.5 + # control.pUnitGamma = 0.2 + # control.boundHandling = 'fold' + # control.adaptPCR = False; + + # control.procedure = 'de' + # control.populationSize = 10 + # control.fWeight = 0.5 + # control.crossoverProbability = 0.8 + # control.strategy = 4 + # control.targetValue = 1 + # control.numGenerations = 500 + + # control.procedure = 'ns' + # control.Nlive = 150 + # control.Nmcmc = 0 + # control.propScale = 0.1 + # control.nsTolerance = 0.1 + + control.checks.fitParam = [1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1] + control.checks.fitBackgroundParam = np.ones((2)) + control.checks.fitQzshift = [0] + control.checks.fitScalefactor = [0, 0] + control.checks.fitBulkIn = [0] + control.checks.fitBulkOut = [0, 0] + control.checks.fitResolutionParam = [0] + + #------------------------------------------------------------------------------------ + # ProblemDef + problem.contrastBackgrounds = [1, 2] + problem.contrastBackgroundsType = [1, 1] + problem.TF = 'non polarised' + problem.resample = [0, 0] + problem.dataPresent = [1, 1] + problem.oilChiDataPresent = [0, 0] + problem.numberOfContrasts = 2 + problem.geometry = 'substrate/liquid' + problem.useImaginary = False + problem.contrastQzshifts = [1, 1] + problem.contrastScalefactors = [1, 1] + problem.contrastBulkIns = [1, 1] + problem.contrastBulkOuts = [1, 2] + problem.contrastResolutions = [1, 1] + problem.backgroundParams = [2.28525214157571e-06, 3.10246417982706e-06] + problem.qzshifts = [0] + problem.scalefactors = [0.102860901766649, 0.151378164199993] + problem.bulkIn = [2.07399989449186e-06] + problem.bulkOut = [5.98067802097389e-06, 2.21000000000000e-06] + problem.resolutionParams = [0.0300] + problem.params = [5.08929897223891, 19.2830495317839, 3.39317612702561e-06, 21.5451088784623, -4.01001212540204e-07, 1.24963548580913, 8.09797576127018, 20.3854719276630, + 0, 5.79580504624961, 1.75686012656988e-06, 10.0916971312704, 11.7066921282983, 1.47000000000000e-06, 5.63694566866001, 17.8733566725932, -4.61089672942576e-07, + 17.8556570737753, 41.4142113901161, 100, 25.6893163532023] + problem.numberOfLayers = 6 + problem.modelType = 'standard layers' + problem.contrastCustomFiles = [np.NAN, np.NaN] + problem.contrastDomainRatios = [0, 0] + problem.domainRatio = [] + problem.numberOfDomainContrasts = 0 + problem.fitParams = [5.08929897223891, 19.2830495317839, 21.5451088784623, 1.24963548580913, 8.09797576127018, + 20.3854719276630, 5.79580504624961, 10.0916971312704, 11.7066921282983, 5.63694566866001, + 17.8733566725932, 17.8556570737753, 41.4142113901161, 25.6893163532023, 2.28525214157571e-06, + 3.10246417982706e-06] + problem.otherParams = [3.39317612702561e-06, -4.01001212540204e-07, 0, 1.75686012656988e-06, 1.47e-06, -4.61089672942576e-07, + 100, 0.102860901766649, 0.151378164199993,0, 2.07399989449186e-06, 5.98067802097389e-06, 2.21e-06, 0.030] + problem.fitLimits = [[2, 8], [5, 60], [15, 35], [1, 50], [1, 15], [10, 28], [5, 17], + [10, 50], [7, 17], [2, 15], [14, 22], [10, 50], [10, 50], [0, 60], [5.0e-10, 7.0e-06], + [1.0e-10, 4.99999987368938e-06]] + problem.otherLimits = [[3.39e-06, 3.41e-06], [-5.0e-07, -3.0e-07], [0, 1.0e-09], [1.0e-07, 2.0e-06], [5.0e-07, 1.5e-06], + [-5.0e-07, 0], [99.9, 100], [0.050, 0.20], [0.050, 0.20], [-0.00010, 0.00010], [2.0e-06, 2.1e-06], + [5.50000004295725e-06, 6.4e-06], [2.0e-06, 4.99999987368938e-06], [0.010, 0.050]] + + #------------------------------------------------------------------------------------ + # Limits + limits.param = [[2, 8], [5, 60], [0, 0], [15, 35], [-0, -0], [1, 50], [1, 15], + [10, 28], [0, 0], [5, 17], [0, 0], [10, 50], [7, 17], [0, 0], [2, 15], + [14, 22], [-0, 0], [10, 50], [10, 50], [99.9,100], [0, 60]] + limits.backgroundParam = [[5.0000e-10, 7.0000e-06], [1.0000e-10, 5.0000e-06]] + limits.scalefactor = [[0.0500, 0.2000], [0.0500, 0.2000]] + limits.qzshift = [[-1.0000e-04, 1.0000e-04]] + limits.bulkIn = [[2.0000e-06, 2.1000e-06]] + limits.bulkOut = [[5.5000e-06, 6.4000e-06], [2.0000e-06, 5.0000e-06]] + limits.resolutionParam = [[0.0100, 0.0500]] + limits.domainRatio = [] + + #------------------------------------------------------------------------------------- + # Cells + cells.f1 = [[0, 1], [0, 1]] + cells.f2 = [np.loadtxt('data/dspc_bilayer/data1.csv', delimiter=','), + np.loadtxt('data/dspc_bilayer/data2.csv', delimiter=',')] + cells.f3 = [[0.011403, 0.59342], [0.011403, 0.59342]] + cells.f4 = [[0.011403, 0.70956], [0.011403, 0.59342]] + cells.f5 = [[1, 2, 3, 4, 5, 6, 6, 5], [1, 2, 3, 4, 5, 6, 6, 5]] + cells.f6 = [[2, 3, 1, 21, 2], + [4, 5, 7, 6, 2], + [10, 11, 7, 12, 2], + [8, 9, 15, 20, 2], + [13, 14, 15, 19, 2], + [16, 17, 15, 18, 2]] + cells.f7 = ['Substrate Roughness', 'Oxide thick', 'Oxide SLD', 'Sam tails thick', 'Sam tails SLD', + 'Sam tails hydration', 'Sam rough', 'cw thick', 'cw SLD', 'SAM head thick', 'SAM head SLD', + 'SAM head hydration', 'Bilayer head thick', 'Bilayer head SLD', 'Bilayer rough', + 'Bilayer tails thick', 'Bilayer tails SLD', 'Bilayer tails hydr', 'Bilayer heads hydr', 'cw hydration', 'Oxide Hydration'] + cells.f8 = ['Backs parameter 1', 'Backs parameter 2'] + cells.f9 = ['Scalefactor 1', 'Scalefactor 2'] + cells.f10 = ['Qz shift 1'] + cells.f11 = ['Air'] + cells.f12 = ['D2O', 'SMW'] + cells.f13 = ['Resolution par 1'] + # cells.f14 = [['', '', '']] + cells.f15 = ['constant', 'constant'] + cells.f16 = ['constant'] + # cells.f17 = [[], []] + # cells.f18 = [] + # cells.f19 = [] + # cells.f20 = [] + + #------------------------------------------------------------------------------------ + # Priors + priors.param = [['Substrate Roughness', 'uniform', 0, np.Inf], + ['Oxide thick', 'uniform', 0, np.Inf], + ['Oxide SLD', 'uniform', 0, np.Inf], + ['Sam tails thick', 'uniform', 0, np.Inf], + ['Sam tails SLD', 'uniform', 0, np.Inf], + ['Sam tails hydra…', 'uniform', 0, np.Inf], + ['Sam rough', 'uniform', 0, np.Inf], + ['cw thick', 'uniform', 0, np.Inf], + ['cw SLD', 'uniform', 0, np.Inf], + ['SAM head thick', 'uniform', 0, np.Inf], + ['SAM head SLD', 'uniform', 0, np.Inf], + ['SAM head hydrat…', 'uniform', 0, np.Inf], + ['Bilayer head th…', 'uniform', 0, np.Inf], + ['Bilayer head SLD', 'uniform', 0, np.Inf], + ['Bilayer rough', 'uniform', 0, np.Inf], + ['Bilayer tails t…', 'uniform', 0, np.Inf], + ['Bilayer tails SLD', 'uniform', 0, np.Inf], + ['Bilayer tails h…', 'uniform', 0, np.Inf], + ['Bilayer heads h…', 'uniform', 0, np.Inf], + ['cw hydration', 'uniform', 0, np.Inf], + ['Oxide Hydration', 'uniform', 0, np.Inf]] + priors.backgroundParam = [['Backs parameter 1', 'uniform', 0, np.Inf], ['Backs parameter 2', 'uniform', 0, np.Inf]] + priors.scalefactor = [['Scalefactor 1', 'uniform', 0, np.Inf], ['Scalefactor 2', 'uniform', 0, np.Inf]] + priors.qzshift = [['Qz shift 1', 'uniform', 0, np.Inf]] + priors.bulkIn = [['Air', 'uniform', 0, np.Inf]] + priors.bulkOut = [['D2O', 'uniform', 0, np.Inf], ['SMW', 'uniform', 0, np.Inf]] + priors.resolutionParam = [['Resolution par 1', 'uniform', 0, np.Inf]] + priors.priorNames = ['Substrate Roughness', 'Oxide thick', 'Oxide SLD', + 'Sam tails thick', 'Sam tails SLD', 'Sam tails hydration', 'Sam rough', + 'cw thick', 'cw SLD', 'SAM head thick', 'SAM head SLD', 'SAM head hydration', + 'Bilayer head thick', 'Bilayer head SLD', 'Bilayer rough', 'Bilayer tails thick', + 'Bilayer tails SLD', 'Bilayer tails hydr', 'Bilayer heads hydr', 'cw hydration', + 'Oxide Hydration','Backs parameter 1', 'Backs parameter 2', 'Resolution par 1', + 'Air', 'D2O', 'SMW', 'Qz shift 1', 'Scalefactor 1', 'Scalefactor 2'] + priors.priorValues = [[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf], + [1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf], + [1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf], + [1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf], + [1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf], + [1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf]] + + problem, contrast_params, result, bayes_results = rat_core.RATMain(problem, cells, limits, control, priors) + + print(contrast_params.ssubs) + print(contrast_params.backgroundParams) + print(contrast_params.qzshifts) + print(contrast_params.scalefactors) + print(contrast_params.bulkIn) + print(contrast_params.bulkOut) + print(contrast_params.resolutionParams) + print(contrast_params.calculations.allChis) + print(contrast_params.calculations.sumChi) + print(contrast_params.allSubRough) + print(contrast_params.resample) + #print(output) + \ No newline at end of file diff --git a/examples/DSPC_custom_layers_example.py b/examples/DSPC_custom_layers_example.py new file mode 100644 index 00000000..d8190b0d --- /dev/null +++ b/examples/DSPC_custom_layers_example.py @@ -0,0 +1,194 @@ +import faulthandler +import numpy as np +from customBilayer import customBilayer +from rat import events, rat_core +from rat.misc import DylibWrapper, MatlabWrapper + +faulthandler.enable() + + +if __name__ == '__main__': + + control = rat_core.Control() + problem = rat_core.ProblemDefinition() + limits = rat_core.Limits() + cells = rat_core.Cells() + priors = rat_core.Priors() + + #------------------------------------------------------------------------------------ + # Control + control.procedure = 'calculate' + control.parallel = 'single' + control.display = 'iter' + control.calcSldDuringFit = False + control.resamPars = [0.9000, 50] + + control.procedure = 'simplex' + control.tolX = 1e-6 + control.tolFun = 1e-6 + control.maxFunEvals = 10000 + control.maxIter = 1 + control.updateFreq = -1 + control.updatePlotFreq = 1 + + # control.procedure = 'dream' + # control.nSamples = 100 + # control.nChains = 10 + # control.jumpProbability = 0.5 + # control.pUnitGamma = 0.2 + # control.boundHandling = 'fold' + # control.adaptPCR = False; + + # control.procedure = 'de' + # control.populationSize = 10 + # control.fWeight = 0.5 + # control.crossoverProbability = 0.8 + # control.strategy = 4 + # control.targetValue = 1 + # control.numGenerations = 500 + + # control.procedure = 'ns' + # control.Nlive = 150 + # control.Nmcmc = 0 + # control.propScale = 0.1 + # control.nsTolerance = 0.1 + + control.checks.fitParam = [1, 1, 1, 1, 1, 1, 1, 1] + control.checks.fitBackgroundParam = np.ones((3)) + control.checks.fitQzshift = [0] + control.checks.fitScalefactor = [1] + control.checks.fitBulkIn = [0] + control.checks.fitBulkOut = [1, 1, 1] + control.checks.fitResolutionParam = [0] + + #------------------------------------------------------------------------------------ + # ProblemDef + problem.contrastBackgrounds = [1, 2, 3] + problem.contrastBackgroundsType = [1, 1, 1] + problem.TF = 'non polarised' + problem.resample = [0, 0, 0] + problem.dataPresent = [1, 1, 1] + problem.oilChiDataPresent = [0, 0, 0] + problem.numberOfContrasts = 3 + problem.geometry = 'substrate/liquid' + problem.useImaginary = False + problem.contrastQzshifts = [1, 1, 1] + problem.contrastScalefactors = [1, 1, 1] + problem.contrastBulkIns = [1, 1, 1] + problem.contrastBulkOuts = [1, 2, 3] + problem.contrastResolutions = [1, 1, 1] + problem.backgroundParams = [1.0e-07, 1.0e-07, 1.0e-07] + problem.qzshifts = [0] + problem.scalefactors = [1] + problem.bulkIn = [2.073e-06] + problem.bulkOut = [6.35e-06, 2.073e-06, -5.6e-07] + problem.resolutionParams = [0.0300] + problem.params = [3, 20, 0.2, 55, 0.2, 0.1, 4, 2] + problem.numberOfLayers = 0 + problem.modelType = 'custom layers' + problem.contrastCustomFiles = [1, 1, 1] + problem.contrastDomainRatios = [0, 0, 0] + problem.domainRatio = [] + problem.numberOfDomainContrasts = 0 + problem.fitParams = [3, 20, 0.2, 55, 0.2, 0.1, 4, 2, 1.0e-07, 1.0e-07, 1.0e-07, 1, 6.35e-06, 2.073e-06, -5.6e-07] + problem.otherParams = [0, 2.073e-06, 0.03] + problem.fitLimits = [[1, 10], [5, 60], [0, 0.5], [45, 65], [0, 0.5], [0, 0.2], [2, 8], [0, 10], + [1.0e-10, 1.0e-05], [1.0e-10, 1.0e-05], [1.0e-10, 1.0e-05], [0.5, 2], [5.0e-06, 6.35e-06], + [1.0e-06, 3.0e-06], [-6.0e-07, -3.0e-07]] + problem.otherLimits = [[-0.0001, 0.0001], [2.07e-06, 2.08e-06], [0.01, 0.05]] + + #------------------------------------------------------------------------------------ + # Limits + limits.param = [[1, 10], [5, 60], [0, 0.5], [45, 65], + [0, 0.5], [0, 0.2], [2, 8], [0, 10]] + limits.backgroundParam = [[1.0000e-10, 1.0000e-05], [1.0000e-10, 1.0000e-05], [1.0000e-10, 1.0000e-05]] + limits.scalefactor = [[0.500, 2]] + limits.qzshift = [[-0.0001, 0.0001]] + limits.bulkIn = [[2.070e-06, 2.080e-06]] + limits.bulkOut = [[5.0000e-06, 6.3500e-06], [1.0000e-06, 3.0000e-06], [-6.0000e-07, -3.0000e-07]] + limits.resolutionParam = [[0.0100, 0.0500]] + limits.domainRatio = [] + + #------------------------------------------------------------------------------------- + # Cells + cells.f1 = [[0, 1], [0, 1], [0, 1]] + cells.f2 = [np.loadtxt('data/dspc_custom/data1.csv', delimiter=','), + np.loadtxt('data/dspc_custom/data2.csv', delimiter=','), + np.loadtxt('data/dspc_custom/data3.csv', delimiter=',')] + cells.f3 = [[0.0130, 0.370], [0.0130, 0.370], [0.0130, 0.370]] + cells.f4 = [[0.00571180, 0.396060], [0.00760290, 0.329960], [0.00633740, 0.330480]] + cells.f5 = [[0, 0, 0]] + cells.f6 = [[0]] + cells.f7 = ['Substrate Roughness', 'Oxide thick', 'Oxide Hydration', 'Lipid APM', + 'Head Hydration', 'Bilayer Hydration', 'Bilayer Roughness', 'Water Thickness'] + cells.f8 = ['Backs par D2O', 'Backs par SMW', 'Backs par H2O'] + cells.f9 = ['Scalefactor 1'] + cells.f10 = ['Qz shift 1'] + cells.f11 = ['Silicon'] + cells.f12 = ['SLD D2O', 'SLD SMW', 'SLD H2O'] + cells.f13 = ['Resolution par 1'] + + # dylib_wrapper = DylibWrapper('examples/customBilayer.dll', 'customBilayer') + # cells.f14 = [dylib_wrapper.getHandle()] # C++ callback + + # matlab_wrapper = MatlabWrapper('examples/customBilayer.m') + # cells.f14 = [matlab_wrapper.getHandle()] # Matlab callback + + cells.f14 = [customBilayer] # Python callback + + cells.f15 = ['constant', 'constant', 'constant'] + cells.f16 = ['constant'] + cells.f17 = [[], [], []] + cells.f18 = [] + cells.f19 = [] + cells.f20 = [] + + #------------------------------------------------------------------------------------ + # Priors + priors.param = [['Substrate Roughness', 'uniform', 0, np.Inf], + ['Oxide thick', 'uniform', 0, np.Inf], + ['Oxide Hydration', 'uniform', 0, np.Inf], + ['Lipid APM', 'uniform', 0, np.Inf], + ['Head Hydration', 'uniform', 0, np.Inf], + ['Bilayer Hydration', 'uniform', 0, np.Inf], + ['Bilayer Roughness', 'uniform', 0, np.Inf], + ['Water Thickness', 'uniform', 0, np.Inf]] + priors.backgroundParam = [['Backs par D2O', 'uniform', 0, np.Inf], ['Backs par SMW', 'uniform', 0, np.Inf], ['Backs par H20', 'uniform', 0, np.Inf]] + priors.scalefactor = [['Scalefactor 1', 'uniform', 0, np.Inf]] + priors.qzshift = [['Qz shift 1', 'uniform', 0, np.Inf]] + priors.bulkIn = [['Silicon', 'uniform', 0, np.Inf]] + priors.bulkOut = [['SLD D2O', 'uniform', 0, np.Inf], ['SLD SMW', 'uniform', 0, np.Inf], ['SLD H20', 'uniform', 0, np.Inf]] + priors.resolutionParam = [['Resolution par 1', 'uniform', 0, np.Inf]] + priors.priorNames = ['Substrate Roughness', 'Oxide thick', 'Oxide Hydration', + 'Lipid APM', 'Head Hydration', 'Bilayer Hydration', + 'Bilayer Roughness', 'Water Thickness', 'Backs par D2O', 'Backs par SMW', + 'Backs par H2O', 'Resolution par 1', 'Silicon', 'SLD D2O', 'SLD SMW', + 'SLD H2O', 'Qz shift 1','Scalefactor 1'] + priors.priorValues = [[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf], + [1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf], + [1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf], + [1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf]] + + + def fakePlot(event): + print('Hello plotting') + + import time + start = time.perf_counter() + events.register(events.EventTypes.Plot, fakePlot) + problem, contrast_params, result, bayes_results = rat_core.RATMain(problem, cells, limits, control, priors) + events.clear() + print(time.perf_counter() - start, 'sec') + # print(contrast_params.ssubs) + # print(contrast_params.backgroundParams) + # print(contrast_params.qzshifts) + # print(contrast_params.scalefactors) + # print(contrast_params.bulkIn) + # print(contrast_params.bulkOut) + # print(contrast_params.resolutionParams) + print(contrast_params.calculations.allChis) + print(contrast_params.calculations.sumChi) + # print(contrast_params.allSubRough) + # print(contrast_params.resample) + #print(output) + diff --git a/examples/alloyDomains.cpp b/examples/alloyDomains.cpp new file mode 100644 index 00000000..564cae4e --- /dev/null +++ b/examples/alloyDomains.cpp @@ -0,0 +1,48 @@ +//alloyDomains.cpp + +#include + +#if defined(_WIN32) || defined(_WIN64) +#define LIB_EXPORT __declspec(dllexport) +#else +#define LIB_EXPORT +#endif + +// We user extern "C" decorator to avoid name mangling.... +extern "C" { + + LIB_EXPORT void alloyDomains(std::vector& params, std::vector& bulkIn, std::vector& bulkOut, int contrast, int domain, std::vector& output, double* outputSize, double* rough) + { + double subRough = params[0]; + double alloyThick = params[1]; + double alloySLDup = params[2]; + double alloySLDdn = params[3]; + double alloyRough = params[4]; + double goldThick = params[5]; + double goldSLD = params[6]; + double goldRough = params[7]; + + // Make the layers + if (domain == 0) { + // alloyUp + output.push_back(alloyThick); + output.push_back(alloySLDup); + output.push_back(alloyRough); + + }else { + // alloyDn + output.push_back(alloyThick); + output.push_back(alloySLDdn); + output.push_back(alloyRough); + } + // Gold + output.push_back(goldThick); + output.push_back(goldSLD); + output.push_back(goldRough); + + *rough = subRough; + + outputSize[0] = 2; // row - Necessary to ouptut how many layers in stack + outputSize[1] = 3; // col - Should be different depending on calculation + } +} // extern "C" \ No newline at end of file diff --git a/examples/alloyDomains.m b/examples/alloyDomains.m new file mode 100644 index 00000000..585eb0db --- /dev/null +++ b/examples/alloyDomains.m @@ -0,0 +1,29 @@ + +function [output,subRough] = alloyDomains(params,bulkIn,bulkOut,contrast,domain) + +% Simple custom model for testing incoherent summing... +% Simple two layer of permalloy / gold, with up/down domains.. + +% Split up the parameters.... +subRough = params(1); +alloyThick = params(2); +alloySLDup = params(3); +alloySLDdn = params(4); +alloyRough = params(5); +goldThick = params(6); +goldSLD = params(7); +goldRough = params(8); + +% Make the layers.... +alloyUp = [alloyThick, alloySLDup, alloyRough]; +alloyDn = [alloyThick, alloySLDdn, alloyRough]; +gold = [goldThick, goldSLD, goldRough]; + +% Make the model dependiong on which domain we are looking at.. +if domain==1 + output = [alloyUp ; gold]; +else + output = [alloyDn ; gold]; +end + +end \ No newline at end of file diff --git a/examples/alloyDomains.py b/examples/alloyDomains.py new file mode 100644 index 00000000..7cbe771a --- /dev/null +++ b/examples/alloyDomains.py @@ -0,0 +1,29 @@ +# alloyDomains.py +import numpy as np + +def alloyDomains(params, bulk_in, bulk_out, contrast, domain): + # Simple custom model for testing incoherent summing... + # Simple two layer of permalloy / gold, with up/down domains.. + + # Split up the parameters.... + subRough = params[0] + alloyThick = params[1] + alloySLDup = params[2] + alloySLDdn = params[3] + alloyRough = params[4] + goldThick = params[5] + goldSLD = params[6] + goldRough = params[7] + + # Make the layers.... + alloyUp = [alloyThick, alloySLDup, alloyRough] + alloyDn = [alloyThick, alloySLDdn, alloyRough] + gold = [goldThick, goldSLD, goldRough] + + # Make the model dependiong on which domain we are looking at.. + if domain == 0: + output = [alloyUp, gold] + else: + output = [alloyDn, gold] + + return output, subRough diff --git a/ratapi/examples/languages/custom_bilayer.m b/examples/customBilayer.m similarity index 83% rename from ratapi/examples/languages/custom_bilayer.m rename to examples/customBilayer.m index 7143228f..eea1ee6e 100644 --- a/ratapi/examples/languages/custom_bilayer.m +++ b/examples/customBilayer.m @@ -1,5 +1,5 @@ %customBilayer.m -function [output,sub_rough] = custom_bilayer(params,bulk_in,bulk_out,contrast) +function [output, sub_rough] = customBilayer(params,bulk_in,bulk_out,contrast) sub_rough = params(1); oxide_thick = params(2); @@ -9,15 +9,14 @@ bilayerHydration = params(6); bilayerRough = params(7); waterThick = params(8); - - + % We have a constant SLD for the bilayer oxide_SLD = 3.41e-6; - - % Now make the lipid layers + + % Now make the lipid layers.. % Use known lipid volume and compositions % to make the layers - + % define all the neutron b's. bc = 0.6646e-4; %Carbon bo = 0.5843e-4; %Oxygen @@ -25,43 +24,43 @@ bp = 0.513e-4; %Phosphorus bn = 0.936e-4; %Nitrogen bd = 0.6671e-4; %Deuterium - - % Now make the lipid groups + + % Now make the lipid groups.. COO = (4*bo) + (2*bc); GLYC = (3*bc) + (5*bh); CH3 = (2*bc) + (6*bh); PO4 = (1*bp) + (4*bo); CH2 = (1*bc) + (2*bh); CHOL = (5*bc) + (12*bh) + (1*bn); - + % Group these into heads and tails: Head = CHOL + PO4 + GLYC + COO; Tails = (34*CH2) + (2*CH3); - + % We need volumes for each. % Use literature values: vHead = 319; vTail = 782; - - % we use the volumes to calculate the SLDs + + % we use the volumes to calculate the SLD's SLDhead = Head / vHead; SLDtail = Tails / vTail; - - % We calculate the layer thickness from + + % We calculate the layer thickness' from % the volumes and the APM... headThick = vHead / lipidAPM; tailThick = vTail / lipidAPM; - - % Manually deal with hydration for layers in this example. + + % Manually deal with hydration for layers in + % this example. oxSLD = (oxide_hydration * bulk_out(contrast)) + ((1 - oxide_hydration) * oxide_SLD); headSLD = (headHydration * bulk_out(contrast)) + ((1 - headHydration) * SLDhead); tailSLD = (bilayerHydration * bulk_out(contrast)) + ((1 - bilayerHydration) * SLDtail); - + % Make the layers oxide = [oxide_thick oxSLD sub_rough]; water = [waterThick bulk_out(contrast) bilayerRough]; head = [headThick headSLD bilayerRough]; tail = [tailThick tailSLD bilayerRough]; - + output = [oxide ; water ; head ; tail ; tail ; head]; -end \ No newline at end of file diff --git a/examples/customBilayer.py b/examples/customBilayer.py new file mode 100644 index 00000000..86a1f378 --- /dev/null +++ b/examples/customBilayer.py @@ -0,0 +1,73 @@ +# customBilayer.py +import numpy as np + +def customBilayer(params, bulk_in, bulk_out, contrast): + params = np.array(params) + bulk_in = np.array(bulk_in) + bulk_out = np.array(bulk_out) + + sub_rough = params[0] + oxide_thick = params[1] + oxide_hydration = params[2] + lipidAPM = params[3] + headHydration = params[4] + bilayerHydration = params[5] + bilayerRough = params[6] + waterThick = params[7] + + # We have a constant SLD for the bilayer + oxide_SLD = 3.41e-6 + + # Now make the lipid layers.. + # Use known lipid volume and compositions + # to make the layers + + # define all the neutron b's. + bc = 0.6646e-4 # Carbon + bo = 0.5843e-4 # Oxygen + bh = -0.3739e-4 # Hydrogen + bp = 0.513e-4 # Phosphorus + bn = 0.936e-4 # Nitrogen + bd = 0.6671e-4 # Deuterium + + # Now make the lipid groups.. + COO = (4*bo) + (2*bc) + GLYC = (3*bc) + (5*bh) + CH3 = (2*bc) + (6*bh) + PO4 = (1*bp) + (4*bo) + CH2 = (1*bc) + (2*bh) + CHOL = (5*bc) + (12*bh) + (1*bn) + + # Group these into heads and tails: + Head = CHOL + PO4 + GLYC + COO + Tails = (34*CH2) + (2*CH3) + + # We need volumes for each. + # Use literature values: + vHead = 319 + vTail = 782 + + # we use the volumes to calculate the SLD's + SLDhead = Head / vHead + SLDtail = Tails / vTail + + # We calculate the layer thickness' from + # the volumes and the APM... + headThick = vHead / lipidAPM + tailThick = vTail / lipidAPM + + # Manually deal with hydration for layers in + # this example. + oxSLD = (oxide_hydration * bulk_out[contrast]) + ((1 - oxide_hydration) * oxide_SLD) + headSLD = (headHydration * bulk_out[contrast]) + ((1 - headHydration) * SLDhead) + tailSLD = (bilayerHydration * bulk_out[contrast]) + ((1 - bilayerHydration) * SLDtail) + + # Make the layers + oxide = [oxide_thick, oxSLD, sub_rough] + water = [waterThick, bulk_out[contrast], bilayerRough] + head = [headThick, headSLD, bilayerRough] + tail = [tailThick, tailSLD, bilayerRough] + + output = np.array([oxide, water, head, tail, tail, head]) + + return output, sub_rough diff --git a/examples/domains_custom_layers_example.py b/examples/domains_custom_layers_example.py new file mode 100644 index 00000000..2981ed8f --- /dev/null +++ b/examples/domains_custom_layers_example.py @@ -0,0 +1,185 @@ +import faulthandler +import numpy as np +from alloyDomains import alloyDomains +from rat import events, rat_core +from rat.misc import DylibWrapper, MatlabWrapper + +faulthandler.enable() + + +if __name__ == '__main__': + + control = rat_core.Control() + problem = rat_core.ProblemDefinition() + limits = rat_core.Limits() + cells = rat_core.Cells() + priors = rat_core.Priors() + + #------------------------------------------------------------------------------------ + # Control + control.procedure = 'calculate' + control.parallel = 'single' + control.display = 'iter' + control.calcSldDuringFit = False + control.resamPars = [0.9000, 50] + + # control.procedure = 'simplex' + # control.tolX = 1e-6 + # control.tolFun = 1e-6 + # control.maxFunEvals = 10000 + # control.maxIter = 1 + # control.updateFreq = -1 + # control.updatePlotFreq = 1 + + # control.procedure = 'dream' + # control.nSamples = 100 + # control.nChains = 10 + # control.jumpProbability = 0.5 + # control.pUnitGamma = 0.2 + # control.boundHandling = 'fold' + # control.adaptPCR = False; + + # control.procedure = 'de' + # control.populationSize = 10 + # control.fWeight = 0.5 + # control.crossoverProbability = 0.8 + # control.strategy = 4 + # control.targetValue = 1 + # control.numGenerations = 500 + + # control.procedure = 'ns' + # control.Nlive = 150 + # control.Nmcmc = 0 + # control.propScale = 0.1 + # control.nsTolerance = 0.1 + + control.checks.fitParam = [1, 1, 1, 1, 1, 1, 1, 1] + control.checks.fitBackgroundParam = [0] + control.checks.fitQzshift = [0] + control.checks.fitScalefactor = [0] + control.checks.fitBulkIn = [0] + control.checks.fitBulkOut = [0] + control.checks.fitResolutionParam = [0] + + #------------------------------------------------------------------------------------ + # ProblemDef + problem.contrastBackgrounds = [1] + problem.contrastBackgroundsType = [1] + problem.TF = 'domains' + problem.resample = [0] + problem.dataPresent = [0] + problem.oilChiDataPresent = [0] + problem.numberOfContrasts = 1 + problem.geometry = 'substrate/liquid' + problem.useImaginary = False + problem.contrastQzshifts = [1] + problem.contrastScalefactors = [1] + problem.contrastBulkIns = [1] + problem.contrastBulkOuts = [1] + problem.contrastResolutions = [1] + problem.backgroundParams = [1.0e-06] + problem.qzshifts = [0] + problem.scalefactors = [0.23] + problem.bulkIn = [2.073e-06] + problem.bulkOut = [6.35e-06] + problem.resolutionParams = [0.0300] + problem.params = [3, 150, 1.1e-05, 7e-06, 7, 150, 4.5e-06, 7] + problem.numberOfLayers = 0 + problem.modelType = 'custom layers' + problem.contrastCustomFiles = [1] + problem.contrastDomainRatios = [1] + problem.domainRatio = [0.5] + problem.numberOfDomainContrasts = 0 + problem.fitParams = [3, 150, 1.1e-05, 7.0e-06, 7, 150, 4.5e-06, 7] + problem.otherParams = [1.0e-06, 0.23, 0, 2.073e-06, 6.35e-06, 0.03, 0.5] + problem.fitLimits = [[1, 5], [100, 200], [9.0e-06, 1.3e-05], [5.0e-06, 1.0e-05], [5, 11], [100, 200], [4.0e-06, 5.0e-06], [5, 11]] + problem.otherLimits = [[1.0e-07, 1.0e-05], [0.02, 0.25], [-0.0001, 0.0001], [0, 0], [6.2e-06, 6.35e-06], [0.01, 0.05], [0.4, 0.6]] + + #------------------------------------------------------------------------------------ + # Limits + limits.param = [[1, 5], [100, 200], [9e-06, 1.3e-05], [5e-06, 1e-05], + [5, 11], [100, 200], [4e-06, 5e-06], [5, 11]] + limits.backgroundParam = [[1.0000e-07, 1.0000e-05]] + limits.scalefactor = [[0.02, 0.25]] + limits.qzshift = [[-0.0001, 0.0001]] + limits.bulkIn = [[0, 0]] + limits.bulkOut = [[6.2000e-06, 6.3500e-06]] + limits.resolutionParam = [[0.01, 0.05]] + limits.domainRatio = [[0.4, 0.6]] + + #------------------------------------------------------------------------------------- + # Cells + cells.f1 = [[0, 1]] + cells.f2 = [[]] + cells.f3 = [[0, 0]] + cells.f4 = [[0.005, 0.7]] + cells.f5 = [[0]] + cells.f6 = [[0]] + cells.f7 = ['Substrate Roughness', 'Alloy thick', 'Alloy SLD up', 'Alloy SLD dn', + 'Alloy rough', 'Gold thick', 'Gold SLD', 'Gold Rough'] + cells.f8 = ['Background Param 1'] + cells.f9 = ['Scalefactor 1'] + cells.f10 = ['Qz shift 1'] + cells.f11 = ['Silicon'] + cells.f12 = ['SLD D2O'] + cells.f13 = ['Resolution par 1'] + + # dylib_wrapper = DylibWrapper('examples/alloyDomains.dll', 'alloyDomains') + # cells.f14 = [dylib_wrapper.getHandle()] # C++ callback + + # matlab_wrapper = MatlabWrapper('examples/alloyDomains.m') + # cells.f14 = [matlab_wrapper.getHandle()] # Matlab callback + + cells.f14 = [alloyDomains] # Python callback + + cells.f15 = ['constant'] + cells.f16 = ['constant'] + cells.f17 = [[]] + cells.f18 = [] + cells.f19 = [] + cells.f20 = ['Domain Ratio 1'] + + #------------------------------------------------------------------------------------ + # Priors + priors.param = [['Substrate Roughness', 'uniform', 0, np.Inf], + ['Alloy thick', 'uniform', 0, np.Inf], + ['Alloy SLD up', 'uniform', 0, np.Inf], + ['Alloy SLD dn', 'uniform', 0, np.Inf], + ['Alloy rough', 'uniform', 0, np.Inf], + ['Gold thick', 'uniform', 0, np.Inf], + ['Gold SLD', 'uniform', 0, np.Inf], + ['Gold Rough', 'uniform', 0, np.Inf]] + priors.backgroundParam = [['Background Param 1', 'uniform', 0, np.Inf], ['Backs par SMW', 'uniform', 0, np.Inf], ['Backs par H20', 'uniform', 0, np.Inf]] + priors.scalefactor = [['Scalefactor 1', 'uniform', 0, np.Inf]] + priors.qzshift = [['Qz shift 1', 'uniform', 0, np.Inf]] + priors.bulkIn = [['Silicon', 'uniform', 0, np.Inf]] + priors.bulkOut = [['SLD D2O', 'uniform', 0, np.Inf]] + priors.domainRatio = [['Domain Ratio 1', 'uniform', 0, np.Inf]] + priors.resolutionParam = [['Resolution par 1', 'uniform', 0, np.Inf]] + priors.priorNames = ['Substrate Roughness', 'Alloy thick', 'Alloy SLD up', + 'Alloy SLD dn', 'Alloy rough', 'Gold thick', + 'Gold SLD', 'Gold Rough', 'Background Param 1', + 'Resolution par 1', 'Silicon', 'SLD D2O', 'Qz shift 1', + 'Scalefactor 1', 'Domain Ratio 1'] + priors.priorValues = [[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf], + [1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf], + [1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf],[1, 0, np.Inf]] + + + import time + start = time.perf_counter() + problem, contrast_params, result, bayes_results = rat_core.RATMain(problem, cells, limits, control, priors) + print(time.perf_counter() - start, 'sec') + # print(contrast_params.ssubs) + # print(contrast_params.backgroundParams) + # print(contrast_params.qzshifts) + # print(contrast_params.scalefactors) + # print(contrast_params.bulkIn) + # print(contrast_params.bulkOut) + # print(contrast_params.resolutionParams) + print(contrast_params.calculations.allChis) + print(contrast_params.calculations.sumChi) + # print(contrast_params.allSubRough) + # print(contrast_params.resample) + #print(output) + diff --git a/pyproject.toml b/pyproject.toml index ab6724ae..515031d0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,94 +1,16 @@ [build-system] requires = [ - 'setuptools>=61', - 'wheel', - 'pybind11>=2.4, <=2.13.6', + "setuptools>=42", + "wheel", + "pybind11>=2.4", ] -build-backend = 'setuptools.build_meta' -[project] -name = "ratapi" -version = "0.0.0.dev14" -description = "Python extension for the Reflectivity Analysis Toolbox (RAT)" -readme = "README.md" -requires-python = ">=3.10" -dependencies = [ - "matplotlib>=3.8.3", - "numpy>=1.20", - "prettytable>=3.9.0", - "pydantic>=2.7.2", - "scipy>=1.13.1", - "strenum>=0.4.15 ; python_full_version < '3.11'", - "tqdm>=4.66.5", -] - -[project.urls] -Documentation = "https://rascalsoftware.github.io/RAT/" -Repository = "https://github.com/RascalSoftware/python-RAT" - -[project.optional-dependencies] -dev = [ - "pytest>=7.4.0", - "pytest-cov>=4.1.0", - "ruff>=0.4.10" -] -orso = [ - "orsopy>=1.2.1", - "pint>=0.24.4" -] -matlab_latest = ["matlabengine"] -matlab_2025b = ["matlabengine == 25.2.*"] -matlab_2025a = ["matlabengine == 25.1.2"] -matlab_2024b = ["matlabengine == 24.2.2"] -matlab_2024a = ["matlabengine == 24.1.4"] -matlab_2023b = ["matlabengine == 23.2.3"] -matlab_2023a = ["matlabengine == 9.14.3"] - -[tool.uv] -conflicts = [ - [ - { extra = "matlab_latest" }, - { extra = "matlab_2025b" }, - { extra = "matlab_2025a" }, - { extra = "matlab_2024b" }, - { extra = "matlab_2024a" }, - { extra = "matlab_2023b" }, - { extra = "matlab_2023a" }, - ], -] - -[tool.ruff] -line-length = 120 -extend-exclude = ["*.ipynb"] - -[tool.ruff.lint] -select = ["E", # pycodestyle errors - "F", # pyflakes - "UP", # pyupgrade - "B", # flake8-bugbear - "SIM", # flake8-simplify - "I", # isort - "D"] # pydocstyle - -ignore = ["SIM103", # needless bool - "SIM108", # if-else block instead of ternary operator - "D105", # undocumented __init__ - "D107", # undocumented magic method - "D203", # blank line before class docstring - "D213", # multi line summary should start at second line - "UP038"] # non pep604 isinstance - to be removed - -# ignore docstring lints in the tests and install script -[tool.ruff.lint.per-file-ignores] -"tests/*" = ["D"] -"setup.py" = ["D"] - -[tool.ruff.lint.flake8-pytest-style] -fixture-parentheses = false -mark-parentheses = false - -[tool.ruff.lint.pydocstyle] -convention = "numpy" +[optional-dependencies] +Matlab-2023b = ["matlabengine==23.2.1"] +Matlab-2023a = ["matlabengine==9.14.3"] +Matlab-2022b = ["matlabengine==9.13.9"] +Matlab-2022a = ["matlabengine==9.12.19"] +Matlab-2021b = ["matlabengine==9.11.21"] +Matlab-2021a = ["matlabengine==9.10.3"] -[tool.ruff.lint.isort] -known-first-party = ["ratapi.rat_core"] +build-backend = "setuptools.build_meta" diff --git a/rat/__init__.py b/rat/__init__.py new file mode 100644 index 00000000..bd3e549b --- /dev/null +++ b/rat/__init__.py @@ -0,0 +1,4 @@ +import os + +dir_path = os.path.dirname(os.path.realpath(__file__)) +os.environ["RAT_PATH"] = os.path.join(dir_path, '') diff --git a/rat/events.py b/rat/events.py new file mode 100644 index 00000000..1dad21fe --- /dev/null +++ b/rat/events.py @@ -0,0 +1,63 @@ +from typing import Callable, Union, List +from rat import rat_core +from rat.rat_core import EventTypes, PlotEventData + + +def notify(event_type: EventTypes, data: Union[str, PlotEventData]) -> None: + """Calls registered callbacks with the data when event type has + been triggered. + + Parameters + ---------- + event_type : EventTypes + The event type that was triggered. + data : str or PlotEventData + The data sent by th event. The message event data is a string. + """ + callbacks = __event_callbacks[event_type] + for callback in callbacks: + callback(data) + +def get_event_callback(event_type: EventTypes) -> List[Callable[[Union[str, PlotEventData]], None]]: + """Returns all callbacks registered for the given event type. + + Parameters + ---------- + event_type : EventTypes + The event type. + + Retuns + ------ + callback : Callable[[Union[str, PlotEventData]], None] + The callback for the event type. + """ + return list(__event_callbacks[event_type]) + + +def register(event_type: EventTypes, callback: Callable[[Union[str, PlotEventData]], None]) -> None: + """Registers a new callback for the event type. + + Parameters + ---------- + event_type : EventTypes + The event type to register. + callback : Callable[[Union[str, PlotEventData]], None] + The callback for when the event is triggered. + """ + if not isinstance(event_type, EventTypes): + raise ValueError("event_type must be a events.EventTypes enum") + + if len(__event_callbacks[event_type]) == 0: + __event_impl.register(event_type) + __event_callbacks[event_type].add(callback) + + +def clear() -> None: + """Clears all event callbacks.""" + __event_impl.clear() + for key in __event_callbacks.keys(): + __event_callbacks[key] = set() + + +__event_impl = rat_core.EventBridge(notify) +__event_callbacks = {EventTypes.Message: set(), EventTypes.Plot: set()} diff --git a/rat/misc.py b/rat/misc.py new file mode 100644 index 00000000..2c86cd1a --- /dev/null +++ b/rat/misc.py @@ -0,0 +1,85 @@ +import pathlib +from typing import Callable, Tuple +import numpy as np +from numpy.typing import ArrayLike +from rat import rat_core + + +class MatlabWrapper: + """Creates a python callback for a MATLAB function. + + Parameters + ---------- + filename : string + The path of the file containing MATLAB function + """ + def __init__(self, filename: str) -> None : + self.engine = None + try: + import matlab.engine + except ImportError: + raise ImportError('matlabengine is required to use MatlabWrapper') + self.engine = matlab.engine.start_matlab() + path = pathlib.Path(filename) + self.engine.cd(str(path.parent), nargout=0) + self.function_name = path.stem + + def __del__(self): + if self.engine is not None: + self.engine.quit() + + def getHandle(self)\ + -> Callable[[ArrayLike, ArrayLike, ArrayLike, int, int], Tuple[ArrayLike, float]]: + """Returns a wrapper for the custom MATLAB function + + Returns + ------- + wrapper : Callable[[ArrayLike, ArrayLike, ArrayLike, int, int], Tuple[ArrayLike, float]] + The wrapper function for the MATLAB callback + """ + def handle(params, bulk_in, bulk_out, contrast, domain=-1): + if domain == -1: + output, sub_rough = getattr(self.engine, self.function_name)(np.array(params, 'float'), + np.array(bulk_in, 'float'), + np.array(bulk_out, 'float'), + float(contrast + 1), nargout=2) + else: + output, sub_rough = getattr(self.engine, self.function_name)(np.array(params, 'float'), + np.array(bulk_in, 'float'), + np.array(bulk_out, 'float'), + float(contrast + 1), float(domain + 1), nargout=2) + return output, sub_rough + return handle + + +class DylibWrapper: + """Creates a python callback for a function in dynamic library. + + Parameters + ---------- + filename : str + The path of the dyanamic library + function_name : str + The name of the function to call + """ + def __init__(self, filename, function_name) -> None: + self.engine = rat_core.DylibEngine(filename, function_name) + + def getHandle(self)\ + -> Callable[[ArrayLike, ArrayLike, ArrayLike, int, int], Tuple[ArrayLike, float]]: + + """Returns a wrapper for the custom dynamic library function + + Returns + ------- + wrapper : Callable[[ArrayLike, ArrayLike, ArrayLike, int, int], Tuple[ArrayLike, float]] + The wrapper function for the dynamic library callback + """ + def handle(params, bulk_in, bulk_out, contrast, domain=-1): + if domain == -1: + output, sub_rough = self.engine.invoke(params, bulk_in, bulk_out, contrast) + else: + output, sub_rough = self.engine.invoke(params, bulk_in, bulk_out, contrast, domain) + return output, sub_rough + return handle + \ No newline at end of file diff --git a/ratapi/__init__.py b/ratapi/__init__.py deleted file mode 100644 index 98683c7e..00000000 --- a/ratapi/__init__.py +++ /dev/null @@ -1,29 +0,0 @@ -"""ratapi is a Python package for modelling, fitting and optimising reflectivity problems.""" - -from contextlib import suppress - -import ratapi.examples as examples -from ratapi import events, models -from ratapi.classlist import ClassList -from ratapi.controls import Controls -from ratapi.outputs import BayesResults, Results -from ratapi.project import Project -from ratapi.run import run -from ratapi.utils import convert, plotting - -with suppress(ImportError): # orsopy is an optional dependency - from ratapi.utils import orso as orso - -__all__ = [ - "examples", - "models", - "events", - "ClassList", - "Controls", - "BayesResults", - "Results", - "Project", - "run", - "plotting", - "convert", -] diff --git a/ratapi/classlist.py b/ratapi/classlist.py deleted file mode 100644 index 29637a5f..00000000 --- a/ratapi/classlist.py +++ /dev/null @@ -1,620 +0,0 @@ -"""The ClassList class, which defines a list containing instances of a particular class.""" - -import collections -import contextlib -import importlib -import warnings -from collections.abc import Sequence -from typing import Any, Generic, TypeVar - -import numpy as np -import prettytable - -T = TypeVar("T") - - -class ClassList(collections.UserList, Generic[T]): - """List of instances of a particular class. - - This class subclasses collections.UserList to construct a list intended to store ONLY instances of a particular - class, given on initialisation. Any attempt to introduce an object of a different type will raise a ValueError. - The class must be able to accept attribute values using keyword arguments. In addition, if the class has the - attribute given in the ClassList's "name_field" attribute (the default is "name"), the ClassList will ensure that - all objects within the ClassList have unique values for that attribute. It is then possible to use this attribute - of an object in the .remove(), .count(), and .index() routines in place of the full object. Due to the requirement - of unique values of the ``name_field`` attribute, the multiplication operators __mul__, __rmul__, and __imul__ have - been disabled, since they cannot allow for unique attribute values by definition. - - We extend the UserList class to enable objects to be added and modified using just the keyword arguments, enable - the object ``name_field`` attribute to be used in place of the full object, and ensure all elements are of the - specified type, with unique ``name_field`` attributes defined. - - Parameters - ---------- - init_list : Sequence [T] or T, optional - An instance, or list of instance(s), of the class to be used in this ClassList. - name_field : str, optional - The field used to define unique objects in the ClassList (default is "name"). - - """ - - def __init__(self, init_list: Sequence[T] | T = None, name_field: str = "name") -> None: - self.name_field = name_field - - # Set input as list if necessary - if init_list and not (isinstance(init_list, Sequence) and not isinstance(init_list, str)): - init_list = [init_list] - - # Set class to be used for this instance of the ClassList, checking that all elements of the input list are of - # the same type and have unique values of the specified name_field - if init_list: - self._class_handle = self._determine_class_handle(init_list) - self._check_classes(init_list) - self._check_unique_name_fields(init_list) - - super().__init__(init_list) - - def __str__(self): - # `display_fields` gives more control over the items displayed from the list if available - if not self.data: - return str([]) - try: - model_display_fields = [model.display_fields for model in self.data] - # get all items included in at least one list - # the list comprehension ensures they are in the order that they're in in the model - required_fields = list(set().union(*model_display_fields)) - table_fields = ["index"] + [i for i in list(self.data[0].__dict__) if i in required_fields] - except AttributeError: - try: - model_display_fields = [model.__dict__ for model in self.data] - table_fields = ["index"] + list(self.data[0].__dict__) - except AttributeError: - return str(self.data) - - if any(model_display_fields): - table = prettytable.PrettyTable() - table.field_names = [field.replace("_", " ") for field in table_fields] - rows = [] - for index, model in enumerate(self.data): - row = [index] - for field in table_fields[1:]: - value = getattr(model, field, "") - if isinstance(value, np.ndarray): - value = ( - f"{'Data array: [' + ' x '.join(str(i) for i in value.shape) if value.size > 0 else '['}]" - ) - elif field == "model": - value = "\n".join(str(element) for element in value) - else: - value = str(value) - row.append(value) - rows.append(row) - table.add_rows(rows) - output = table.get_string() - else: - if any(model.__dict__ for model in self.data): - table = prettytable.PrettyTable() - table.field_names = ["index"] + [key.replace("_", " ") for key in self.data[0].__dict__] - table.add_rows( - [ - [index] - + list( - f"{'Data array: [' + ' x '.join(str(i) for i in v.shape) if v.size > 0 else '['}]" - if isinstance(v, np.ndarray) - else "\n".join(element for element in v) - if k == "model" - else str(v) - for k, v in model.__dict__.items() - ) - for index, model in enumerate(self.data) - ] - ) - output = table.get_string() - else: - output = str(self.data) - return output - - def __getitem__(self, index: int | slice | str | T) -> T: - """Get an item by its index, name, a slice, or the object itself.""" - if isinstance(index, (int, slice)): - return self.data[index] - elif isinstance(index, (str, self._class_handle)): - return self.data[self.index(index)] - else: - raise IndexError("ClassLists can only be indexed by integers, slices, name strings, or objects.") - - def __setitem__(self, index: int, item: T) -> None: - """Replace the object at an existing index of the ClassList.""" - self._setitem(index, item) - - def _setitem(self, index: int, item: T) -> None: - """Auxiliary routine of "__setitem__" used to enable wrapping.""" - self._check_classes([item]) - self._check_unique_name_fields([item]) - self.data[index] = item - - def __delitem__(self, index: int) -> None: - """Delete an object from the list by index.""" - self._delitem(index) - - def _delitem(self, index: int) -> None: - """Auxiliary routine of "__delitem__" used to enable wrapping.""" - del self.data[index] - - def __iadd__(self, other: Sequence[T]) -> "ClassList": - """Define in-place addition using the "+=" operator.""" - return self._iadd(other) - - def _iadd(self, other: Sequence[T]) -> "ClassList": - """Auxiliary routine of "__iadd__" used to enable wrapping.""" - if other and not (isinstance(other, Sequence) and not isinstance(other, str)): - other = [other] - if not hasattr(self, "_class_handle"): - self._class_handle = self._determine_class_handle(self + other) - self._check_classes(other) - self._check_unique_name_fields(other) - super().__iadd__(other) - return self - - def __mul__(self, n: int) -> None: - """Define multiplication using the "*" operator.""" - raise TypeError(f"unsupported operand type(s) for *: '{self.__class__.__name__}' and '{n.__class__.__name__}'") - - def __rmul__(self, n: int) -> None: - """Define multiplication using the "*" operator.""" - raise TypeError(f"unsupported operand type(s) for *: '{n.__class__.__name__}' and '{self.__class__.__name__}'") - - def __imul__(self, n: int) -> None: - """Define in-place multiplication using the "*=" operator.""" - raise TypeError(f"unsupported operand type(s) for *=: '{self.__class__.__name__}' and '{n.__class__.__name__}'") - - def append(self, obj: T = None, **kwargs) -> None: - """Append a new object to the ClassList. - - This method can use the object itself, or can provide attribute values as keyword arguments for a new object. - - Parameters - ---------- - obj : T, optional - An instance of the class specified by self._class_handle. - **kwargs : dict[str, Any], optional - The input keyword arguments for a new object in the ClassList. - - Raises - ------ - ValueError - Raised if the input arguments contain a ``name_field`` value already defined in the ClassList. - - Warnings - -------- - SyntaxWarning - Raised if the input arguments contain BOTH an object and keyword arguments. In this situation the object is - appended to the ClassList and the keyword arguments are discarded. - - """ - if obj and kwargs: - warnings.warn( - "ClassList.append() called with both an object and keyword arguments. " - "The keyword arguments will be ignored.", - SyntaxWarning, - stacklevel=2, - ) - if obj: - if not hasattr(self, "_class_handle"): - self._class_handle = type(obj) - self._check_classes([obj]) - self._check_unique_name_fields([obj]) - self.data.append(obj) - else: - if not hasattr(self, "_class_handle"): - raise TypeError( - "ClassList.append() called with keyword arguments for a ClassList without a class " - "defined. Call ClassList.append() with an object to define the class.", - ) - self._validate_name_field(kwargs) - self.data.append(self._class_handle(**kwargs)) - - def insert(self, index: int, obj: T = None, **kwargs) -> None: - """Insert a new object at a given index. - - This method can use the object itself, or can provide attribute values as keyword arguments for a new object. - - Parameters - ---------- - index: int - The index at which to insert a new object in the ClassList. - obj : T, optional - An instance of the class specified by self._class_handle. - **kwargs : dict[str, Any], optional - The input keyword arguments for a new object in the ClassList. - - Raises - ------ - ValueError - Raised if the input arguments contain a ``name_field`` value already defined in the ClassList. - - Warnings - -------- - SyntaxWarning - Raised if the input arguments contain both an object and keyword arguments. In this situation the object is - inserted into the ClassList and the keyword arguments are discarded. - - """ - if obj and kwargs: - warnings.warn( - "ClassList.insert() called with both an object and keyword arguments. " - "The keyword arguments will be ignored.", - SyntaxWarning, - stacklevel=2, - ) - if obj: - if not hasattr(self, "_class_handle"): - self._class_handle = type(obj) - self._check_classes([obj]) - self._check_unique_name_fields([obj]) - self.data.insert(index, obj) - else: - if not hasattr(self, "_class_handle"): - raise TypeError( - "ClassList.insert() called with keyword arguments for a ClassList without a class " - "defined. Call ClassList.insert() with an object to define the class.", - ) - self._validate_name_field(kwargs) - self.data.insert(index, self._class_handle(**kwargs)) - - def remove(self, item: T | str) -> None: - """Remove an object from the ClassList using either the object itself or its ``name_field`` value.""" - item = self._get_item_from_name_field(item) - self.data.remove(item) - - def count(self, item: T | str) -> int: - """Return the number of times an object appears in the ClassList. - - This method can use either the object itself or its ``name_field`` value. - - """ - item = self._get_item_from_name_field(item) - return self.data.count(item) - - def index(self, item: T | str, offset: bool = False, *args) -> int: - """Return the index of a particular object in the ClassList. - - This method can use either the object itself or its ``name_field`` value. - If offset is specified, add one to the index. This is used to account for one-based indexing. - - """ - item = self._get_item_from_name_field(item) - return self.data.index(item, *args) + int(offset) - - def extend(self, other: Sequence[T]) -> None: - """Extend the ClassList by adding another sequence.""" - if other and not (isinstance(other, Sequence) and not isinstance(other, str)): - other = [other] - if not hasattr(self, "_class_handle"): - self._class_handle = self._determine_class_handle(self + other) - self._check_classes(other) - self._check_unique_name_fields(other) - self.data.extend(other) - - def union(self, other: Sequence[T]) -> None: - """Extend the ClassList by a sequence, ignoring input items with names that already exist.""" - if other and not (isinstance(other, Sequence) and not isinstance(other, str)): - other = [other] - - self.extend( - [ - item - for item in other - if hasattr(item, self.name_field) and getattr(item, self.name_field) not in self.get_names() - ] - ) - - def set_fields(self, index: int | slice | str | T, **kwargs) -> None: - """Assign the values of an existing object's attributes using keyword arguments.""" - self._validate_name_field(kwargs) - pydantic_object = False - - # Find index if name or object is supplied - if isinstance(index, (str, self._class_handle)): - index = self.index(index) - - # Prioritise changing language to avoid CustomFile validator bug - value = kwargs.pop("language", None) - if value is not None: - kwargs = {"language": value, **kwargs} - - if importlib.util.find_spec("pydantic"): - # Pydantic is installed, so set up a context manager that will - # suppress custom validation errors until all fields have been set. - from pydantic import BaseModel, ValidationError - - if isinstance(self.data[index], BaseModel): - pydantic_object = True - - # Define a custom context manager - class SuppressCustomValidation(contextlib.AbstractContextManager): - """Context manager to suppress "value_error" based validation errors in pydantic. - - This validation context is necessary because errors can occur whilst individual - model values are set, which are resolved when all of the input values are set. - - After the exception is suppressed, execution proceeds with the next - statement following the with statement. - - with SuppressCustomValidation(): - setattr(self.data[index], key, value) - # Execution still resumes here if the attribute cannot be set - """ - - def __init__(self): - pass - - def __enter__(self): - pass - - def __exit__(self, exctype, excinst, exctb): - # If the return of __exit__ is True or truthy, the exception is suppressed. - # Otherwise, the default behaviour of raising the exception applies. - # - # To suppress errors arising from field and model validators in pydantic, - # we will examine the validation errors raised. If all of the errors - # listed in the exception have the type "value_error", this indicates - # they have arisen from field or model validators and will be suppressed. - # Otherwise, they will be raised. - if exctype is None: - return - if issubclass(exctype, ValidationError) and all( - [error["type"] == "value_error" for error in excinst.errors()] - ): - return True - return False - - validation_context = SuppressCustomValidation() - else: - validation_context = contextlib.nullcontext() - - for key, value in kwargs.items(): - with validation_context: - setattr(self.data[index], key, value) - - # We have suppressed custom validation errors for pydantic objects. - # We now must revalidate the pydantic model outside the validation context - # to catch any errors that remain after setting all of the fields. - if pydantic_object: - self._class_handle.model_validate(self.data[index]) - - def get_names(self) -> list[str]: - """Return a list of the values of the ``name_field`` attribute of each class object in the list. - - Returns - ------- - names : list [str] - The value of the ``name_field`` attribute of each object in the ClassList. - - """ - return [getattr(model, self.name_field) for model in self.data if hasattr(model, self.name_field)] - - def get_all_matches(self, value: Any) -> list[tuple]: - """Return a list of all (index, field) tuples where the value of the field is equal to the given value. - - Parameters - ---------- - value : str - The value we are searching for in the ClassList. - - Returns - ------- - : list [tuple] - A list of (index, field) tuples matching the given value. - - """ - return [ - (index, field) - for index, element in enumerate(self.data) - for field in vars(element) - if getattr(element, field) == value - ] - - def _validate_name_field(self, input_args: dict[str, Any]) -> None: - """Raise a ValueError if the user tries to add an object with a ``name_field`` already in the ClassList. - - Parameters - ---------- - input_args : dict [str, Any] - The input keyword arguments for a new object in the ClassList. - - Raises - ------ - ValueError - Raised if the input arguments contain a ``name_field`` value already defined in the ClassList. - - """ - names = [name.lower() for name in self.get_names()] - with contextlib.suppress(KeyError): - name = input_args[self.name_field].lower() - if name in names: - raise ValueError( - f"Input arguments contain the {self.name_field} '{input_args[self.name_field]}', " - f"which is already specified at index {names.index(name)} of the ClassList", - ) - - def _check_unique_name_fields(self, input_list: Sequence[T]) -> None: - """Raise a ValueError if any value of the ``name_field`` attribute is repeated in a list of class objects. - - Parameters - ---------- - input_list : iterable - An iterable of instances of the class given in self._class_handle. - - Raises - ------ - ValueError - Raised if the input list defines more than one object with the same value of name_field. - - """ - error_list = [] - try: - existing_names = [name.lower() for name in self.get_names()] - except AttributeError: - existing_names = [] - - new_names = [getattr(model, self.name_field).lower() for model in input_list if hasattr(model, self.name_field)] - full_names = existing_names + new_names - - # There are duplicate names if this test fails - if len(set(full_names)) != len(full_names): - unique_names = [*dict.fromkeys(new_names)] - - for name in unique_names: - existing_indices = [i for i, other_name in enumerate(existing_names) if other_name == name] - new_indices = [i for i, other_name in enumerate(new_names) if other_name == name] - if (len(existing_indices) + len(new_indices)) > 1: - existing_string = "" - new_string = "" - if existing_indices: - existing_list = ", ".join(str(i) for i in existing_indices[:-1]) - existing_string = ( - f" item{f's {existing_list} and ' if existing_list else ' '}" - f"{existing_indices[-1]} of the existing ClassList" - ) - if new_indices: - new_list = ", ".join(str(i) for i in new_indices[:-1]) - new_string = ( - f" item{f's {new_list} and ' if new_list else ' '}{new_indices[-1]} of the input list" - ) - error_list.append( - f" '{name}' is shared between{existing_string}" - f"{', and' if existing_string and new_string else ''}{new_string}" - ) - - if error_list: - newline = "\n" - raise ValueError( - f"The value of the '{self.name_field}' attribute must be unique for each item in the ClassList:\n" - f"{newline.join(error for error in error_list)}" - ) - - def _check_classes(self, input_list: Sequence[T]) -> None: - """Raise a ValueError if any object in a list of objects is not of the type specified by ``self._class_handle``. - - Parameters - ---------- - input_list : iterable - A list of instances of the class given in ``self._class_handle``. - - Raises - ------ - ValueError - If the input list contains objects of any type other than that given in ``self._class_handle``. - - """ - error_list = [] - for i, element in enumerate(input_list): - if not isinstance(element, self._class_handle): - error_list.append(f" index {i} is of type {type(element).__name__}") - if error_list: - newline = "\n" - raise ValueError( - f"This ClassList only supports elements of type {self._class_handle.__name__}. " - f"In the input list:\n{newline.join(error for error in error_list)}\n" - ) - - def _get_item_from_name_field(self, value: T | str) -> T | str: - """Return the object with the given value of the ``name_field`` attribute in the ClassList. - - Parameters - ---------- - value : T or str - Either an object in the ClassList, or the value of the ``name_field`` for an object in the ClassList. - - Returns - ------- - instance : T or str - Either the object with the value of the ``name_field`` attribute given by value, or the input value if an - object with that value of the ``name_field`` attribute cannot be found. - - """ - try: - lower_value = value.lower() - except AttributeError: - lower_value = value - - return next((model for model in self.data if getattr(model, self.name_field).lower() == lower_value), value) - - @staticmethod - def _determine_class_handle(input_list: Sequence[T]): - """Determine the class handle from a sequence of objects. - - The ``_class_handle`` of the sequence is the type of the first element in the sequence - which is a subclass of all elements in the sequence. If no such element exists, the handle - is set to be the type of the first element in the list. - - Parameters - ---------- - input_list : Sequence[T] - A list of instances to populate the ClassList. - - Returns - ------- - class_handle : type - The type object of the first element which is a subclass of all of the other - elements, or the first element if no such element exists. - - """ - for element in input_list: - if all(issubclass(type(instance), type(element)) for instance in input_list): - class_handle = type(element) - break - else: - class_handle = type(input_list[0]) - - return class_handle - - # Pydantic core schema which allows ClassLists to be validated - # in short: it validates that each ClassList is indeed a ClassList, - # and then validates ClassList.data as though it were a typed list - # e.g. ClassList[str] data is validated like list[str] - @classmethod - def __get_pydantic_core_schema__(cls, source: Any, handler): - # import here so that the ClassList can be instantiated and used without Pydantic installed - from typing import get_args, get_origin - - from pydantic import ValidatorFunctionWrapHandler - from pydantic.types import ( - core_schema, # import core_schema through here rather than making pydantic_core a dependency - ) - - # if annotated with a class, get the item type of that class - origin = get_origin(source) - item_tp = Any if origin is None else get_args(source)[0] - - list_schema = handler.generate_schema(list[item_tp]) - - def coerce(v: Any, handler: ValidatorFunctionWrapHandler) -> ClassList[T]: - """If a sequence is given, try to coerce it to a ClassList.""" - if isinstance(v, Sequence): - classlist = ClassList() - if len(v) > 0 and isinstance(v[0], dict): - # we want to be OK if the type is a model and is passed as a dict; - # pydantic will coerce it or fall over later - classlist._class_handle = dict - elif item_tp is not Any: - classlist._class_handle = item_tp - classlist.extend(v) - v = classlist - v = handler(v) - return v - - def validate_items(v: ClassList[T], handler: ValidatorFunctionWrapHandler) -> ClassList[T]: - v.data = handler(v.data) - return v - - schema = core_schema.chain_schema( - [ - core_schema.no_info_wrap_validator_function(coerce, core_schema.is_instance_schema(cls)), - core_schema.no_info_wrap_validator_function(validate_items, list_schema), - ], - serialization=core_schema.plain_serializer_function_ser_schema(lambda x: x), - ) - - return schema diff --git a/ratapi/controls.py b/ratapi/controls.py deleted file mode 100644 index 9dd815b5..00000000 --- a/ratapi/controls.py +++ /dev/null @@ -1,258 +0,0 @@ -"""The Controls class for providing RAT algorithm settings.""" - -import contextlib -import os -import tempfile -import warnings -from pathlib import Path - -import prettytable -from pydantic import ( - BaseModel, - Field, - ValidationError, - ValidatorFunctionWrapHandler, - model_serializer, - model_validator, -) - -from ratapi.utils.custom_errors import custom_pydantic_validation_error -from ratapi.utils.enums import BoundHandling, Display, Parallel, Procedures, Strategies - -common_fields = [ - "procedure", - "parallel", - "numSimulationPoints", - "resampleMinAngle", - "resampleNPoints", - "display", -] -update_fields = ["updateFreq", "updatePlotFreq"] -fields = { - "calculate": common_fields, - "simplex": [*common_fields, "xTolerance", "funcTolerance", "maxFuncEvals", "maxIterations", *update_fields], - "de": [ - *common_fields, - "populationSize", - "fWeight", - "crossoverProbability", - "strategy", - "targetValue", - "numGenerations", - *update_fields, - ], - "ns": [*common_fields, "nLive", "nMCMC", "propScale", "nsTolerance"], - "dream": [*common_fields, "nSamples", "nChains", "jumpProbability", "pUnitGamma", "boundHandling", "adaptPCR"], -} - - -class Controls(BaseModel, validate_assignment=True, extra="forbid", use_attribute_docstrings=True): - """The full set of controls parameters for all five procedures that are required for the compiled RAT code.""" - - # All Procedures - procedure: Procedures = Procedures.Calculate - """Which procedure RAT should execute. Can be 'calculate', 'simplex', 'de', 'ns', or 'dream'.""" - - parallel: Parallel = Parallel.Single - """How the calculation should be parallelised. Can be 'single', 'contrasts' or 'points'.""" - - numSimulationPoints: int = Field(500, ge=2) - """The number of points used for reflectivity simulations where no data is supplied.""" - - resampleMinAngle: float = Field(0.9, le=1, gt=0) - """The upper threshold on the angle between three sampled points for resampling, in units of radians over pi.""" - - resampleNPoints: int = Field(50, gt=0) - """The number of initial points to use for resampling.""" - - display: Display = Display.Iter - """How much RAT should print to the terminal. Can be 'off', 'iter', 'notify', or 'final'.""" - - # Simplex - xTolerance: float = Field(1.0e-6, gt=0.0) - """[SIMPLEX] The termination tolerance for step size.""" - - funcTolerance: float = Field(1.0e-6, gt=0.0) - """[SIMPLEX] The termination tolerance for change in chi-squared.""" - - maxFuncEvals: int = Field(10000, gt=0) - """[SIMPLEX] The maximum number of function evaluations before the algorithm terminates.""" - - maxIterations: int = Field(1000, gt=0) - """[SIMPLEX] The maximum number of iterations before the algorithm terminates.""" - - # Simplex and DE - updateFreq: int = 1 - """[SIMPLEX, DE] Number of iterations between printing progress updates to the terminal.""" - - updatePlotFreq: int = 20 - """[SIMPLEX, DE] Number of iterations between updates to live plots.""" - - # DE - populationSize: int = Field(20, ge=1) - """[DE] The number of candidate solutions that exist at any time.""" - - fWeight: float = Field(0.5, gt=0.0) - """[DE] The step size for how different mutations are to their parents.""" - - crossoverProbability: float = Field(0.8, gt=0.0, lt=1.0) - """[DE] The probability of exchange of parameters between individuals at any iteration.""" - - strategy: Strategies = Strategies.RandomWithPerVectorDither - """[DE] The algorithm used to generate new candidates.""" - - targetValue: float = Field(1.0, ge=1.0) - """[DE] The value of chi-squared at which the algorithm will terminate.""" - - numGenerations: int = Field(500, ge=1) - """[DE] The maximum number of iterations before the algorithm terminates.""" - - # NS - nLive: int = Field(150, ge=1) - """[NS] The number of points to sample.""" - - nMCMC: int = Field(0, ge=0) - """[NS] If non-zero, an MCMC process with ``nMCMC`` chains will be used instead of MultiNest.""" - - propScale: float = Field(0.1, gt=0.0, lt=1.0) - """[NS] A scaling factor for the ellipsoid generated by MultiNest.""" - - nsTolerance: float = Field(0.1, ge=0.0) - """[NS] The tolerance threshold for when the algorithm should terminate.""" - - # Dream - nSamples: int = Field(20000, ge=0) - """[DREAM] The total number of function evaluations (number of algorithm generations times number of chains).""" - - nChains: int = Field(10, gt=1) - """[DREAM] The number of Markov chains to use in the algorithm.""" - - jumpProbability: float = Field(0.5, gt=0.0, lt=1.0) - """[DREAM] The probability range for the size of jumps in sampling. Larger values mean more variable jumps.""" - - pUnitGamma: float = Field(0.2, gt=0.0, lt=1.0) - """[DREAM] The probability that the scaling-down factor of jumps will be ignored and a larger jump will be taken.""" - - boundHandling: BoundHandling = BoundHandling.Reflect - """[DREAM] How steps past the space boundaries should be handled. Can be 'off', 'reflect', 'bound', or 'fold'.""" - - adaptPCR: bool = True - """[DREAM] Whether the crossover probability for differential evolution should be adapted during the run.""" - - # Private field for IPC file - _IPCFilePath: str = "" - - @model_validator(mode="wrap") - def warn_setting_incorrect_properties(self, handler: ValidatorFunctionWrapHandler) -> "Controls": - """Raise a warning if the user sets fields that apply to other procedures.""" - model_input = self - try: - input_dict = model_input.__dict__ - except AttributeError: - input_dict = model_input - - validated_self = None - try: - validated_self = handler(self) - except ValidationError as exc: - procedure = input_dict.get("procedure", Procedures.Calculate) - custom_error_msgs = { - "extra_forbidden": f'Extra inputs are not permitted. The fields for the "{procedure}"' - f" controls procedure are:\n " - f"{', '.join(fields.get('procedure', []))}\n", - } - custom_error_list = custom_pydantic_validation_error(exc.errors(include_url=False), custom_error_msgs) - raise ValidationError.from_exception_data(exc.title, custom_error_list, hide_input=True) from None - - if isinstance(model_input, validated_self.__class__): - # This is for changing fields in a defined model - changed_fields = [key for key in input_dict if input_dict[key] != validated_self.__dict__[key]] - elif isinstance(model_input, dict): - # This is for a newly-defined model - changed_fields = input_dict.keys() - else: - raise ValueError('The input to the "Controls" model is invalid.') - - new_procedure = validated_self.procedure - allowed_fields = fields[new_procedure] - for field in changed_fields: - if field not in allowed_fields: - incorrect_procedures = [key for (key, value) in fields.items() if field in value] - warnings.warn( - f'\nThe current controls procedure is "{new_procedure}", but the property' - f' "{field}" applies instead to the {", ".join(incorrect_procedures)} procedure.\n\n' - f' The fields for the "{new_procedure}" controls procedure are:\n' - f" {', '.join(fields[new_procedure])}\n", - stacklevel=2, - ) - - return validated_self - - @model_serializer - def serialize(self): - """Filter fields so only those applying to the chosen procedure are serialized.""" - return {model_field: getattr(self, model_field) for model_field in fields[self.procedure]} - - def __repr__(self) -> str: - fields_repr = ", ".join(repr(v) if a is None else f"{a}={v!r}" for a, v in self.model_dump().items()) - return f"{self.__repr_name__()}({fields_repr})" - - def __str__(self) -> str: - table = prettytable.PrettyTable() - table.field_names = ["Property", "Value"] - table.add_rows([[k, v] for k, v in self.model_dump().items()]) - return table.get_string() - - def initialise_IPC(self): - """Set up the inter-process communication file.""" - IPC_obj, self._IPCFilePath = tempfile.mkstemp() - os.write(IPC_obj, b"\x00") - os.close(IPC_obj) - return None - - def sendStopEvent(self): - """Send the stop event via the inter-process communication file. - - Warnings - -------- - UserWarning - Raised if we try to delete an IPC file that was not initialised. - - """ - if os.path.isfile(self._IPCFilePath): - with open(self._IPCFilePath, "wb") as f: - f.write(b"\x01") - else: - warnings.warn("An IPC file was not initialised.", UserWarning, stacklevel=2) - return None - - def delete_IPC(self): - """Delete the inter-process communication file.""" - with contextlib.suppress(FileNotFoundError): - os.remove(self._IPCFilePath) - self._IPCFilePath = "" - return None - - def save(self, filepath: str | Path = "./controls.json"): - """Save a controls object to a JSON file. - - Parameters - ---------- - filepath : str or Path - The path to where the controls file will be written. - """ - filepath = Path(filepath).with_suffix(".json") - filepath.write_text(self.model_dump_json()) - - @classmethod - def load(cls, path: str | Path) -> "Controls": - """Load a controls object from file. - - Parameters - ---------- - path : str or Path - The path to the controls object file. - - """ - file = Path(path) - return cls.model_validate_json(file.read_text()) diff --git a/ratapi/events.py b/ratapi/events.py deleted file mode 100644 index 2383159c..00000000 --- a/ratapi/events.py +++ /dev/null @@ -1,88 +0,0 @@ -"""Hooks for connecting to run callback events.""" - -import os -from collections.abc import Callable - -from ratapi.rat_core import EventBridge, EventTypes, PlotEventData, ProgressEventData - - -def notify(event_type: EventTypes, data: str | PlotEventData | ProgressEventData) -> None: - """Call registered callbacks with data when event type has been triggered. - - Parameters - ---------- - event_type : EventTypes - The event type that was triggered. - data : str or PlotEventData or ProgressEventData - The data sent by the event. The message event data is a string. - - """ - callbacks = __event_callbacks[event_type] - for callback in callbacks: - callback(data) - - -def get_event_callback(event_type: EventTypes) -> list[Callable[[str | PlotEventData | ProgressEventData], None]]: - """Return all callbacks registered for the given event type. - - Parameters - ---------- - event_type : EventTypes - The event type. - - Returns - ------- - callback : Callable[[Union[str, PlotEventData, ProgressEventData]], None] - The callback for the event type. - - """ - return list(__event_callbacks[event_type]) - - -def register(event_type: EventTypes, callback: Callable[[str | PlotEventData | ProgressEventData], None]) -> None: - """Register a new callback for the event type. - - Parameters - ---------- - event_type : EventTypes - The event type to register. - callback : Callable[[Union[str, PlotEventData, ProgressEventData]], None] - The callback for when the event is triggered. - - """ - if not isinstance(event_type, EventTypes): - raise ValueError("event_type must be a events.EventTypes enum") - - if len(__event_callbacks[event_type]) == 0: - __event_impl.register(event_type) - __event_callbacks[event_type].add(callback) - - -def clear(key=None, callback=None) -> None: - """Clear all event callbacks or specific callback. - - Parameters - ---------- - key : EventTypes, optional - The event type of the callback to clear if given. - callback : Callable[[Union[str, PlotEventData, ProgressEventData]], None], optional - A callback for an event which will be cleared if given. - - """ - if key is None and callback is None: - for key in __event_callbacks: - __event_callbacks[key] = set() - elif key is not None and callback is not None: - __event_callbacks[key].remove(callback) - - for value in __event_callbacks.values(): - if value: - break - else: - __event_impl.clear() - - -dir_path = os.path.dirname(os.path.realpath(__file__)) -os.environ["RAT_PATH"] = os.path.join(dir_path, "") -__event_impl = EventBridge(notify) -__event_callbacks = {EventTypes.Message: set(), EventTypes.Plot: set(), EventTypes.Progress: set()} diff --git a/ratapi/examples/__init__.py b/ratapi/examples/__init__.py deleted file mode 100644 index b85aebed..00000000 --- a/ratapi/examples/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -"""Usage examples for the Python RAT API.""" - -from ratapi.examples.absorption.absorption import absorption -from ratapi.examples.convert_rascal_project.convert_rascal import convert_rascal -from ratapi.examples.domains.domains_custom_layers import domains_custom_layers -from ratapi.examples.domains.domains_custom_XY import domains_custom_XY -from ratapi.examples.domains.domains_standard_layers import domains_standard_layers -from ratapi.examples.normal_reflectivity.DSPC_custom_layers import DSPC_custom_layers -from ratapi.examples.normal_reflectivity.DSPC_custom_XY import DSPC_custom_XY -from ratapi.examples.normal_reflectivity.DSPC_data_background import DSPC_data_background -from ratapi.examples.normal_reflectivity.DSPC_function_background import DSPC_function_background -from ratapi.examples.normal_reflectivity.DSPC_standard_layers import DSPC_standard_layers - -__all__ = [ - "absorption", - "domains_custom_layers", - "domains_custom_XY", - "domains_standard_layers", - "DSPC_custom_layers", - "DSPC_custom_XY", - "DSPC_standard_layers", - "DSPC_data_background", - "DSPC_function_background", - "convert_rascal", -] diff --git a/ratapi/examples/absorption/__init__.py b/ratapi/examples/absorption/__init__.py deleted file mode 100644 index bf48e7ae..00000000 --- a/ratapi/examples/absorption/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""An example of using absorption in a RAT project.""" diff --git a/ratapi/examples/absorption/absorption.ipynb b/ratapi/examples/absorption/absorption.ipynb deleted file mode 100644 index 696103bc..00000000 --- a/ratapi/examples/absorption/absorption.ipynb +++ /dev/null @@ -1,305 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pathlib\n", - "\n", - "import numpy as np\n", - "from IPython.display import Code\n", - "\n", - "import ratapi as RAT\n", - "from ratapi.models import Parameter" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Absorption (imaginary SLD) - effect below the critical edge\n", - "\n", - "RAT allows the use of an imaginary, as well as real part of the SLD. The effect of this is usually seen below the critical edge, and must sometimes be accounted for.\n", - "\n", - "The example used here is Custom Layers. It analyses a bilayer sample on a permalloy / gold substrate, measured using polarised neutrons, against D2O and H2O, leading to 4 contrasts in total. Absorption (i.e. imaginary SLD) is defined for Gold and the Permalloy, to account for non-flat data below the critical edge.\n", - "\n", - "For absorption with standard layers, an additional column appears in the layers block to accommodate the imagainary component of the SLD. For custom functions, we add an extra column to the output.\n", - "\n", - "For all calculation types, to activate this functionality it is necessary to set the 'absorption' flag when creating the project." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "problem = RAT.Project(name=\"Absorption example\", calculation=\"normal\", model=\"custom layers\", geometry=\"substrate/liquid\", absorption=True)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We now define our parameters, noting that each SLD parameter has both a real and imaginary component:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "parameter_list = [\n", - " Parameter(name=\"Alloy Thickness\", min=100.0, value=135.6, max=200.0, fit=True),\n", - " Parameter(name=\"Alloy SLD up\", min=6.0e-6, value=9.87e-6, max=1.2e-5, fit=True),\n", - " Parameter(name=\"Alloy SLD imaginary up\", min=1.0e-9, value=4.87e-8, max=1.0e-7, fit=True),\n", - " Parameter(name=\"Alloy SLD down\", min=6.0e-6, value=7.05e-6, max=1.3e-5, fit=True),\n", - " Parameter(name=\"Alloy SLD imaginary down\", min=1.0e-9, value=4.87e-8, max=1.0e-7, fit=True),\n", - " Parameter(name=\"Alloy Roughness\", min=2.0, value=5.71, max=10.0, fit=True),\n", - " #\n", - " Parameter(name=\"Gold Thickness\", min=100.0, value=154.7, max=200.0, fit=True),\n", - " Parameter(name=\"Gold Roughness\", min=0.1, value=5.42, max=10.0, fit=True),\n", - " Parameter(name=\"Gold SLD\", min=4.0e-6, value=4.49e-6, max=5.0e-6, fit=True),\n", - " Parameter(name=\"Gold SLD imaginary\", min=1.0e-9, value=4.20e-8, max=1.0e-7, fit=True),\n", - " #\n", - " Parameter(name=\"Thiol APM\", min=40.0, value=56.27, max=100.0, fit=True),\n", - " Parameter(name=\"Thiol Head Hydration\", min=20.0, value=30.0, max=50.0, fit=True),\n", - " Parameter(name=\"Thiol Coverage\", min=0.5, value=0.9, max=1.0, fit=True),\n", - " #\n", - " Parameter(name=\"CW Thickness\", min=1.0, value=12.87, max=25.0, fit=True),\n", - " #\n", - " Parameter(name=\"Bilayer APM\", min=48.0, value=65.86, max=90.0, fit=True),\n", - " Parameter(name=\"Bilayer Head Hydration\", min=20.0, value=30.0, max=50.0, fit=True),\n", - " Parameter(name=\"Bilayer Roughness\", min=1.0, value=3.87, max=10.0, fit=True),\n", - " Parameter(name=\"Bilayer Coverage\", min=0.5, value=0.94, max=1.0, fit=True)\n", - "]\n", - "\n", - "problem.parameters.extend(parameter_list)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Set the bulk in and bulk out parameters:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "problem.bulk_in.set_fields(0, name=\"Silicon\", min=2.0e-6, value=2.073e-6, max=2.1e-6)\n", - "\n", - "problem.bulk_out.set_fields(0, name=\"D2O\", min=5.8e-06, value=6.21e-06, max=6.35e-06, fit=True)\n", - "problem.bulk_out.append(name=\"H2O\", min=-5.6e-07, value=-3.15e-07, max=0.0, fit=True)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Use a different scalefactor for each dataset:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "del problem.scalefactors[0]\n", - "problem.scalefactors.append(name=\"Scalefactor 1\", min=0.5, value=1, max=1.5, fit=True)\n", - "problem.scalefactors.append(name=\"Scalefactor 2\", min=0.5, value=1, max=1.5, fit=True)\n", - "problem.scalefactors.append(name=\"Scalefactor 3\", min=0.5, value=1, max=1.5, fit=True)\n", - "problem.scalefactors.append(name=\"Scalefactor 4\", min=0.5, value=1, max=1.5, fit=True)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Set the backgrounds and resolutions:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "del problem.backgrounds[0]\n", - "del problem.background_parameters[0]\n", - "\n", - "problem.background_parameters.append(name=\"Background parameter 1\", min=5.0e-08, value=7.88e-06, max=9.0e-05, fit=True)\n", - "problem.background_parameters.append(name=\"Background parameter 2\", min=1.0e-08, value=5.46e-06, max=9.0e-05, fit=True)\n", - "problem.background_parameters.append(name=\"Background parameter 3\", min=1.0e-06, value=9.01e-06, max=9.0e-05, fit=True)\n", - "problem.background_parameters.append(name=\"Background parameter 4\", min=1.0e-06, value=5.61e-06, max=9.0e-05, fit=True)\n", - "\n", - "problem.backgrounds.append(name=\"Background 1\", type=\"constant\", source=\"Background parameter 1\")\n", - "problem.backgrounds.append(name=\"Background 2\", type=\"constant\", source=\"Background parameter 2\")\n", - "problem.backgrounds.append(name=\"Background 3\", type=\"constant\", source=\"Background parameter 3\")\n", - "problem.backgrounds.append(name=\"Background 4\", type=\"constant\", source=\"Background parameter 4\")\n", - "\n", - "# Make the resolution fittable\n", - "problem.resolution_parameters.set_fields(0, fit=True)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Add the datasets:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "data_path = pathlib.Path(\"../data\")\n", - "\n", - "data_1 = np.loadtxt(data_path / \"D2O_spin_down.dat\")\n", - "problem.data.append(name=\"D2O_dn\", data=data_1)\n", - "\n", - "data_2 = np.loadtxt(data_path / \"D2O_spin_up.dat\")\n", - "problem.data.append(name=\"D2O_up\", data=data_2)\n", - "\n", - "data_3 = np.loadtxt(data_path / \"H2O_spin_down.dat\")\n", - "problem.data.append(name=\"H2O_dn\", data=data_3)\n", - "\n", - "data_4 = np.loadtxt(data_path / \"H2O_spin_up.dat\")\n", - "problem.data.append(name=\"H2O_up\", data=data_4)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Add the custom file. We can see that we add an extra column for the output in our custom function." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "problem.custom_files.append(\n", - " name=\"DPPC absorption\",\n", - " filename=\"volume_thiol_bilayer.py\",\n", - " language=\"python\",\n", - " path=pathlib.Path.cwd().resolve(),\n", - ")\n", - "Code(filename='volume_thiol_bilayer.py', language='python')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Finally, add the contrasts:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "problem.contrasts.append(\n", - " name=\"D2O Down\",\n", - " data=\"D2O_dn\",\n", - " background=\"Background 1\",\n", - " bulk_in=\"Silicon\",\n", - " bulk_out=\"D2O\",\n", - " scalefactor=\"Scalefactor 1\",\n", - " resolution=\"Resolution 1\",\n", - " resample=True,\n", - " model=[\"DPPC absorption\"],\n", - ")\n", - "\n", - "problem.contrasts.append(\n", - " name=\"D2O Up\",\n", - " data=\"D2O_up\",\n", - " background=\"Background 2\",\n", - " bulk_in=\"Silicon\",\n", - " bulk_out=\"D2O\",\n", - " scalefactor=\"Scalefactor 2\",\n", - " resolution=\"Resolution 1\",\n", - " resample=True,\n", - " model=[\"DPPC absorption\"],\n", - ")\n", - "\n", - "problem.contrasts.append(\n", - " name=\"H2O Down\",\n", - " data=\"H2O_dn\",\n", - " background=\"Background 3\",\n", - " bulk_in=\"Silicon\",\n", - " bulk_out=\"H2O\",\n", - " scalefactor=\"Scalefactor 3\",\n", - " resolution=\"Resolution 1\",\n", - " resample=True,\n", - " model=[\"DPPC absorption\"],\n", - ")\n", - "\n", - "problem.contrasts.append(\n", - " name=\"H2O Up\",\n", - " data=\"H2O_up\",\n", - " background=\"Background 4\",\n", - " bulk_in=\"Silicon\",\n", - " bulk_out=\"H2O\",\n", - " scalefactor=\"Scalefactor 4\",\n", - " resolution=\"Resolution 1\",\n", - " resample=True,\n", - " model=[\"DPPC absorption\"],\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now run RAT and plot the results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "controls = RAT.Controls(parallel=\"contrasts\", resampleMinAngle=0.9, resampleNPoints=150.0)\n", - "problem, results = RAT.run(problem, controls)\n", - "\n", - "RAT.plotting.plot_ref_sld(problem, results)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/ratapi/examples/absorption/absorption.py b/ratapi/examples/absorption/absorption.py deleted file mode 100644 index 5d100aff..00000000 --- a/ratapi/examples/absorption/absorption.py +++ /dev/null @@ -1,172 +0,0 @@ -"""An example for using absorption in RAT.""" - -import pathlib - -import numpy as np - -import ratapi as RAT - - -def absorption(): - """Run a custom layers model including absorption. - - RAT allows the use of an imaginary, as well as real part of the SLD. - The effect of this is usually seen below the critical edge, and must sometimes be accounted for. - - This is an example of a Custom Layers project using absorption. used here is Custom Layers. - It analyses a bilayer sample on a permalloy / gold substrate, - measured using polarised neutrons, against D2O and H2O, leading to 4 contrasts in total. - Absorption (i.e. imaginary SLD) is defined for Gold and the Permalloy, - to account for non-flat data below the critical edge. - """ - problem = RAT.Project( - name="Absorption example", - calculation="normal", - model="custom layers", - geometry="substrate/liquid", - absorption=True, - ) - - # Add the required parameters (substrate roughness is already there by default) - problem.parameters.append(name="Alloy Thickness", min=100.0, value=135.6, max=200.0, fit=True) - problem.parameters.append(name="Alloy SLD up", min=6.0e-6, value=9.87e-6, max=1.2e-5, fit=True) - problem.parameters.append(name="Alloy SLD imaginary up", min=1.0e-9, value=4.87e-8, max=1.0e-7, fit=True) - problem.parameters.append(name="Alloy SLD down", min=6.0e-6, value=7.05e-6, max=1.3e-5, fit=True) - problem.parameters.append(name="Alloy SLD imaginary down", min=1.0e-9, value=4.87e-8, max=1.0e-7, fit=True) - problem.parameters.append(name="Alloy Roughness", min=2.0, value=5.71, max=10.0, fit=True) - problem.parameters.append(name="Gold Thickness", min=100.0, value=154.7, max=200.0, fit=True) - problem.parameters.append(name="Gold Roughness", min=0.1, value=5.42, max=10.0, fit=True) - problem.parameters.append(name="Gold SLD", min=4.0e-6, value=4.49e-6, max=5.0e-6, fit=True) - problem.parameters.append(name="Gold SLD imaginary", min=1.0e-9, value=4.20e-8, max=1.0e-7, fit=True) - - problem.parameters.append(name="Thiol APM", min=40.0, value=56.27, max=100.0, fit=True) - problem.parameters.append(name="Thiol Head Hydration", min=20.0, value=30.0, max=50.0, fit=True) - problem.parameters.append(name="Thiol Coverage", min=0.5, value=0.9, max=1.0, fit=True) - - problem.parameters.append(name="CW Thickness", min=1.0, value=12.87, max=25.0, fit=True) - problem.parameters.append(name="Bilayer APM", min=48.0, value=65.86, max=90.0, fit=True) - problem.parameters.append(name="Bilayer Head Hydration", min=20.0, value=30.0, max=50.0, fit=True) - problem.parameters.append(name="Bilayer Roughness", min=1.0, value=3.87, max=10.0, fit=True) - problem.parameters.append(name="Bilayer Coverage", min=0.5, value=0.94, max=1.0, fit=True) - - # Change the existing Bulk In parameter to be Silicon - problem.bulk_in.set_fields(0, name="Silicon", min=2.0e-6, value=2.073e-6, max=2.1e-6) - - # We need 2 bulk outs - D2O and H2O - problem.bulk_out.set_fields(0, name="D2O", min=5.8e-06, value=6.21e-06, max=6.35e-06, fit=True) - problem.bulk_out.append(name="H2O", min=-5.6e-07, value=-3.15e-07, max=0.0, fit=True) - - # Use a different scalefactor for each dataset - del problem.scalefactors[0] - problem.scalefactors.append(name="Scalefactor 1", min=0.5, value=1, max=1.5, fit=True) - problem.scalefactors.append(name="Scalefactor 2", min=0.5, value=1, max=1.5, fit=True) - problem.scalefactors.append(name="Scalefactor 3", min=0.5, value=1, max=1.5, fit=True) - problem.scalefactors.append(name="Scalefactor 4", min=0.5, value=1, max=1.5, fit=True) - - # Similarly, use an individual background for each dataset - del problem.backgrounds[0] - del problem.background_parameters[0] - - problem.background_parameters.append( - name="Background parameter 1", min=5.0e-08, value=7.88e-06, max=9.0e-05, fit=True - ) - problem.background_parameters.append( - name="Background parameter 2", min=1.0e-08, value=5.46e-06, max=9.0e-05, fit=True - ) - problem.background_parameters.append( - name="Background parameter 3", min=1.0e-06, value=9.01e-06, max=9.0e-05, fit=True - ) - problem.background_parameters.append( - name="Background parameter 4", min=1.0e-06, value=5.61e-06, max=9.0e-05, fit=True - ) - - problem.backgrounds.append(name="Background 1", type="constant", source="Background parameter 1") - problem.backgrounds.append(name="Background 2", type="constant", source="Background parameter 2") - problem.backgrounds.append(name="Background 3", type="constant", source="Background parameter 3") - problem.backgrounds.append(name="Background 4", type="constant", source="Background parameter 4") - - # Make the resolution fittable - problem.resolution_parameters.set_fields(0, fit=True) - - # Now add the data we need - data_path = pathlib.Path(__file__).parents[1] / "data" - - data_1 = np.loadtxt(data_path / "D2O_spin_down.dat") - problem.data.append(name="D2O_dn", data=data_1) - - data_2 = np.loadtxt(data_path / "D2O_spin_up.dat") - problem.data.append(name="D2O_up", data=data_2) - - data_3 = np.loadtxt(data_path / "H2O_spin_down.dat") - problem.data.append(name="H2O_dn", data=data_3) - - data_4 = np.loadtxt(data_path / "H2O_spin_up.dat") - problem.data.append(name="H2O_up", data=data_4) - - # Add the custom file - problem.custom_files.append( - name="DPPC absorption", - filename="volume_thiol_bilayer.py", - language="python", - path=pathlib.Path(__file__).parent, - ) - - # Finally add the contrasts - problem.contrasts.append( - name="D2O Down", - data="D2O_dn", - background="Background 1", - bulk_in="Silicon", - bulk_out="D2O", - scalefactor="Scalefactor 1", - resolution="Resolution 1", - resample=True, - model=["DPPC absorption"], - ) - - problem.contrasts.append( - name="D2O Up", - data="D2O_up", - background="Background 2", - bulk_in="Silicon", - bulk_out="D2O", - scalefactor="Scalefactor 2", - resolution="Resolution 1", - resample=True, - model=["DPPC absorption"], - ) - - problem.contrasts.append( - name="H2O Down", - data="H2O_dn", - background="Background 3", - bulk_in="Silicon", - bulk_out="H2O", - scalefactor="Scalefactor 3", - resolution="Resolution 1", - resample=True, - model=["DPPC absorption"], - ) - - problem.contrasts.append( - name="H2O Up", - data="H2O_up", - background="Background 4", - bulk_in="Silicon", - bulk_out="H2O", - scalefactor="Scalefactor 4", - resolution="Resolution 1", - resample=True, - model=["DPPC absorption"], - ) - - # Now make a controls block and run the code - controls = RAT.Controls(parallel="contrasts", resampleNPoints=150) - problem, results = RAT.run(problem, controls) - - return problem, results - - -if __name__ == "__main__": - problem, results = absorption() - RAT.plotting.plot_ref_sld(problem, results, True) diff --git a/ratapi/examples/absorption/volume_thiol_bilayer.py b/ratapi/examples/absorption/volume_thiol_bilayer.py deleted file mode 100644 index 2b9f7fd4..00000000 --- a/ratapi/examples/absorption/volume_thiol_bilayer.py +++ /dev/null @@ -1,144 +0,0 @@ -"""Custom layer model file for the absorption example.""" - - -def volume_thiol_bilayer(params, bulk_in, bulk_out, contrast): - """VolumeThiolBilayer RAT Custom Layer Model File. - - This file accepts 3 vectors containing the values for params, bulk in and bulk out. - The final parameter is an index of the contrast being calculated - - The function should output a matrix of layer values, in the form... - - Output = [thick 1, SLD 1, Rough 1, Percent Hydration 1, Hydrate how 1 - .... - thick n, SLD n, Rough n, Percent Hydration n, Hydration how n] - - The "hydrate how" parameter decides if the layer is hydrated with Bulk out or Bulk in phases. - Set to 1 for Bulk out, zero for Bulk in. - Alternatively, leave out hydration and just return... - - Output = [thick 1, SLD 1, Rough 1, - .... - thick n, SLD n, Rough n] - - The second output parameter should be the substrate roughness. - """ - # Note - The first contrast number is 1 (not 0) so be careful if you use - # this variable for array indexing. - - subRough = params[0] - alloyThick = params[1] - alloySLDUp = params[2] - alloyISLDUp = params[3] - alloySLDDown = params[4] - alloyISLDDown = params[5] - alloyRough = params[6] - goldThick = params[7] - goldRough = params[8] - goldSLD = params[9] - goldISLD = params[10] - thiolAPM = params[11] - thiolHeadHydr = params[12] - thiolCoverage = params[13] - cwThick = params[14] - bilayerAPM = params[15] - bilHeadHydr = params[16] - bilayerRough = params[17] - bilayerCoverage = params[18] - - # Make the metal layers - gold = [goldThick, goldSLD, goldISLD, goldRough] - alloyUp = [alloyThick, alloySLDUp, alloyISLDUp, alloyRough] - alloyDown = [alloyThick, alloySLDDown, alloyISLDDown, alloyRough] - - # Neutron b's.. - # define all the neutron b's. - bc = 0.6646e-4 # Carbon - bo = 0.5843e-4 # Oxygen - bh = -0.3739e-4 # Hydrogen - bp = 0.513e-4 # Phosphorus - bn = 0.936e-4 # Nitrogen - - # Work out the total scattering length in each fragment - # Define scattering lengths - # Hydrogenated version - COO = (2 * bo) + (bc) - GLYC = (3 * bc) + (5 * bh) - CH3 = (1 * bc) + (3 * bh) - PO4 = (1 * bp) + (4 * bo) - CH2 = (1 * bc) + (2 * bh) - CH = (1 * bc) + (1 * bh) - CHOL = (5 * bc) + (12 * bh) + (1 * bn) - - # And also volumes - vCH3 = 52.7 # CH3 volume in the paper appears to be for 2 * CH3's - vCH2 = 28.1 - vCOO = 39.0 - vGLYC = 68.8 - vPO4 = 53.7 - vCHOL = 120.4 - vCHCH = 42.14 - - vHead = vCHOL + vPO4 + vGLYC + 2 * vCOO - vTail = (28 * vCH2) + (1 * vCHCH) + (2 * vCH3) # Tail volume - - # Calculate sum_b's for other fragments - sumbHead = CHOL + PO4 + GLYC + 2 * COO - sumbTail = (28 * CH2) + (2 * CH) + 2 * CH3 - - # Calculate SLDs and Thickness - sldHead = sumbHead / vHead - thickHead = vHead / thiolAPM - - sldTail = sumbTail / vTail - thickTail = vTail / thiolAPM - - # Correct head SLD based on hydration - thiolHeadHydr = thiolHeadHydr / 100 - sldHead = sldHead * (1 - thiolHeadHydr) + (thiolHeadHydr * bulk_out[contrast - 1]) - - # Now correct both the SLDs for the coverage parameter - sldTail = (thiolCoverage * sldTail) + ((1 - thiolCoverage) * bulk_out[contrast - 1]) - sldHead = (thiolCoverage * sldHead) + ((1 - thiolCoverage) * bulk_out[contrast - 1]) - - SAMTAILS = [thickTail, sldTail, 0, goldRough] - SAMHEAD = [thickHead, sldHead, 0, goldRough] - - # Now do the same for the bilayer - vHead = vCHOL + vPO4 + vGLYC + 2 * vCOO - vTail = 28 * vCH2 # Tail volume - vMe = 2 * vCH3 - - sumbHead = CHOL + PO4 + GLYC + 2 * COO - sumbTail = 28 * CH2 - sumbMe = 2 * CH3 - - sldHead = sumbHead / vHead - thickHead = vHead / bilayerAPM - bilHeadHydr = bilHeadHydr / 100 - sldHead = sldHead * (1 - bilHeadHydr) + (bilHeadHydr * bulk_out[contrast - 1]) - - sldTail = sumbTail / vTail - thickTail = vTail / bilayerAPM - - sldMe = sumbMe / vMe - thickMe = vMe / bilayerAPM - - sldTail = (bilayerCoverage * sldTail) + ((1 - bilayerCoverage) * bulk_out[contrast - 1]) - sldHead = (bilayerCoverage * sldHead) + ((1 - bilayerCoverage) * bulk_out[contrast - 1]) - sldMe = (bilayerCoverage * sldMe) + ((1 - bilayerCoverage) * bulk_out[contrast - 1]) - - BILTAILS = [thickTail, sldTail, 0, bilayerRough] - BILHEAD = [thickHead, sldHead, 0, bilayerRough] - BILME = [thickMe, sldMe, 0, bilayerRough] - - BILAYER = [BILHEAD, BILTAILS, BILME, BILME, BILTAILS, BILHEAD] - - CW = [cwThick, bulk_out[contrast - 1], 0, bilayerRough] - - if contrast == 2 or contrast == 4: - output = [alloyUp, gold, SAMTAILS, SAMHEAD, CW, *BILAYER] - elif contrast == 1 or contrast == 3: - output = [alloyDown, gold, SAMTAILS, SAMHEAD, CW, *BILAYER] - - return output, subRough diff --git a/ratapi/examples/bayes_benchmark/bayes_benchmark.ipynb b/ratapi/examples/bayes_benchmark/bayes_benchmark.ipynb deleted file mode 100644 index bb9bba9f..00000000 --- a/ratapi/examples/bayes_benchmark/bayes_benchmark.ipynb +++ /dev/null @@ -1,365 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Bayesian parameter estimation for low-dimensional examples\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The Bayesian procedures available in RAT ([Nested Sampler (NS)](https://en.wikipedia.org/wiki/Nested_sampling_algorithm) and [DREAM](https://doi.org/10.1016/j.envsoft.2015.08.013)) estimate the parameters of our reflectivity model - that is, they find the maximum value of \n", - "$$P((X_1, X_2, ...) = (x_1, x_2, ...) | I)$$\n", - "where $P$ is a probability measure, $X_1, X_2, ...$ are our parameters, $x_1, x_2, ...$ are proposed values of these parameters, and $I$ is our background information on the model (e.g. our data), over a range of values of $x_1, x_2, ...$ between given minimum and maximum values. It can be shown that under some weak assumptions about our data, this probability is proportional to $\\exp(-\\chi^2/2)$, where $\\chi^2$ is the chi-squared measure of fit given by the least-squares solution. [1]\n", - "\n", - "If we want to calculate $\\chi^2$ directly for a sample of $N$ values between some given minimum and maximum values for each parameter, we would have to perform $N^P$ calculations, where $P$ is the number of parameters. Of course, for large numbers of parameters, this is infeasible, hence why algorithms such as NS and DREAM have been developed to do so more efficiently. However, for a small number of parameters, it is feasible for us to perform this direct calculation and compare it to the results of NS and DREAM. Here we will do so for an example of 2 and 3 parameters.\n", - "\n", - "*[1] D. S. Sivia, J. R. P. Webster,\n", - " \"The Bayesian approach to reflectivity data\",\n", - " Physica B: Condensed Matter,\n", - " Volume 248, June 1998, pages 327-337 \n", - " DOI: 10.1016/S0921-4526(98)00259-2 \n", - " URL: https://bayes.wustl.edu/sivia/98_20feb03.pdf*" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Two-parameter example\n", - "We will start with a two-dimensional example on a simple project. This project represents a bare D2O substrate, and we will estimate the true values of the substrate roughness and background signal for this project." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "\n", - "import ratapi as RAT\n", - "from ratapi.models import Parameter, Background, Resolution, Data, Contrast" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "project = RAT.Project(\n", - " name=\"Bare D2O Substrate\",\n", - " calculation=\"normal\",\n", - " model=\"standard layers\",\n", - " geometry=\"air/substrate\",\n", - " absorption=\"False\",\n", - " parameters=[Parameter(name=\"Substrate Roughness\", min=3.0, value=4.844363132849221, max=8.0, fit=True)],\n", - " background_parameters=[\n", - " Parameter(name=\"Background parameter 1\", min=5e-08, value=3.069003361230152e-06, max=7e-06, fit=True)\n", - " ],\n", - " scalefactors=[Parameter(name=\"Scalefactor 1\", min=0.07, value=0.10141560336360426, max=0.13, fit=False)],\n", - " bulk_in=[Parameter(name=\"Air\", min=0.0, value=0.0, max=0.0, fit=False)],\n", - " bulk_out=[Parameter(name=\"D2O\", min=6.3e-06, value=6.35e-06, max=6.4e-06, fit=False)],\n", - " resolution_parameters=[Parameter(name=\"Resolution parameter 1\", min=0.01, value=0.03, max=0.05, fit=False)],\n", - " backgrounds=[Background(name=\"Background 1\", type=\"constant\", source=\"Background parameter 1\")],\n", - " resolutions=[Resolution(name=\"Resolution 1\", type=\"constant\", source=\"Resolution parameter 1\")],\n", - " data=[\n", - " Data(name=\"Simulation\", data=np.empty([0, 3]), simulation_range=[0.005, 0.7]),\n", - " Data(\n", - " name=\"f82395c\",\n", - " data=np.array(\n", - " [\n", - " [4.8866e-02, 1.2343e-04, 1.3213e-06],\n", - " [5.1309e-02, 1.0063e-04, 1.0803e-06],\n", - " [5.3874e-02, 8.2165e-05, 8.8779e-07],\n", - " [5.6568e-02, 6.4993e-05, 7.2018e-07],\n", - " [5.9396e-02, 5.3958e-05, 6.0015e-07],\n", - " [6.2366e-02, 4.3590e-05, 5.0129e-07],\n", - " [6.5485e-02, 3.5780e-05, 4.1957e-07],\n", - " [6.8759e-02, 2.9130e-05, 3.5171e-07],\n", - " [7.2197e-02, 2.3481e-05, 3.0586e-07],\n", - " [7.5807e-02, 1.8906e-05, 2.6344e-07],\n", - " [7.9597e-02, 1.4642e-05, 2.2314e-07],\n", - " [8.3577e-02, 1.1589e-05, 1.8938e-07],\n", - " [8.7756e-02, 9.5418e-06, 1.6220e-07],\n", - " [9.2143e-02, 7.5694e-06, 1.3809e-07],\n", - " [9.6751e-02, 6.3831e-06, 1.2097e-07],\n", - " [1.0159e-01, 5.0708e-06, 1.0333e-07],\n", - " [1.0667e-01, 4.1041e-06, 8.9548e-08],\n", - " [1.1200e-01, 3.4253e-06, 7.9830e-08],\n", - " [1.1760e-01, 2.8116e-06, 7.1554e-08],\n", - " [1.2348e-01, 2.3767e-06, 6.3738e-08],\n", - " [1.2966e-01, 1.9241e-06, 5.6586e-08],\n", - " [1.3614e-01, 1.5642e-06, 5.2778e-08],\n", - " [1.4294e-01, 1.2922e-06, 4.9730e-08],\n", - " [1.5009e-01, 1.1694e-06, 5.1175e-08],\n", - " [1.5760e-01, 9.7837e-07, 5.0755e-08],\n", - " [1.6548e-01, 8.9138e-07, 5.3542e-08],\n", - " [1.7375e-01, 7.9420e-07, 5.4857e-08],\n", - " [1.8244e-01, 7.9131e-07, 5.8067e-08],\n", - " [1.9156e-01, 6.5358e-07, 5.7717e-08],\n", - " [2.0114e-01, 6.2970e-07, 5.7951e-08],\n", - " [2.1119e-01, 5.0130e-07, 5.5262e-08],\n", - " [2.2175e-01, 5.0218e-07, 5.6461e-08],\n", - " [2.3284e-01, 3.9299e-07, 5.0685e-08],\n", - " [2.4448e-01, 3.5324e-07, 5.0194e-08],\n", - " [2.5671e-01, 4.4475e-07, 5.6485e-08],\n", - " [2.6954e-01, 5.1338e-07, 6.2247e-08],\n", - " [2.8302e-01, 3.4918e-07, 4.9745e-08],\n", - " [2.9717e-01, 4.3037e-07, 5.5488e-08],\n", - " [3.1203e-01, 4.0099e-07, 5.3591e-08],\n", - " [3.2763e-01, 3.8397e-07, 5.1303e-08],\n", - " [3.4401e-01, 3.0995e-07, 4.5965e-08],\n", - " [3.6121e-01, 3.9357e-07, 5.0135e-08],\n", - " [3.7927e-01, 3.0997e-07, 4.3680e-08],\n", - " [3.9824e-01, 2.9656e-07, 4.2432e-08],\n", - " [4.1815e-01, 2.1909e-07, 3.6117e-08],\n", - " [4.3906e-01, 2.3153e-07, 3.6307e-08],\n", - " [4.6101e-01, 3.3428e-07, 4.3874e-08],\n", - " [4.8406e-01, 2.3441e-07, 3.7488e-08],\n", - " [5.0826e-01, 1.5496e-07, 3.0585e-08],\n", - " [5.3368e-01, 2.4708e-07, 3.9376e-08],\n", - " [5.6036e-01, 2.2157e-07, 3.8258e-08],\n", - " [5.8838e-01, 2.2798e-07, 4.6976e-08],\n", - " [6.1169e-01, 6.0272e-07, 2.3239e-07],\n", - " ]\n", - " ),\n", - " data_range=[0.048866, 0.61169],\n", - " simulation_range=[0.048866, 0.61169],\n", - " ),\n", - " ],\n", - " contrasts=[\n", - " Contrast(\n", - " name=\"Chain-d, acmw\",\n", - " data=\"f82395c\",\n", - " background=\"Background 1\",\n", - " background_action=\"add\",\n", - " bulk_in=\"Air\",\n", - " bulk_out=\"D2O\",\n", - " scalefactor=\"Scalefactor 1\",\n", - " resolution=\"Resolution 1\",\n", - " resample=False,\n", - " model=[],\n", - " )\n", - " ],\n", - " )" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Firstly, we will run calculations using nested sampling and DREAM." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "ns_controls = RAT.Controls(procedure=\"ns\", nsTolerance=1, nLive=500, display=\"final\")\n", - "_, ns_results = RAT.run(project, ns_controls)\n", - "\n", - "dream_controls = RAT.Controls(procedure=\"dream\", display=\"final\")\n", - "_, dream_results = RAT.run(project, dream_controls)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we will perform our direct calculation. The standard `'calculate'` procedure in RAT runs an Abelès calculation for the reflectivity of our model, and calculates the $\\chi^2$ statistic for how well this reflectivity fits the given data. We will take a sample of 30 values between the minimum and maximum value of our roughness and background parameters, and calculate $\\exp(-\\chi^2 / 2)$ on this roughness-background grid. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "rough_param = project.parameters[0]\n", - "roughness = np.linspace(rough_param.min, rough_param.max, 30)\n", - "\n", - "back_param = project.background_parameters[0]\n", - "background = np.linspace(back_param.min, back_param.max, 30)\n", - "\n", - "controls = RAT.Controls(procedure=\"calculate\", display=\"off\")\n", - "\n", - "# function to calculate exp(-chi_squared / 2) for a given pair of roughness/background values\n", - "def calculate_posterior(roughness_index: int, background_index: int) -> float:\n", - " \"\"\"Calculate the posterior for an item in the roughness and background vectors.\n", - "\n", - " Parameters\n", - " ----------\n", - " roughness_index : int\n", - " The index of the roughness vector to use as the roughness parameter value.\n", - " background_index : int\n", - " The index of the background vector to use as the background parameter value.\n", - "\n", - " Returns\n", - " -------\n", - " float\n", - " The value of exp(-chi^2 / 2) for the given roughness and background values.\n", - " \"\"\"\n", - " project.parameters[0].value = roughness[roughness_index]\n", - " project.background_parameters[0].value = background[background_index]\n", - "\n", - " _, results = RAT.run(project, controls)\n", - " chi_squared = results.calculationResults.sumChi\n", - "\n", - " return np.exp(-chi_squared / 2)\n", - "\n", - "# we vectorise the calculation to make it faster by running it over a matrix of indices (x, y)\n", - "vectorized_calc_posterior = np.vectorize(calculate_posterior)\n", - "probability_array = vectorized_calc_posterior(*np.indices((30, 30), dtype=int))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can get the parameter values that best fit our model for each method:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# get the vector indices that produced the lowest chi-squared\n", - "best_indices = np.unravel_index(np.argmax(probability_array, axis=None), probability_array.shape)\n", - "print(\"Best values according to direct calculation:\\n\",\n", - " \"Roughness: \", roughness[best_indices[0]], \"\\n\",\n", - " \"Background: \", background[best_indices[1]])\n", - "\n", - "print(\"Best values according to Nested Sampler:\\n\",\n", - " \"Roughness: \", ns_results.fitParams[0], \"\\n\",\n", - " \"Background: \", ns_results.fitParams[1])\n", - "\n", - "print(\"Best values according to DREAM:\\n\",\n", - " \"Roughness: \", dream_results.fitParams[0], \"\\n\",\n", - " \"Background: \", dream_results.fitParams[1])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "And finally, we will plot the posteriors created via each method to compare, as well as contour plots\n", - "for each method." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "from matplotlib import colormaps\n", - "import ratapi.utils.plotting as RATplot\n", - "\n", - "fig, axes = plt.subplots(3, 2, figsize=(6, 9))\n", - "\n", - "# plot NS and DREAM for each parameter\n", - "for i in [0, 1]:\n", - " RATplot.plot_one_hist(ns_results, i, axes=axes[0][i])\n", - " RATplot.plot_one_hist(dream_results, i, axes=axes[1][i])\n", - " # we want all 3 plots to have the same x-range\n", - " # so we will use the nested sampler x-range as our base\n", - " axes[1][i].set_xlim(*axes[0][i].get_xlim())\n", - " axes[1][i].set_title(\"\")\n", - "\n", - "# marginalise the probability array to get distributions for each parameter\n", - "roughness_distribution = np.sum(probability_array, axis=1)\n", - "background_distribution = np.sum(probability_array, axis=0)\n", - "\n", - "axes[2][0].hist(\n", - " roughness,\n", - " bins=25,\n", - " range=axes[0][0].get_xlim(),\n", - " weights=roughness_distribution,\n", - " density=True,\n", - " edgecolor=\"black\",\n", - " linewidth=1.2,\n", - " color=\"white\",\n", - " )\n", - "\n", - "axes[2][1].hist(\n", - " background,\n", - " bins=25,\n", - " range=axes[0][1].get_xlim(),\n", - " weights=background_distribution,\n", - " density=True,\n", - " edgecolor=\"black\",\n", - " linewidth=1.2,\n", - " color=\"white\",\n", - " )\n", - "\n", - "axes[0][0].set_ylabel(\"nested sampler\")\n", - "axes[1][0].set_ylabel(\"DREAM\")\n", - "axes[2][0].set_ylabel(\"direct calculation\")\n", - "fig.tight_layout()\n", - "\n", - "fig.show()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "contour_fig, axes = plt.subplots(1, 3, figsize=(9, 3))\n", - "\n", - "# plot NS and DREAM for each parameter\n", - "RATplot.plot_contour(ns_results, 0, 1, axes=axes[0])\n", - "RATplot.plot_contour(dream_results, 0, 1, axes=axes[1])\n", - "\n", - "axes[2].pcolormesh(roughness, background, probability_array.max() - probability_array.T, cmap=colormaps[\"Greys\"].reversed())\n", - "axes[2].contour(roughness, background, probability_array.max() - probability_array.T, colors=\"black\")\n", - "\n", - "axes[1].set_xlim(*axes[0].get_xlim())\n", - "axes[1].set_ylim(*axes[0].get_ylim())\n", - "axes[2].set_xlim(*axes[0].get_xlim())\n", - "axes[2].set_ylim(*axes[0].get_ylim())\n", - "\n", - "axes[0].set_title(\"NS\")\n", - "axes[1].set_title(\"DREAM\")\n", - "axes[2].set_title(\"direct\")\n", - "axes[1].set_ylabel(\"\")\n", - "axes[2].set_ylabel(\"\")\n", - "axes[2].set_xlabel(\"Substrate Roughness\")\n", - "fig.tight_layout()\n", - "fig.show()" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": ".venv", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.16" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/ratapi/examples/bayes_benchmark/bayes_benchmark.py b/ratapi/examples/bayes_benchmark/bayes_benchmark.py deleted file mode 100644 index ee6ea96e..00000000 --- a/ratapi/examples/bayes_benchmark/bayes_benchmark.py +++ /dev/null @@ -1,366 +0,0 @@ -"""An example script to compare different methods of Bayesian fitting. - -This example compares three Bayesian posteriors for a low-dimensional -example: a posterior generated by DREAM, one generated by NS, and -one calculated directly. - -The likelihood of the parameters being equal to a certain value is proportional -to exp(-chi^2 / 2) [1], so for a low-dimensional example we can calculate this directly -for a sample of parameter values. - -Citation: -[1] D. S. Sivia, J. R. P. Webster, - "The Bayesian approach to reflectivity data", - Physica B: Condensed Matter, - Volume 248, June 1998, pages 327-337 - DOI: 10.1016/S0921-4526(98)00259-2 - URL: https://bayes.wustl.edu/sivia/98_20feb03.pdf - -""" - -from dataclasses import dataclass -from pathlib import Path - -import matplotlib.pyplot as plt -import numpy as np - -import ratapi as RAT -import ratapi.utils.plotting as RATplot -from ratapi.models import Background, Contrast, Data, Parameter, Resolution - -PWD = Path(__file__).parents[0] - - -# function to get our starting project -# this is the RasCAL-1 default project -# it is a bare D2O substrate -def get_project() -> RAT.Project: - """Create the project used as our example.""" - return RAT.Project( - name="Bare D2O Substrate", - calculation="normal", - model="standard layers", - geometry="air/substrate", - absorption="False", - parameters=[Parameter(name="Substrate Roughness", min=3.0, value=4.844363132849221, max=8.0, fit=True)], - background_parameters=[ - Parameter(name="Background parameter 1", min=5e-08, value=3.069003361230152e-06, max=7e-06, fit=True) - ], - scalefactors=[Parameter(name="Scalefactor 1", min=0.07, value=0.10141560336360426, max=0.13, fit=False)], - bulk_in=[Parameter(name="Air", min=0.0, value=0.0, max=0.0, fit=False)], - bulk_out=[Parameter(name="D2O", min=6.3e-06, value=6.35e-06, max=6.4e-06, fit=False)], - resolution_parameters=[Parameter(name="Resolution parameter 1", min=0.01, value=0.03, max=0.05, fit=False)], - backgrounds=[Background(name="Background 1", type="constant", source="Background parameter 1")], - resolutions=[Resolution(name="Resolution 1", type="constant", source="Resolution parameter 1")], - data=[ - Data(name="Simulation", data=np.empty([0, 3]), simulation_range=[0.005, 0.7]), - Data( - name="f82395c", - data=np.array( - [ - [4.8866e-02, 1.2343e-04, 1.3213e-06], - [5.1309e-02, 1.0063e-04, 1.0803e-06], - [5.3874e-02, 8.2165e-05, 8.8779e-07], - [5.6568e-02, 6.4993e-05, 7.2018e-07], - [5.9396e-02, 5.3958e-05, 6.0015e-07], - [6.2366e-02, 4.3590e-05, 5.0129e-07], - [6.5485e-02, 3.5780e-05, 4.1957e-07], - [6.8759e-02, 2.9130e-05, 3.5171e-07], - [7.2197e-02, 2.3481e-05, 3.0586e-07], - [7.5807e-02, 1.8906e-05, 2.6344e-07], - [7.9597e-02, 1.4642e-05, 2.2314e-07], - [8.3577e-02, 1.1589e-05, 1.8938e-07], - [8.7756e-02, 9.5418e-06, 1.6220e-07], - [9.2143e-02, 7.5694e-06, 1.3809e-07], - [9.6751e-02, 6.3831e-06, 1.2097e-07], - [1.0159e-01, 5.0708e-06, 1.0333e-07], - [1.0667e-01, 4.1041e-06, 8.9548e-08], - [1.1200e-01, 3.4253e-06, 7.9830e-08], - [1.1760e-01, 2.8116e-06, 7.1554e-08], - [1.2348e-01, 2.3767e-06, 6.3738e-08], - [1.2966e-01, 1.9241e-06, 5.6586e-08], - [1.3614e-01, 1.5642e-06, 5.2778e-08], - [1.4294e-01, 1.2922e-06, 4.9730e-08], - [1.5009e-01, 1.1694e-06, 5.1175e-08], - [1.5760e-01, 9.7837e-07, 5.0755e-08], - [1.6548e-01, 8.9138e-07, 5.3542e-08], - [1.7375e-01, 7.9420e-07, 5.4857e-08], - [1.8244e-01, 7.9131e-07, 5.8067e-08], - [1.9156e-01, 6.5358e-07, 5.7717e-08], - [2.0114e-01, 6.2970e-07, 5.7951e-08], - [2.1119e-01, 5.0130e-07, 5.5262e-08], - [2.2175e-01, 5.0218e-07, 5.6461e-08], - [2.3284e-01, 3.9299e-07, 5.0685e-08], - [2.4448e-01, 3.5324e-07, 5.0194e-08], - [2.5671e-01, 4.4475e-07, 5.6485e-08], - [2.6954e-01, 5.1338e-07, 6.2247e-08], - [2.8302e-01, 3.4918e-07, 4.9745e-08], - [2.9717e-01, 4.3037e-07, 5.5488e-08], - [3.1203e-01, 4.0099e-07, 5.3591e-08], - [3.2763e-01, 3.8397e-07, 5.1303e-08], - [3.4401e-01, 3.0995e-07, 4.5965e-08], - [3.6121e-01, 3.9357e-07, 5.0135e-08], - [3.7927e-01, 3.0997e-07, 4.3680e-08], - [3.9824e-01, 2.9656e-07, 4.2432e-08], - [4.1815e-01, 2.1909e-07, 3.6117e-08], - [4.3906e-01, 2.3153e-07, 3.6307e-08], - [4.6101e-01, 3.3428e-07, 4.3874e-08], - [4.8406e-01, 2.3441e-07, 3.7488e-08], - [5.0826e-01, 1.5496e-07, 3.0585e-08], - [5.3368e-01, 2.4708e-07, 3.9376e-08], - [5.6036e-01, 2.2157e-07, 3.8258e-08], - [5.8838e-01, 2.2798e-07, 4.6976e-08], - [6.1169e-01, 6.0272e-07, 2.3239e-07], - ] - ), - data_range=[0.048866, 0.61169], - simulation_range=[0.048866, 0.61169], - ), - ], - contrasts=[ - Contrast( - name="Chain-d, acmw", - data="f82395c", - background="Background 1", - background_action="add", - bulk_in="Air", - bulk_out="D2O", - scalefactor="Scalefactor 1", - resolution="Resolution 1", - resample=False, - model=[], - ) - ], - ) - - -@dataclass -class CalculationResults: - """Data class for results from a direct calculation.""" - - x_data: list[np.array] - distribution: np.array - - -def bayes_benchmark_2d(grid_size: int) -> (RAT.outputs.BayesResults, CalculationResults): - """Bayes benchmark for a 2-dimensional example. - - Parameters - ---------- - grid_size : int - The number of points to sample for each fit parameter. - - Here we estimate the substrate roughness and background using two different methods: - nested sampling (the 'ns' procedure in RAT) and through a direct calculation of chi-squared - over a range of parameter values. - - Returns - ------- - RAT.BayesResults - The BayesResults object from a nested sampler calculation. - CalculationResults - Results from the direct calculation. - - """ - problem = get_project() - - ns_controls = RAT.Controls(procedure="ns", nsTolerance=1, nLive=500, display="final") - _, ns_results = RAT.run(problem, ns_controls) - - dream_controls = RAT.Controls(procedure="dream", display="final") - _, dream_results = RAT.run(problem, dream_controls) - - # now we get the parameters and use them to do a direct calculation - rough_param = problem.parameters[0] - roughness = np.linspace(rough_param.min, rough_param.max, grid_size) - - back_param = problem.background_parameters[0] - background = np.linspace(back_param.min, back_param.max, grid_size) - - controls = RAT.Controls(procedure="calculate", display="off") - - def calculate_posterior(roughness_index: int, background_index: int) -> float: - """Calculate the posterior for an item in the roughness and background vectors. - - Parameters - ---------- - roughness_index : int - The index of the roughness vector to use as the roughness parameter value. - background_index : int - The index of the background vector to use as the background parameter value. - - Returns - ------- - float - The value of exp(-chi^2 / 2) for the given roughness and background values. - - """ - problem.parameters[0].value = roughness[roughness_index] - problem.background_parameters[0].value = background[background_index] - - _, results = RAT.run(problem, controls) - chi_squared = results.calculationResults.sumChi - - return np.exp(-chi_squared / 2) - - vectorized_calc_posterior = np.vectorize(calculate_posterior) - - print("Calculating posterior directly...") - probability_array = vectorized_calc_posterior(*np.indices((grid_size, grid_size), dtype=int)) - - return ns_results, dream_results, CalculationResults(x_data=[roughness, background], distribution=probability_array) - - -def bayes_benchmark_3d(grid_size: int) -> (RAT.outputs.BayesResults, CalculationResults): - """Bayes benchmark for a 3-dimensional example. - - Here we estimate the substrate roughness and background using two different methods: - nested sampling (the 'ns' procedure in RAT) and through a direct calculation of chi-squared - over a range of parameter values. - - Parameters - ---------- - grid_size : int - The number of points to sample for each fit parameter. - - Returns - ------- - RAT.BayesResults - The BayesResults object from a nested sampler calculation. - CalculationResults - Results from the direct calculation. - - """ - problem = get_project() - problem.scalefactors[0].fit = True - - ns_controls = RAT.Controls(procedure="ns", nsTolerance=1, nLive=500, display="final") - _, ns_results = RAT.run(problem, ns_controls) - - dream_controls = RAT.Controls(procedure="dream", display="final") - _, dream_results = RAT.run(problem, dream_controls) - - # now we get the parameters and use them to do a direct calculation - rough_param = problem.parameters[0] - roughness = np.linspace(rough_param.min, rough_param.max, grid_size) - - back_param = problem.background_parameters[0] - background = np.linspace(back_param.min, back_param.max, grid_size) - - scale_param = problem.scalefactors[0] - scalefactor = np.linspace(scale_param.min, scale_param.max, grid_size) - - controls = RAT.Controls(procedure="calculate", display="off") - - def calculate_posterior(roughness_index: int, background_index: int, scalefactor_index: int) -> float: - """Calculate the posterior for an item in the roughness, background, and scalefactor vectors. - - Parameters - ---------- - roughness_index : int - The index of the roughness vector to use as the roughness parameter value. - background_index : int - The index of the background vector to use as the background parameter value. - scalefactor_index : int - The index of the scalefactor vector to use as the scalefactor parameter. - - Returns - ------- - float - The value of exp(-chi^2 / 2) for the given roughness and background values. - - """ - problem.parameters[0].value = roughness[roughness_index] - problem.background_parameters[0].value = background[background_index] - problem.scalefactors[0].value = scalefactor[scalefactor_index] - - _, results = RAT.run(problem, controls) - chi_squared = results.calculationResults.sumChi - - return np.exp(-chi_squared / 2) - - vectorized_calc_posterior = np.vectorize(calculate_posterior) - - print("Calculating posterior directly...") - probability_array = vectorized_calc_posterior(*np.indices((grid_size, grid_size, grid_size), dtype=int)) - - return ( - ns_results, - dream_results, - CalculationResults(x_data=[roughness, background, scalefactor], distribution=probability_array), - ) - - -def plot_posterior_comparison( - ns_results: RAT.outputs.BayesResults, dream_results: RAT.outputs.BayesResults, calc_results: CalculationResults -): - """Create a grid of marginalised posteriors comparing different calculation methods. - - Parameters - ---------- - ns_results : RAT.BayesResults - The BayesResults object from a nested sampler calculation. - dream_results : RAT.BayesResults - The BayesResults object from a DREAM calculation. - calc_results : CalculationResults - The results from a direct calculation. - - """ - num_params = calc_results.distribution.ndim - fig, axes = plt.subplots(3, num_params, figsize=(3 * num_params, 9)) - - def plot_marginalised_result(dimension: int, axes: plt.Axes, limits: tuple[float]): - """Plot a histogram of a marginalised posterior from the calculation results. - - Parameters - ---------- - dimension : int - The dimension of the array to marginalise over. - axes : plt.Axes - The Axes object to plot the histogram onto. - limits : tuple[float] - The x-axis limits for the histogram. - - """ - # marginalise to the dimension - # note we don't need to normalise here as np.histogram normalises for us - sum_axes = tuple(i for i in range(0, num_params) if i != dimension) - distribution = np.sum(calc_results.distribution, axis=sum_axes) - distribution /= np.sum(calc_results.distribution) - - # create histogram - axes.hist( - calc_results.x_data[dimension], - bins=25, - range=limits, - weights=distribution, - density=True, - edgecolor="black", - linewidth=1.2, - color="white", - ) - - # row 0 contains NS histograms for each parameter - # row 1 contains direct calculation histograms for each parameter - for i in range(0, num_params): - RATplot.plot_one_hist(ns_results, i, axes=axes[0][i]) - RATplot.plot_one_hist(dream_results, i, axes=axes[1][i]) - # we want all 3 plots to have the same x-axis - axes[1][i].set_xlim(*axes[0][i].get_xlim()) - axes[1][i].set_title("") - plot_marginalised_result(i, axes[2][i], limits=axes[0][i].get_xlim()) - - axes[0][0].set_ylabel("nested sampler") - axes[1][0].set_ylabel("DREAM") - axes[2][0].set_ylabel("direct calculation") - - fig.tight_layout() - fig.show() - - -if __name__ == "__main__": - ns_2d, dream_2d, calc_2d = bayes_benchmark_2d(30) - ns_3d, dream_3d, calc_3d = bayes_benchmark_3d(30) - - plot_posterior_comparison(ns_2d, dream_2d, calc_2d) - plot_posterior_comparison(ns_3d, dream_3d, calc_3d) diff --git a/ratapi/examples/convert_rascal_project/Model_IIb.m b/ratapi/examples/convert_rascal_project/Model_IIb.m deleted file mode 100644 index 1f906560..00000000 --- a/ratapi/examples/convert_rascal_project/Model_IIb.m +++ /dev/null @@ -1,130 +0,0 @@ -function [output,sub_rough] = Model_IIb(params,bulk_in,bulk_out,contrast) -%MODEL_1 RASCAL Custom Layer Model File. -% -% -% This file accepts 3 vectors containing the values for -% Params, bulk in and bulk out -% The final parameter is an index of the contrast being calculated -% The m-file should output a matrix of layer values, in the form.. -% Output = [thick 1, SLD 1, Rough 1, Percent Hydration 1, Hydrate how 1 -% .... -% thick n, SLD n, Rough n, Percent Hydration n, Hydration how n] -% The "hydrate how" parameter decides if the layer is hydrated with -% Bulk out or Bulk in phases. Set to 1 for Bulk out, zero for Bulk in. -% Alternatively, leave out hydration and just return.. -% Output = [thick 1, SLD 1, Rough 1, -% .... -% thick n, SLD n, Rough n] }; -% The second output parameter should be the substrate roughness - - -Roughness = params(1); -APM = params(2); -thickHead = params(3); -theta = params(4); -% vTail = params(4); -% vHead = params(5); - -%Make a flag to say which deuteration this is calculating -%[subs head tail] -deut = [0 0 1; - 1 0 1; - 0 1 0; - 1 1 0; - 0 1 1; - 1 1 1; - 1 0 0]; - - -%Neutron b's.. -%define all the neutron b's. -bc = 0.6646e-4; %Carbon -bo = 0.5843e-4; %Oxygen -bh = -0.3739e-4; %Hydrogen -bp = 0.513e-4; %Phosphorus -bn = 0.936e-4; %Nitrogen -bd = 0.6671e-4; %Deuterium - -%Work out the total scattering length in each fragment.... -%Define scattering lengths.. -%Hydrogenated version.... -COO = (4*bo) + (2*bc); -GLYC = (3*bc) + (5*bh); -CH3 = (2*bc) + (6*bh); -PO4 = (1*bp) + (4*bo); -CH2 = (1*bc) + (2*bh); -CHOL = (5*bc) + (12*bh) + (1*bn); -H2O = (2*bh) + (1*bo); - -%..and deuterated... -dGLYC = (3*bc) + (5*bd); -dCH3 = (2*bc) + (6*bd); -dCH2 = (1*bc) + (2*bd); -dCHOL = (5*bc) + (12*bd) + (1*bn); -D2O = (2*bd) + (1*bo); - -%And also volumes.... -vCH3 = 52.7; -vCH2 = 28.1; -vCOO = 39.0; -vGLYC = 68.8; -vPO4 = 53.7; -vCHOL = 120.4; -vWAT = 30.4; - -vHead = vCHOL + vPO4 + vGLYC + 2*vCOO; -vTail = 2*(16*vCH2)+ 2*(vCH3); - -%Make the SLD's first... -thisMask = deut(contrast,:); - -switch thisMask(1) - case 0 - thisWater = (H2O * 0.9249) + (D2O * 0.0871); - case 1 - thisWater = D2O; -end - -%Calculate mole fraction of D2O from the bulk SLD.. -d2o_molfr = (1/D2O-H2O)*((bulk_out(contrast)/0.036182336306)-H2O); -thisWater = (d2o_molfr * D2O) + ((1-d2o_molfr)*H2O); - - -switch thisMask(2) - case 0 - thisHead = CHOL + PO4 + GLYC + COO; - case 1 - thisHead = dCHOL + PO4 + GLYC + COO; -end - -switch thisMask(3); - case 0 - thisTail = (32*CH2) + CH3; - case 1 - thisTail = (32*dCH2) + dCH3; -end - -noWat = ((thickHead*APM)-vHead)/vWAT; -thisHead = thisHead + noWat*thisWater; -vHead = vHead + noWat*vWAT; - - -sldHead = thisHead/vHead; -%thickHead = vHead/APM; - -sldTail = thisTail/vTail; -%thickTail = vTail/APM; - -thickTail = (1.5 + 16*1.265)*cosd(theta); - -output = [thickTail sldTail Roughness; - thickHead sldHead Roughness;]; - - -sub_rough = Roughness; - - - - - - diff --git a/ratapi/examples/convert_rascal_project/Model_IIb.py b/ratapi/examples/convert_rascal_project/Model_IIb.py deleted file mode 100644 index 2e15d5d1..00000000 --- a/ratapi/examples/convert_rascal_project/Model_IIb.py +++ /dev/null @@ -1,90 +0,0 @@ -"""A custom model file for a monolayer volume model.""" - -from math import cos, radians - - -def Model_IIb(params, bulk_in, bulk_out, contrast): - """Calculate layer parameters for a monolayer volume model at two deuterations.""" - # Note - The first contrast number is 1 (not 0) so be careful if you use - # this variable for array indexing. Same applies to the domain number. - - # converted from matlab file Model_IIb.m - - Roughness, APM, thickHead, theta = params - - # Make a flag to say which deuteration this is calculating - # [subs head tail] - deut = [[0, 0, 1], [1, 0, 1], [0, 1, 0], [1, 1, 0], [0, 1, 1], [1, 1, 1], [1, 0, 0]] - - bc = 0.6646e-4 # Carbon - bo = 0.5843e-4 # Oxygen - bh = -0.3739e-4 # Hydrogen - bp = 0.513e-4 # Phosphorus - bn = 0.936e-4 # Nitrogen - bd = 0.6671e-4 # Deuterium - - # Work out the total scattering length in each fragment - # for hydrogenated: - COO = (4 * bo) + (2 * bc) - GLYC = (3 * bc) + (5 * bh) - CH3 = (2 * bc) + (6 * bh) - PO4 = (1 * bp) + (4 * bo) - CH2 = (1 * bc) + (2 * bh) - CHOL = (5 * bc) + (12 * bh) + (1 * bn) - H2O = (2 * bh) + (1 * bo) - - # for deuterated: - dCH3 = (2 * bc) + (6 * bd) - dCH2 = (1 * bc) + (2 * bd) - dCHOL = (5 * bc) + (12 * bd) + (1 * bn) - D2O = (2 * bd) + (1 * bo) - - # for volumes: - vCH3 = 52.7 - vCH2 = 28.1 - vCOO = 39.0 - vGLYC = 68.8 - vPO4 = 53.7 - vCHOL = 120.4 - vWAT = 30.4 - - vHead = vCHOL + vPO4 + vGLYC + 2 * vCOO - vTail = 2 * (16 * vCH2) + 2 * (vCH3) - - # make SLDs - thisMask = deut[contrast - 1] - - if thisMask[0] == 0: - thisWater = (H2O * 0.9249) + (D2O * 0.0871) - else: - thisWater = D2O - - # Calculate mole fraction of D2O from the bulk SLD - d2o_molfr = (1 / D2O - H2O) * ((bulk_out[contrast - 1] / 0.036182336306) - H2O) - thisWater = (d2o_molfr * D2O) + ((1 - d2o_molfr) * H2O) - - if thisMask[1] == 0: - thisHead = CHOL + PO4 + GLYC + COO - else: - thisHead = dCHOL + PO4 + GLYC + COO - - if thisMask[2] == 0: - thisTail = (32 * CH2) + CH3 - else: - thisTail = (32 * dCH2) + dCH3 - - noWat = ((thickHead * APM) - vHead) / vWAT - thisHead = thisHead + noWat * thisWater - vHead = vHead + noWat * vWAT - - sldHead = thisHead / vHead - - sldTail = thisTail / vTail - - thickTail = (1.5 + 16 * 1.265) * cos(radians(theta)) - - output = [[thickTail, sldTail, Roughness], [thickHead, sldHead, Roughness]] - - sub_rough = Roughness - - return output, sub_rough diff --git a/ratapi/examples/convert_rascal_project/R1monolayerVolumeModel.mat b/ratapi/examples/convert_rascal_project/R1monolayerVolumeModel.mat deleted file mode 100644 index e6604917..00000000 Binary files a/ratapi/examples/convert_rascal_project/R1monolayerVolumeModel.mat and /dev/null differ diff --git a/ratapi/examples/convert_rascal_project/__init__.py b/ratapi/examples/convert_rascal_project/__init__.py deleted file mode 100644 index 0648853e..00000000 --- a/ratapi/examples/convert_rascal_project/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""An example of converting between RAT and RasCAL-1.""" diff --git a/ratapi/examples/convert_rascal_project/convert_rascal.ipynb b/ratapi/examples/convert_rascal_project/convert_rascal.ipynb deleted file mode 100644 index aebd749a..00000000 --- a/ratapi/examples/convert_rascal_project/convert_rascal.ipynb +++ /dev/null @@ -1,157 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### RasCAL-1 to RAT\n", - "\n", - "RasCAL-1 (R1) project structs can be converted to RAT Projects, and vice versa. This is done via the functions `r1_to_project` and `project_to_r1`.\n", - "\n", - "Converting from R1 to a `Project` is very simple. We use the example R1 project in the file `R1monolayerVolumeModel.mat`, which is a project for analysing a monolayer of DSPC with various deuterations (tail-deuterated, head-deuterated, fully deuterated, hydrogenated)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Simply give the file path to the function `r1_to_project`, and it returns a RAT `Project` that you can use exactly like any other." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from ratapi.utils.convert import r1_to_project\n", - "\n", - "project = r1_to_project(\"R1monolayerVolumeModel.mat\")\n", - "print(project)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note that there are various features of RAT which do not feature in RasCAL-1, such as `prior_type`, `mu` and `sigma` for parameters. These are given sensible default values (again e.g. for parameters, `prior_type = uniform`, `mu = 0.0`, `sigma=inf`), but you may change these if you would like to use these new features:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "project.parameters[\"Head Thickness\"].prior_type = 'gaussian'\n", - "project.parameters[\"Theta\"].mu = 2.0\n", - "project.parameters[\"Area per molecule\"].sigma = 50.0\n", - "# etc...\n", - "print(project.parameters)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Also note that any custom files must be available to RAT. By default, RAT will assume these files are in the same directory that you are running RAT from, but if they are elsewhere you may change the relevant file location: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# e.g. if our model is in the directory `my_models/`\n", - "project.custom_files[0].filename = \"my_models/Model_IIb.m\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As well as MATLAB functions, RAT can also run custom files provided in Python or C++ format. This may be beneficial if you do not have access to MATLAB, do not have access to the custom files from your old RasCAL project, or find it more convenient to use Python. This is done similarly to changing the file path: if we have a function defined in the Python custom file `Model_IIb.py`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "project.custom_files[0].filename = \"Model_IIb.py\"\n", - "project.custom_files[0].language = 'python'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### RAT to RasCAL-1\n", - "\n", - "To demonstrate the other way around, we will use the DSPC lipid bilayer model project from another tutorial." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from ratapi.examples import DSPC_standard_layers\n", - "lipid_bilayer_project = DSPC_standard_layers()[0]\n", - "print(lipid_bilayer_project)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`project_to_r1` takes parameters `project` and `filename`, which are the `Project` object and filename for the produced .mat file respectively. This .mat file can then be loaded into RasCAL-1.\n", - "\n", - "Alternatively, if one sets `return_struct=True`, the struct is returned as a Python dictionary instead of being saved.\n", - "\n", - "Note that a MATLAB engine is used to save the project to a .mat file, so the Python library `matlabengine` must be installed." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from ratapi.utils.convert import project_to_r1\n", - "from pprint import pp # for printing the struct\n", - "\n", - "# save to a file called lipid_bilayer.mat\n", - "project_to_r1(lipid_bilayer_project, filename=\"lipid_bilayer.mat\")\n", - "\n", - "# return as a Python dictionary\n", - "struct = project_to_r1(lipid_bilayer_project, return_struct=True)\n", - "pp(struct)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/ratapi/examples/convert_rascal_project/convert_rascal.py b/ratapi/examples/convert_rascal_project/convert_rascal.py deleted file mode 100644 index 15179b35..00000000 --- a/ratapi/examples/convert_rascal_project/convert_rascal.py +++ /dev/null @@ -1,49 +0,0 @@ -"""An example of how to convert a RasCAL-1 project to RAT.""" - -import pathlib -from pprint import pp - -import ratapi as RAT - - -# convert R1 project to Project class -def convert_rascal(mat_filename="lipid_bilayer.mat"): - """Convert a project from RasCAL-1 and a project to RasCAL-1. - - We convert a RasCAL-1 monolayer volume model to RAT, and the DSPC Standard Layers - example to RasCAL-1. - - Parameters - ---------- - mat_filename : str - The filename of the output of the RAT project converted to RasCAL-2. - - Returns - ------- - project, struct - A RasCAL-1 monolayer volume model converted to a RAT project, and the - struct of the DSPC standard layers example converted to a RasCAL-1 struct. - - """ - project_path = pathlib.Path(__file__).parent / "R1monolayerVolumeModel.mat" - project = RAT.utils.convert.r1_to_project(project_path) - - # change values if you like, including ones not supported by R1 - project.parameters["Head Thickness"].prior_type = "gaussian" - project.parameters["Theta"].mu = 2.0 - project.parameters["Area per molecule"].sigma = 50.0 - - # convert DSPC standard layers example to a struct and save as file - lipid_bilayer_project = RAT.examples.DSPC_standard_layers()[0] - RAT.utils.convert.project_to_r1(lipid_bilayer_project, filename=mat_filename) - - # convert and return as a Python dictionary - struct = RAT.utils.convert.project_to_r1(lipid_bilayer_project, return_struct=True) - - return project, struct - - -if __name__ == "__main__": - project, struct = convert_rascal() - print(project) - pp(struct) diff --git a/ratapi/examples/data/D2O_spin_down.dat b/ratapi/examples/data/D2O_spin_down.dat deleted file mode 100644 index eaf8aee2..00000000 --- a/ratapi/examples/data/D2O_spin_down.dat +++ /dev/null @@ -1,100 +0,0 @@ -0.01218 1.015359223955 0.0231718818417596 -0.012545 0.919431439253596 0.0193509380578665 -0.012922 0.924921688167335 0.0183337262959345 -0.013309 0.892889622419078 0.01658695139614 -0.013709 0.88564788305433 0.0151834012597258 -0.01412 0.954057058169692 0.0152655865808885 -0.014544 0.801205833810502 0.0128764862406952 -0.01498 0.57206372730641 0.00977028529084846 -0.015429 0.507292263127758 0.00840850146518913 -0.015892 0.441240863619522 0.0072616120448651 -0.016369 0.411263430900333 0.00703930748762168 -0.01686 0.398699855165213 0.00667722051938428 -0.017366 0.369396072619489 0.00590757519620061 -0.017887 0.333584829398094 0.00529590083869447 -0.018423 0.300131361783826 0.00480817811310586 -0.018976 0.254862070126983 0.00436222169827209 -0.019545 0.218629795547172 0.0038320590117552 -0.020132 0.183303580450672 0.00337229276836539 -0.020736 0.158391997035939 0.00306386203644447 -0.021358 0.128249520024251 0.00266512849877059 -0.021998 0.0956717976354879 0.0021819192293442 -0.022658 0.0688201017211762 0.00176311091650106 -0.023338 0.0481760921553437 0.00145639799252248 -0.024038 0.0328252888275119 0.00118309811714777 -0.024759 0.0183323789955876 0.000868570851156994 -0.025502 0.0106467041665263 0.000644514803462562 -0.026267 0.00788878035636094 0.000551382666981037 -0.027055 0.0069025565024083 0.0005165549530129 -0.027867 0.00807841288019132 0.000666341069082825 -0.028703 0.0104166526322881 0.000419481963016605 -0.029564 0.0134376368351915 0.000465997507494358 -0.030451 0.0158250530499512 0.000492135134224797 -0.031365 0.018520664219071 0.000528646973626596 -0.032305 0.0188403112263801 0.000530903701707703 -0.033275 0.0189720098352925 0.000529859543938832 -0.034273 0.0167957829499141 0.000677826804540402 -0.035301 0.0143561588467109 0.000448314190440904 -0.03636 0.0120825895112668 0.000385361581730607 -0.037451 0.00911010812085284 0.000338273434605409 -0.038574 0.0064407693084981 0.000272228771598909 -0.039732 0.00380747078042373 0.000191909461416686 -0.040924 0.00219977095894102 0.000139024554548823 -0.042151 0.00106749974738118 9.30715079659133e-05 -0.043416 0.000526289198019469 6.53777493347705e-05 -0.044718 0.000538684361211223 6.36026811276904e-05 -0.04606 0.000666071609013439 6.89514635050019e-05 -0.047442 0.00096513860352319 8.1892283337263e-05 -0.048865 0.00123628279834282 9.06632085957762e-05 -0.050331 0.000932500252618815 7.56441779783758e-05 -0.051841 0.000704570716426959 6.33837448213143e-05 -0.053396 0.000422547071305871 4.87823773114622e-05 -0.054998 0.000225234935497996 3.52790595843578e-05 -0.056648 0.000224295193506012 3.47502441981879e-05 -0.058347 0.000348546599750749 4.2399541917882e-05 -0.060098 0.000753444036511839 6.21105459934656e-05 -0.061901 0.00108427363670046 0.000132874128465088 -0.063758 0.00147590016504429 6.80656135268955e-05 -0.06567 0.00157522988312169 6.65397958839974e-05 -0.06764 0.00123685540099027 5.63878877698811e-05 -0.06967 0.000809188588366061 4.4090403853279e-05 -0.07176 0.000394860049176463 3.01087945030146e-05 -0.073913 0.000158546936575836 1.87827141365489e-05 -0.07613 0.000205156792077874 2.11738354272626e-05 -0.078414 0.000432213951295092 3.08747347502442e-05 -0.080766 0.000654956381151268 3.77210414631682e-05 -0.083189 0.000798309138064603 4.33157061537943e-05 -0.085685 0.000842635319478595 5.73848900266092e-05 -0.088255 0.000695947994206608 4.00080838020816e-05 -0.090903 0.000486577520293712 3.1324396241032e-05 -0.09363 0.000518575903533295 3.11105123109569e-05 -0.096439 0.000572434234901815 3.26076998214827e-05 -0.099332 0.000634309003334568 3.34605409410893e-05 -0.10231 0.000482232476674863 2.81521775741857e-05 -0.10538 0.000365623631648085 2.39677995217084e-05 -0.10854 0.000216433695981677 1.81376940954562e-05 -0.1118 0.00016573141567584 1.53181312944188e-05 -0.11515 0.000215844252079895 1.6793425174307e-05 -0.11861 0.000301364141601267 1.9534170905049e-05 -0.12217 0.000246353868436121 1.75755330256998e-05 -0.12583 0.000162551786857085 1.40661524470343e-05 -0.12961 7.50985213378692e-05 9.36878978746337e-06 -0.13349 6.5539425376402e-05 8.69884468995251e-06 -0.1375 4.34100171780794e-05 7.01707703189734e-06 -0.14162 4.008555357203e-05 6.73885951025632e-06 -0.14587 3.09498467445855e-05 5.80450671966048e-06 -0.15025 9.04307992859308e-06 3.1003401933376e-06 -0.15476 1.20906733133484e-05 3.56933544410388e-06 -0.1594 1.50092626898851e-05 4.01428138367746e-06 -0.16418 2.38057866549901e-05 5.21304186735828e-06 -0.16911 2.45653272255718e-05 5.35080332783186e-06 -0.17418 1.01465189127286e-05 3.58853447404763e-06 -0.17941 9.15355855704133e-06 3.55249418976725e-06 -0.18479 4.82434571726902e-06 2.64124760012126e-06 -0.19033 1.52628919801947e-06 1.52659234059753e-06 -0.19604 3.69800262723568e-06 2.61612044865102e-06 -0.20192 1.54286099228671e-06 1.90198389976085e-06 -0.20798 1.2093704739129e-05 5.23729327360302e-06 -0.21422 2.37360638620364e-06 2.37431371888578e-06 -0.22065 5.71086934554886e-06 4.04257469096298e-06 -0.22727 3.01060999023207e-06 3.01168783050962e-06 diff --git a/ratapi/examples/data/D2O_spin_up.dat b/ratapi/examples/data/D2O_spin_up.dat deleted file mode 100644 index e78d2832..00000000 --- a/ratapi/examples/data/D2O_spin_up.dat +++ /dev/null @@ -1,101 +0,0 @@ -0.01218 0.992633447203191 0.0219469837210634 -0.012545 0.990954025840188 0.0202675623580603 -0.012922 0.970629210481116 0.0186524551995267 -0.013309 0.905284451993359 0.0164253134601805 -0.013709 0.849691788011222 0.0143674497604916 -0.01412 0.923719918319052 0.0144663066089047 -0.014544 0.836695356781618 0.012738792725052 -0.01498 0.690394854863642 0.0107616557567893 -0.015429 0.647588694440734 0.00960800778640814 -0.015892 0.645336743067616 0.00911143342430199 -0.016369 0.610183400446573 0.00884272600622149 -0.01686 0.591499837783164 0.00840359548846352 -0.017366 0.570029962403863 0.00761083226779137 -0.017887 0.536078932804061 0.00690967384873757 -0.018423 0.512433443386324 0.00652970476535812 -0.018976 0.471688390999828 0.006198019046165 -0.019545 0.440256493444531 0.00566003167999389 -0.020132 0.404511536479704 0.00527032958644249 -0.020736 0.349147884501613 0.0046943643962671 -0.021358 0.312582301188954 0.00428099772896429 -0.021998 0.259890455924731 0.00367278001488578 -0.022658 0.218038512185347 0.00320883986335617 -0.023338 0.177852630775396 0.00283478692341457 -0.024038 0.13474112101376 0.00240080917574763 -0.024759 0.106736769785683 0.00208190996011374 -0.025502 0.0800339701139335 0.00173986144773755 -0.026267 0.0629630336456803 0.00151831141815684 -0.027055 0.0486268821924083 0.00133304070688372 -0.027867 0.0438443481745835 0.00145884463443959 -0.028703 0.0414683486326075 0.000859081280177103 -0.029564 0.0396858718677837 0.000810072711311285 -0.030451 0.0431706711960152 0.000821790492184965 -0.031365 0.0430351724269547 0.000802038206836008 -0.032305 0.0459130899444646 0.000825282925246665 -0.033275 0.0442355770148285 0.000801618351495258 -0.034273 0.0424817267505105 0.0010891810912422 -0.035301 0.0378423252352144 0.000770091032271608 -0.03636 0.0340178247676482 0.000687723048149774 -0.037451 0.0269470791427317 0.000604820702685166 -0.038574 0.0201473310559362 0.00049903624114964 -0.039732 0.0148899788163896 0.000390637225901258 -0.040924 0.00926448978033932 0.000286551270062406 -0.042151 0.00525296284280234 0.00020761846600126 -0.043416 0.00224450848298632 0.00013476020534743 -0.044718 0.000825225672245654 7.76465199717552e-05 -0.04606 0.00042697379720987 5.50773869730338e-05 -0.047442 0.000539342353861715 6.0461077501479e-05 -0.048865 0.000610355159449608 6.25775301055364e-05 -0.050331 0.000652340693524686 6.20679783965343e-05 -0.051841 0.000645756598408367 6.00030534933873e-05 -0.053396 0.00044294738449207 4.94608675738087e-05 -0.054998 0.000240195423576786 3.60025954693792e-05 -0.056648 0.000272715128151301 3.79568312372374e-05 -0.058347 0.000626595927403195 5.63579457623237e-05 -0.060098 0.00105784461535525 7.26731426172255e-05 -0.061901 0.00191091433042615 0.000145273764766503 -0.063758 0.00242199278612187 7.67476478558751e-05 -0.06567 0.00245310025000477 7.36216340006489e-05 -0.06764 0.00208229164678715 6.49897898814863e-05 -0.06967 0.00148174583484418 5.32605584076032e-05 -0.07176 0.000760739708773068 3.778698066757e-05 -0.073913 0.000348289089486441 2.5634076986202e-05 -0.07613 0.00026177980495811 2.18076680852688e-05 -0.078414 0.000482070268516575 2.89681100784366e-05 -0.080766 0.000822000419855341 3.91591442584782e-05 -0.083189 0.00107937174373557 4.62298898833947e-05 -0.085685 0.00121868737953014 5.89152464741694e-05 -0.088255 0.00093064753144144 3.58632798335846e-05 -0.090903 0.000683219145403538 2.85902402717609e-05 -0.09363 0.000617206435237314 2.6059657627054e-05 -0.096439 0.000679364110002099 2.74680814519361e-05 -0.099332 0.000679421363003111 2.6527223801981e-05 -0.10231 0.000618313326590202 2.4697036202981e-05 -0.10538 0.000397373995686941 1.91950228057787e-05 -0.10854 0.000221130174239966 1.40565659649993e-05 -0.1118 0.000169302849291017 1.18072863985954e-05 -0.11515 0.000282123704650852 1.46924559629001e-05 -0.11861 0.000364777953777744 1.65755071661673e-05 -0.12217 0.000370522338212561 1.66440199240444e-05 -0.12583 0.000266913490715472 1.3984999713735e-05 -0.12961 0.000126966163476402 9.38891963587091e-06 -0.13349 5.18254165155824e-05 5.89228802076375e-06 -0.1375 5.09036431992977e-05 5.82740128628409e-06 -0.14162 4.02125994770893e-05 5.18807610832268e-06 -0.14587 2.1658810282639e-05 3.67926868833375e-06 -0.15025 1.67732208629936e-05 3.19147311971603e-06 -0.15476 2.08839863356171e-05 3.584037863318e-06 -0.1594 3.48040993148724e-05 4.68959331284948e-06 -0.16418 3.53556365579496e-05 4.88158170957461e-06 -0.16911 3.13460180537797e-05 4.67241741254604e-06 -0.17418 1.44691692589553e-05 3.24471841065669e-06 -0.17941 5.15238840435886e-06 2.00729021546213e-06 -0.18479 6.53466669211245e-06 2.35882364167255e-06 -0.19033 4.82146605851257e-06 2.15881982480582e-06 -0.19604 8.58737762171034e-06 3.03975266703563e-06 -0.20192 6.21767590984561e-06 2.78402259585107e-06 -0.20798 1.10605164220691e-05 3.85923395484647e-06 -0.21422 3.31304032519705e-06 2.17542319509914e-06 -0.22065 3.88347105860799e-06 2.50004771083418e-06 -0.23408 9.81030172331533e-06 4.33519723658848e-06 -0.23877 1.4051604038245e-05 9.12402908452451e-06 diff --git a/ratapi/examples/data/DSPC_D2O.dat b/ratapi/examples/data/DSPC_D2O.dat deleted file mode 100644 index 54f2f496..00000000 --- a/ratapi/examples/data/DSPC_D2O.dat +++ /dev/null @@ -1,82 +0,0 @@ -0.011403,0.10063,0.0019003 -0.011973,0.11082,0.001883 -0.012572,0.10766,0.0016413 -0.013201,0.10652,0.0014669 -0.013861,0.090118,0.0011774 -0.014554,0.034255,0.00048888 -0.015281,0.017209,0.00026267 -0.016045,0.010465,0.00017551 -0.016848,0.0070455,0.00013083 -0.01769,0.0045958,9.7193e-05 -0.018575,0.0034925,8.0937e-05 -0.019503,0.002451,6.4505e-05 -0.020479,0.0017544,5.1254e-05 -0.021502,0.0013384,4.2675e-05 -0.022578,0.0010447,3.5865e-05 -0.023706,0.00076523,2.9299e-05 -0.024892,0.00064257,2.6236e-05 -0.026136,0.00050024,1.3657e-05 -0.027443,0.00039982,1.1639e-05 -0.028815,0.00034301,1.0137e-05 -0.030256,0.00027746,8.5758e-06 -0.031769,0.00026396,8.2806e-06 -0.033357,0.00023596,7.8864e-06 -0.035025,0.0002028,1.0041e-05 -0.036777,0.00018591,4.9391e-06 -0.038615,0.00015427,4.3142e-06 -0.040546,0.00014273,3.958e-06 -0.042573,0.00012868,3.6645e-06 -0.044702,0.00011002,3.2644e-06 -0.046937,9.1148e-05,2.8227e-06 -0.049284,9.1217e-05,2.7234e-06 -0.051748,7.6323e-05,2.3706e-06 -0.054336,6.6691e-05,2.1365e-06 -0.057052,6.4594e-05,2.4647e-06 -0.059905,6.0971e-05,1.3241e-06 -0.0629,6.3097e-05,1.2946e-06 -0.066045,6.0729e-05,1.1791e-06 -0.069348,5.9985e-05,1.1102e-06 -0.072815,6.1021e-05,1.1013e-06 -0.076456,5.6755e-05,1.035e-06 -0.080279,5.8755e-05,1.5569e-06 -0.084292,5.4071e-05,9.5338e-07 -0.088507,4.6964e-05,8.4392e-07 -0.092932,4.2634e-05,7.7134e-07 -0.097579,3.27e-05,6.528e-07 -0.10246,2.54e-05,5.4648e-07 -0.10758,1.7075e-05,4.2154e-07 -0.11296,1.2197e-05,3.4055e-07 -0.11861,7.8205e-06,2.5881e-07 -0.12454,5.091e-06,2.0153e-07 -0.13077,4.1579e-06,1.762e-07 -0.1373,3.6345e-06,1.6248e-07 -0.14417,3.3455e-06,1.5143e-07 -0.15138,2.7295e-06,1.3191e-07 -0.15895,1.8245e-06,1.0679e-07 -0.16689,1.2171e-06,8.7591e-08 -0.17524,4.9313e-07,5.6663e-08 -0.184,2.4038e-07,4.1253e-08 -0.1932,3.3832e-07,5.3216e-08 -0.20286,3.2022e-07,5.5047e-08 -0.213,4.1948e-07,6.8549e-08 -0.22365,3.1493e-07,6.3396e-08 -0.23484,2.3214e-07,5.5974e-08 -0.24658,3.3414e-07,6.8415e-08 -0.25891,3.9863e-07,8.2061e-08 -0.27185,2.5113e-07,6.271e-08 -0.28544,2.2469e-07,6.3286e-08 -0.29972,2.0862e-07,6.0631e-08 -0.3147,2.0861e-07,6.1379e-08 -0.33044,3.3381e-07,7.7193e-08 -0.34696,1.8378e-07,6.049e-08 -0.36431,2.3515e-07,6.6222e-08 -0.38252,2.1154e-07,6.3084e-08 -0.40165,2.4662e-07,6.6637e-08 -0.42173,2.017e-07,6.2432e-08 -0.44282,2.4563e-07,6.9088e-08 -0.46496,1.9906e-07,6.0793e-08 -0.48821,2.8635e-07,7.3878e-08 -0.51262,1.9471e-07,6.1764e-08 -0.53825,2.8836e-07,7.5438e-08 -0.56516,2.3816e-07,7.061e-08 -0.59342,2.1782e-07,6.6918e-08 diff --git a/ratapi/examples/data/DSPC_SMW.dat b/ratapi/examples/data/DSPC_SMW.dat deleted file mode 100644 index 9bdab7b0..00000000 --- a/ratapi/examples/data/DSPC_SMW.dat +++ /dev/null @@ -1,82 +0,0 @@ -0.011403,0.0018074,0.00010983 -0.011973,0.0014774,9.0584e-05 -0.012572,0.001325,7.7039e-05 -0.013201,0.0012216,6.6408e-05 -0.013861,0.0010077,5.5778e-05 -0.014554,0.0010266,5.1388e-05 -0.015281,0.00091489,4.521e-05 -0.016045,0.00080921,3.995e-05 -0.016848,0.00061576,3.3466e-05 -0.01769,0.00060308,3.1557e-05 -0.018575,0.00046074,2.6813e-05 -0.019503,0.00040453,2.4355e-05 -0.020479,0.00036496,2.2031e-05 -0.021502,0.00032468,2.0023e-05 -0.022578,0.0002479,1.6581e-05 -0.023706,0.00027709,1.7017e-05 -0.024892,0.00021141,1.4388e-05 -0.026136,0.00017034,7.5065e-06 -0.027443,0.00015127,6.7139e-06 -0.028815,0.00013632,5.9548e-06 -0.030256,0.00011151,5.2534e-06 -0.031769,9.5843e-05,4.7729e-06 -0.033357,7.5905e-05,4.2186e-06 -0.035025,6.919e-05,6.2034e-06 -0.036777,5.272e-05,2.3936e-06 -0.038615,3.9182e-05,1.9828e-06 -0.040546,2.938e-05,1.6381e-06 -0.042573,2.2329e-05,1.3936e-06 -0.044702,1.471e-05,1.0942e-06 -0.046937,8.1966e-06,7.7674e-07 -0.049284,6.4866e-06,6.6572e-07 -0.051748,3.0853e-06,4.3607e-07 -0.054336,2.6025e-06,3.888e-07 -0.057052,2.7294e-06,4.9982e-07 -0.059905,4.3615e-06,3.1992e-07 -0.0629,5.4926e-06,3.4522e-07 -0.066045,7.2943e-06,3.6968e-07 -0.069348,8.9112e-06,3.8947e-07 -0.072815,1.0612e-05,4.1912e-07 -0.076456,1.2411e-05,4.4241e-07 -0.080279,1.4576e-05,7.0225e-07 -0.084292,1.4768e-05,4.5606e-07 -0.088507,1.3957e-05,4.2438e-07 -0.092932,1.1624e-05,3.7299e-07 -0.097579,1.0598e-05,3.4827e-07 -0.10246,7.7689e-06,2.8497e-07 -0.10758,6.4311e-06,2.4647e-07 -0.11296,4.952e-06,2.0748e-07 -0.11861,2.8957e-06,1.5122e-07 -0.12454,1.9786e-06,1.2104e-07 -0.13077,1.1837e-06,9.0553e-08 -0.1373,9.5591e-07,8.0264e-08 -0.14417,9.9179e-07,7.9466e-08 -0.15138,8.1026e-07,6.9286e-08 -0.15895,7.8161e-07,6.7637e-08 -0.16689,6.039e-07,5.9878e-08 -0.17524,4.8559e-07,5.489e-08 -0.184,4.1425e-07,5.2852e-08 -0.1932,4.375e-07,5.9223e-08 -0.20286,3.0001e-07,5.1646e-08 -0.213,4.9488e-07,7.1141e-08 -0.22365,2.7977e-07,5.7809e-08 -0.23484,2.3853e-07,5.4901e-08 -0.24658,2.1767e-07,5.3744e-08 -0.25891,2.5677e-07,6.3708e-08 -0.27185,5.7975e-07,9.3465e-08 -0.28544,3.2659e-07,7.4563e-08 -0.29972,3.0527e-07,7.1553e-08 -0.3147,3.3603e-07,7.6342e-08 -0.33044,3.8583e-07,8.1122e-08 -0.34696,2.9402e-07,7.285e-08 -0.36431,3.0297e-07,7.2958e-08 -0.38252,4.0996e-07,8.5727e-08 -0.40165,4.0612e-07,8.3403e-08 -0.42173,5.3059e-07,9.7535e-08 -0.44282,4.9546e-07,9.5624e-08 -0.46496,3.5423e-07,7.8721e-08 -0.48821,3.5614e-07,7.9969e-08 -0.51262,3.7628e-07,8.3392e-08 -0.53825,5.8915e-07,1.0457e-07 -0.56516,3.2619e-07,7.9702e-08 -0.59342,3.068e-07,7.7062e-08 diff --git a/ratapi/examples/data/H2O_spin_down.dat b/ratapi/examples/data/H2O_spin_down.dat deleted file mode 100644 index a5a82b57..00000000 --- a/ratapi/examples/data/H2O_spin_down.dat +++ /dev/null @@ -1,102 +0,0 @@ -0.01218 0.671793398788385 0.0176660747858784 -0.012545 0.644505953624399 0.0154311155212033 -0.012922 0.620221433047838 0.0142020054313766 -0.013309 0.586849801545853 0.0126900981825778 -0.013709 0.536818466680593 0.0110429287654063 -0.01412 0.514074576979319 0.0102055044913307 -0.014544 0.49879883016503 0.00955530603718404 -0.01498 0.458977438897013 0.00867427407562148 -0.015429 0.412915186964696 0.007567108836432 -0.015892 0.368054104867349 0.00665656987674953 -0.016369 0.32760601629413 0.00629439105911845 -0.01686 0.288515771882181 0.0056298307917276 -0.017366 0.252874973887612 0.00483444746187591 -0.017887 0.220398997284312 0.00426415291414247 -0.018423 0.18478431167746 0.00373067683308962 -0.018976 0.149527365782327 0.00331705661165657 -0.019545 0.117427407562147 0.00279115312304157 -0.020132 0.0955112805514936 0.00243545017756424 -0.020736 0.0731642991435137 0.00208220179653228 -0.021358 0.0571626279506998 0.00178966471694172 -0.021998 0.0435293503237936 0.00149031230415709 -0.022658 0.0324838103196156 0.00123566429914351 -0.023338 0.0236706183413411 0.0010463494881972 -0.024038 0.0180465322749112 0.000903331940672655 -0.024759 0.0156246083141842 0.000830008355964069 -0.025502 0.0135426676415291 0.000754230206810111 -0.026267 0.0129645393774807 0.000735481512429497 -0.027055 0.0130843952371005 0.000739685606851891 -0.027867 0.0139662105702945 0.000870247545435555 -0.028703 0.0154924796323376 0.000508303739293921 -0.029564 0.016434092333403 0.000510209943597243 -0.030451 0.016574576979319 0.000502245665343639 -0.031365 0.0161698349697096 0.000487857739711719 -0.032305 0.0150783371631502 0.00047122414873616 -0.033275 0.0149590035512847 0.000470022978901191 -0.034273 0.0125342072279089 0.000605833507415918 -0.035301 0.0114445372884897 0.000364137246709839 -0.03636 0.00940986003760184 0.000309040108627533 -0.037451 0.00774284520576562 0.000284572801336954 -0.038574 0.00572905786505118 0.000233447357426363 -0.039732 0.00428687069145603 0.000186630457489033 -0.040924 0.00302094213494882 0.000149059954042198 -0.042151 0.0018035303948193 0.000111035095049091 -0.043416 0.000843847921453938 7.5799039064132e-05 -0.044718 0.000547733444746188 5.85753081261751e-05 -0.04606 0.000229230206810111 3.67949655316482e-05 -0.047442 0.000348182577814915 4.46782953833299e-05 -0.048865 0.000422994568623355 4.81407979945686e-05 -0.050331 0.000684457906831001 5.89957175684145e-05 -0.051841 0.000815750992270733 6.20247545435555e-05 -0.053396 0.000878342385627742 6.42599749321078e-05 -0.054998 0.00101070607896386 6.82891163567997e-05 -0.056648 0.000820790683100063 6.08157509922707e-05 -0.058347 0.000605781282640485 5.08956548986839e-05 -0.060098 0.000380692500522248 4.03436390223522e-05 -0.061901 0.000300318571130144 5.40526425736369e-05 -0.063758 0.000191644035930645 2.21320764570712e-05 -0.06567 0.00010858314184249 1.54277209108001e-05 -0.06764 0.000199717986212659 2.00757259243785e-05 -0.06967 0.000334499686651347 2.51444015040735e-05 -0.07176 0.000430123250470023 2.81439314810946e-05 -0.073913 0.000419103822853562 2.74728431167746e-05 -0.07613 0.000410068936703572 2.69088155420932e-05 -0.078414 0.000315045957802381 2.39680384374347e-05 -0.080766 0.000239265197409651 2.10841863379987e-05 -0.083189 0.000125002611238772 1.58859933152287e-05 -0.085685 5.68936703572175e-05 1.23999895550449e-05 -0.088255 2.96323375809484e-05 7.13938792563192e-06 -0.090903 3.24655316482139e-05 7.07019009818258e-06 -0.09363 4.33335074159181e-05 7.85956757885941e-06 -0.096439 7.03389387925632e-05 9.97101524963443e-06 -0.099332 5.94239607269689e-05 8.93043659912262e-06 -0.10231 5.06214748276582e-05 7.99274075621475e-06 -0.10538 2.5376018383121e-05 5.52825360350951e-06 -0.10854 1.72558491748485e-05 4.54198871944851e-06 -0.1118 3.16560476289952e-05 5.8959160225611e-06 -0.11515 5.1558909546689e-05 7.19579068310006e-06 -0.11861 6.05467933987884e-05 7.6853979527888e-06 -0.12217 5.03655734280343e-05 6.95607896386046e-06 -0.12583 2.71856068518905e-05 5.05091915604763e-06 -0.12961 1.50430854397326e-05 3.69124712763735e-06 -0.13349 6.32389805723835e-06 2.39147691664926e-06 -0.1375 1.05776060162941e-05 3.05541048673491e-06 -0.14162 7.04016085230834e-06 2.49015562983079e-06 -0.14587 6.21030917067057e-06 2.28875078337163e-06 -0.15025 3.75626697305202e-06 1.74626592855651e-06 -0.15476 5.59327344892417e-06 2.1459160225611e-06 -0.1594 6.88870900355128e-06 2.40646542719866e-06 -0.16418 1.41638813453102e-05 3.54345101316064e-06 -0.16911 5.95571339043242e-06 2.34755588050971e-06 -0.17418 7.29318988928348e-06 2.65458533528306e-06 -0.17941 6.28211823689158e-06 2.56590766659703e-06 -0.18479 7.84155003133487e-06 2.96741174012952e-06 -0.19033 9.05603718404011e-06 3.42620639231251e-06 -0.19604 2.86087319824525e-06 2.02389283476081e-06 -0.20192 1.33115730102361e-05 4.71903070816795e-06 -0.20798 1.44652182995613e-05 5.1190724879883e-06 -0.21422 6.84849592646752e-06 3.62048255692501e-06 -0.22065 2.94234384792145e-06 2.47461875913934e-06 -0.22727 6.87434719030708e-06 3.97273866722373e-06 -0.23408 7.563975349906e-06 4.37774180071026e-06 -0.23877 7.5399519532066e-06 7.54282431585544e-06 diff --git a/ratapi/examples/data/H2O_spin_up.dat b/ratapi/examples/data/H2O_spin_up.dat deleted file mode 100644 index db2eeb67..00000000 --- a/ratapi/examples/data/H2O_spin_up.dat +++ /dev/null @@ -1,102 +0,0 @@ -0.01218 0.855928694401465 0.0193592956610805 -0.012545 0.8480615424848 0.0177581885937194 -0.012922 0.822193649617539 0.0162403295050886 -0.013309 0.814958484973958 0.0149567415607906 -0.013709 0.752282781615708 0.0129300237540044 -0.01412 0.745309128947196 0.0121387321027742 -0.014544 0.701287946477216 0.0109987578181184 -0.01498 0.685989495935668 0.0105023209187787 -0.015429 0.663826356048554 0.0095911696123085 -0.015892 0.634929282803408 0.00883845097740101 -0.016369 0.581929522522719 0.0083860352605313 -0.01686 0.549828927582976 0.00784710266524288 -0.017366 0.511953276527121 0.00692113234685205 -0.017887 0.458604833613006 0.0060923573125286 -0.018423 0.425000544816615 0.00564299256870138 -0.018976 0.361627476191514 0.00509447120099375 -0.019545 0.331771525704448 0.0046117636803452 -0.020132 0.28454682153987 0.00412339006690348 -0.020736 0.245298232614902 0.00368339616884957 -0.021358 0.21799202388476 0.00335367315361649 -0.021998 0.178721642295203 0.00286595332011245 -0.022658 0.149338592629721 0.00250833569420533 -0.023338 0.127615664567307 0.00228234576241637 -0.024038 0.104480571839519 0.00202525769825877 -0.024759 0.0884542463006952 0.00182302177087192 -0.025502 0.0770697583193497 0.00165401965698346 -0.026267 0.0712184278771765 0.00157201386013468 -0.027055 0.060003922679626 0.00144417808965502 -0.027867 0.0580752718634907 0.00167524571229324 -0.028703 0.0526031337851679 0.000996905441628348 -0.029564 0.0511931483862532 0.000941094427615665 -0.030451 0.0478218231743195 0.000873384618737333 -0.031365 0.0436899339682263 0.000805195371238041 -0.032305 0.0430317954976355 0.000791531370540676 -0.033275 0.0401333711072853 0.000757164338483666 -0.034273 0.0359578965720139 0.00101277050144921 -0.035301 0.0322945496545863 0.000726785364046462 -0.03636 0.0284525028875281 0.000643450214657746 -0.037451 0.0234532656307887 0.000581559047224704 -0.038574 0.0184121864580382 0.000493015450999194 -0.039732 0.0146165580665548 0.00040261947828361 -0.040924 0.0101087453962996 0.000313269553468303 -0.042151 0.00730795214330856 0.000257414954126441 -0.043416 0.0042269052237017 0.000194231481683265 -0.044718 0.00221260923573125 0.000133410334081548 -0.04606 0.00111497809837209 9.29980168675224e-05 -0.047442 0.00048536622572842 5.98666288927147e-05 -0.048865 0.000298167236908057 4.57384444396016e-05 -0.050331 0.000510253448689171 5.73539346655916e-05 -0.051841 0.000786301131039292 6.93878440516922e-05 -0.053396 0.00112199533636978 8.28317388367076e-05 -0.054998 0.00139612526423606 9.13984352866825e-05 -0.056648 0.00127421709852464 8.6257545710114e-05 -0.058347 0.001081569943557 7.75491969403099e-05 -0.060098 0.000916011070673611 7.0819622115196e-05 -0.061901 0.000690260858195132 8.21409113692331e-05 -0.063758 0.000484995750430405 3.52845032362107e-05 -0.06567 0.000463508183145553 3.30006319872731e-05 -0.06764 0.000508226730882385 3.31531806393968e-05 -0.06967 0.000711508706169503 3.80434545731907e-05 -0.07176 0.000932399154444614 4.34458561248284e-05 -0.073913 0.00109495063961471 4.75145466036132e-05 -0.07613 0.00105653017194412 4.63878658443568e-05 -0.078414 0.000904134068472552 4.30034650336697e-05 -0.080766 0.000647917710898512 3.65136095190359e-05 -0.083189 0.000387538954387953 2.99147906814566e-05 -0.085685 0.000218624011157844 2.59812147231242e-05 -0.088255 8.9402227210321e-05 1.16902390655305e-05 -0.090903 5.22304792206943e-05 8.29603155577833e-06 -0.09363 4.09222655654107e-05 7.03903066227908e-06 -0.096439 5.00490334953255e-05 7.83119402009284e-06 -0.099332 5.55451435046963e-05 7.99311351798984e-06 -0.10231 4.74927539390241e-05 7.19964260030074e-06 -0.10538 4.42957700438033e-05 6.77882624708523e-06 -0.10854 4.78632292370388e-05 6.96471767603025e-06 -0.1118 7.88981628783751e-05 8.58500228822978e-06 -0.11515 0.000108653867108331 9.69098001612657e-06 -0.11861 0.000136979972541243 1.07788698324144e-05 -0.12217 0.00010743783642426 9.50356310066032e-06 -0.12583 6.88822542332251e-05 7.53546756161876e-06 -0.12961 4.55946128533136e-05 5.99537995510711e-06 -0.13349 1.58101423060998e-05 3.45871379693595e-06 -0.1375 1.3898489768344e-05 3.23424935166823e-06 -0.14162 1.1293394643363e-05 2.92087083487698e-06 -0.14587 6.01848017957156e-06 2.08115588292981e-06 -0.15025 7.7183080175213e-06 2.31285549284111e-06 -0.15476 1.47192015167695e-05 3.22378887266546e-06 -0.1594 2.20694314293809e-05 3.99241615272299e-06 -0.16418 2.05467779545405e-05 3.96735458844553e-06 -0.16911 2.17689105846972e-05 4.15891211018371e-06 -0.17418 1.75060474644235e-05 3.81742105607253e-06 -0.17941 7.62743260618476e-06 2.60291585852202e-06 -0.18479 7.16346677708283e-06 2.65042386732626e-06 -0.19033 5.7271122540153e-06 2.47107023775797e-06 -0.19604 1.11545753699305e-05 3.73940331684355e-06 -0.20192 1.2624926449757e-05 4.29206529082311e-06 -0.20798 1.85283413602981e-05 5.37581450083902e-06 -0.21422 1.67341512846776e-05 5.21476670952557e-06 -0.22065 4.2125220650729e-06 2.7123150347593e-06 -0.22727 8.98729487654456e-06 4.22232876413799e-06 -0.23408 1.18595680693878e-05 5.00817224922091e-06 -0.23877 1.68956349292828e-05 1.04944755595267e-05 diff --git a/ratapi/examples/data/__init__.py b/ratapi/examples/data/__init__.py deleted file mode 100644 index 9fc1b9dd..00000000 --- a/ratapi/examples/data/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Data files used by the examples.""" diff --git a/ratapi/examples/data/c_PLP0011859_q.ort b/ratapi/examples/data/c_PLP0011859_q.ort deleted file mode 100644 index 7a7bf1fd..00000000 --- a/ratapi/examples/data/c_PLP0011859_q.ort +++ /dev/null @@ -1,441 +0,0 @@ -# # ORSO reflectivity data file | 1.1 standard | YAML encoding | https://www.reflectometry.org/ -# # handwritten test file header created to test RAT orsopy integration! -# # example data from refnx: https://refnx.readthedocs.io/en/latest/getting_started.html#fitting-a-neutron-reflectometry-dataset -# data_source: -# owner: -# name: null -# affiliation: null -# measurement: -# instrument_settings: null -# data_files: null -# experiment: -# title: -# probe: neutron -# instrument: None -# start_date: 1970-01-01T00:00:00 -# sample: -# name: film on silicon -# model: -# stack: Si | SiO2 30 | film 250 | D2O -# materials: -# film: -# sld: 2.0e-6 -# roughness: 3 -# reduction: -# software: null -# timestamp: null -# data_set: 0 -# columns: -# - {name: Qz, unit: 1/angstrom, physical_quantity: normal momentum transfer} -# - {name: R, unit: '', physical_quantity: specular reflectivity} -# - {error_of: R, error_type: uncertainty, value_is: sigma} -# - {error_of: Qz, error_type: resolution, value_is: sigma} -# # Qz (1/angstrom) R () sR sQz -0.00806022 0.709581 0.0850676 0.000331422 -0.00813662 0.862281 0.11237 0.000334619 -0.00826375 0.908647 0.0790047 0.000339939 -0.00837067 0.773292 0.0792728 0.000344412 -0.00845033 1.05797 0.125959 0.000347744 -0.00853083 1.01566 0.113295 0.000351111 -0.00861217 0.734717 0.0611566 0.000354512 -0.00869437 0.769216 0.0617058 0.000357949 -0.00877743 1.11574 0.11273 0.000361421 -0.00886136 0.972303 0.089716 0.000364929 -0.00894616 0.751214 0.0549393 0.000368473 -0.00903185 0.797649 0.0567122 0.000372053 -0.00911844 0.922189 0.0685841 0.000375671 -0.00920593 0.975755 0.0729395 0.000379325 -0.00929432 0.819504 0.0521617 0.000383017 -0.00938364 0.78832 0.0479473 0.000386748 -0.00947389 0.794701 0.0460224 0.000390516 -0.00956508 0.8744 0.0515164 0.000394323 -0.00965721 0.839662 0.0474285 0.00039817 -0.0097503 0.800872 0.0439958 0.000402055 -0.00984436 1.1171 0.073733 0.000405981 -0.00993939 0.888411 0.049541 0.000409947 -0.0100354 0.779129 0.0389873 0.000413953 -0.0101324 0.799968 0.0389974 0.000418001 -0.0102304 0.843124 0.041598 0.00042209 -0.0103294 0.961332 0.0492536 0.00042622 -0.0104868 0.880544 0.0299083 0.000432781 -0.0106327 0.755735 0.0320851 0.000438868 -0.0107359 0.971231 0.0453485 0.00044317 -0.0108401 0.895549 0.0390542 0.000447516 -0.0109454 0.862589 0.0358072 0.000451906 -0.0110518 0.890992 0.0361257 0.000456342 -0.0111593 0.900348 0.0367924 0.000460822 -0.0112679 0.845927 0.0321881 0.000465348 -0.0113776 0.943152 0.0365533 0.000469921 -0.0114884 0.995631 0.0390116 0.00047454 -0.0116004 0.969594 0.0363623 0.000479205 -0.0117135 0.905181 0.032041 0.000483919 -0.0118278 0.893381 0.0306119 0.00048868 -0.0119433 0.919602 0.0314677 0.00049349 -0.0120599 0.918998 0.0306097 0.000498349 -0.0121777 0.781056 0.0235542 0.000503257 -0.0122968 0.864915 0.0272025 0.000508215 -0.012417 0.843516 0.0255015 0.000513223 -0.0125385 0.998418 0.0319722 0.000518283 -0.0126612 0.88126 0.0260273 0.000523393 -0.0127852 0.883569 0.0255862 0.000528556 -0.0129105 0.93767 0.0274651 0.000533771 -0.013037 1.0192 0.0305107 0.000539039 -0.0131648 0.845526 0.0226269 0.00054436 -0.0132939 0.873804 0.0232468 0.000549735 -0.0134243 0.865953 0.0224906 0.000555165 -0.0135561 0.877982 0.0224491 0.00056065 -0.0136892 0.947545 0.0248985 0.00056619 -0.0138237 0.888154 0.0220962 0.000571787 -0.0139595 0.891362 0.0218148 0.00057744 -0.0140967 0.888456 0.0215092 0.00058315 -0.0142353 0.913717 0.0222586 0.000588919 -0.0143753 0.810364 0.0188289 0.000594745 -0.0145168 0.738548 0.0168827 0.000600631 -0.0146597 0.68651 0.0159742 0.000606576 -0.014804 0.58224 0.0135021 0.000612582 -0.0149498 0.446855 0.0100626 0.000618648 -0.015097 0.392461 0.00915549 0.000624775 -0.0152458 0.320517 0.00731959 0.000630965 -0.0153961 0.281006 0.00639909 0.000637217 -0.0155479 0.2401 0.00544239 0.000643532 -0.0157012 0.220881 0.00502437 0.000649911 -0.0158561 0.192033 0.00431441 0.000656354 -0.0160126 0.179849 0.00405159 0.000662863 -0.0161707 0.160069 0.00356202 0.000669437 -0.0163303 0.153129 0.00346777 0.000676078 -0.0164916 0.13422 0.003016 0.000682786 -0.0166545 0.12833 0.00288853 0.000689562 -0.016819 0.124794 0.00286182 0.000696406 -0.0169853 0.109127 0.0024831 0.000703319 -0.0171532 0.104429 0.00235392 0.000710302 -0.0173228 0.094683 0.00209162 0.000717355 -0.0175881 0.0896911 0.00143938 0.000728391 -0.0178419 0.0809144 0.00187278 0.000738945 -0.0180185 0.0746544 0.00171422 0.000746287 -0.0181968 0.0703661 0.00163423 0.000753704 -0.018377 0.0690445 0.0016053 0.000761195 -0.0185589 0.0627055 0.00146146 0.000768762 -0.0187427 0.0593915 0.00140007 0.000776405 -0.0189284 0.0575477 0.00136095 0.000784125 -0.0191159 0.0513833 0.00122668 0.000791923 -0.0193054 0.0492267 0.00117824 0.0007998 -0.0194967 0.0452174 0.00107962 0.000807755 -0.01969 0.0424556 0.00102225 0.000815792 -0.0198852 0.0412613 0.000994781 0.000823909 -0.0200824 0.0352333 0.00087779 0.000832108 -0.0202815 0.0335271 0.000836747 0.000840389 -0.0204827 0.0332684 0.000833959 0.000848754 -0.0206859 0.0316644 0.000789886 0.000857204 -0.0208912 0.02916 0.000749613 0.000865738 -0.0210985 0.0265201 0.000706383 0.000874359 -0.021308 0.0251829 0.000671389 0.000883066 -0.0215195 0.0238757 0.000642693 0.000891861 -0.0217331 0.0228929 0.000633068 0.000900745 -0.021949 0.0208646 0.000593128 0.000909718 -0.0221669 0.0208771 0.00059201 0.000918781 -0.0223871 0.0182228 0.000529205 0.000927936 -0.0226095 0.0177346 0.000525152 0.000937183 -0.0228341 0.0158714 0.000481877 0.000946523 -0.023061 0.0143255 0.000451619 0.000955957 -0.0232902 0.0142776 0.000452249 0.000965486 -0.0235217 0.0126624 0.000419845 0.000975112 -0.0237555 0.0122128 0.000413786 0.000984834 -0.0239917 0.0104608 0.000374532 0.000994654 -0.0242302 0.0106133 0.000381052 0.00100457 -0.0244712 0.00987903 0.000364128 0.00101459 -0.0247145 0.00837203 0.000331393 0.00102471 -0.0249603 0.00767048 0.000307705 0.00103493 -0.0252086 0.00734489 0.000304978 0.00104526 -0.0254594 0.00679865 0.000289868 0.00105569 -0.0257127 0.0059163 0.000267178 0.00106622 -0.0259685 0.00534498 0.000251536 0.00107686 -0.0262269 0.00512265 0.000247412 0.0010876 -0.026488 0.00475031 0.000237953 0.00109846 -0.0267516 0.00430715 0.00022385 0.00110942 -0.0270179 0.00401817 0.000220051 0.0011205 -0.0272868 0.00353915 0.000204653 0.00113168 -0.0275585 0.00381819 0.000207944 0.00114298 -0.0278329 0.00286475 0.000181921 0.0011544 -0.02811 0.0027958 0.000176691 0.00116592 -0.02839 0.0026215 0.000175002 0.00117757 -0.0286727 0.00248477 0.000169456 0.00118933 -0.0289583 0.00242009 0.000170925 0.00120121 -0.0292467 0.00235926 0.00017006 0.0012132 -0.0295381 0.00197856 0.000160021 0.00122532 -0.0298323 0.0019472 0.000158282 0.00123757 -0.0301296 0.00173593 0.000152731 0.00124993 -0.0304298 0.00189459 0.000160305 0.00126242 -0.030733 0.00169668 0.000152574 0.00127504 -0.0310392 0.00179369 0.000159245 0.00128778 -0.0313486 0.00178686 0.000155202 0.00130065 -0.031661 0.00187201 0.000158395 0.00131365 -0.0319766 0.00168818 0.000149984 0.00132678 -0.0322953 0.00173237 0.000154325 0.00134004 -0.0326173 0.0015376 0.000145396 0.00135344 -0.0329424 0.00154134 0.000149756 0.00136697 -0.0332708 0.00170033 0.000157208 0.00138064 -0.0336026 0.00214224 0.000172887 0.00139445 -0.0339376 0.00194402 0.000168689 0.0014084 -0.0342205 0.001914 0.000107714 0.00141748 -0.0346645 0.00198641 0.000143828 0.00143727 -0.0350219 0.00184974 0.000127974 0.00145177 -0.035385 0.00193264 0.000122708 0.00146643 -0.0357162 0.00218899 0.000149598 0.00148083 -0.0360773 0.00231432 0.000150345 0.00149568 -0.0364677 0.00183177 0.000104159 0.00151093 -0.0368263 0.00179715 0.000101292 0.00152596 -0.0371616 0.00227874 0.000141733 0.0015409 -0.0375421 0.00218339 0.00012946 0.00155639 -0.0379404 0.001799 9.62498e-05 0.00157213 -0.0383128 0.00182808 9.73464e-05 0.00158778 -0.038684 0.00194985 0.00010826 0.00160356 -0.0390692 0.00204214 0.000112245 0.00161957 -0.0394734 0.00165946 8.39554e-05 0.00163584 -0.0398633 0.00162031 8.07338e-05 0.00165215 -0.0402658 0.00158862 7.61769e-05 0.00166867 -0.0406608 0.00158251 7.82912e-05 0.0016853 -0.0410701 0.0014299 7.03445e-05 0.00170214 -0.0414781 0.00133612 6.49882e-05 0.00171913 -0.0418744 0.0017219 9.20006e-05 0.00173625 -0.0423049 0.00140489 6.78817e-05 0.00175363 -0.0427317 0.00114648 5.31515e-05 0.00177115 -0.0431546 0.00103013 4.8728e-05 0.00178884 -0.0435835 0.00101864 4.85163e-05 0.0018067 -0.0440155 0.00106025 5.14888e-05 0.00182475 -0.0444549 0.000911561 4.51767e-05 0.00184298 -0.0448983 0.000779536 3.74676e-05 0.00186138 -0.045347 0.000595757 2.86778e-05 0.00187998 -0.0457947 0.000647645 3.28669e-05 0.00189877 -0.0462512 0.000526839 2.66621e-05 0.00191774 -0.0467124 0.000436546 2.24095e-05 0.00193691 -0.0471783 0.000369605 1.92965e-05 0.00195626 -0.0476469 0.000331564 1.80855e-05 0.00197583 -0.0481208 0.000254584 1.44062e-05 0.00199557 -0.0485994 0.00020908 1.31243e-05 0.00201553 -0.0490828 0.000192937 1.26159e-05 0.00203569 -0.049571 0.000130922 9.99222e-06 0.00205605 -0.050064 0.000109823 9.08051e-06 0.00207663 -0.0505619 9.56548e-05 8.37009e-06 0.00209741 -0.0510655 7.92572e-05 7.69913e-06 0.00211839 -0.0515734 7.95605e-05 6.89856e-06 0.0021396 -0.0520864 7.22495e-05 6.10273e-06 0.00216102 -0.0526045 7.82513e-05 6.39136e-06 0.00218266 -0.0531279 8.63712e-05 6.56186e-06 0.00220452 -0.0536565 0.000133162 8.78984e-06 0.0022266 -0.0541905 0.000143632 8.17884e-06 0.00224891 -0.0547298 0.000158682 8.56534e-06 0.00227144 -0.0552745 0.000190007 9.75524e-06 0.00229421 -0.0558247 0.00023542 1.14172e-05 0.00231721 -0.0563804 0.000233932 1.03452e-05 0.00234044 -0.0569417 0.00024339 1.05955e-05 0.0023639 -0.0575087 0.000270858 1.12513e-05 0.00238761 -0.0580813 0.000310966 1.23355e-05 0.00241156 -0.0586597 0.000348327 1.35786e-05 0.00243575 -0.0592439 0.000332957 1.27559e-05 0.0024602 -0.059834 0.000354659 1.32236e-05 0.00248489 -0.06043 0.000354467 1.30661e-05 0.00250983 -0.0610319 0.000385515 1.40893e-05 0.00253502 -0.06164 0.000332509 1.20176e-05 0.00256048 -0.0622541 0.000333087 1.19715e-05 0.00258619 -0.0628744 0.000330307 1.19723e-05 0.00261217 -0.0635009 0.000322469 1.16291e-05 0.00263842 -0.0641337 0.000274462 9.94879e-06 0.00266493 -0.0647728 0.000279243 1.02537e-05 0.00269171 -0.0654184 0.000238938 8.96085e-06 0.00271877 -0.0660704 0.000233028 8.72665e-06 0.00274611 -0.066729 0.000186343 7.23614e-06 0.00277372 -0.0673942 0.000164949 6.6195e-06 0.00280162 -0.068066 0.000133244 5.54157e-06 0.00282981 -0.0687446 0.000115376 4.97162e-06 0.00285828 -0.06943 8.25033e-05 3.95115e-06 0.00288705 -0.0701223 6.71923e-05 3.57018e-06 0.00291611 -0.0708215 5.03322e-05 2.92623e-06 0.00294547 -0.0715278 3.33612e-05 2.5097e-06 0.00297513 -0.0722411 2.29052e-05 2.11638e-06 0.0030051 -0.0729338 1.87944e-05 1.86053e-06 0.00303317 -0.0736683 1.55344e-05 1.79821e-06 0.00306431 -0.0744015 1.82452e-05 1.95184e-06 0.00309508 -0.0751405 2.23562e-05 1.801e-06 0.00312604 -0.0758721 2.77362e-05 1.89014e-06 0.00315615 -0.0766402 3.93101e-05 2.30095e-06 0.00318888 -0.0773964 4.59669e-05 2.3324e-06 0.00322041 -0.0781061 5.54131e-05 2.45926e-06 0.00324807 -0.0788682 6.72605e-05 2.72957e-06 0.00327954 -0.0797953 7.65064e-05 2.77309e-06 0.00331828 -0.0807289 7.79472e-05 2.85741e-06 0.00335684 -0.0815334 8.50542e-05 2.9904e-06 0.00339073 -0.0823318 9.68569e-05 3.2227e-06 0.00342487 -0.0831605 9.4624e-05 3.16621e-06 0.00345952 -0.0840252 8.58564e-05 2.82446e-06 0.00349469 -0.0848648 8.10144e-05 2.66254e-06 0.00353001 -0.0857342 7.65592e-05 2.54978e-06 0.00356583 -0.0865553 7.38543e-05 2.48584e-06 0.00360169 -0.0874372 6.24971e-05 2.19092e-06 0.00363822 -0.0883163 5.49543e-05 2.00127e-06 0.00367507 -0.0891108 5.69454e-05 2.08158e-06 0.00371178 -0.0900416 4.2292e-05 1.72971e-06 0.00374959 -0.0909546 3.36754e-05 1.45891e-06 0.00378764 -0.0918504 2.54564e-05 1.24963e-06 0.00382594 -0.0927435 2.09221e-05 1.15976e-06 0.00386459 -0.0936289 1.53112e-05 1.06014e-06 0.00390356 -0.0945527 1.26565e-05 9.57753e-07 0.0039431 -0.0955178 9.33124e-06 8.62139e-07 0.0039832 -0.0964771 8.90152e-06 7.82897e-07 0.00402366 -0.0974189 1.07915e-05 8.93847e-07 0.0040644 -0.0984259 1.21368e-05 9.11308e-07 0.00410584 -0.0994201 1.5408e-05 9.07777e-07 0.0041476 -0.100425 1.93803e-05 9.60253e-07 0.00418981 -0.101434 2.09116e-05 1.04089e-06 0.00423243 -0.102499 2.51925e-05 1.07837e-06 0.0042757 -0.103498 2.8188e-05 1.13217e-06 0.00431908 -0.104546 2.9981e-05 1.17853e-06 0.0043631 -0.105608 3.05628e-05 1.15049e-06 0.0044076 -0.106682 2.81903e-05 1.09907e-06 0.00445257 -0.107758 2.69263e-05 1.0374e-06 0.00449797 -0.108831 2.54192e-05 1.01256e-06 0.0045438 -0.109916 2.2827e-05 9.3671e-07 0.00459012 -0.11104 1.76917e-05 7.9045e-07 0.00463704 -0.112117 1.54751e-05 7.6254e-07 0.00468423 -0.113244 1.17258e-05 6.68805e-07 0.00473208 -0.114319 1.05027e-05 6.59805e-07 0.00478019 -0.115464 8.12153e-06 5.84703e-07 0.00482905 -0.116645 4.98884e-06 5.26719e-07 0.00487853 -0.117762 4.90999e-06 5.36096e-07 0.00492824 -0.118925 5.30434e-06 5.24084e-07 0.00497863 -0.120129 5.68905e-06 4.91234e-07 0.00502965 -0.121346 6.44471e-06 5.06107e-07 0.00508123 -0.122586 7.45619e-06 5.05803e-07 0.0051334 -0.123823 8.24842e-06 5.0256e-07 0.00518608 -0.125091 1.06749e-05 5.84539e-07 0.00523939 -0.126361 1.13162e-05 5.72228e-07 0.00529323 -0.127643 1.1044e-05 5.76255e-07 0.00534765 -0.128932 1.06258e-05 5.65534e-07 0.00540265 -0.13021 9.33766e-06 5.25472e-07 0.00545814 -0.131547 8.9228e-06 5.00068e-07 0.00551441 -0.132854 6.43611e-06 4.44688e-07 0.00557113 -0.134162 6.18113e-06 4.55625e-07 0.00562844 -0.135515 4.68568e-06 4.03478e-07 0.00568647 -0.136824 4.66754e-06 3.80929e-07 0.00574496 -0.138204 4.2625e-06 3.76301e-07 0.00580426 -0.139589 3.8843e-06 3.57158e-07 0.00586419 -0.140989 3.69948e-06 3.79662e-07 0.00592478 -0.14243 3.65993e-06 3.54338e-07 0.00598611 -0.143851 4.55939e-06 3.66569e-07 0.00604802 -0.145263 4.58088e-06 3.47062e-07 0.00611055 -0.14675 4.82929e-06 3.50392e-07 0.00617393 -0.148225 4.93092e-06 3.5333e-07 0.00623794 -0.14971 4.781e-06 3.61256e-07 0.00630265 -0.151225 4.64484e-06 3.39711e-07 0.00636812 -0.152736 4.36508e-06 3.32459e-07 0.00643425 -0.154261 3.80706e-06 3.25378e-07 0.00650113 -0.155825 3.54415e-06 3.05388e-07 0.00656881 -0.157366 2.63269e-06 2.77355e-07 0.00663715 -0.158941 2.12968e-06 2.57061e-07 0.0067063 -0.160511 2.50908e-06 2.68417e-07 0.00677617 -0.162137 2.60626e-06 2.68354e-07 0.00684694 -0.163755 2.46796e-06 2.61811e-07 0.00691843 -0.165404 2.43769e-06 2.45708e-07 0.00699078 -0.167035 2.81846e-06 2.62635e-07 0.00706385 -0.168736 3.20191e-06 2.67722e-07 0.00713789 -0.17041 3.02096e-06 2.54866e-07 0.00721266 -0.172119 2.39855e-06 2.32464e-07 0.00728832 -0.173839 2.45824e-06 2.38546e-07 0.00736483 -0.175574 2.03366e-06 2.23196e-07 0.00744222 -0.177336 1.68404e-06 2.04828e-07 0.00752051 -0.179087 1.29383e-06 2.00765e-07 0.00759963 -0.180907 1.43967e-06 1.88207e-07 0.00767979 -0.182715 1.5402e-06 1.99998e-07 0.0077608 -0.184535 1.33849e-06 1.86482e-07 0.00784273 -0.186383 1.61599e-06 1.86369e-07 0.00792563 -0.188247 1.49347e-06 1.88386e-07 0.00800949 -0.190126 2.05968e-06 1.9207e-07 0.00809433 -0.192038 1.69015e-06 1.7677e-07 0.00818019 -0.193954 1.48837e-06 1.79274e-07 0.00826701 -0.1959 1.40382e-06 1.74728e-07 0.00835488 -0.19786 1.34689e-06 1.70569e-07 0.00844376 -0.199845 9.4771e-07 1.61779e-07 0.00853372 -0.201833 1.08955e-06 1.73502e-07 0.00862469 -0.203863 1.24635e-06 1.65466e-07 0.0087168 -0.205904 1.22737e-06 1.6449e-07 0.00880998 -0.207959 1.16896e-06 1.58456e-07 0.00890425 -0.210042 1.16172e-06 1.52198e-07 0.00899967 -0.21214 1.21689e-06 1.58854e-07 0.00909622 -0.214257 1.31757e-06 1.54607e-07 0.00919392 -0.216399 1.03279e-06 1.47292e-07 0.00929281 -0.21857 1.03066e-06 1.51473e-07 0.00939292 -0.220781 5.94535e-07 1.51172e-07 0.00949429 -0.222988 7.27996e-07 1.42928e-07 0.00959682 -0.225216 7.80631e-07 1.48525e-07 0.0097006 -0.227467 1.06339e-06 1.4993e-07 0.00980565 -0.229741 6.52697e-07 1.29668e-07 0.00991199 -0.232037 1.07438e-06 1.48453e-07 0.0100196 -0.234356 8.68763e-07 1.46862e-07 0.0101286 -0.236698 9.21868e-07 1.45082e-07 0.0102389 -0.239064 6.47149e-07 1.36809e-07 0.0103506 -0.241454 5.36393e-07 1.35688e-07 0.0104637 -0.243867 6.33717e-07 1.30403e-07 0.0105782 -0.246304 6.2927e-07 1.36557e-07 0.0106942 -0.248766 6.33292e-07 1.22453e-07 0.0108116 -0.251253 1.03705e-06 1.35409e-07 0.0109304 -0.253764 8.25286e-07 1.43161e-07 0.0110508 -0.256301 6.26825e-07 1.19257e-07 0.0111727 -0.258863 5.25259e-07 1.22741e-07 0.0112962 -0.26145 5.21832e-07 1.30918e-07 0.0114212 -0.264064 3.91659e-07 1.2137e-07 0.0115479 -0.266703 4.72439e-07 1.39973e-07 0.0116762 -0.269369 5.59536e-07 1.39151e-07 0.0118061 -0.272062 6.6407e-07 1.44867e-07 0.0119377 -0.274782 4.59378e-07 1.51466e-07 0.012071 -0.277529 3.66961e-07 1.43546e-07 0.0122061 -0.280303 5.31531e-07 1.48308e-07 0.012343 -0.283105 4.28914e-07 1.36145e-07 0.0124816 -0.285935 5.52006e-07 1.41983e-07 0.0126221 -0.288793 5.70264e-07 1.529e-07 0.0127644 -0.29168 5.04731e-07 1.36429e-07 0.0129086 -0.294596 6.61923e-07 1.40793e-07 0.0130548 -0.297541 7.60132e-07 1.60721e-07 0.0132029 -0.300516 4.68527e-07 1.34887e-07 0.0133529 -0.30352 4.4286e-07 1.47134e-07 0.0135051 -0.306554 4.89979e-07 1.4043e-07 0.0136592 -0.309619 3.60163e-07 1.33728e-07 0.0138155 -0.312714 2.90563e-07 1.48062e-07 0.0139739 -0.315841 5.19963e-07 1.51562e-07 0.0141344 -0.318998 4.66665e-07 1.56256e-07 0.0142972 -0.322187 3.88883e-07 1.57011e-07 0.0144622 -0.325408 4.46778e-07 1.55512e-07 0.0146295 -0.328662 3.23885e-07 1.52586e-07 0.0147991 -0.331947 3.78736e-07 1.5818e-07 0.0149711 -0.335266 3.88199e-07 1.53911e-07 0.0151455 -0.338618 4.42877e-07 1.49098e-07 0.0153224 -0.342003 2.47787e-07 1.46321e-07 0.0155017 -0.345423 2.85769e-07 1.35135e-07 0.0156836 -0.348876 4.75964e-07 1.53664e-07 0.0158681 -0.352364 4.49639e-07 1.53956e-07 0.0160552 -0.355887 2.47147e-07 1.44322e-07 0.0162449 -0.359445 2.16764e-07 1.49181e-07 0.0164375 -0.363039 5.20585e-07 1.57369e-07 0.0166327 -0.366669 5.24697e-07 1.54541e-07 0.0168309 -0.370335 3.64403e-07 1.55024e-07 0.0170319 -0.374037 4.59752e-07 1.65308e-07 0.0172358 -0.377777 5.35922e-07 1.82043e-07 0.0174427 -0.381554 4.26807e-07 1.77003e-07 0.0176527 -0.385369 4.03666e-07 1.8111e-07 0.0178658 -0.389222 2.55454e-07 1.59729e-07 0.018082 -0.393113 9.26972e-08 1.65402e-07 0.0183015 -0.397044 1.10672e-07 1.80888e-07 0.0185242 -0.401014 4.52163e-07 1.73191e-07 0.0187503 -0.405023 3.78066e-07 1.51597e-07 0.0189798 -0.409073 3.09136e-07 1.57195e-07 0.0192128 -0.413163 3.41774e-07 1.44818e-07 0.0194493 -0.417294 3.44924e-07 1.59581e-07 0.0196894 -0.421466 2.5184e-07 1.59757e-07 0.0199332 -0.42568 4.01737e-07 1.53814e-07 0.0201807 -0.429936 3.17279e-07 1.6913e-07 0.0204321 -0.434235 5.50631e-07 1.61142e-07 0.0206873 -0.438577 5.0851e-07 1.6499e-07 0.0209465 -0.442962 6.02593e-07 1.73835e-07 0.0212097 -0.447391 4.38454e-07 1.6535e-07 0.0214771 -0.451865 3.38757e-07 1.87639e-07 0.0217487 -0.456383 4.35846e-07 1.97826e-07 0.0220245 -0.460946 3.85579e-07 1.76143e-07 0.0223047 -0.465555 3.83415e-07 1.88454e-07 0.0225894 diff --git a/ratapi/examples/data/d2o_background_data.dat b/ratapi/examples/data/d2o_background_data.dat deleted file mode 100644 index 93b2fd38..00000000 --- a/ratapi/examples/data/d2o_background_data.dat +++ /dev/null @@ -1,82 +0,0 @@ -0.011403 1.90034798968076e-06 -9.65035874608547e-07 -0.011973 1.81361996101478e-06 -4.67852140773275e-09 -0.012572 1.5763144199176e-06 -1.36151693657437e-06 -0.013201 2.66861902156408e-06 5.28737972088124e-07 -0.013861 1.19184137102607e-06 6.5429177234931e-07 -0.014554 1.75409120253422e-06 -4.50039804064594e-07 -0.015281 1.51534921649628e-06 3.54060605152339e-07 -0.016045 1.76294603973655e-06 2.30273872099416e-07 -0.016848 1.66691808740296e-06 1.02729272466451e-06 -0.01769 2.2391873415575e-06 2.02710446930881e-07 -0.018575 1.47947093349392e-06 9.31566506641381e-07 -0.019503 1.58967045467121e-06 6.58308695637623e-09 -0.020479 2.05056480300655e-06 -4.18637528083399e-07 -0.021502 2.54199126843229e-06 6.96150360898885e-08 -0.022578 1.07273638130851e-06 -5.94598550176916e-08 -0.023706 2.89987639289405e-06 8.05335897612554e-07 -0.024892 1.56081284721073e-06 5.50847432744533e-08 -0.026136 2.32386636321661e-06 -5.72991095509919e-07 -0.027443 2.52478251612625e-06 -2.38750704688337e-08 -0.028815 2.66154668842285e-06 1.05087573637142e-06 -0.030256 1.74132051718101e-06 -2.3192582338868e-07 -0.031769 2.01215747485553e-06 -4.26893410009117e-07 -0.033357 1.91881656322323e-06 8.87192534478923e-07 -0.035025 1.69716945696631e-06 1.80981995646851e-07 -0.036777 2.13585488200451e-06 -1.90164659296111e-07 -0.038615 2.17932170608953e-06 -4.91062265460096e-07 -0.040546 1.82384243860966e-06 -1.08387392818395e-06 -0.042573 2.06617996409986e-06 2.22697399577916e-07 -0.044702 3.33679088859971e-06 -1.53613977488785e-07 -0.046937 1.99621696227773e-06 3.55134601922439e-07 -0.049284 2.3551514683307e-06 -1.06523727035749e-06 -0.051748 1.76873031859355e-06 1.15746760150783e-06 -0.054336 1.73606104969994e-06 4.89763150040874e-07 -0.057052 1.82710646654775e-06 -1.15330099931726e-06 -0.059905 2.28227888686718e-06 9.45647703159621e-07 -0.0629 1.59923042799896e-06 -3.70062237263438e-07 -0.066045 1.07352660741589e-06 3.41777294345909e-07 -0.069348 2.02660800872659e-06 2.75569910736786e-07 -0.072815 1.78179239147256e-06 -6.0256088120987e-07 -0.076456 2.14000373613308e-06 -2.18911980741668e-06 -0.080279 2.04230294359047e-06 5.284442372682e-07 -0.084292 2.36455952978407e-06 -1.73629847921614e-07 -0.088507 2.45037654782291e-06 -3.78287083788833e-07 -0.092932 1.33718085273407e-06 4.35130166728242e-07 -0.097579 1.23771058575749e-06 -4.51744576618967e-07 -0.10246 2.25121666653143e-06 6.36952833032752e-07 -0.10758 2.15319571282475e-06 2.20717968415214e-07 -0.11296 1.53041976734067e-06 -6.93055107868105e-07 -0.11861 2.61870106321507e-06 7.69463958198665e-07 -0.12454 2.01650595727752e-06 4.79607176188218e-07 -0.13077 2.06178415911062e-06 1.10173268381594e-06 -0.1373 2.13696968977538e-06 -6.14098124528528e-07 -0.14417 2.3770829041412e-06 -6.16219383494697e-07 -0.15138 2.7622487528669e-06 3.50660742020884e-07 -0.15895 1.86901211887215e-06 6.33626529015099e-07 -0.16689 1.13465824611353e-06 7.62493241842828e-07 -0.17524 2.50673214999504e-06 1.05207422581854e-07 -0.184 1.53613195077685e-06 -8.87137577093779e-08 -0.1932 2.62184014311179e-06 6.22256875962273e-07 -0.20286 1.70525565120706e-06 1.67162600924891e-06 -0.213 2.74574086739327e-06 8.07667338780613e-07 -0.22365 1.59701095264287e-06 1.67629565660922e-07 -0.23484 1.4437004736234e-06 -3.59611249006791e-07 -0.24658 2.47846978404969e-06 4.99800504594724e-07 -0.25891 1.31847420553136e-06 -2.87283586089481e-07 -0.27185 2.34029248136207e-06 2.90756508518823e-07 -0.28544 2.21891181128286e-06 7.22598553179947e-07 -0.29972 1.92836622666398e-06 8.39418345516717e-07 -0.3147 1.82923374769972e-06 5.70510331434857e-07 -0.33044 3.02890531703209e-06 1.20234742176368e-06 -0.34696 1.8127324822871e-06 1.58096394623758e-06 -0.36431 1.90489840127358e-06 -1.41813181395574e-06 -0.38252 1.53063379469415e-06 -1.32294734328625e-06 -0.40165 1.59326881780842e-06 -6.38112989285387e-07 -0.42173 1.7081906242357e-06 -1.49834166690205e-06 -0.44282 2.85476268526193e-06 -1.85680046178151e-07 -0.46496 1.80479009111448e-06 -1.69120607911057e-07 -0.48821 1.6549673183601e-06 3.00340803829798e-07 -0.51262 1.77588964903545e-06 3.28929520936145e-07 -0.53825 2.35718817504981e-06 -4.48934854489947e-07 -0.56516 1.34213437585845e-06 -5.50651590195596e-07 -0.59342 2.31356104763158e-06 7.347220470815e-07 diff --git a/ratapi/examples/domains/__init__.py b/ratapi/examples/domains/__init__.py deleted file mode 100644 index ed955f76..00000000 --- a/ratapi/examples/domains/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Examples for how to use RAT with domains models.""" diff --git a/ratapi/examples/domains/alloy_domains.py b/ratapi/examples/domains/alloy_domains.py deleted file mode 100644 index 90da84fd..00000000 --- a/ratapi/examples/domains/alloy_domains.py +++ /dev/null @@ -1,34 +0,0 @@ -"""Custom model file for the domains custom layers example.""" - - -def alloy_domains(params, bulkIn, bulkOut, contrast, domain): - """Calculate custom model layers for a permalloy/gold model with domains. - - Simple custom model for testing incoherent summing. - Simple two layer of permalloy / gold, with up/down domains. - """ - # Note - The first contrast number is 1 (not 0) so be careful if you use - # this variable for array indexing. Same applies to the domain number. - - # Split up the parameters - subRough = params[0] - alloyThick = params[1] - alloySLDup = params[2] - alloySLDdn = params[3] - alloyRough = params[4] - goldThick = params[5] - goldSLD = params[6] - goldRough = params[7] - - # Make the layers - alloyUp = [alloyThick, alloySLDup, alloyRough] - alloyDn = [alloyThick, alloySLDdn, alloyRough] - gold = [goldThick, goldSLD, goldRough] - - # Make the model depending on which domain we are looking at - if domain == 1: - output = [alloyUp, gold] - elif domain == 2: - output = [alloyDn, gold] - - return output, subRough diff --git a/ratapi/examples/domains/domains_XY_model.py b/ratapi/examples/domains/domains_XY_model.py deleted file mode 100644 index 6a288ba2..00000000 --- a/ratapi/examples/domains/domains_XY_model.py +++ /dev/null @@ -1,75 +0,0 @@ -"""Custom model file for the domains custom XY example.""" - -from math import sqrt - -import numpy as np -from scipy.special import erf - - -def domains_XY_model(params, bulk_in, bulk_out, contrast, domain): - """Calculate the SLD profile for a domains custom XY model.""" - # Note - The first contrast number is 1 (not 0) so be careful if you use - # this variable for array indexing. Same applies to the domain number. - - # Split up the parameters for convenience - subRough = params[0] - oxideThick = params[1] - layerThick = params[2] - layerSLD = params[3] - layerRough = params[4] - domainSLD = params[5] - - # Make an array of z values for our model - z = np.arange(0, 141) - - # Make the volume fraction distribution for our Silicon substrate - [vfSilicon, siSurf] = make_layer(z, -25, 50, 1, subRough, subRough) - - # ... and the Oxide ... - [vfOxide, oxSurface] = make_layer(z, siSurf, oxideThick, 1, subRough, subRough) - - # ... and also our layer. - [vfLayer, laySurface] = make_layer(z, oxSurface, layerThick, 1, subRough, layerRough) - - # Everything that is not already occupied will be filled will water - totalVF = vfSilicon + vfOxide + vfLayer - vfWater = 1 - totalVF - - # Now convert the Volume Fractions to SLDs - siSLD = vfSilicon * bulk_in - oxSLD = vfOxide * 3.41e-6 - - # Layer SLD depends on whether we are calculating the domain or not - if domain == 1: - laySLD = vfLayer * layerSLD - elif domain == 2: - laySLD = vfLayer * domainSLD - - # ... and finally the water SLD. - waterSLD = vfWater * bulk_out[contrast - 1] - - # Make the total SLD by just adding them all up - totalSLD = siSLD + oxSLD + laySLD + waterSLD - - # The output is just a [n x 2] array of z against SLD - SLD = np.column_stack([z, totalSLD]) - - return SLD, subRough - - -def make_layer(z, prevLaySurf, thickness, height, Sigma_L, Sigma_R): - """Produce a layer, with a defined thickness, height and roughness. - - Each side of the layer has its own roughness value. - """ - # Find the edges - left = prevLaySurf - right = prevLaySurf + thickness - - # Make our heaviside - erf_left = erf((z - left) / (sqrt(2) * Sigma_L)) - erf_right = erf((z - right) / (sqrt(2) * Sigma_R)) - - VF = np.array((0.5 * height) * (erf_left - erf_right)) - - return VF, right diff --git a/ratapi/examples/domains/domains_custom_XY.ipynb b/ratapi/examples/domains/domains_custom_XY.ipynb deleted file mode 100644 index 0a153e9d..00000000 --- a/ratapi/examples/domains/domains_custom_XY.ipynb +++ /dev/null @@ -1,179 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pathlib\n", - "from IPython.display import Code\n", - "\n", - "import ratapi as RAT\n", - "from ratapi.models import Parameter" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Simple example of a layer containing domains using a custom XY model\n", - "\n", - "Domains custom XY models operate in the same way as domains custom layer models, in that there is an additional input to the custom model specifying the domain to be calculated:\n", - "\n", - "This is then used within the function to calculate the correct SLD profile for each contrast and domain. In this example, we simulate a hydrogenated layer on a silicon substrate, containing domains of a larger SLD, against D2O, SMW and water.\n", - "\n", - "Start by making the project and adding the parameters:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "problem = RAT.Project(calculation=\"domains\", model=\"custom xy\", geometry=\"substrate/liquid\")\n", - "\n", - "parameter_list = [\n", - " Parameter(name=\"Oxide Thickness\", min=10.0, value=20.0, max=50.0, fit=True),\n", - " Parameter(name=\"Layer Thickness\", min=1.0, value=30.0, max=500.0, fit=True),\n", - " Parameter(name=\"Layer SLD\", min=-0.5e-6, value=-0.5e-6, max=0.0, fit=True),\n", - " Parameter(name=\"Layer Roughness\", min=2.0, value=5.0, max=7.0, fit=True),\n", - " Parameter(name=\"Domain SLD\", min=1.0e-6, value=1.0e-6, max=5.0e-6, fit=True)\n", - "]\n", - "\n", - "problem.parameters.extend(parameter_list)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now set the SLDs of the bulk phases for our samples." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "problem.bulk_in.set_fields(0, name=\"Silicon\", value=2.073e-6, max=1.0, fit=False)\n", - "\n", - "problem.bulk_out.append(name=\"SLD SMW\", min=2.0e-6, value=2.073e-6, max=2.1e-6)\n", - "problem.bulk_out.append(name=\"SLD H2O\", min=-0.6e-6, value=-0.56e-6, max=-0.5e-6)\n", - "\n", - "problem.scalefactors.set_fields(0, min=0.8, value=1.0, max=1.1, fit=True)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The custom file takes the parameters and build the model as usual, changing the SLD of the layer depending on whether we are calculating the layer (domain = 0), or the domain (domain = 1)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "Code(\"domains_XY_model.py\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Finally, add the custom file to the project, and make our three contrasts." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "problem.custom_files.append(name=\"Domain Layer\", filename=\"domains_XY_model.py\", language=\"python\", path=pathlib.Path.cwd().resolve())\n", - "\n", - "# Make contrasts\n", - "problem.contrasts.append(\n", - " name=\"D2O\",\n", - " background=\"Background 1\",\n", - " resolution=\"Resolution 1\",\n", - " scalefactor=\"Scalefactor 1\",\n", - " bulk_in=\"Silicon\",\n", - " bulk_out=\"SLD D2O\",\n", - " domain_ratio=\"Domain Ratio 1\",\n", - " data=\"Simulation\",\n", - " model=[\"Domain Layer\"],\n", - ")\n", - "\n", - "problem.contrasts.append(\n", - " name=\"SMW\",\n", - " background=\"Background 1\",\n", - " resolution=\"Resolution 1\",\n", - " scalefactor=\"Scalefactor 1\",\n", - " bulk_in=\"Silicon\",\n", - " bulk_out=\"SLD SMW\",\n", - " domain_ratio=\"Domain Ratio 1\",\n", - " data=\"Simulation\",\n", - " model=[\"Domain Layer\"],\n", - ")\n", - "\n", - "problem.contrasts.append(\n", - " name=\"H2O\",\n", - " background=\"Background 1\",\n", - " resolution=\"Resolution 1\",\n", - " scalefactor=\"Scalefactor 1\",\n", - " bulk_in=\"Silicon\",\n", - " bulk_out=\"SLD H2O\",\n", - " domain_ratio=\"Domain Ratio 1\",\n", - " data=\"Simulation\",\n", - " model=[\"Domain Layer\"],\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Finally, run the simulation and plot the results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "controls = RAT.Controls()\n", - "problem, results = RAT.run(problem, controls)\n", - "\n", - "RAT.plotting.plot_ref_sld(problem, results)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/ratapi/examples/domains/domains_custom_XY.py b/ratapi/examples/domains/domains_custom_XY.py deleted file mode 100644 index 38d4f031..00000000 --- a/ratapi/examples/domains/domains_custom_XY.py +++ /dev/null @@ -1,86 +0,0 @@ -"""An example of using domains with a Custom XY model.""" - -import pathlib - -import ratapi as RAT - - -def domains_custom_XY(): - """Calculate an example of a layer containing domains using a custom XY model. - - Domains custom XY models operate in the same way as domains custom layer models, - in that there is an additional input to the custom model - specifying the domain to be calculated. - - This is then used within the function to calculate the correct SLD profile - for each contrast and domain. In this example, we simulate a hydrogenated layer - on a silicon substrate, containing domains of a larger SLD, against D2O, SMW and water. - """ - problem = RAT.Project(calculation="domains", model="custom xy", geometry="substrate/liquid") - - problem.parameters.append(name="Oxide Thickness", min=10.0, value=20.0, max=50.0, fit=True) - problem.parameters.append(name="Layer Thickness", min=1.0, value=30.0, max=500.0, fit=True) - problem.parameters.append(name="Layer SLD", min=-0.5e-6, value=-0.5e-6, max=0.0, fit=True) - problem.parameters.append(name="Layer Roughness", min=2.0, value=5.0, max=7.0, fit=True) - problem.parameters.append(name="Domain SLD", min=1.0e-6, value=1.0e-6, max=5.0e-6, fit=True) - - problem.bulk_in.set_fields(0, name="Silicon", value=2.073e-6, max=1.0, fit=False) - problem.scalefactors.set_fields(0, min=0.8, value=1.0, max=1.1, fit=True) - - problem.bulk_out.append(name="SLD SMW", min=2.0e-6, value=2.073e-6, max=2.1e-6) - problem.bulk_out.append(name="SLD H2O", min=-0.6e-6, value=-0.56e-6, max=-0.5e-6) - - # Add the custom file - problem.custom_files.append( - name="Domain Layer", - filename="domains_XY_model.py", - language="python", - path=pathlib.Path(__file__).parent, - ) - - # Make contrasts - problem.contrasts.append( - name="D2O", - background="Background 1", - resolution="Resolution 1", - scalefactor="Scalefactor 1", - bulk_in="Silicon", - bulk_out="SLD D2O", - domain_ratio="Domain Ratio 1", - data="Simulation", - model=["Domain Layer"], - ) - - problem.contrasts.append( - name="SMW", - background="Background 1", - resolution="Resolution 1", - scalefactor="Scalefactor 1", - bulk_in="Silicon", - bulk_out="SLD SMW", - domain_ratio="Domain Ratio 1", - data="Simulation", - model=["Domain Layer"], - ) - - problem.contrasts.append( - name="H2O", - background="Background 1", - resolution="Resolution 1", - scalefactor="Scalefactor 1", - bulk_in="Silicon", - bulk_out="SLD H2O", - domain_ratio="Domain Ratio 1", - data="Simulation", - model=["Domain Layer"], - ) - - controls = RAT.Controls() - problem, results = RAT.run(problem, controls) - - return problem, results - - -if __name__ == "__main__": - problem, results = domains_custom_XY() - RAT.plotting.plot_ref_sld(problem, results, True) diff --git a/ratapi/examples/domains/domains_custom_layers.ipynb b/ratapi/examples/domains/domains_custom_layers.ipynb deleted file mode 100644 index 3016e977..00000000 --- a/ratapi/examples/domains/domains_custom_layers.ipynb +++ /dev/null @@ -1,141 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pathlib\n", - "from IPython.display import Code\n", - "\n", - "import ratapi as RAT\n", - "from ratapi.models import Parameter" - ] - }, - { - "attachments": { - "33c727cd-f7da-4589-aef2-f96e0f70c4d2.png": { - "image/png": "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mZmZmZmZmRVgIo+ZmZmZmZmZWQEm8piZmZmZmZmZFWAij5mZmZmZmZlZASbymJmZmZmZmZkVYCKPmZmZmZmZmVkBJvKYmZmZmZmZmRVgIo+ZmZmZmZmZWQEm8piZmZmZmZmZFWAij5mZmZmZmZlZASbymJmZmZmZmZkVYCKPmZmZmZmZmVkBJvKYmZmZmZmZmRVgIo+ZmZmZmZmZWQEm8piZmZmZmZmZFWAij5mZmZmZmZlZASbymJmZmZmZmZkVYCKPmZmZmZmZmVkBJvKYmZmZmZmZmRVgIo+ZmZmZmZmZWQEm8piZmZmZmZmZFWAij5mZmZmZmZlZASbymJmZmZmZmZkVYCKPmZmZmZmZmVkBJvKYmZmZmZmZmRVgIo+ZmZmZmZmZWQEm8piZmZmZmZmZFWAij5mZmZmZmZlZASbymJmZmZmZmZkVYCKPmZmZmZmZmVkBJvKYmZmZmZmZmRVgIo+ZmZmZmZmZWQEm8piZmZmZmZmZFWAij5mZmZmZmZlZASbymJmZmZmZmZkVYCKPmZmZmZmZmVkBJvKYmZmZmZmZmRVgIo+ZmZmZmZmZWQEm8piZmZmZmZmZFWAij5mZmZmZmZlZASbymJmZmZmZmZkVYCKPmZmZmZmZmVkB9v8BDmqwDDoJKuwAAAAASUVORK5CYII=" - } - }, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Analysing Domains Samples Using Custom Layers Models\n", - "\n", - "For custom models, all the work with calculating the reflectivity from the different domains is done within the custom model itself. To do this, there is an additional input into the custom model file which denotes the domain to be calculated:\n", - "\n", - "The final 'domain' input is always either 0 or 1, denoting which domain is being calculated. Then, within the custom model, we can calculate the layers structure for whichever domain structure is required in this pass through the function:\n", - "\n", - "We will make a simple example of a permalloy layer on silicon, which has spin up and spin down domains, each with different SLDs\n", - "\n", - "![image.png](attachment:33c727cd-f7da-4589-aef2-f96e0f70c4d2.png)\n", - "We start by setting up the project:\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "problem = RAT.Project(calculation=\"domains\", model=\"custom layers\", geometry=\"substrate/liquid\")\n", - "\n", - "# Make some parameters\n", - "parameter_list = [\n", - " Parameter(name=\"Alloy Thickness\", min=100.0, value=150.0, max=200.0, fit=True),\n", - " Parameter(name=\"Alloy SLD up\", min=9.0e-6, value=11.0e-6, max=13.0e-6, fit=True),\n", - " Parameter(name=\"Alloy SLD down\", min=5.0e-6, value=7.0e-6, max=10.0e-6, fit=True),\n", - " Parameter(name=\"Alloy Roughness\", min=5.0, value=7.0, max=11.0, fit=True),\n", - " Parameter(name=\"Gold Thickness\", min=100.0, value=150.0, max=200.0, fit=True),\n", - " Parameter(name=\"Gold SLD\", min=4.0e-6, value=4.5e-6, max=5.0e-6, fit=True),\n", - " Parameter(name=\"Gold Roughness\", min=5.0, value=7.0, max=11.0, fit=True)\n", - "]\n", - "\n", - "problem.parameters.extend(parameter_list)\n", - "\n", - "# Set the bulk SLD\n", - "problem.bulk_in.set_fields(0, name=\"Silicon\", value=2.073e-6, max=1.0)\n", - "\n", - "# Add the custom file\n", - "problem.custom_files.append(name=\"Alloy domains\", filename=\"alloy_domains.py\", language=\"python\", path=pathlib.Path.cwd().resolve(),\n", - ")\n", - "\n", - "# Make a contrast\n", - "problem.contrasts.append(\n", - " name=\"D2O Contrast\",\n", - " data=\"Simulation\",\n", - " background=\"Background 1\",\n", - " bulk_in=\"Silicon\",\n", - " bulk_out=\"SLD D2O\",\n", - " scalefactor=\"Scalefactor 1\",\n", - " resolution=\"Resolution 1\",\n", - " resample=False,\n", - " domain_ratio=\"Domain Ratio 1\",\n", - " model=[\"Alloy domains\"],\n", - ")\n", - "\n", - "print(problem)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the project, we are using a custom function which we have called 'alloy_domains':" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "Code(\"alloy_domains.py\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note that the main difference between this and a 'normal' custom function is the extra 'domain' input, which we then use to select which domain we compute using the 'if / else' instruction at the end of the function\n", - "\n", - "To run this, we make a controls block as usual, and send it to RAT." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "controls = RAT.Controls()\n", - "problem, results = RAT.run(problem, controls)\n", - "\n", - "RAT.plotting.plot_ref_sld(problem, results)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/ratapi/examples/domains/domains_custom_layers.py b/ratapi/examples/domains/domains_custom_layers.py deleted file mode 100644 index 92b5e037..00000000 --- a/ratapi/examples/domains/domains_custom_layers.py +++ /dev/null @@ -1,60 +0,0 @@ -"""An example of using domains with custom layer models.""" - -import pathlib - -import ratapi as RAT - - -def domains_custom_layers(): - """Calculate an example custom layers domains project involving incoherent summing on a permalloy layer. - - For a custom layers model, rather than being forced to define our layers as [Thick SLD Rough…. etc], - we can parameterise however we like and then use a function to calculate the parameters for each layer. - So for example, if the volume of lipid tails are known (from the literature), - then all we need is the Area per molecule to calculate the layers. - """ - problem = RAT.Project(calculation="domains", model="custom layers", geometry="substrate/liquid") - - # Make some parameters... - problem.parameters.append(name="Alloy Thickness", min=100.0, value=150.0, max=200.0, fit=True) - problem.parameters.append(name="Alloy SLD up", min=9.0e-6, value=11.0e-6, max=13.0e-6, fit=True) - problem.parameters.append(name="Alloy SLD down", min=5.0e-6, value=7.0e-6, max=10.0e-6, fit=True) - problem.parameters.append(name="Alloy Roughness", min=5.0, value=7.0, max=11.0, fit=True) - problem.parameters.append(name="Gold Thickness", min=100.0, value=150.0, max=200.0, fit=True) - problem.parameters.append(name="Gold SLD", min=4.0e-6, value=4.5e-6, max=5.0e-6, fit=True) - problem.parameters.append(name="Gold Roughness", min=5.0, value=7.0, max=11.0, fit=True) - - # Set the bulk SLD - problem.bulk_in.set_fields(0, name="Silicon", value=2.073e-6, max=1.0) - - # Add the custom file - problem.custom_files.append( - name="Alloy domains", - filename="alloy_domains.py", - language="python", - path=pathlib.Path(__file__).parent, - ) - - # Make a contrast - problem.contrasts.append( - name="D2O Contrast", - data="Simulation", - background="Background 1", - bulk_in="Silicon", - bulk_out="SLD D2O", - scalefactor="Scalefactor 1", - resolution="Resolution 1", - resample=False, - domain_ratio="Domain Ratio 1", - model=["Alloy domains"], - ) - - controls = RAT.Controls() - problem, results = RAT.run(problem, controls) - - return problem, results - - -if __name__ == "__main__": - problem, results = domains_custom_layers() - RAT.plotting.plot_ref_sld(problem, results, True) diff --git a/ratapi/examples/domains/domains_standard_layers.ipynb b/ratapi/examples/domains/domains_standard_layers.ipynb deleted file mode 100644 index 300207d3..00000000 --- a/ratapi/examples/domains/domains_standard_layers.ipynb +++ /dev/null @@ -1,200 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import ratapi as RAT\n", - "from ratapi.models import Layer, Parameter" - ] - }, - { - "attachments": { - "f38e04ec-f12b-4e68-b486-6cf8bffef1bd.png": { - "image/png": "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k7gQTWsVBTiKdSVWbZX36//4J1k4JOC4TgOq+Pj4mjVrTp8+nb6gXMZx6wIO98YOJy1UpD0FFQg4XnnllaFDh0JU0bD75Zdfrl+/PmnB3NzcpKQkjPyeeOIJ0o4Q3A8++OCqVaseeughIAPoPCi8Bx54AInLli2DMjh69Ojf//733r17h4WFTZgwgeTgu+++m5GRAQH3xRdfzJo167///W+/fv2QjQUfARS81NatWzF4bdSo0bZt22jIRbWqCqCbWgAVg7g/deoUfQI0Ef6dPHky5XnttdcGDRqE4TXgCP5FNrTt9u3bBw8ePGDAgPT09J9++mn06NF333032pCwFxqnb9++aE8qBBrirbfemjZtGuLQfwBeyHD//ff/5S9/UQSzNiMYWuzSrl27hx9+WLSjkL6pgoMVMMnOnTvRaPi4BA6ys7OhRCdOnEga66mnngoODgbLgaPwFmCMjz76CE0Htunfv/977733+++/P/vss2AwgBV639mzZ4MJIyMj0f5kbYIWnDNnDiJZWVnjxo0DmEYGSNUdO3ZQHdB6JFt5EUybNm3efPNNPA7pVdM4hI756quvAr6vWLECfIU2PHDgAMNiihDCIE5gmwReB4mM78mKw/iDbqHZGRTOK2DQFCiHCkEimy2RGf+iI7Rq1app06b/93//RxlEsHjtgENvVLfwAGeAm/07dVaNHFaHXDR6XYzoVmunTp3ATuiY4gI1Sbci4ND2Kag4o6REP336TIvFVnrP0rUCjjFjxkBB8jTw4cOHwXmQaBggIoJf582bBwVQt25djOAhgDAGQjrG09CRkIAY4nz44YePPPIIUAKkNqT8sGHDoCahJJBt06ZNKPbee+997rnnEIGiRWJsbCzURr169WhsxNsrSCxiCIU8a9asqdylGx6imQlytkaNGmfPniVFBb2Fl3rppZcw3AzTaMaMGRDBeIX169fjFapXr46me/vttwEImjVrhvQXXnghOjoaEdz+8ccfP/roo0Bjf/3rX9GSaHN8gscff5yaC0CkVq1aQDDAHJDszz//PGkCWvnB8h2gp3HjxvgKDC/wNenXqjlYz8nJwevzmgNQ165dExISwF1BQUHADQsWLADAQp7vvvsOv955552IA3VB3SKCJh05ciSG4z4+PqmpqQcPHgTABVZYuXIlGJKQGT5KYmIiXj8lJQX5fX19wXIo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" - } - }, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Domains Samples Using Standard Layers\n", - "\n", - "Domains standard layers projects proceed in much the same way as a normal standard layers problem, except that there is an additional grouping step between layers and contrasts.\n", - "\n", - "Layers are grouped into 'Domain Contrasts'. The model for the actual experimental contrast is built from these domain contrasts rather than from layers. There are exactly two domains for each contrast, with the the ratio of them controlled by a fittable 'domain ratio' parameter.\n", - "\n", - "![image.png](attachment:f38e04ec-f12b-4e68-b486-6cf8bffef1bd.png)\n", - "\n", - "In this we will set up a simple example of a simulated system consisting of two layered domains to illustrate this process.\n", - "\n", - "Start by making the project, specifying that this is a domains calculation:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "problem = RAT.Project(calculation=\"domains\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Define the parameters we need to define our two domains:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "parameter_list = [\n", - " Parameter(name=\"L1 Thickness\", min=5.0, value=20.0, max=60.0, fit=True),\n", - " Parameter(name=\"L1 SLD\", min=3.0e-6, value=4.1e-6, max=5.0e-6, fit=False),\n", - " Parameter(name=\"L1 Roughness\", min=2.0, value=5.0, max=20.0, fit=True),\n", - " Parameter(name=\"L1 Hydration\", min=10.0, value=20.0, max=30.0, fit=True),\n", - " #\n", - " Parameter(name=\"L2 Thickness\", min=5.0, value=60.0, max=100.0, fit=True),\n", - " Parameter(name=\"L2 SLD\", min=2.1e-6, value=3.0e-6, max=5.0e-6, fit=False),\n", - " Parameter(name=\"L2 Roughness\", min=2.0, value=5.0, max=20.0, fit=True),\n", - " Parameter(name=\"L2 Hydration\", min=10.0, value=20.0, max=30.0, fit=True),\n", - " #\n", - " Parameter(name=\"L3 Thickness\", min=5.0, value=200.0, max=300.0, fit=True),\n", - " Parameter(name=\"L3 SLD\", min=3.0e-6, value=7.0e-6, max=8.0e-6, fit=False),\n", - " Parameter(name=\"L3 Roughness\", min=2.0, value=5.0, max=20.0, fit=True),\n", - " Parameter(name=\"L3 Hydration\", min=10.0, value=20.0, max=30.0, fit=True)\n", - "]\n", - "\n", - "problem.parameters.extend(parameter_list)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now group these into layers as usual:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "layers = [\n", - "Layer(name=\"Layer 1\", thickness=\"L1 Thickness\", SLD=\"L1 SLD\", roughness=\"L1 Roughness\", hydration=\"L1 Hydration\", hydrate_with=\"bulk out\"),\n", - "Layer(name=\"Layer 2\", thickness=\"L2 Thickness\", SLD=\"L2 SLD\", roughness=\"L2 Roughness\", hydration=\"L2 Hydration\", hydrate_with=\"bulk out\"),\n", - "Layer(name=\"Layer 3\", thickness=\"L3 Thickness\", SLD=\"L3 SLD\", roughness=\"L3 Roughness\", hydration=\"L3 Hydration\", hydrate_with=\"bulk out\")\n", - "]\n", - "\n", - "problem.layers.extend(layers)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If we look at the project, there are two extra groups as compared to a normal standard layers - Domain Contrasts and Domain Ratios" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(problem)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now, make a couple of Domain Contrasts" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "problem.domain_contrasts.append(name=\"Domain 1\", model=[\"Layer 1\"])\n", - "problem.domain_contrasts.append(name=\"Domain 2\", model=[\"Layer 2\", \"Layer 3\"])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now make a contrast as with standard models, but this time also including the default domain ratio (\"Domain Ratio 1\"). Note that the model for each experimental contrast **must** have **exactly** two domain contrasts." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "problem.contrasts.append(\n", - " name=\"Domain Test\",\n", - " background=\"Background 1\",\n", - " resolution=\"Resolution 1\",\n", - " scalefactor=\"Scalefactor 1\",\n", - " resample=False,\n", - " bulk_in=\"SLD Air\",\n", - " bulk_out=\"SLD D2O\",\n", - " domain_ratio=\"Domain Ratio 1\",\n", - " data=\"Simulation\",\n", - " model=[\"Domain 1\", \"Domain 2\"],\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we can run our simulation as usual, and plot the results:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "controls = RAT.Controls()\n", - "problem, results = RAT.run(problem, controls)\n", - "\n", - "RAT.plotting.plot_ref_sld(problem, results)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/ratapi/examples/domains/domains_standard_layers.py b/ratapi/examples/domains/domains_standard_layers.py deleted file mode 100644 index 9a251233..00000000 --- a/ratapi/examples/domains/domains_standard_layers.py +++ /dev/null @@ -1,92 +0,0 @@ -"""An example using domains with standard layers.""" - -import ratapi as RAT - - -def domains_standard_layers(): - """Calculate an example for using standard layers with domains. - - Domains standard layers projects proceed in much the same way as a normal standard layers problem, - except that there is an additional grouping step between layers and contrasts. - - Layers are grouped into ‘Domain Contrasts’. The model for the actual experimental contrast - is built from these domain contrasts rather than from layers. There are exactly - two domains for each contrast, with the the ratio of them controlled by - a fittable ‘domain ratio’ parameter. - """ - problem = RAT.Project(calculation="domains") - - # Define the parameters we need to define our two domains - problem.parameters.append(name="L1 Thickness", min=5.0, value=20.0, max=60.0, fit=True) - problem.parameters.append(name="L1 SLD", min=3.0e-6, value=4.1e-6, max=5.0e-6, fit=False) - problem.parameters.append(name="L1 Roughness", min=2.0, value=5.0, max=20.0, fit=True) - problem.parameters.append(name="L1 Hydration", min=10.0, value=20.0, max=30.0, fit=True) - - problem.parameters.append(name="L2 Thickness", min=5.0, value=60.0, max=100.0, fit=True) - problem.parameters.append(name="L2 SLD", min=2.1e-6, value=3.0e-6, max=5.0e-6, fit=False) - problem.parameters.append(name="L2 Roughness", min=2.0, value=5.0, max=20.0, fit=True) - problem.parameters.append(name="L2 Hydration", min=10.0, value=20.0, max=30.0, fit=True) - - problem.parameters.append(name="L3 Thickness", min=5.0, value=200.0, max=300.0, fit=True) - problem.parameters.append(name="L3 SLD", min=3.0e-6, value=7.0e-6, max=8.0e-6, fit=False) - problem.parameters.append(name="L3 Roughness", min=2.0, value=5.0, max=20.0, fit=True) - problem.parameters.append(name="L3 Hydration", min=10.0, value=20.0, max=30.0, fit=True) - - # Now group these parameters into layers - problem.layers.append( - name="Layer 1", - thickness="L1 Thickness", - SLD="L1 SLD", - roughness="L1 Roughness", - hydration="L1 Hydration", - hydrate_with="bulk out", - ) - - problem.layers.append( - name="Layer 2", - thickness="L2 Thickness", - SLD="L2 SLD", - roughness="L2 Roughness", - hydration="L2 Hydration", - hydrate_with="bulk out", - ) - - problem.layers.append( - name="Layer 3", - thickness="L3 Thickness", - SLD="L3 SLD", - roughness="L3 Roughness", - hydration="L3 Hydration", - hydrate_with="bulk out", - ) - - # If we look at the project, there are two extra groups as compared to a normal standard layers calculation: - # Domain Contrasts and Domain Ratios - problem.domain_contrasts.append(name="Domain 1", model=["Layer 1"]) - problem.domain_contrasts.append(name="Domain 2", model=["Layer 2", "Layer 3"]) - - # Now make a contrast as with standard models, but this time also including the default domain ratio - # ("Domain Ratio 1") - problem.contrasts.append( - name="Domain Test", - background="Background 1", - resolution="Resolution 1", - scalefactor="Scalefactor 1", - resample=False, - bulk_in="SLD Air", - bulk_out="SLD D2O", - domain_ratio="Domain Ratio 1", - data="Simulation", - model=["Domain 1", "Domain 2"], - ) - - # Now we can run our simulation as usual - controls = RAT.Controls() - problem, results = RAT.run(problem, controls) - - return problem, results - - -if __name__ == "__main__": - problem, results = domains_standard_layers() - RAT.plotting.plot_ref_sld(problem, results, True) diff --git a/ratapi/examples/extras/two_contrast_example.py b/ratapi/examples/extras/two_contrast_example.py deleted file mode 100644 index 86811056..00000000 --- a/ratapi/examples/extras/two_contrast_example.py +++ /dev/null @@ -1,215 +0,0 @@ -"""The example project with two contrasts from the user guide.""" - -import numpy as np - -import ratapi as RAT - - -def two_contrast_example(): - """Generate the two-contrast example project from the user guide.""" - problem = RAT.Project(name="DSPC monolayers") - parameters = [ - RAT.models.Parameter(name="Tails Thickness", min=10, value=20, max=30, fit=True), - RAT.models.Parameter(name="Heads Thickness", min=3, value=11, max=16, fit=True), - RAT.models.Parameter(name="Tails Roughness", min=2, value=5, max=9, fit=True), - RAT.models.Parameter(name="Heads Roughness", min=2, value=5, max=9, fit=True), - RAT.models.Parameter(name="Deuterated Tails SLD", min=4e-6, value=6e-6, max=2e-5, fit=True), - RAT.models.Parameter(name="Hydrogenated Tails SLD", min=-0.6e-6, value=-0.4e-6, max=0, fit=True), - RAT.models.Parameter(name="Deuterated Heads SLD", min=1e-6, value=3e-6, max=8e-6, fit=True), - RAT.models.Parameter(name="Hydrogenated Heads SLD", min=0.1e-6, value=1.4e-6, max=3e-6, fit=True), - RAT.models.Parameter(name="Heads Hydration", min=0, value=0.3, max=0.5, fit=True), - ] - - problem.parameters.extend(parameters) - H_Heads = RAT.models.Layer( - name="Hydrogenated Heads", - thickness="Heads Thickness", - SLD="Hydrogenated Heads SLD", - roughness="Heads Roughness", - hydration="Heads Hydration", - hydrate_with="bulk out", - ) - - D_Heads = RAT.models.Layer( - name="Deuterated Heads", - thickness="Heads Thickness", - SLD="Deuterated Heads SLD", - roughness="Heads Roughness", - hydration="Heads Hydration", - hydrate_with="bulk out", - ) - - D_Tails = RAT.models.Layer( - name="Deuterated Tails", thickness="Tails Thickness", SLD="Deuterated Tails SLD", roughness="Tails Roughness" - ) - - H_Tails = RAT.models.Layer( - name="Hydrogenated Tails", - thickness="Tails Thickness", - SLD="Hydrogenated Tails SLD", - roughness="Tails Roughness", - ) - - problem.layers.extend([H_Heads, D_Heads, H_Tails, D_Tails]) - - problem.background_parameters.set_fields(0, name="Backs Value ACMW") - problem.background_parameters.set_fields(0, value=5.5e-6) - problem.background_parameters.append(name="Backs Value D2O", min=1e-8, value=2.8e-6, max=1e-5) - - problem.backgrounds.append(name="Background D2O", type="constant", value_1="Backs Value D2O") - problem.backgrounds.set_fields(0, name="Background ACMW", value_1="Backs Value ACMW") - - problem.bulk_out.append(name="SLD ACMW", min=-0.6e-6, value=-0.56e-6, max=-0.3e-6, fit=True) - - d13acmw20 = np.array( - [ - [5.1793e-02, 1.8087e-05, 7.9683e-07], - [5.4383e-02, 1.4582e-05, 6.3691e-07], - [5.7102e-02, 1.3621e-05, 5.5407e-07], - [5.9957e-02, 1.2409e-05, 4.8014e-07], - [6.2955e-02, 1.0992e-05, 4.1824e-07], - [6.6103e-02, 1.0619e-05, 3.7541e-07], - [6.9408e-02, 1.0162e-05, 3.4945e-07], - [7.2878e-02, 1.0716e-05, 3.3763e-07], - [7.6522e-02, 8.3468e-06, 2.8040e-07], - [8.0348e-02, 7.5250e-06, 2.5702e-07], - [8.4365e-02, 6.4395e-06, 2.2528e-07], - [8.8584e-02, 6.0544e-06, 2.0545e-07], - [9.3013e-02, 5.9517e-06, 1.9417e-07], - [9.7664e-02, 5.6433e-06, 1.8108e-07], - [1.0255e-01, 4.8172e-06, 1.6076e-07], - [1.0767e-01, 4.8066e-06, 1.5520e-07], - [1.1306e-01, 4.1559e-06, 1.4115e-07], - [1.1871e-01, 4.1418e-06, 1.3926e-07], - [1.2465e-01, 3.4580e-06, 1.2273e-07], - [1.3088e-01, 3.2376e-06, 1.1791e-07], - [1.3742e-01, 3.0976e-06, 1.1948e-07], - [1.4429e-01, 2.7478e-06, 1.1518e-07], - [1.5151e-01, 2.5492e-06, 1.1573e-07], - [1.5908e-01, 2.7500e-06, 1.2812e-07], - [1.6704e-01, 2.1813e-06, 2.0450e-07], - [1.7539e-01, 1.8609e-06, 5.4900e-07], - [1.8416e-01, 1.9405e-06, 1.5660e-07], - [1.9337e-01, 1.7421e-06, 2.3280e-07], - [2.0304e-01, 1.8050e-06, 3.9820e-07], - [2.1319e-01, 1.5801e-06, 1.4110e-07], - [2.2385e-01, 1.6724e-06, 7.7900e-08], - [2.3504e-01, 1.4150e-06, 4.0820e-07], - [2.4679e-01, 1.4340e-06, 5.3180e-07], - [2.5913e-01, 1.3102e-06, 2.6000e-07], - [2.7209e-01, 1.3702e-06, 2.8540e-07], - [2.8569e-01, 1.2468e-06, 2.3230e-07], - [2.9998e-01, 1.2956e-06, 5.3240e-07], - [3.1497e-01, 1.2947e-06, 3.9940e-07], - [3.3072e-01, 1.2488e-06, 2.1390e-07], - [3.4726e-01, 1.4620e-06, 3.3640e-07], - [3.6462e-01, 1.3056e-06, 2.1600e-07], - [3.8285e-01, 1.4553e-06, 2.3170e-07], - [4.0200e-01, 1.1579e-06, 2.6740e-07], - [4.2210e-01, 1.1753e-06, 3.0940e-07], - [4.4320e-01, 1.0066e-06, 5.2040e-07], - [4.6536e-01, 1.1043e-06, 3.1870e-07], - [4.8863e-01, 1.2969e-06, 4.1670e-07], - [5.1306e-01, 1.2495e-06, 2.0890e-07], - [5.3871e-01, 1.3898e-06, 4.7560e-07], - [5.6565e-01, 1.1225e-06, 3.0470e-07], - [5.8877e-01, 8.3346e-07, 3.8944e-07], - ] - ) - - d70d2o20 = np.array( - [ - [5.1793e-02, 1.4943e-04, 3.2517e-06], - [5.4383e-02, 1.1882e-04, 2.5846e-06], - [5.7102e-02, 9.2164e-05, 2.0507e-06], - [5.9957e-02, 7.7813e-05, 1.7070e-06], - [6.2955e-02, 6.1143e-05, 1.3983e-06], - [6.6103e-02, 4.8033e-05, 1.1343e-06], - [6.9408e-02, 4.1379e-05, 1.0006e-06], - [7.2878e-02, 3.5090e-05, 8.6919e-07], - [7.6522e-02, 3.0350e-05, 7.5890e-07], - [8.0348e-02, 2.4115e-05, 6.5226e-07], - [8.4365e-02, 2.0755e-05, 5.7445e-07], - [8.8584e-02, 1.7500e-05, 4.9617e-07], - [9.3013e-02, 1.5011e-05, 4.3754e-07], - [9.7664e-02, 1.3632e-05, 3.9907e-07], - [1.0255e-01, 1.2997e-05, 3.7469e-07], - [1.0767e-01, 1.1656e-05, 3.4282e-07], - [1.1306e-01, 1.0820e-05, 3.2299e-07], - [1.1871e-01, 9.5831e-06, 3.0088e-07], - [1.2465e-01, 8.9996e-06, 2.8102e-07], - [1.3088e-01, 8.6498e-06, 2.7363e-07], - [1.3742e-01, 7.9412e-06, 2.7158e-07], - [1.4429e-01, 7.4042e-06, 2.6829e-07], - [1.5151e-01, 6.8321e-06, 2.6877e-07], - [1.5908e-01, 5.6809e-06, 2.6232e-07], - [1.6704e-01, 5.6646e-06, 2.8607e-07], - [1.7539e-01, 4.7762e-06, 2.7767e-07], - [1.8416e-01, 4.1971e-06, 2.7353e-07], - [1.9337e-01, 4.1815e-06, 2.9140e-07], - [2.0304e-01, 3.2725e-06, 2.3160e-07], - [2.1319e-01, 2.3244e-06, 4.2270e-07], - [2.2385e-01, 2.2892e-06, 1.4970e-07], - [2.3504e-01, 1.9198e-06, 8.1460e-07], - [2.4679e-01, 1.4828e-06, 1.0840e-07], - [2.5913e-01, 1.1450e-06, 4.7440e-07], - [2.7209e-01, 1.3047e-06, 1.8840e-07], - [2.8569e-01, 9.6081e-07, 3.9385e-07], - [2.9998e-01, 8.2280e-07, 2.3955e-07], - [3.1497e-01, 6.3219e-07, 3.5324e-07], - [3.3072e-01, 6.1254e-07, 5.0846e-07], - [3.4726e-01, 7.4092e-07, 2.2312e-07], - [3.6462e-01, 6.3584e-07, 4.2866e-07], - [3.8285e-01, 7.7287e-07, 2.9493e-07], - [4.0200e-01, 9.4637e-07, 2.3347e-07], - [4.2210e-01, 7.0576e-07, 3.3494e-07], - [4.4320e-01, 7.8969e-07, 2.3371e-07], - [4.6536e-01, 5.8374e-07, 3.2624e-07], - [4.8863e-01, 5.6711e-07, 6.0419e-07], - [5.1306e-01, 4.7782e-07, 3.4822e-07], - [5.3871e-01, 6.3813e-07, 4.3279e-07], - [5.6565e-01, 4.6186e-07, 1.8863e-07], - [5.8877e-01, 5.6129e-07, 4.3960e-07], - ] - ) - - problem.data.append(name="H-tail / D-head / ACMW", data=d13acmw20) - problem.data.append(name="D-tail / H-head / D2O", data=d70d2o20) - - problem.contrasts.append( - name="D-tail/H-Head/D2O", - background="Background D2O", - resolution="Resolution 1", - scalefactor="Scalefactor 1", - bulk_out="SLD D2O", - bulk_in="SLD Air", - data="D-tail / H-head / D2O", - ) - - problem.contrasts.append( - name="H-tail/D-Head/ACMW", - background="Background ACMW", - resolution="Resolution 1", - scalefactor="Scalefactor 1", - bulk_out="SLD ACMW", - bulk_in="SLD Air", - data="D-tail / H-head / D2O", - ) - - problem.contrasts.set_fields(0, model=["Deuterated Tails", "Hydrogenated Heads"]) - problem.contrasts.set_fields(1, model=["Hydrogenated Tails", "Deuterated Heads"]) - - problem.background_parameters.set_fields(0, fit=True) - problem.background_parameters.set_fields(1, fit=True) - problem.scalefactors.set_fields(0, fit=True) - problem.bulk_out.set_fields(0, fit=True) - - return problem - - -if __name__ == "__main__": - problem = two_contrast_example() - controls = RAT.Controls() - problem, results = RAT.run(problem, controls) - - RAT.plotting.plot_ref_sld(problem, results, True) diff --git a/ratapi/examples/languages/__init__.py b/ratapi/examples/languages/__init__.py deleted file mode 100644 index 99fd5e1f..00000000 --- a/ratapi/examples/languages/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""A benchmark for using RAT custom files in three different languages.""" diff --git a/ratapi/examples/languages/custom_bilayer.cpp b/ratapi/examples/languages/custom_bilayer.cpp deleted file mode 100644 index 2cf0ca81..00000000 --- a/ratapi/examples/languages/custom_bilayer.cpp +++ /dev/null @@ -1,110 +0,0 @@ -//custom_bilayer.cpp - -#include - -#if defined(_WIN32) || defined(_WIN64) -#define LIB_EXPORT __declspec(dllexport) -#else -#define LIB_EXPORT -#endif - -// We user extern "C" decorator to avoid name mangling -extern "C" { - - LIB_EXPORT void custom_bilayer(std::vector& params, std::vector& bulkIn, std::vector& bulkOut, int contrast, std::vector& output, double* outputSize, double* rough) - { - // Note - The first contrast number is 1 (not 0) so be careful if you use - // this variable for array indexing. - double subRough = params[0]; - double oxideThick = params[1]; - double oxideHydration = params[2]; - double lipidAPM = params[3]; - double headHydration = params[4]; - double bilayerHydration = params[5]; - double bilayerRough = params[6]; - double waterThick = params[7]; - - // We have a constant SLD for the oxide - double oxideSLD = 3.41e-6; - - // Now make the lipid layers - // Use known lipid volume and compositions - // to make the layers - - // define all the neutron b's - double bc = 0.6646e-4; //Carbon - double bo = 0.5843e-4; //Oxygen - double bh = -0.3739e-4; //Hydrogen - double bp = 0.513e-4; //Phosphorus - double bn = 0.936e-4; //Nitrogen - double bd = 0.6671e-4; //Deuterium - - // Now make the lipid groups - double COO = (4*bo) + (2*bc); - double GLYC = (3*bc) + (5*bh); - double CH3 = (2*bc) + (6*bh); - double PO4 = (1*bp) + (4*bo); - double CH2 = (1*bc) + (2*bh); - double CHOL = (5*bc) + (12*bh) + (1*bn); - - // Group these into heads and tails: - double Head = CHOL + PO4 + GLYC + COO; - double Tails = (34*CH2) + (2*CH3); - - // We need volumes for each. - // Use literature values: - double vHead = 319; - double vTail = 782; - - // we use the volumes to calculate the SLDs - double SLDhead = Head / vHead; - double SLDtail = Tails / vTail; - - // We calculate the layer thickness from - // the volumes and the APM - double headThick = vHead / lipidAPM; - double tailThick = vTail / lipidAPM; - - // Manually deal with hydration for layers in - // this example. - double oxSLD = (oxideHydration * bulkOut[contrast-1]) + ((1 - oxideHydration) * oxideSLD); - double headSLD = (headHydration * bulkOut[contrast-1]) + ((1 - headHydration) * SLDhead); - double tailSLD = (bilayerHydration * bulkOut[contrast-1]) + ((1 - bilayerHydration) * SLDtail); - - // Make the layers - // oxide... - output.push_back(oxideThick); - output.push_back(oxSLD); - output.push_back(subRough); - - // Water... - output.push_back(waterThick); - output.push_back(bulkOut[contrast-1]); - output.push_back(bilayerRough); - - // Heads... - output.push_back(headThick); - output.push_back(headSLD); - output.push_back(bilayerRough); - - // Tails... - output.push_back(tailThick); - output.push_back(tailSLD); - output.push_back(bilayerRough); - - // Tails... - output.push_back(tailThick); - output.push_back(tailSLD); - output.push_back(bilayerRough); - - // Heads... - output.push_back(headThick); - output.push_back(headSLD); - output.push_back(bilayerRough); - - *rough = subRough; - - outputSize[0] = 6; // row - Necessary to output how many layers in stack - outputSize[1] = 3; // col - Should be different depending on calculation - } -} // extern "C" \ No newline at end of file diff --git a/ratapi/examples/languages/custom_bilayer.py b/ratapi/examples/languages/custom_bilayer.py deleted file mode 100644 index bed82ca3..00000000 --- a/ratapi/examples/languages/custom_bilayer.py +++ /dev/null @@ -1,72 +0,0 @@ -"""A custom bilayer model for the custom file languages benchmark.""" - -import numpy as np - - -def custom_bilayer(params, bulk_in, bulk_out, contrast): - """Calculate the layer parameters for a custom bilayer model.""" - # Note - The first contrast number is 1 (not 0) so be careful if you use - # this variable for array indexing. - - sub_rough = params[0] - oxide_thick = params[1] - oxide_hydration = params[2] - lipidAPM = params[3] - headHydration = params[4] - bilayerHydration = params[5] - bilayerRough = params[6] - waterThick = params[7] - - # We have a constant SLD for the bilayer - oxide_SLD = 3.41e-6 - - # Now make the lipid layers - # Use known lipid volume and compositions - # to make the layers - - # define all the neutron b's. - bc = 0.6646e-4 # Carbon - bo = 0.5843e-4 # Oxygen - bh = -0.3739e-4 # Hydrogen - bp = 0.513e-4 # Phosphorus - bn = 0.936e-4 # Nitrogen - - # Now make the lipid groups - COO = (4 * bo) + (2 * bc) - GLYC = (3 * bc) + (5 * bh) - CH3 = (2 * bc) + (6 * bh) - PO4 = (1 * bp) + (4 * bo) - CH2 = (1 * bc) + (2 * bh) - CHOL = (5 * bc) + (12 * bh) + (1 * bn) - - # Group these into heads and tails: - Head = CHOL + PO4 + GLYC + COO - Tails = (34 * CH2) + (2 * CH3) - - # We need volumes for each. - # Use literature values: - vHead = 319 - vTail = 782 - - # we use the volumes to calculate the SLDs - SLDhead = Head / vHead - SLDtail = Tails / vTail - - # We calculate the layer thickness from the volumes and the APM - headThick = vHead / lipidAPM - tailThick = vTail / lipidAPM - - # Manually deal with hydration for layers in this example. - oxSLD = (oxide_hydration * bulk_out[contrast - 1]) + ((1 - oxide_hydration) * oxide_SLD) - headSLD = (headHydration * bulk_out[contrast - 1]) + ((1 - headHydration) * SLDhead) - tailSLD = (bilayerHydration * bulk_out[contrast - 1]) + ((1 - bilayerHydration) * SLDtail) - - # Make the layers - oxide = [oxide_thick, oxSLD, sub_rough] - water = [waterThick, bulk_out[contrast - 1], bilayerRough] - head = [headThick, headSLD, bilayerRough] - tail = [tailThick, tailSLD, bilayerRough] - - output = np.array([oxide, water, head, tail, tail, head]) - - return output, sub_rough diff --git a/ratapi/examples/languages/run_custom_file_languages.py b/ratapi/examples/languages/run_custom_file_languages.py deleted file mode 100644 index 2f6025ae..00000000 --- a/ratapi/examples/languages/run_custom_file_languages.py +++ /dev/null @@ -1,41 +0,0 @@ -"""Test custom function languages.""" - -import pathlib -import time - -import setup_problem - -import ratapi as RAT - -path = pathlib.Path(__file__).parent - -project = setup_problem.make_example_problem() -controls = RAT.Controls() - -# Python -start = time.time() -project, results = RAT.run(project, controls) -end = time.time() -print(f"Python time is: {end - start}s\n") - -RAT.plotting.plot_ref_sld(project, results) - -# Matlab -project.custom_files.set_fields(0, filename="custom_bilayer.m", language="matlab", path=path) - -start = time.time() -project, results = RAT.run(project, controls) -end = time.time() -print(f"Matlab time is: {end - start}s\n") - -RAT.plotting.plot_ref_sld(project, results) - -# C++ -project.custom_files.set_fields(0, filename="custom_bilayer.dll", language="cpp", path=path) - -start = time.time() -project, results = RAT.run(project, controls) -end = time.time() -print(f"C++ time is: {end - start}s\n") - -RAT.plotting.plot_ref_sld(project, results) diff --git a/ratapi/examples/languages/setup_problem.py b/ratapi/examples/languages/setup_problem.py deleted file mode 100644 index dbf300db..00000000 --- a/ratapi/examples/languages/setup_problem.py +++ /dev/null @@ -1,130 +0,0 @@ -"""A custom example problem for the languages benchmark.""" - -import pathlib - -import numpy as np - -import ratapi as RAT - - -def make_example_problem(): - """Generate a Custom Layers example for Supported DSPC layer. - - Example of using custom layers to model a DSPC supported bilayer. - """ - problem = RAT.Project(name="Orso lipid example - custom layers", model="custom layers", geometry="substrate/liquid") - - # First we need to set up a parameters group. We will be using a pre-prepared custom model file, so we need to add - # the relevant parameters we are going to need to define the model (note that Substrate Roughness always exists as - # parameter 1). - problem.parameters.append(name="Oxide Thickness", min=5.0, value=20.0, max=60.0, fit=True) - problem.parameters.append(name="Oxide Hydration", min=0.0, value=0.2, max=0.5, fit=True) - problem.parameters.append(name="Lipid APM", min=45.0, value=55.0, max=65.0, fit=True) - problem.parameters.append(name="Head Hydration", min=00.0, value=0.2, max=0.5, fit=True) - problem.parameters.append(name="Bilayer Hydration", min=0.0, value=0.1, max=0.2, fit=True) - problem.parameters.append(name="Bilayer Roughness", min=2.0, value=4.0, max=8.0, fit=True) - problem.parameters.append(name="Water Thickness", min=0.0, value=2.0, max=10.0, fit=True) - - problem.parameters.set_fields(0, min=1.0, max=10.0) - - # Need to add the relevant Bulk SLDs. - # Change the bulk in from air to silicon, and add two additional water contrasts: - problem.bulk_in.set_fields(0, name="Silicon", min=2.07e-6, value=2.073e-6, max=2.08e-6, fit=False) - - problem.bulk_out.append(name="SLD SMW", min=1.0e-6, value=2.073e-6, max=3.0e-6, fit=True) - problem.bulk_out.append(name="SLD H2O", min=-0.6e-6, value=-0.56e-6, max=-0.3e-6, fit=True) - - problem.bulk_out.set_fields(0, min=5.0e-6, fit=True) - - # Now add the datafiles. We have three datasets we need to consider - the bilayer against D2O, Silicon Matched Water - # and H2O. Load these datafiles in and put them in the data block - - # Read in the datafiles - data_path = pathlib.Path(__file__).parents[1] / "data" - D2O_data = np.loadtxt(data_path / "c_PLP0016596.dat", delimiter=",") - SMW_data = np.loadtxt(data_path / "c_PLP0016601.dat", delimiter=",") - H2O_data = np.loadtxt(data_path / "c_PLP0016607.dat", delimiter=",") - - # Add the data to the project - note this data has a resolution 4th column - problem.data.append(name="Bilayer / D2O", data=D2O_data) - problem.data.append(name="Bilayer / SMW", data=SMW_data) - problem.data.append(name="Bilayer / H2O", data=H2O_data) - - # Add the custom file to the project - problem.custom_files.append( - name="DSPC Model", - filename="custom_bilayer.py", - language="python", - path=pathlib.Path(__file__).parent, - ) - - # Also, add the relevant background parameters - one each for each contrast: - problem.background_parameters.set_fields( - 0, - name="Background parameter D2O", - fit=True, - min=1.0e-10, - max=1.0e-5, - value=1.0e-07, - ) - - problem.background_parameters.append( - name="Background parameter SMW", - min=1.0e-10, - value=1.0e-7, - max=1.0e-5, - fit=True, - ) - problem.background_parameters.append( - name="Background parameter H2O", - min=1.0e-10, - value=1.0e-7, - max=1.0e-5, - fit=True, - ) - - # And add the two new constant backgrounds - problem.backgrounds.append(name="Background SMW", type="constant", source="Background parameter SMW") - problem.backgrounds.append(name="Background H2O", type="constant", source="Background parameter H2O") - - # And edit the other one - problem.backgrounds.set_fields(0, name="Background D2O", source="Background parameter D2O") - - # Finally modify some of the other parameters to be more suitable values for a solid / liquid experiment - problem.scalefactors.set_fields(0, value=1.0, min=0.5, max=2.0, fit=True) - - # Now add the three contrasts - problem.contrasts.append( - name="Bilayer / D2O", - background="Background D2O", - resolution="Resolution 1", - scalefactor="Scalefactor 1", - bulk_out="SLD D2O", - bulk_in="Silicon", - data="Bilayer / D2O", - model=["DSPC Model"], - ) - - problem.contrasts.append( - name="Bilayer / SMW", - background="Background SMW", - resolution="Resolution 1", - scalefactor="Scalefactor 1", - bulk_out="SLD SMW", - bulk_in="Silicon", - data="Bilayer / SMW", - model=["DSPC Model"], - ) - - problem.contrasts.append( - name="Bilayer / H2O", - background="Background H2O", - resolution="Resolution 1", - scalefactor="Scalefactor 1", - bulk_out="SLD H2O", - bulk_in="Silicon", - data="Bilayer / H2O", - model=["DSPC Model"], - ) - - return problem diff --git a/ratapi/examples/normal_reflectivity/DSPC_custom_XY.py b/ratapi/examples/normal_reflectivity/DSPC_custom_XY.py deleted file mode 100644 index 72511977..00000000 --- a/ratapi/examples/normal_reflectivity/DSPC_custom_XY.py +++ /dev/null @@ -1,149 +0,0 @@ -"""An example of analysing a Custom XY model.""" - -import pathlib - -import numpy as np - -import ratapi as RAT - - -def DSPC_custom_XY(): - r"""Calculate a Custom XY Example for Supported DSPC layer. - - In this example, we model the same data (DSPC supported bilayer) as the Custom Layers example, but this time we will - use continuous distributions of the volume fractions of each component to build up the SLD profiles (as described in - Shekhar et al, J. Appl. Phys., 110, 102216 (2011).) - - In this type of model, each 'layer' in the sample is described by a roughened Heaviside step function (really, just - two error functions back to back). So, in our case, we will need an oxide, a (possible) intervening water layer, and - then the bilayer itself. - - We can define our lipid in terms of an Area per Molecule, almost in its entirety, if we recognise that where the - volume is known, the thickness of the layer is simply given by the layer volume / APM: - - .. math:: d_{\textrm{layer}} =\frac{V_{\textrm{layer}} }{{\textrm{APM}}_{\textrm{layer}}}. - - We can then define the Volume Fraction of this layer with a roughened Heaviside of length dlayer and a height of 1. - Then, the total volume occupied will be given by the sum of the volume fractions across the interface. Of course, - this does not permit any hydration, so to deal with this, we can simply scale the (full occupation) Heaviside - functions by relevant coverage parameters. When this is correctly done, we can obtain the remaining water - distribution as: - - .. math:: {\textrm{VF}}_{\textrm{wat}} =1-\\sum_n {\textrm{VF}}_n - - where VFn is the Volume Fraction of the n'th layer. - """ - # Start by making the class and setting it to a custom XY type: - problem = RAT.Project(name="Orso lipid example - custom XY", model="custom xy", geometry="substrate/liquid") - - # We need to add the relevant parameters we are going to need to define the model - # (note that Substrate Roughness always exists as parameter 1). - problem.parameters.append(name="Oxide Thickness", min=10.0, value=15.0, max=30.0, fit=True) - problem.parameters.append(name="Oxide Hydration", min=0.1, value=0.2, max=0.4, fit=True) - problem.parameters.append(name="Water Thickness", min=0.0, value=5.0, max=20.0, fit=True) - problem.parameters.append(name="Lipid APM", min=40.0, value=50.0, max=90.0, fit=True) - problem.parameters.append(name="Lipid Coverage", min=0.9, value=1.0, max=1.0, fit=True) - problem.parameters.append(name="Bilayer Roughness", min=3.0, value=5.0, max=8.0, fit=True) - - problem.parameters.set_fields(0, min=1.0, max=10.0) - - # Need to add the relevant Bulk SLDs. Change the bulk in from air to silicon, and add two additional water - # contrasts: - problem.bulk_in.set_fields(0, name="Silicon", min=2.07e-6, value=2.073e-6, max=2.08e-6, fit=False) - - problem.bulk_out.append(name="SLD SMW", min=1.0e-6, value=2.073e-6, max=3.0e-6, fit=True) - problem.bulk_out.append(name="SLD H2O", min=-0.6e-6, value=-0.56e-6, max=-0.3e-6, fit=True) - - problem.bulk_out.set_fields(0, min=5.0e-6, value=6.1e-6, fit=True) - - # Now add the datafiles. We have three datasets we need to consider - the bilayer against D2O, Silicon Matched - # Water and H2O. Load these datafiles in and put them in the data block - - # Read in the datafiles - data_path = pathlib.Path(__file__).parents[1] / "data" - D2O_data = np.loadtxt(data_path / "c_PLP0016596.dat", delimiter=",") - SMW_data = np.loadtxt(data_path / "c_PLP0016601.dat", delimiter=",") - H2O_data = np.loadtxt(data_path / "c_PLP0016607.dat", delimiter=",") - - # Add the data to the project - note this data has a resolution 4th column - problem.data.append(name="Bilayer / D2O", data=D2O_data) - problem.data.append(name="Bilayer / SMW", data=SMW_data) - problem.data.append(name="Bilayer / H2O", data=H2O_data) - - # Add the custom file to the project - problem.custom_files.append( - name="DSPC Model", - filename="custom_XY_DSPC.py", - language="python", - path=pathlib.Path(__file__).parent, - ) - - # Also, add the relevant background parameters - one each for each contrast: - problem.background_parameters.set_fields( - 0, - name="Background parameter D2O", - fit=True, - min=1.0e-10, - max=1.0e-5, - value=1.0e-07, - ) - - problem.background_parameters.append(name="Background parameter SMW", min=0.0, value=1.0e-7, max=1.0e-5, fit=True) - problem.background_parameters.append(name="Background parameter H2O", min=0.0, value=1.0e-7, max=1.0e-5, fit=True) - - # And add the two new constant backgrounds - problem.backgrounds.append(name="Background SMW", type="constant", source="Background parameter SMW") - problem.backgrounds.append(name="Background H2O", type="constant", source="Background parameter H2O") - - # And edit the other one - problem.backgrounds.set_fields(0, name="Background D2O", source="Background parameter D2O") - - # Finally modify some of the other parameters to be more suitable values for a solid / liquid experiment - problem.scalefactors.set_fields(0, value=1.0, min=0.5, max=2.0, fit=True) - - # Also, we are going to use the data resolution - problem.resolutions.append(name="Data Resolution", type="data") - - # Now add the three contrasts - problem.contrasts.append( - name="Bilayer / D2O", - background="Background D2O", - resolution="Data Resolution", - scalefactor="Scalefactor 1", - bulk_out="SLD D2O", - bulk_in="Silicon", - data="Bilayer / D2O", - model=["DSPC Model"], - ) - - problem.contrasts.append( - name="Bilayer / SMW", - background="Background SMW", - resolution="Data Resolution", - scalefactor="Scalefactor 1", - bulk_out="SLD SMW", - bulk_in="Silicon", - data="Bilayer / SMW", - model=["DSPC Model"], - ) - - problem.contrasts.append( - name="Bilayer / H2O", - background="Background H2O", - resolution="Data Resolution", - scalefactor="Scalefactor 1", - bulk_out="SLD H2O", - bulk_in="Silicon", - data="Bilayer / H2O", - model=["DSPC Model"], - ) - - controls = RAT.Controls() - problem, results = RAT.run(problem, controls) - - return problem, results - - -if __name__ == "__main__": - problem, results = DSPC_custom_XY() - RAT.plotting.plot_ref_sld(problem, results, True) diff --git a/ratapi/examples/normal_reflectivity/DSPC_custom_layers.ipynb b/ratapi/examples/normal_reflectivity/DSPC_custom_layers.ipynb deleted file mode 100644 index b90c4aa3..00000000 --- a/ratapi/examples/normal_reflectivity/DSPC_custom_layers.ipynb +++ /dev/null @@ -1,349 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "id": "4b988c4a-3a09-4b75-8a87-8ba8402635ba", - "metadata": {}, - "outputs": [], - "source": [ - "import pathlib\n", - "\n", - "import numpy as np\n", - "from IPython.display import Code\n", - "\n", - "import ratapi as RAT\n", - "from ratapi.models import Parameter" - ] - }, - { - "cell_type": "markdown", - "id": "793d9c50-698e-438b-87f7-85e3a9f11d6b", - "metadata": {}, - "source": [ - "# Custom Layers Example for Supported DSPC layer\n", - "\n", - "Example of using Custom layers to model a DSPC supported bilayer.\n", - "Start by making the project and setting it to a custom layers type:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9a60cd45-0e1d-448a-b4bd-4c02bd6a3475", - "metadata": {}, - "outputs": [], - "source": [ - "problem = RAT.Project(name=\"Orso lipid example - custom layers\", model=\"custom layers\", geometry=\"substrate/liquid\")\n", - "problem.show_priors()" - ] - }, - { - "cell_type": "markdown", - "id": "9cc56e51-3d52-460a-bbb1-6d68571887c6", - "metadata": {}, - "source": [ - "For a custom layers model, rather than being forced to define our layers as \\[Thick SLD Rough.... etc\\], we can parameterise however we like and then use a function to calculate the \\[d $\\rho$ $\\sigma$\\] arrangement for each layer. So for example, if the volume of lipid tails are known (from the literature), then all we need is the Area per molecule, because then:\n", - "\n", - "$$\n", - "d = \\frac{V}{APM},\n", - "$$\n", - "where d is the thickness and V is the volume.\n", - "\n", - "Likewise, the SLD is:\n", - "$$\n", - "\\rho = \\frac{\\sum_{i}n_{i}b_{i}}{V},\n", - "$$\n", - "\n", - "as usual.\n", - "\n", - "In this folder there is a pre-prepared Python custom model for a DSPC on a Silicon substrate. We can display it here to see what we mean:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9038b77f-e3fc-4946-87fe-af4addf8ee84", - "metadata": {}, - "outputs": [], - "source": [ - "Code(filename='custom_bilayer_DSPC.py', language='python')" - ] - }, - { - "cell_type": "markdown", - "id": "002b67c8-1091-4544-9325-58227a012e4e", - "metadata": {}, - "source": [ - "We need to add the parameters we are going to need to define the model (note that Substrate Roughness always exists as parameter 0 as before, and that we are setting a Gaussian prior on the Head Hydration here)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "70494ef9-6cc5-47dc-9d02-6506645de46b", - "metadata": {}, - "outputs": [], - "source": [ - "parameter_list = [\n", - " Parameter(name=\"Oxide Thickness\", min=5.0, value=20.0, max=60.0, fit=True),\n", - " Parameter(name=\"Oxide Hydration\", min=0.0, value=0.2, max=0.5, fit=True),\n", - " Parameter(name=\"Lipid APM\", min=45.0, value=55.0, max=65.0, fit=True),\n", - " Parameter(name=\"Head Hydration\", min=0.0, value=0.2, max=0.5, fit=True, prior_type='gaussian', mu=0.3, sigma=0.03),\n", - " Parameter(name=\"Bilayer Hydration\", min=0.0, value=0.1, max=0.2, fit=True),\n", - " Parameter(name=\"Bilayer Roughness\", min=2.0, value=4.0, max=8.0, fit=True),\n", - " Parameter(name=\"Water Thickness\", min=0.0, value=2.0, max=10.0, fit=True)\n", - "]\n", - "\n", - "problem.parameters.extend(parameter_list)\n", - "problem.parameters.set_fields(0, min=1.0, max=10.0)" - ] - }, - { - "cell_type": "markdown", - "id": "a11897b0-244b-46c2-8bcd-a3d65bd8fc5c", - "metadata": {}, - "source": [ - "Need to add the relevant Bulk SLD's. Change the bulk in from air to silicon, and add two additional water contrasts:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "453fe3d2-162a-42bb-91ee-b1d020ffd29e", - "metadata": {}, - "outputs": [], - "source": [ - "# Change the bulk in from air to silicon:\n", - "problem.bulk_in.set_fields(0, name=\"Silicon\", min=2.07e-6, value=2.073e-6, max=2.08e-6, fit=False)\n", - "\n", - "problem.bulk_out.append(name=\"SLD SMW\", min=1.0e-6, value=2.073e-6, max=3.0e-6, fit=True)\n", - "problem.bulk_out.append(name=\"SLD H2O\", min=-0.6e-6, value=-0.56e-6, max=-0.3e-6, fit=True)\n", - "\n", - "problem.bulk_out.set_fields(0, min=5.0e-6, fit=True)" - ] - }, - { - "cell_type": "markdown", - "id": "d767523b-70ab-42a9-b28f-cd013a8b177e", - "metadata": {}, - "source": [ - "Now add the datafiles. We have three datasets we need to consider - the bilayer against D2O, Silicon Matched water and H2O. Load these datafiles in and put them in the data block:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fa4c1b96-3a1b-4aa6-8d61-68f24b0cb482", - "metadata": {}, - "outputs": [], - "source": [ - "# Read in the datafiles\n", - "data_path = pathlib.Path(\"../data\")\n", - "D2O_data = np.loadtxt(data_path / \"c_PLP0016596.dat\", delimiter=\",\")\n", - "SMW_data = np.loadtxt(data_path / \"c_PLP0016601.dat\", delimiter=\",\")\n", - "H2O_data = np.loadtxt(data_path / \"c_PLP0016607.dat\", delimiter=\",\")\n", - "\n", - "# Add the data to the project - note this data has a resolution 4th column\n", - "problem.data.append(name=\"Bilayer / D2O\", data=D2O_data, data_range=[0.013, 0.37])\n", - "problem.data.append(name=\"Bilayer / SMW\", data=SMW_data, data_range=[0.013, 0.32996])\n", - "problem.data.append(name=\"Bilayer / H2O\", data=H2O_data, data_range=[0.013, 0.33048])" - ] - }, - { - "cell_type": "markdown", - "id": "e60cd052-54f9-41b4-ab8b-6d4dde1c50fa", - "metadata": {}, - "source": [ - "Add the custom file to the project:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2e649c26-b32b-4c79-8ae7-fa701c87e6c2", - "metadata": {}, - "outputs": [], - "source": [ - "problem.custom_files.append(name=\"DSPC Model\", filename=\"custom_bilayer_DSPC.py\", language=\"python\", path=pathlib.Path.cwd().resolve())" - ] - }, - { - "cell_type": "markdown", - "id": "19a57f11-3d3c-49c5-b7a6-52bf449a3878", - "metadata": {}, - "source": [ - "Also, add the relevant background parameters - one each for each contrast:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5d51954f-469a-4044-9a7d-1b6e30474a6b", - "metadata": {}, - "outputs": [], - "source": [ - "problem.background_parameters.set_fields(0, name=\"Background parameter D2O\", min=1.0e-10, max=1.0e-5, value=1.0e-07, fit=True)\n", - "\n", - "problem.background_parameters.append(name=\"Background parameter SMW\", min=1.0e-10, value=1.0e-7, max=1.0e-5, fit=True)\n", - "problem.background_parameters.append(name=\"Background parameter H2O\", min=1.0e-10, value=1.0e-7, max=1.0e-5, fit=True)\n", - "\n", - "# And add the two new constant backgrounds\n", - "problem.backgrounds.append(name=\"Background SMW\", type=\"constant\", source=\"Background parameter SMW\")\n", - "problem.backgrounds.append(name=\"Background H2O\", type=\"constant\", source=\"Background parameter H2O\")\n", - "\n", - "# And edit the other one\n", - "problem.backgrounds.set_fields(0, name=\"Background D2O\", source=\"Background parameter D2O\")\n", - "\n", - "# Finally modify some of the other parameters to be more suitable values for a solid / liquid experiment\n", - "problem.scalefactors.set_fields(0, value=1.0, min=0.5, max=2.0, fit=True)" - ] - }, - { - "cell_type": "markdown", - "id": "a69a6d51-202a-4834-a6be-5c30f67d9107", - "metadata": {}, - "source": [ - "We need to use the data resolution (i.e. the fourth column of our datafiles). Do do this, we need to add a 'Data' resolution object to our resolutions table" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b1e4d313-8450-459b-b60e-868fe82f06b0", - "metadata": {}, - "outputs": [], - "source": [ - "problem.resolutions.append(name=\"Data Resolution\", type=\"data\")" - ] - }, - { - "cell_type": "markdown", - "id": "ddde7088-1382-4f56-9e05-6f1683ec2260", - "metadata": {}, - "source": [ - "Now add the three contrasts as before:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "efc7b351-2112-40c4-862b-a47e4570d173", - "metadata": {}, - "outputs": [], - "source": [ - "problem.contrasts.append(\n", - " name=\"Bilayer / D2O\",\n", - " background=\"Background D2O\",\n", - " resolution=\"Data Resolution\",\n", - " scalefactor=\"Scalefactor 1\",\n", - " bulk_out=\"SLD D2O\",\n", - " bulk_in=\"Silicon\",\n", - " data=\"Bilayer / D2O\",\n", - " model=[\"DSPC Model\"],\n", - ")\n", - "\n", - "problem.contrasts.append(\n", - " name=\"Bilayer / SMW\",\n", - " background=\"Background SMW\",\n", - " resolution=\"Data Resolution\",\n", - " scalefactor=\"Scalefactor 1\",\n", - " bulk_out=\"SLD SMW\",\n", - " bulk_in=\"Silicon\",\n", - " data=\"Bilayer / SMW\",\n", - " model=[\"DSPC Model\"],\n", - ")\n", - "\n", - "problem.contrasts.append(\n", - " name=\"Bilayer / H2O\",\n", - " background=\"Background H2O\",\n", - " resolution=\"Data Resolution\",\n", - " scalefactor=\"Scalefactor 1\",\n", - " bulk_out=\"SLD H2O\",\n", - " bulk_in=\"Silicon\",\n", - " data=\"Bilayer / H2O\",\n", - " model=[\"DSPC Model\"],\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "89f110e4-c3f8-488d-91d5-4f5fb5fbe9d7", - "metadata": {}, - "source": [ - "Note that the model is simply the custom file we've just added to the project.\n", - "\n", - "Look at the complete model definition before sending it to RAT:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ee889e55-8357-4363-860d-fb1c13bb8e8b", - "metadata": {}, - "outputs": [], - "source": [ - "print(problem)" - ] - }, - { - "cell_type": "markdown", - "id": "861b6e03-773a-46c3-b3fd-0df47c99d27e", - "metadata": {}, - "source": [ - "To run it, we need to make a controls block" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "154a33df-06b9-4035-aa4c-a0e095c1bb06", - "metadata": {}, - "outputs": [], - "source": [ - "controls = RAT.Controls()\n", - "print(controls)" - ] - }, - { - "cell_type": "markdown", - "id": "384f0a34-1a2b-40f7-a945-6d44db9391ab", - "metadata": {}, - "source": [ - ". . . and send this to RAT" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d5d9a782-0fb1-40b6-b1fa-86307abe32a6", - "metadata": {}, - "outputs": [], - "source": [ - "problem, results = RAT.run(problem, controls)\n", - "RAT.plotting.plot_ref_sld(problem, results)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.16" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/ratapi/examples/normal_reflectivity/DSPC_custom_layers.py b/ratapi/examples/normal_reflectivity/DSPC_custom_layers.py deleted file mode 100644 index 8de14903..00000000 --- a/ratapi/examples/normal_reflectivity/DSPC_custom_layers.py +++ /dev/null @@ -1,130 +0,0 @@ -"""Example of using custom layers to model a DSPC supported bilayer.""" - -import pathlib - -import numpy as np - -import ratapi as RAT - - -def DSPC_custom_layers(): - """Calculate a Custom Layers example for a supported DSPC layer.""" - problem = RAT.Project(name="Orso lipid example - custom layers", model="custom layers", geometry="substrate/liquid") - - # First we need to set up a parameters group. We will be using a pre-prepared custom model file, so we need to add - # the relevant parameters we are going to need to define the model (note that Substrate Roughness always exists as - # parameter 1). - problem.parameters.append(name="Oxide Thickness", min=5.0, value=20.0, max=60.0, fit=True) - problem.parameters.append(name="Oxide Hydration", min=0.0, value=0.2, max=0.5, fit=True) - problem.parameters.append(name="Lipid APM", min=45.0, value=55.0, max=65.0, fit=True) - problem.parameters.append(name="Head Hydration", min=0.0, value=0.2, max=0.5, fit=True) - problem.parameters.append(name="Bilayer Hydration", min=0.0, value=0.1, max=0.2, fit=True) - problem.parameters.append(name="Bilayer Roughness", min=2.0, value=4.0, max=8.0, fit=True) - problem.parameters.append(name="Water Thickness", min=0.0, value=2.0, max=10.0, fit=True) - - problem.parameters.set_fields(0, min=1.0, max=10.0) - - # Need to add the relevant Bulk SLDs. Change the bulk in from air to silicon, and add two additional water - # contrasts: - problem.bulk_in.set_fields(0, name="Silicon", min=2.07e-6, value=2.073e-6, max=2.08e-6, fit=False) - - problem.bulk_out.append(name="SLD SMW", min=1.0e-6, value=2.073e-6, max=3.0e-6, fit=True) - problem.bulk_out.append(name="SLD H2O", min=-0.6e-6, value=-0.56e-6, max=-0.3e-6, fit=True) - - problem.bulk_out.set_fields(0, min=5.0e-6, fit=True) - - # Now add the datafiles. We have three datasets we need to consider - the bilayer against D2O, Silicon Matched - # Water and H2O. Load these datafiles in and put them in the data block - - # Read in the datafiles - data_path = pathlib.Path(__file__).parents[1] / "data" - D2O_data = np.loadtxt(data_path / "c_PLP0016596.dat", delimiter=",") - SMW_data = np.loadtxt(data_path / "c_PLP0016601.dat", delimiter=",") - H2O_data = np.loadtxt(data_path / "c_PLP0016607.dat", delimiter=",") - - # Add the data to the project - note this data has a resolution 4th column - problem.data.append(name="Bilayer / D2O", data=D2O_data, data_range=[0.013, 0.37]) - problem.data.append(name="Bilayer / SMW", data=SMW_data, data_range=[0.013, 0.32996]) - problem.data.append(name="Bilayer / H2O", data=H2O_data, data_range=[0.013, 0.33048]) - - # Add the custom file to the project - problem.custom_files.append( - name="DSPC Model", - filename="custom_bilayer_DSPC.py", - language="python", - path=pathlib.Path(__file__).parent, - ) - - # Also, add the relevant background parameters - one each for each contrast: - problem.background_parameters.set_fields( - 0, - name="Background parameter D2O", - min=1.0e-10, - max=1.0e-5, - value=1.0e-07, - fit=True, - ) - - problem.background_parameters.append( - name="Background parameter SMW", min=1.0e-10, value=1.0e-7, max=1.0e-5, fit=True - ) - problem.background_parameters.append( - name="Background parameter H2O", min=1.0e-10, value=1.0e-7, max=1.0e-5, fit=True - ) - - # And add the two new constant backgrounds - problem.backgrounds.append(name="Background SMW", type="constant", source="Background parameter SMW") - problem.backgrounds.append(name="Background H2O", type="constant", source="Background parameter H2O") - - # And edit the other one - problem.backgrounds.set_fields(0, name="Background D2O", source="Background parameter D2O") - - # Finally modify some of the other parameters to be more suitable values for a solid / liquid experiment - problem.scalefactors.set_fields(0, value=1.0, min=0.5, max=2.0, fit=True) - - # Also, we are going to use the data resolution - problem.resolutions.append(name="Data Resolution", type="data") - - # Now add the three contrasts - problem.contrasts.append( - name="Bilayer / D2O", - background="Background D2O", - resolution="Data Resolution", - scalefactor="Scalefactor 1", - bulk_out="SLD D2O", - bulk_in="Silicon", - data="Bilayer / D2O", - model=["DSPC Model"], - ) - - problem.contrasts.append( - name="Bilayer / SMW", - background="Background SMW", - resolution="Data Resolution", - scalefactor="Scalefactor 1", - bulk_out="SLD SMW", - bulk_in="Silicon", - data="Bilayer / SMW", - model=["DSPC Model"], - ) - - problem.contrasts.append( - name="Bilayer / H2O", - background="Background H2O", - resolution="Data Resolution", - scalefactor="Scalefactor 1", - bulk_out="SLD H2O", - bulk_in="Silicon", - data="Bilayer / H2O", - model=["DSPC Model"], - ) - - controls = RAT.Controls() - problem, results = RAT.run(problem, controls) - - return problem, results - - -if __name__ == "__main__": - problem, results = DSPC_custom_layers() - RAT.plotting.plot_ref_sld(problem, results, True) diff --git a/ratapi/examples/normal_reflectivity/DSPC_custom_xy.ipynb b/ratapi/examples/normal_reflectivity/DSPC_custom_xy.ipynb deleted file mode 100644 index 0c0472c9..00000000 --- a/ratapi/examples/normal_reflectivity/DSPC_custom_xy.ipynb +++ /dev/null @@ -1,284 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "id": "956a341a-2a40-466c-b5c4-f8ea334ee81c", - "metadata": {}, - "outputs": [], - "source": [ - "import pathlib\n", - "\n", - "import numpy as np\n", - "from IPython.display import Code\n", - "\n", - "import ratapi as RAT\n", - "from ratapi.models import Parameter" - ] - }, - { - "attachments": { - "bf3e4c3d-0fc8-4565-8f2d-f4f8386d582c.png": { - "image/png": "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" - } - }, - "cell_type": "markdown", - "id": "2c6e70fd-f282-47e6-b310-8f4a3e305b7e", - "metadata": {}, - "source": [ - "# Custom XY Example for Supported DSPC layer.\n", - "\n", - "In this example, we model the same data (DSPC supported bilayer) as the Custom Layers example, but this time we will use continuous distributions of the volume fractions of each component to build up the SLD profiles (as described in Shekhar et al, *J. Appl. Phys.*, **110**, 102216 (2011).)\n", - "\n", - "In this type of model, each 'layer' in the sample is described by a roughened Heaviside step function (really, just two error functions back to back). So, in our case, we will need an oxide, a (possible) intervening water layer, and then the bilayer itself.\n", - "\n", - "We can define our lipid in terms of an Area per Molecule, almost in it's entirity, if we recognise that where the volume is known, the thickness of the layer is simply given by the layer volume / APM\n", - "$$\n", - "d = \\frac{V}{APM}.\n", - "$$\n", - "We can then define the Volume Fraction of this layer with a roughened Heaviside of length dlayer and a height of 1. Then, the total volume occupied will be given by the sum of the volume fractions across the interface. Of course, this does not permit any hydration, so to deal with this, we can simply scale the (full occupation) Heaviside functions by relevant coverage parameters. When this is correctly done, we can obtain the remaining water distribution as\n", - "$$\n", - "VF_{water} = 1 - \\sum_{n}VF_{n},\n", - "$$\n", - "where $VF_{n}$ is the Volume Fraction of the n'th layer.\n", - "![image.png](attachment:bf3e4c3d-0fc8-4565-8f2d-f4f8386d582c.png)\n", - "Start by making the class and setting it to a custom XY type:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d53c3ea9-b06f-4bf1-b7cc-da2264ca7322", - "metadata": {}, - "outputs": [], - "source": [ - "problem = RAT.Project(name=\"Orso lipid example - custom XY\", model=\"custom xy\", geometry=\"substrate/liquid\")" - ] - }, - { - "cell_type": "markdown", - "id": "f73d2471-a59c-4394-bd9f-7bed3f7f6057", - "metadata": {}, - "source": [ - "We need to add the relevant parameters we are going to need to define the model (note that Substrate Roughness always exists as parameter 0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4ba58003-096e-45cb-b384-f82d66259fed", - "metadata": {}, - "outputs": [], - "source": [ - "parameter_list = [\n", - " Parameter(name=\"Oxide Thickness\", min=10.0, value=15.0, max=30.0, fit=True),\n", - " Parameter(name=\"Oxide Hydration\", min=0.1, value=0.2, max=0.4, fit=True),\n", - " Parameter(name=\"Water Thickness\", min=0.0, value=5.0, max=20.0, fit=True),\n", - " Parameter(name=\"Lipid APM\", min=40.0, value=50.0, max=90.0, fit=True),\n", - " Parameter(name=\"Lipid Coverage\", min=0.9, value=1.0, max=1.0, fit=True),\n", - " Parameter(name=\"Bilayer Roughness\", min=3.0, value=5.0, max=8.0, fit=True)\n", - "]\n", - "\n", - "problem.parameters.extend(parameter_list)\n", - "\n", - "problem.parameters.set_fields(0, min=1.0, max=10.0)" - ] - }, - { - "cell_type": "markdown", - "id": "b1fe7c6e-2200-4c83-9485-ec3590e950d5", - "metadata": {}, - "source": [ - "Need to add the relevant Bulk SLDs. Change the bulk in from air to silicon, and add two additional water contrasts:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d0ef585b-4893-440b-9e63-6dcc8102d4c6", - "metadata": {}, - "outputs": [], - "source": [ - "# Change the bulk in from air to silicon\n", - "problem.bulk_in.set_fields(0, name=\"Silicon\", min=2.07e-6, value=2.073e-6, max=2.08e-6, fit=False)\n", - "\n", - "problem.bulk_out.append(name=\"SLD SMW\", min=1.0e-6, value=2.073e-6, max=3.0e-6, fit=True)\n", - "problem.bulk_out.append(name=\"SLD H2O\", min=-0.6e-6, value=-0.56e-6, max=-0.3e-6, fit=True)\n", - "\n", - "problem.bulk_out.set_fields(0, min=5.0e-6, value=6.1e-6, fit=True)" - ] - }, - { - "cell_type": "markdown", - "id": "643dd278-57d7-4756-b568-824e0b3cb2d5", - "metadata": {}, - "source": [ - "Now add our datafiles:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "372cf5bc-5ec5-4e96-8ade-05a8b0baa3a2", - "metadata": {}, - "outputs": [], - "source": [ - "# Read in the datafiles\n", - "data_path = pathlib.Path(\"../data\")\n", - "D2O_data = np.loadtxt(data_path / \"c_PLP0016596.dat\", delimiter=\",\")\n", - "SMW_data = np.loadtxt(data_path / \"c_PLP0016601.dat\", delimiter=\",\")\n", - "H2O_data = np.loadtxt(data_path / \"c_PLP0016607.dat\", delimiter=\",\")\n", - "\n", - "# Add the data to the project - note this data has a resolution 4th column\n", - "problem.data.append(name=\"Bilayer / D2O\", data=D2O_data)\n", - "problem.data.append(name=\"Bilayer / SMW\", data=SMW_data)\n", - "problem.data.append(name=\"Bilayer / H2O\", data=H2O_data)" - ] - }, - { - "cell_type": "markdown", - "id": "7f4a1730-f6af-40f4-b1dc-1d76eeaaa08e", - "metadata": {}, - "source": [ - "Add the custom file to the project. We can view the code first." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "60a4b771-7967-4b46-bd3c-1c7cb4eaa24b", - "metadata": {}, - "outputs": [], - "source": [ - "Code(\"custom_XY_DSPC.py\")\n", - "problem.custom_files.append(name=\"DSPC Model\", filename=\"custom_XY_DSPC.py\", language=\"python\", path=pathlib.Path.cwd().resolve())" - ] - }, - { - "cell_type": "markdown", - "id": "c4157f30-47c0-476c-b9d3-736f0af21e79", - "metadata": {}, - "source": [ - "Add and modify the remaining parameters - backgrounds, scalefactors, and resolutions:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "57303283-9319-4b1c-817b-04d6441a2992", - "metadata": {}, - "outputs": [], - "source": [ - "problem.background_parameters.set_fields(0, name=\"Background parameter D2O\", fit=True, min=1.0e-10, max=1.0e-5, value=1.0e-07)\n", - "\n", - "problem.background_parameters.append(name=\"Background parameter SMW\", min=0.0, value=1.0e-7, max=1.0e-5, fit=True)\n", - "problem.background_parameters.append(name=\"Background parameter H2O\", min=0.0, value=1.0e-7, max=1.0e-5, fit=True)\n", - "\n", - "# And add the two new constant backgrounds\n", - "problem.backgrounds.append(name=\"Background SMW\", type=\"constant\", source=\"Background parameter SMW\")\n", - "problem.backgrounds.append(name=\"Background H2O\", type=\"constant\", source=\"Background parameter H2O\")\n", - "\n", - "# And edit the other one\n", - "problem.backgrounds.set_fields(0, name=\"Background D2O\", source=\"Background parameter D2O\")\n", - "\n", - "# Finally modify some of the other parameters to be more suitable values for a solid / liquid experiment\n", - "problem.scalefactors.set_fields(0, value=1.0, min=0.5, max=2.0, fit=True)\n", - "\n", - "# Also, we are going to use the data resolution\n", - "problem.resolutions.append(name=\"Data Resolution\", type=\"data\")" - ] - }, - { - "cell_type": "markdown", - "id": "d941b284-13b0-4866-90c7-765fb2dc4ed1", - "metadata": {}, - "source": [ - "Now add the three contrasts as before:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6815648e-ad4a-4193-ba39-83f5f15781b1", - "metadata": {}, - "outputs": [], - "source": [ - "problem.contrasts.append(\n", - " name=\"Bilayer / D2O\",\n", - " background=\"Background D2O\",\n", - " resolution=\"Data Resolution\",\n", - " scalefactor=\"Scalefactor 1\",\n", - " bulk_out=\"SLD D2O\",\n", - " bulk_in=\"Silicon\",\n", - " data=\"Bilayer / D2O\",\n", - " model=[\"DSPC Model\"],\n", - ")\n", - "\n", - "problem.contrasts.append(\n", - " name=\"Bilayer / SMW\",\n", - " background=\"Background SMW\",\n", - " resolution=\"Data Resolution\",\n", - " scalefactor=\"Scalefactor 1\",\n", - " bulk_out=\"SLD SMW\",\n", - " bulk_in=\"Silicon\",\n", - " data=\"Bilayer / SMW\",\n", - " model=[\"DSPC Model\"],\n", - ")\n", - "\n", - "problem.contrasts.append(\n", - " name=\"Bilayer / H2O\",\n", - " background=\"Background H2O\",\n", - " resolution=\"Data Resolution\",\n", - " scalefactor=\"Scalefactor 1\",\n", - " bulk_out=\"SLD H2O\",\n", - " bulk_in=\"Silicon\",\n", - " data=\"Bilayer / H2O\",\n", - " model=[\"DSPC Model\"],\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "ca0e6c93-e617-482c-b8bd-41dc0df4f586", - "metadata": {}, - "source": [ - "## Running the Model\n", - "\n", - "We do this by first making a controls block as previously. We'll run a Differential Evolution:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "821571d9-3593-4ac6-a5db-4d83998ff4db", - "metadata": {}, - "outputs": [], - "source": [ - "controls = RAT.Controls(procedure=\"de\", parallel=\"contrasts\", display=\"final\")\n", - "problem, results = RAT.run(problem, controls)\n", - "RAT.plotting.plot_ref_sld(problem, results)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/ratapi/examples/normal_reflectivity/DSPC_data_background.py b/ratapi/examples/normal_reflectivity/DSPC_data_background.py deleted file mode 100644 index 11a14730..00000000 --- a/ratapi/examples/normal_reflectivity/DSPC_data_background.py +++ /dev/null @@ -1,220 +0,0 @@ -"""A standard layers example with a data background.""" - -import pathlib - -import numpy as np - -import ratapi as RAT - - -def DSPC_data_background(): - """Calculate a Standard Layers fit of a DSPC floating bilayer with a data background.""" - problem = RAT.Project(name="original_dspc_bilayer", model="standard layers", geometry="substrate/liquid") - - # Set up the relevant parameters - problem.parameters.append(name="Oxide Thickness", min=5.0, value=19.54, max=60.0, fit=True) - problem.parameters.append(name="Oxide SLD", min=3.39e-06, value=3.39e-06, max=3.41e-06, fit=False) - problem.parameters.append(name="SAM Tails Thickness", min=15.0, value=22.66, max=35.0, fit=True) - problem.parameters.append(name="SAM Tails SLD", min=-5e-07, value=-4.01e-07, max=-3e-07, fit=False) - problem.parameters.append(name="SAM Tails Hydration", min=1.0, value=5.252, max=50.0, fit=True) - problem.parameters.append(name="SAM Roughness", min=1.0, value=5.64, max=15.0, fit=True) - problem.parameters.append(name="CW Thickness", min=10.0, value=17.12, max=28.0, fit=True) - problem.parameters.append(name="CW SLD", min=0.0, value=0.0, max=1e-09, fit=False) - - problem.parameters.append( - name="SAM Heads Thickness", - min=5.0, - value=8.56, - max=17.0, - fit=True, - prior_type="gaussian", - mu=10.0, - sigma=2.0, - ) - problem.parameters.append(name="SAM Heads SLD", min=1.0e-07, value=1.75e-06, max=2.0e-06, fit=False) - problem.parameters.append( - name="SAM Heads Hydration", - min=10.0, - value=45.45, - max=50.0, - fit=True, - prior_type="gaussian", - mu=30.0, - sigma=3.0, - ) - problem.parameters.append( - name="Bilayer Heads Thickness", - min=7.0, - value=10.7, - max=17.0, - fit=True, - prior_type="gaussian", - mu=10.0, - sigma=2.0, - ) - problem.parameters.append(name="Bilayer Heads SLD", min=5.0e-07, value=1.47e-06, max=1.5e-06, fit=False) - problem.parameters.append(name="Bilayer Roughness", min=2.0, value=6.014, max=15.0, fit=True) - problem.parameters.append(name="Bilayer Tails Thickness", min=14.0, value=17.82, max=22.0, fit=True) - problem.parameters.append(name="Bilayer Tails SLD", min=-5.0e-07, value=-4.61e-07, max=0.0, fit=False) - problem.parameters.append(name="Bilayer Tails Hydration", min=10.0, value=17.64, max=50.0, fit=True) - problem.parameters.append(name="Bilayer Heads Hydration", min=10.0, value=36.15, max=50.0, fit=True) - problem.parameters.append(name="CW Hydration", min=99.9, value=100.0, max=100.0, fit=False) - problem.parameters.append(name="Oxide Hydration", min=0.0, value=23.61, max=60.0, fit=True) - - problem.parameters.set_fields(0, max=10) - - # Group these into layers - problem.layers.append( - name="Oxide", - thickness="Oxide Thickness", - SLD="Oxide SLD", - roughness="Substrate Roughness", - hydration="Oxide Hydration", - hydrate_with="bulk out", - ) - - problem.layers.append( - name="SAM Tails", - thickness="SAM Tails Thickness", - SLD="SAM Tails SLD", - roughness="SAM Roughness", - hydration="SAM Tails Hydration", - hydrate_with="bulk out", - ) - - problem.layers.append( - name="SAM Heads", - thickness="SAM Heads Thickness", - SLD="SAM Heads SLD", - roughness="SAM Roughness", - hydration="SAM Heads Hydration", - hydrate_with="bulk out", - ) - - problem.layers.append( - name="Central Water", - thickness="CW Thickness", - SLD="CW SLD", - roughness="Bilayer Roughness", - hydration="CW Hydration", - hydrate_with="bulk out", - ) - - problem.layers.append( - name="Bilayer Heads", - thickness="Bilayer Heads Thickness", - SLD="Bilayer Heads SLD", - roughness="Bilayer Roughness", - hydration="Bilayer Heads Hydration", - hydrate_with="bulk out", - ) - - problem.layers.append( - name="Bilayer Tails", - thickness="Bilayer Tails Thickness", - SLD="Bilayer Tails SLD", - roughness="Bilayer Roughness", - hydration="Bilayer Tails Hydration", - hydrate_with="bulk out", - ) - - # Make the bulk SLDs - del problem.bulk_in[0] - problem.bulk_in.append(name="Silicon", min=2.0e-06, value=2.073e-06, max=2.1e-06, fit=False) - - del problem.bulk_out[0] - problem.bulk_out.append(name="D2O", min=5.50e-06, value=5.98e-06, max=6.4e-06, fit=True) - problem.bulk_out.append(name="SMW", min=1.0e-06, value=2.21e-06, max=4.99e-06, fit=True) - - # Set the scalefactors - use one for each contrast - del problem.scalefactors[0] - problem.scalefactors.append(name="Scalefactor 1", min=0.05, value=0.10, max=0.2, fit=False) - problem.scalefactors.append(name="Scalefactor 2", min=0.05, value=0.15, max=0.2, fit=False) - - # Now deal with the backgrounds - # SMW has a constant background - del problem.backgrounds[0] - del problem.background_parameters[0] - problem.background_parameters.append( - name="Background parameter SMW", - min=1.0e-10, - value=3.38e-06, - max=4.99e-06, - fit=True, - ) - problem.backgrounds.append(name="SMW Background", type="constant", source="Background parameter SMW") - - data_path = pathlib.Path(__file__).parents[1] / "data" - - # load in background data for D2O - d2o_background = np.loadtxt(data_path / "d2o_background_data.dat") - problem.data.append(name="D2O Background Data", data=d2o_background) - - # add background parameter for the offset - problem.background_parameters.append( - name="D2O Data Offset", - min=-1e-8, - value=0, - max=1e-8, - fit=True, - ) - - # add the background with data and offset - problem.backgrounds.append( - name="D2O Data Background", - type="data", - source="D2O Background Data", - value_1="D2O Data Offset", - ) - - # Now add the data - d2o_dat = np.loadtxt(data_path / "DSPC_D2O.dat", delimiter=",") - problem.data.append(name="dspc_bil_D2O", data=d2o_dat) - - smw_dat = np.loadtxt(data_path / "DSPC_SMW.dat", delimiter=",") - problem.data.append(name="dspc_bil_smw", data=smw_dat) - - # Set the model - stack = [ - "Oxide", - "SAM Tails", - "SAM Heads", - "Central Water", - "Bilayer Heads", - "Bilayer Tails", - "Bilayer Tails", - "Bilayer Heads", - ] - - # Then make the two contrasts - problem.contrasts.append( - name="D2O", - bulk_in="Silicon", - bulk_out="D2O", - background="D2O Data Background", - resolution="Resolution 1", - scalefactor="Scalefactor 1", - data="dspc_bil_D2O", - model=stack, - ) - - problem.contrasts.append( - name="SMW", - bulk_in="Silicon", - bulk_out="SMW", - background="SMW Background", - resolution="Resolution 1", - scalefactor="Scalefactor 2", - data="dspc_bil_smw", - model=stack, - ) - - controls = RAT.Controls() - problem, results = RAT.run(problem, controls) - - return problem, results - - -if __name__ == "__main__": - problem, results = DSPC_data_background() - RAT.plotting.plot_ref_sld(problem, results, True) diff --git a/ratapi/examples/normal_reflectivity/DSPC_function_background.py b/ratapi/examples/normal_reflectivity/DSPC_function_background.py deleted file mode 100644 index e6a87b69..00000000 --- a/ratapi/examples/normal_reflectivity/DSPC_function_background.py +++ /dev/null @@ -1,219 +0,0 @@ -"""A standard layers example with a function background.""" - -import pathlib - -import numpy as np - -import ratapi as RAT - - -def DSPC_function_background(): - """Calculate a standard Layers fit of a DSPC floating bilayer with a function background.""" - problem = RAT.Project(name="original_dspc_bilayer", model="standard layers", geometry="substrate/liquid") - - # Set up the relevant parameters - problem.parameters.append(name="Oxide Thickness", min=5.0, value=19.54, max=60.0, fit=True) - problem.parameters.append(name="Oxide SLD", min=3.39e-06, value=3.39e-06, max=3.41e-06, fit=False) - problem.parameters.append(name="SAM Tails Thickness", min=15.0, value=22.66, max=35.0, fit=True) - problem.parameters.append(name="SAM Tails SLD", min=-5e-07, value=-4.01e-07, max=-3e-07, fit=False) - problem.parameters.append(name="SAM Tails Hydration", min=1.0, value=5.252, max=50.0, fit=True) - problem.parameters.append(name="SAM Roughness", min=1.0, value=5.64, max=15.0, fit=True) - problem.parameters.append(name="CW Thickness", min=10.0, value=17.12, max=28.0, fit=True) - problem.parameters.append(name="CW SLD", min=0.0, value=0.0, max=1e-09, fit=False) - - problem.parameters.append( - name="SAM Heads Thickness", - min=5.0, - value=8.56, - max=17.0, - fit=True, - prior_type="gaussian", - mu=10.0, - sigma=2.0, - ) - problem.parameters.append(name="SAM Heads SLD", min=1.0e-07, value=1.75e-06, max=2.0e-06, fit=False) - problem.parameters.append( - name="SAM Heads Hydration", - min=10.0, - value=45.45, - max=50.0, - fit=True, - prior_type="gaussian", - mu=30.0, - sigma=3.0, - ) - problem.parameters.append( - name="Bilayer Heads Thickness", - min=7.0, - value=10.7, - max=17.0, - fit=True, - prior_type="gaussian", - mu=10.0, - sigma=2.0, - ) - problem.parameters.append(name="Bilayer Heads SLD", min=5.0e-07, value=1.47e-06, max=1.5e-06, fit=False) - problem.parameters.append(name="Bilayer Roughness", min=2.0, value=6.014, max=15.0, fit=True) - problem.parameters.append(name="Bilayer Tails Thickness", min=14.0, value=17.82, max=22.0, fit=True) - problem.parameters.append(name="Bilayer Tails SLD", min=-5.0e-07, value=-4.61e-07, max=0.0, fit=False) - problem.parameters.append(name="Bilayer Tails Hydration", min=10.0, value=17.64, max=50.0, fit=True) - problem.parameters.append(name="Bilayer Heads Hydration", min=10.0, value=36.15, max=50.0, fit=True) - problem.parameters.append(name="CW Hydration", min=99.9, value=100.0, max=100.0, fit=False) - problem.parameters.append(name="Oxide Hydration", min=0.0, value=23.61, max=60.0, fit=True) - - problem.parameters.set_fields(0, max=10) - - # Group these into layers - problem.layers.append( - name="Oxide", - thickness="Oxide Thickness", - SLD="Oxide SLD", - roughness="Substrate Roughness", - hydration="Oxide Hydration", - hydrate_with="bulk out", - ) - - problem.layers.append( - name="SAM Tails", - thickness="SAM Tails Thickness", - SLD="SAM Tails SLD", - roughness="SAM Roughness", - hydration="SAM Tails Hydration", - hydrate_with="bulk out", - ) - - problem.layers.append( - name="SAM Heads", - thickness="SAM Heads Thickness", - SLD="SAM Heads SLD", - roughness="SAM Roughness", - hydration="SAM Heads Hydration", - hydrate_with="bulk out", - ) - - problem.layers.append( - name="Central Water", - thickness="CW Thickness", - SLD="CW SLD", - roughness="Bilayer Roughness", - hydration="CW Hydration", - hydrate_with="bulk out", - ) - - problem.layers.append( - name="Bilayer Heads", - thickness="Bilayer Heads Thickness", - SLD="Bilayer Heads SLD", - roughness="Bilayer Roughness", - hydration="Bilayer Heads Hydration", - hydrate_with="bulk out", - ) - - problem.layers.append( - name="Bilayer Tails", - thickness="Bilayer Tails Thickness", - SLD="Bilayer Tails SLD", - roughness="Bilayer Roughness", - hydration="Bilayer Tails Hydration", - hydrate_with="bulk out", - ) - - # Make the bulk SLDs - del problem.bulk_in[0] - problem.bulk_in.append(name="Silicon", min=2.0e-06, value=2.073e-06, max=2.1e-06, fit=False) - - del problem.bulk_out[0] - problem.bulk_out.append(name="D2O", min=5.50e-06, value=5.98e-06, max=6.4e-06, fit=True) - problem.bulk_out.append(name="SMW", min=1.0e-06, value=2.21e-06, max=4.99e-06, fit=True) - - # Set the scalefactors - use one for each contrast - del problem.scalefactors[0] - problem.scalefactors.append(name="Scalefactor 1", min=0.05, value=0.10, max=0.2, fit=False) - problem.scalefactors.append(name="Scalefactor 2", min=0.05, value=0.15, max=0.2, fit=False) - - # Now deal with the backgrounds - # SMW has a constant background - del problem.backgrounds[0] - del problem.background_parameters[0] - problem.background_parameters.append( - name="Background parameter SMW", - min=1.0e-10, - value=3.38e-06, - max=4.99e-06, - fit=True, - ) - problem.backgrounds.append(name="SMW Background", type="constant", source="Background parameter SMW") - - problem.custom_files.append( - name="D2O Background Function", - filename="background_function.py", - language="python", - path=pathlib.Path(__file__).parent, - ) - - problem.background_parameters.append(name="Fn Ao", min=5e-7, value=8e-6, max=5e-5) - problem.background_parameters.append(name="Fn k", min=40, value=70, max=90) - problem.background_parameters.append(name="Fn Const", min=1e-7, value=8e-6, max=1e-5) - - problem.backgrounds.append( - name="D2O Function Background", - type="function", - source="D2O Background Function", - value_1="Fn Ao", - value_2="Fn k", - value_3="Fn Const", - ) - - # Now add the data - data_path = pathlib.Path(__file__).parents[1] / "data" - - d2o_dat = np.loadtxt(data_path / "DSPC_D2O.dat", delimiter=",") - problem.data.append(name="dspc_bil_D2O", data=d2o_dat) - - smw_dat = np.loadtxt(data_path / "DSPC_SMW.dat", delimiter=",") - problem.data.append(name="dspc_bil_smw", data=smw_dat) - - # Set the model - stack = [ - "Oxide", - "SAM Tails", - "SAM Heads", - "Central Water", - "Bilayer Heads", - "Bilayer Tails", - "Bilayer Tails", - "Bilayer Heads", - ] - - # Then make the two contrasts - problem.contrasts.append( - name="D2O", - bulk_in="Silicon", - bulk_out="D2O", - background="D2O Function Background", - resolution="Resolution 1", - scalefactor="Scalefactor 1", - data="dspc_bil_D2O", - model=stack, - ) - - problem.contrasts.append( - name="SMW", - bulk_in="Silicon", - bulk_out="SMW", - background="SMW Background", - resolution="Resolution 1", - scalefactor="Scalefactor 2", - data="dspc_bil_smw", - model=stack, - ) - - controls = RAT.Controls() - problem, results = RAT.run(problem, controls) - - return problem, results - - -if __name__ == "__main__": - problem, results = DSPC_function_background() - RAT.plotting.plot_ref_sld(problem, results, True) diff --git a/ratapi/examples/normal_reflectivity/DSPC_standard_layers.ipynb b/ratapi/examples/normal_reflectivity/DSPC_standard_layers.ipynb deleted file mode 100644 index 3110cfe5..00000000 --- a/ratapi/examples/normal_reflectivity/DSPC_standard_layers.ipynb +++ /dev/null @@ -1,337 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "id": "1ca14405-4a7c-4588-93cd-46534c374a36", - "metadata": {}, - "outputs": [], - "source": [ - "import pathlib\n", - "\n", - "import numpy as np\n", - "\n", - "import ratapi as RAT\n", - "from ratapi.models import Layer, Parameter" - ] - }, - { - "attachments": { - "e72d4765-3d29-4d8b-a0c5-2b9ba546588c.png": { - "image/png": "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" - } - }, - "cell_type": "markdown", - "id": "74ca6ea0-5261-4712-b202-043c00b7e4c2", - "metadata": {}, - "source": [ - "# Standard Layers Analysis of a DSPC Floating Bilayer\n", - "\n", - "In this worksheet, we will carry out an analysis of a floating bilayer sample using a 'standard layers' model. \n", - "The sample consists of a DSPC bilayer, on a silane SAM on Silicon:\n", - "\n", - "![image.png](attachment:e72d4765-3d29-4d8b-a0c5-2b9ba546588c.png)\n", - "\n", - "So we are going to need layers for Oxide, SAM tails, SAM heads, and the Heads/Tails of the Bilayer. We also need to consider hydration of the submerged bilayer." - ] - }, - { - "cell_type": "markdown", - "id": "be9b7c0d-dff4-4971-9efa-722215eb5227", - "metadata": {}, - "source": [ - "## Making the Project\n", - "\n", - "Start by initialising a project:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "24510c3b-eb41-4981-ac34-9503f742a8dc", - "metadata": {}, - "outputs": [], - "source": [ - "problem = RAT.Project(name=\"original_dspc_bilayer\", calculation=\"normal\", model=\"standard layers\", geometry=\"substrate/liquid\", absorption=False)" - ] - }, - { - "cell_type": "markdown", - "id": "31584d08-aea4-4411-9b3c-84f4eadbef66", - "metadata": {}, - "source": [ - "The add the parameters we are going to need:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f75a8713-0e9c-4972-a803-fae5b5028056", - "metadata": {}, - "outputs": [], - "source": [ - "parameter_list = [\n", - " Parameter(name=\"Oxide Thickness\", min=5.0, value=19.54, max=60.0, fit=True, prior_type=\"uniform\"),\n", - " Parameter(name=\"Oxide SLD\", min=3.39e-06, value=3.39e-06, max=3.41e-06, fit=False, prior_type=\"uniform\"),\n", - " Parameter(name=\"Oxide Hydration\", min=0.0, value=23.61, max=60.0, fit=True, prior_type=\"uniform\"),\n", - " #\n", - " Parameter(name=\"SAM Tails Thickness\", min=15.0, value=22.66, max=35.0, fit=True, prior_type=\"uniform\"),\n", - " Parameter(name=\"SAM Tails SLD\", min=-5e-07, value=-4.01e-07, max=-3e-07, fit=False, prior_type=\"uniform\"),\n", - " Parameter(name=\"SAM Tails Hydration\", min=1.0, value=5.252, max=50.0, fit=True, prior_type=\"uniform\"),\n", - " Parameter(name=\"SAM Roughness\", min=1.0, value=5.64, max=15.0, fit=True, prior_type=\"uniform\"),\n", - " #\n", - " Parameter(name=\"SAM Heads Thickness\", min=5.0, value=8.56, max=17.0, fit=True, prior_type=\"gaussian\", mu=10.0, sigma=2.0),\n", - " Parameter(name=\"SAM Heads SLD\", min=1.0e-07, value=1.75e-06, max=2.0e-06, fit=False, prior_type=\"uniform\"),\n", - " Parameter(name=\"SAM Heads Hydration\", min=10.0, value=45.45, max=50.0, fit=True, prior_type=\"gaussian\", mu=30.0, sigma=3.0),\n", - " #\n", - " Parameter(name=\"CW Thickness\", min=10.0, value=17.12, max=28.0, fit=True, prior_type=\"uniform\"),\n", - " Parameter(name=\"CW SLD\", min=0.0, value=0.0, max=1e-09, fit=False, prior_type=\"uniform\"),\n", - " Parameter(name=\"CW Hydration\", min=99.9, value=100.0, max=100.0, fit=False, prior_type=\"uniform\"),\n", - " #\n", - " Parameter(name=\"Bilayer Heads Thickness\", min=7.0, value=10.7, max=17.0, fit=True, prior_type=\"gaussian\", mu=10.0, sigma=2.0),\n", - " Parameter(name=\"Bilayer Heads SLD\", min=5.0e-07, value=1.47e-06, max=1.5e-06, fit=False, prior_type=\"uniform\"),\n", - " Parameter(name=\"Bilayer Heads Hydration\", min=10.0, value=36.15, max=50.0, fit=True, prior_type=\"gaussian\", mu=30.0, sigma=3.0),\n", - " Parameter(name=\"Bilayer Roughness\", min=2.0, value=6.014, max=15.0, fit=True, prior_type=\"uniform\"),\n", - " Parameter(name=\"Bilayer Tails Thickness\", min=14.0, value=17.82, max=22.0, fit=True, prior_type=\"uniform\"),\n", - " Parameter(name=\"Bilayer Tails SLD\", min=-5.0e-07, value=-4.61e-07, max=0.0, fit=False, prior_type=\"uniform\"),\n", - " Parameter(name=\"Bilayer Tails Hydration\", min=10.0, value=17.64, max=50.0, fit=True, prior_type=\"uniform\") \n", - "]\n", - "\n", - "problem.parameters.extend(parameter_list)\n", - "\n", - "# In addition to these, there is also Substrate Roughness which is always parameter 1. Increase the allowed range of this a bit\n", - "problem.parameters.set_fields(0, max=10)" - ] - }, - { - "cell_type": "markdown", - "id": "52f6752b-ce20-4c36-b357-988eb8ee178b", - "metadata": {}, - "source": [ - "Now we can group these parameters into the layers we need, and add them to the project:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f9fb80fe-41a3-4062-b84d-1e4ed524d02b", - "metadata": {}, - "outputs": [], - "source": [ - "layers = [\n", - " Layer(name=\"Oxide\", thickness=\"Oxide Thickness\", SLD=\"Oxide SLD\", roughness=\"Substrate Roughness\",\n", - " hydration=\"Oxide Hydration\", hydrate_with=\"bulk out\"),\n", - " Layer(name=\"SAM Tails\", thickness=\"SAM Tails Thickness\", SLD=\"SAM Tails SLD\", roughness=\"SAM Roughness\",\n", - " hydration=\"SAM Tails Hydration\", hydrate_with=\"bulk out\"),\n", - " Layer(name=\"SAM Heads\", thickness=\"SAM Heads Thickness\", SLD=\"SAM Heads SLD\", roughness=\"SAM Roughness\",\n", - " hydration=\"SAM Heads Hydration\", hydrate_with=\"bulk out\"),\n", - " Layer(name=\"Central Water\", thickness=\"CW Thickness\", SLD=\"CW SLD\", roughness=\"Bilayer Roughness\",\n", - " hydration=\"CW Hydration\", hydrate_with=\"bulk out\"),\n", - " Layer(name=\"Bilayer Heads\", thickness=\"Bilayer Heads Thickness\", SLD=\"Bilayer Heads SLD\", roughness=\"Bilayer Roughness\",\n", - " hydration=\"Bilayer Heads Hydration\", hydrate_with=\"bulk out\"),\n", - " Layer(name=\"Bilayer Tails\", thickness=\"Bilayer Tails Thickness\", SLD=\"Bilayer Tails SLD\", roughness=\"Bilayer Roughness\",\n", - " hydration=\"Bilayer Tails Hydration\", hydrate_with=\"bulk out\")\n", - "]\n", - "\n", - "problem.layers.extend(layers)" - ] - }, - { - "cell_type": "markdown", - "id": "356964f9-83a6-4a92-8092-4d250b68ac16", - "metadata": {}, - "source": [ - "Now deal with the experimental parameters. We will delete the predefined default parameters and add new ones for this specific problem. We need a bulk in of Silicon, and two Bulk outs - D2O and SMW." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b197f3ea-c6ef-4831-9500-9ff0cb5011f3", - "metadata": {}, - "outputs": [], - "source": [ - "del problem.bulk_in[0]\n", - "problem.bulk_in.append(name=\"Silicon\", min=2.0e-06, value=2.073e-06, max=2.1e-06, fit=False)\n", - "\n", - "del problem.bulk_out[0]\n", - "problem.bulk_out.append(name=\"D2O\", min=5.5e-06, value=5.98e-06, max=6.4e-06, fit=True)\n", - "problem.bulk_out.append(name=\"SMW\", min=1.0e-06, value=2.21e-06, max=4.99e-06, fit=True)" - ] - }, - { - "cell_type": "markdown", - "id": "420b57a9-4fc7-49d5-acaa-68570f1876d2", - "metadata": {}, - "source": [ - "Likewise the scalefactors and backgrounds:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "92a26ca2-b1ee-41c8-89ce-8b72c0892438", - "metadata": {}, - "outputs": [], - "source": [ - "del problem.scalefactors[0]\n", - "problem.scalefactors.append(name=\"Scalefactor 1\", min=0.05, value=0.10, max=0.2, fit=False)\n", - "problem.scalefactors.append(name=\"Scalefactor 2\", min=0.05, value=0.15, max=0.2, fit=False)\n", - "\n", - "# Now deal with the backgrounds\n", - "del problem.backgrounds[0]\n", - "del problem.background_parameters[0]\n", - "problem.background_parameters.append(name=\"Background parameter D2O\", min=5.0e-10, value=2.23e-06, max=7.0e-06, fit=True)\n", - "problem.background_parameters.append(name=\"Background parameter SMW\", min=1.0e-10, value=3.38e-06, max=4.99e-06, fit=True)\n", - "\n", - "problem.backgrounds.append(name=\"D2O Background\", type=\"constant\", source=\"Background parameter D2O\")\n", - "problem.backgrounds.append(name=\"SMW Background\", type=\"constant\", source=\"Background parameter SMW\")" - ] - }, - { - "cell_type": "markdown", - "id": "a1b04d8b-8cc8-4e35-9e06-a6be3de90c53", - "metadata": {}, - "source": [ - "Now load in and add the data:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "73681532-2688-4bfd-8153-1ab763f5687a", - "metadata": {}, - "outputs": [], - "source": [ - "data_path = pathlib.Path(\"../data\")\n", - "\n", - "d2o_dat = np.loadtxt(data_path / \"DSPC_D2O.dat\", delimiter=\",\")\n", - "problem.data.append(name=\"dspc_bil_D2O\", data=d2o_dat)\n", - "\n", - "smw_dat = np.loadtxt(data_path / \"DSPC_SMW.dat\", delimiter=\",\")\n", - "problem.data.append(name=\"dspc_bil_smw\", data=smw_dat)" - ] - }, - { - "cell_type": "markdown", - "id": "0668e70b-3d7a-4d35-bb37-90f73c17cb77", - "metadata": {}, - "source": [ - "Finally, we build everything up into the two contrasts:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e5475631-2aa2-4419-9227-aa41cd94b4ed", - "metadata": {}, - "outputs": [], - "source": [ - "# Set the model\n", - "stack = [\"Oxide\", \"SAM Tails\", \"SAM Heads\", \"Central Water\", \"Bilayer Heads\", \"Bilayer Tails\", \"Bilayer Tails\", \"Bilayer Heads\"]\n", - "\n", - "# Then make the two contrasts\n", - "problem.contrasts.append(\n", - " name=\"D2O\",\n", - " bulk_in=\"Silicon\",\n", - " bulk_out=\"D2O\",\n", - " background=\"D2O Background\",\n", - " resolution=\"Resolution 1\",\n", - " scalefactor=\"Scalefactor 1\",\n", - " data=\"dspc_bil_D2O\",\n", - " model=stack,\n", - ")\n", - "\n", - "problem.contrasts.append(\n", - " name=\"SMW\",\n", - " bulk_in=\"Silicon\",\n", - " bulk_out=\"SMW\",\n", - " background=\"SMW Background\",\n", - " resolution=\"Resolution 1\",\n", - " scalefactor=\"Scalefactor 2\",\n", - " data=\"dspc_bil_smw\",\n", - " model=stack,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "85c539d2-84f2-4a0d-a62b-666fbe9b2407", - "metadata": {}, - "source": [ - "Print our project, to check what we have:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e0409648-05f4-448b-93d6-5c4382e0dad6", - "metadata": {}, - "outputs": [], - "source": [ - "print(problem)" - ] - }, - { - "cell_type": "markdown", - "id": "136e2c63-f439-4c2d-bb10-453950bbf41b", - "metadata": {}, - "source": [ - "## Running the Project\n", - "\n", - "To run a project in RAT, we first need to define a controls block:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c9ec7e39-48a8-4651-b74c-19d5800c67d7", - "metadata": {}, - "outputs": [], - "source": [ - "controls = RAT.Controls(display='iter')\n", - "print(controls)" - ] - }, - { - "cell_type": "markdown", - "id": "05f44162-c5b2-46e4-9233-b63e81089fd8", - "metadata": {}, - "source": [ - "The default action (\"procedure\") is just a single calculation. So call RAT.run() with this, and then plot the results:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e59bf938-804c-458c-891c-c3e56ed32820", - "metadata": {}, - "outputs": [], - "source": [ - "problem, results = RAT.run(problem, controls)\n", - "RAT.plotting.plot_ref_sld(problem, results)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/ratapi/examples/normal_reflectivity/DSPC_standard_layers.py b/ratapi/examples/normal_reflectivity/DSPC_standard_layers.py deleted file mode 100644 index 6962f036..00000000 --- a/ratapi/examples/normal_reflectivity/DSPC_standard_layers.py +++ /dev/null @@ -1,210 +0,0 @@ -"""An example of a standard layers model in RAT.""" - -import pathlib - -import numpy as np - -import ratapi as RAT - - -def DSPC_standard_layers(): - """Calculate a standard Layers fit of a DSPC floating bilayer. - - The sample consists of a DSPC bilayer, on a silane SAM on Silicon. - """ - problem = RAT.Project(name="original_dspc_bilayer", model="standard layers", geometry="substrate/liquid") - - # Set up the relevant parameters - problem.parameters.append(name="Oxide Thickness", min=5.0, value=19.54, max=60.0, fit=True) - problem.parameters.append(name="Oxide SLD", min=3.39e-06, value=3.39e-06, max=3.41e-06, fit=False) - problem.parameters.append(name="SAM Tails Thickness", min=15.0, value=22.66, max=35.0, fit=True) - problem.parameters.append(name="SAM Tails SLD", min=-5e-07, value=-4.01e-07, max=-3e-07, fit=False) - problem.parameters.append(name="SAM Tails Hydration", min=1.0, value=5.252, max=50.0, fit=True) - problem.parameters.append(name="SAM Roughness", min=1.0, value=5.64, max=15.0, fit=True) - problem.parameters.append(name="CW Thickness", min=10.0, value=17.12, max=28.0, fit=True) - problem.parameters.append(name="CW SLD", min=0.0, value=0.0, max=1e-09, fit=False) - - problem.parameters.append( - name="SAM Heads Thickness", - min=5.0, - value=8.56, - max=17.0, - fit=True, - prior_type="gaussian", - mu=10.0, - sigma=2.0, - ) - problem.parameters.append(name="SAM Heads SLD", min=1.0e-07, value=1.75e-06, max=2.0e-06, fit=False) - problem.parameters.append( - name="SAM Heads Hydration", - min=10.0, - value=45.45, - max=50.0, - fit=True, - prior_type="gaussian", - mu=30.0, - sigma=3.0, - ) - problem.parameters.append( - name="Bilayer Heads Thickness", - min=7.0, - value=10.7, - max=17.0, - fit=True, - prior_type="gaussian", - mu=10.0, - sigma=2.0, - ) - problem.parameters.append(name="Bilayer Heads SLD", min=5.0e-07, value=1.47e-06, max=1.5e-06, fit=False) - problem.parameters.append(name="Bilayer Roughness", min=2.0, value=6.014, max=15.0, fit=True) - problem.parameters.append(name="Bilayer Tails Thickness", min=14.0, value=17.82, max=22.0, fit=True) - problem.parameters.append(name="Bilayer Tails SLD", min=-5.0e-07, value=-4.61e-07, max=0.0, fit=False) - problem.parameters.append(name="Bilayer Tails Hydration", min=10.0, value=17.64, max=50.0, fit=True) - problem.parameters.append(name="Bilayer Heads Hydration", min=10.0, value=36.15, max=50.0, fit=True) - problem.parameters.append(name="CW Hydration", min=99.9, value=100.0, max=100.0, fit=False) - problem.parameters.append(name="Oxide Hydration", min=0.0, value=23.61, max=60.0, fit=True) - - problem.parameters.set_fields(0, max=10) - - # Group these into layers - problem.layers.append( - name="Oxide", - thickness="Oxide Thickness", - SLD="Oxide SLD", - roughness="Substrate Roughness", - hydration="Oxide Hydration", - hydrate_with="bulk out", - ) - - problem.layers.append( - name="SAM Tails", - thickness="SAM Tails Thickness", - SLD="SAM Tails SLD", - roughness="SAM Roughness", - hydration="SAM Tails Hydration", - hydrate_with="bulk out", - ) - - problem.layers.append( - name="SAM Heads", - thickness="SAM Heads Thickness", - SLD="SAM Heads SLD", - roughness="SAM Roughness", - hydration="SAM Heads Hydration", - hydrate_with="bulk out", - ) - - problem.layers.append( - name="Central Water", - thickness="CW Thickness", - SLD="CW SLD", - roughness="Bilayer Roughness", - hydration="CW Hydration", - hydrate_with="bulk out", - ) - - problem.layers.append( - name="Bilayer Heads", - thickness="Bilayer Heads Thickness", - SLD="Bilayer Heads SLD", - roughness="Bilayer Roughness", - hydration="Bilayer Heads Hydration", - hydrate_with="bulk out", - ) - - problem.layers.append( - name="Bilayer Tails", - thickness="Bilayer Tails Thickness", - SLD="Bilayer Tails SLD", - roughness="Bilayer Roughness", - hydration="Bilayer Tails Hydration", - hydrate_with="bulk out", - ) - - # Make the bulk SLDs - del problem.bulk_in[0] - problem.bulk_in.append(name="Silicon", min=2.0e-06, value=2.073e-06, max=2.1e-06, fit=False) - - del problem.bulk_out[0] - problem.bulk_out.append(name="D2O", min=5.50e-06, value=5.98e-06, max=6.4e-06, fit=True) - problem.bulk_out.append(name="SMW", min=1.0e-06, value=2.21e-06, max=4.99e-06, fit=True) - - # Set the scalefactors - use one for each contrast - del problem.scalefactors[0] - problem.scalefactors.append(name="Scalefactor 1", min=0.05, value=0.10, max=0.2, fit=False) - problem.scalefactors.append(name="Scalefactor 2", min=0.05, value=0.15, max=0.2, fit=False) - - # Now deal with the backgrounds - del problem.backgrounds[0] - del problem.background_parameters[0] - problem.background_parameters.append( - name="Background parameter D2O", - min=5.0e-10, - value=2.23e-06, - max=7.0e-06, - fit=True, - ) - problem.background_parameters.append( - name="Background parameter SMW", - min=1.0e-10, - value=3.38e-06, - max=4.99e-06, - fit=True, - ) - - problem.backgrounds.append(name="D2O Background", type="constant", source="Background parameter D2O") - problem.backgrounds.append(name="SMW Background", type="constant", source="Background parameter SMW") - - # Now add the data - data_path = pathlib.Path(__file__).parents[1] / "data" - - d2o_dat = np.loadtxt(data_path / "DSPC_D2O.dat", delimiter=",") - problem.data.append(name="dspc_bil_D2O", data=d2o_dat) - - smw_dat = np.loadtxt(data_path / "DSPC_SMW.dat", delimiter=",") - problem.data.append(name="dspc_bil_smw", data=smw_dat) - - # Set the model - stack = [ - "Oxide", - "SAM Tails", - "SAM Heads", - "Central Water", - "Bilayer Heads", - "Bilayer Tails", - "Bilayer Tails", - "Bilayer Heads", - ] - - # Then make the two contrasts - problem.contrasts.append( - name="D2O", - bulk_in="Silicon", - bulk_out="D2O", - background="D2O Background", - resolution="Resolution 1", - scalefactor="Scalefactor 1", - data="dspc_bil_D2O", - model=stack, - ) - - problem.contrasts.append( - name="SMW", - bulk_in="Silicon", - bulk_out="SMW", - background="SMW Background", - resolution="Resolution 1", - scalefactor="Scalefactor 2", - data="dspc_bil_smw", - model=stack, - ) - - controls = RAT.Controls() - problem, results = RAT.run(problem, controls) - - return problem, results - - -if __name__ == "__main__": - problem, results = DSPC_standard_layers() - RAT.plotting.plot_ref_sld(problem, results, True) diff --git a/ratapi/examples/normal_reflectivity/__init__.py b/ratapi/examples/normal_reflectivity/__init__.py deleted file mode 100644 index 382a9167..00000000 --- a/ratapi/examples/normal_reflectivity/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Examples of normal reflectivity calculations in RAT.""" diff --git a/ratapi/examples/normal_reflectivity/background_function.py b/ratapi/examples/normal_reflectivity/background_function.py deleted file mode 100644 index 43624a08..00000000 --- a/ratapi/examples/normal_reflectivity/background_function.py +++ /dev/null @@ -1,16 +0,0 @@ -"""A background function for an example.""" - -import numpy as np - - -def background_function(xdata, params): - """Return the background function for a given set of points in q.""" - # Split up the params array - Ao = params[0] - k = params[1] - back_const = params[2] - - # Make an exponential decay background - background = Ao * np.exp(-k * np.array(xdata)) + back_const - - return background diff --git a/ratapi/examples/normal_reflectivity/custom_XY_DSPC.py b/ratapi/examples/normal_reflectivity/custom_XY_DSPC.py deleted file mode 100644 index c57adecf..00000000 --- a/ratapi/examples/normal_reflectivity/custom_XY_DSPC.py +++ /dev/null @@ -1,141 +0,0 @@ -"""A custom XY model for a supported DSPC bilayer.""" - -from math import sqrt - -import numpy as np -from scipy.special import erf - - -def custom_XY_DSPC(params, bulk_in, bulk_out, contrast): - """Calculate the continuous SLD of a supported DSPC bilayer using volume restricted distribution functions.""" - # Note - The first contrast number is 1 (not 0) so be careful if you use - # this variable for array indexing. - - # Split up the parameters - subRough = params[0] - oxideThick = params[1] - oxideHydration = params[2] - waterThick = params[3] - lipidAPM = params[4] - lipidCoverage = params[5] - bilayerRough = params[6] - - # We are going to need our Neutron scattering cross-sections, plus the component volumes - # (the volumes are taken from Armen et al as usual). - # Define these first - - # define all the neutron b's. - bc = 0.6646e-4 # Carbon - bo = 0.5843e-4 # Oxygen - bh = -0.3739e-4 # Hydrogen - bp = 0.513e-4 # Phosphorus - bn = 0.936e-4 # Nitrogen - - # Now make the lipid groups - COO = (4 * bo) + (2 * bc) - GLYC = (3 * bc) + (5 * bh) - CH3 = (2 * bc) + (6 * bh) - PO4 = (1 * bp) + (4 * bo) - CH2 = (1 * bc) + (2 * bh) - CHOL = (5 * bc) + (12 * bh) + (1 * bn) - - # Group these into heads and tails - heads = CHOL + PO4 + GLYC + COO - tails = (34 * CH2) + (2 * CH3) - - # We need volumes for each. Use literature values - vHead = 319 - vTail = 782 - - # Start making our sections. For each we are using a roughened Heaviside to describe our groups. - # We will make these as Volume Fractions (i.e. with a height of 1 for full occupancy), - # which we will correct later for hydration. - - # Make an array of z values for our model - z = np.arange(0, 141) - - # Make our Silicon substrate - vfSilicon, siSurf = make_layer(z, -25, 50, 1, subRough, subRough) - - # Add the Oxide - vfOxide, oxSurface = make_layer(z, siSurf, oxideThick, 1, subRough, subRough) - - # We fill in the water at the end, but there may be a hydration layer between the bilayer and the oxide, - # so we start the bilayer stack an appropriate distance away - watSurface = oxSurface + waterThick - - # Now make the first lipid head group - # Work out the thickness - headThick = vHead / lipidAPM - - # ... and make a box for the volume fraction (1 for now, we correct for coverage later) - vfHeadL, headLSurface = make_layer(z, watSurface, headThick, 1, bilayerRough, bilayerRough) - - # ... also do the same for the tails - # We'll make both together, so the thickness will be twice the volume - tailsThick = (2 * vTail) / lipidAPM - vfTails, tailsSurf = make_layer(z, headLSurface, tailsThick, 1, bilayerRough, bilayerRough) - - # Finally the upper head ... - vfHeadR, headSurface = make_layer(z, tailsSurf, headThick, 1, bilayerRough, bilayerRough) - - # Making the model - # We've created the volume fraction profiles corresponding to each of the groups. - # We now convert them to SLDs, taking in account of the hydrations to scale the volume fractions - - # 1. Oxide ... - vfOxide = vfOxide * (1 - oxideHydration) - - # 2. Lipid ... - # Scale both the heads and tails according to overall coverage - vfTails = vfTails * lipidCoverage - vfHeadL = vfHeadL * lipidCoverage - vfHeadR = vfHeadR * lipidCoverage - - # Some extra work to deal with head hydration, which we take to be an additional 30% always - vfHeadL = vfHeadL * 0.7 - vfHeadR = vfHeadR * 0.7 - - # Make a total Volume Fraction across the whole interface - vfTot = vfSilicon + vfOxide + vfHeadL + vfTails + vfHeadR - - # All the volume that's left, we will fill with water - vfWat = 1 - vfTot - - # Now convert all the Volume Fractions to SLDs - sld_Value_Tails = tails / vTail - sld_Value_Head = heads / vHead - - sldSilicon = vfSilicon * 2.073e-6 - sldOxide = vfOxide * 3.41e-6 - - sldHeadL = vfHeadL * sld_Value_Head - sldHeadR = vfHeadR * sld_Value_Head - sldTails = vfTails * sld_Value_Tails - sldWat = vfWat * bulk_out[contrast - 1] - - # Put this all together - totSLD = sldSilicon + sldOxide + sldHeadL + sldTails + sldHeadR + sldWat - - # Make the SLD array for output - SLD = np.column_stack((z, totSLD)) - - return SLD, subRough - - -def make_layer(z, prevLaySurf, thickness, height, Sigma_L, Sigma_R): - """Produce a layer, with a defined thickness, height and roughness. - - Each side of the layer has its own roughness value. - """ - # Find the edges - left = prevLaySurf - right = prevLaySurf + thickness - - # Make our heaviside - erf_left = erf((z - left) / (sqrt(2) * Sigma_L)) - erf_right = erf((z - right) / (sqrt(2) * Sigma_R)) - - VF = np.array((0.5 * height) * (erf_left - erf_right)) - - return VF, right diff --git a/ratapi/examples/normal_reflectivity/custom_bilayer_DSPC.py b/ratapi/examples/normal_reflectivity/custom_bilayer_DSPC.py deleted file mode 100644 index 8646de71..00000000 --- a/ratapi/examples/normal_reflectivity/custom_bilayer_DSPC.py +++ /dev/null @@ -1,89 +0,0 @@ -"""A custom layer model for a DSPC supported bilayer.""" - -import numpy as np - - -def custom_bilayer_DSPC(params, bulk_in, bulk_out, contrast): - """Calculate layer parameters for a DSPC supported bilayer. - - This file accepts 3 vectors containing the values for params, bulk in and bulk out. - The final parameter is an index of the contrast being calculated. - - The function should output a matrix of layer values, in the form... - - Output = [thick 1, SLD 1, Rough 1, Percent Hydration 1, Hydrate how 1 - .... - thick n, SLD n, Rough n, Percent Hydration n, Hydration how n] - - The "hydrate how" parameter decides if the layer is hydrated with Bulk out or Bulk in phases. - Set to 1 for Bulk out, zero for Bulk in. - Alternatively, leave out hydration and just return... - - Output = [thick 1, SLD 1, Rough 1, - .... - thick n, SLD n, Rough n] - - The second output parameter should be the substrate roughness. - """ - # Note - The first contrast number is 1 (not 0) so be careful if you use - # this variable for array indexing. - sub_rough = params[0] - oxide_thick = params[1] - oxide_hydration = params[2] - lipidAPM = params[3] - headHydration = params[4] - bilayerHydration = params[5] - bilayerRough = params[6] - waterThick = params[7] - - # We have a constant SLD for the bilayer - oxide_SLD = 3.41e-6 - - # Now make the lipid layers - # Use known lipid volume and compositions to make the layers - - # define all the neutron b's. - bc = 0.6646e-4 # Carbon - bo = 0.5843e-4 # Oxygen - bh = -0.3739e-4 # Hydrogen - bp = 0.513e-4 # Phosphorus - bn = 0.936e-4 # Nitrogen - - # Now make the lipid groups - COO = (4 * bo) + (2 * bc) - GLYC = (3 * bc) + (5 * bh) - CH3 = (2 * bc) + (6 * bh) - PO4 = (1 * bp) + (4 * bo) - CH2 = (1 * bc) + (2 * bh) - CHOL = (5 * bc) + (12 * bh) + (1 * bn) - - # Group these into heads and tails: - Head = CHOL + PO4 + GLYC + COO - Tails = (34 * CH2) + (2 * CH3) - - # We need volumes for each. Use literature values: - vHead = 319 - vTail = 782 - - # We use the volumes to calculate the SLDs - SLDhead = Head / vHead - SLDtail = Tails / vTail - - # We calculate the layer thickness' from the volumes and the APM - headThick = vHead / lipidAPM - tailThick = vTail / lipidAPM - - # Manually deal with hydration for layers in this example. - oxSLD = (oxide_hydration * bulk_out[contrast - 1]) + ((1 - oxide_hydration) * oxide_SLD) - headSLD = (headHydration * bulk_out[contrast - 1]) + ((1 - headHydration) * SLDhead) - tailSLD = (bilayerHydration * bulk_out[contrast - 1]) + ((1 - bilayerHydration) * SLDtail) - - # Make the layers - oxide = [oxide_thick, oxSLD, sub_rough] - water = [waterThick, bulk_out[contrast - 1], bilayerRough] - head = [headThick, headSLD, bilayerRough] - tail = [tailThick, tailSLD, bilayerRough] - - output = np.array([oxide, water, head, tail, tail, head]) - - return output, sub_rough diff --git a/ratapi/examples/orso_integration/orso_integration.ipynb b/ratapi/examples/orso_integration/orso_integration.ipynb deleted file mode 100644 index 03ec671e..00000000 --- a/ratapi/examples/orso_integration/orso_integration.ipynb +++ /dev/null @@ -1,188 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# ``orsopy`` Integration" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "``python-RAT`` contains some integration with ``orsopy``, allowing for convenient interaction with the ``.ort`` file format. This integration is available through the `ratapi.utils.orso` submodule." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import ratapi.utils.orso" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Creating models from the ORSO model description language\n", - "\n", - "The [ORSO model description format](https://www.reflectometry.org/advanced_and_expert_level/file_format/simple_model) allows the description of a standard slab model as a one-line string, provided that all the layer materials are defined [in the ORSO SLD database](https://slddb.esss.dk/slddb/).\n", - "\n", - "The function `ratapi.utils.orso.orso_model_to_rat` function can read a model and return an `ORSOSample` dataclass, which gives bulk in and bulk out parameters for the model, a list of all layers defined in the model, and all the parameters needed to define those layers as RAT models. \n", - "\n", - "**Note:** the ORSO format gives the thicknesses of materials in *nanometres*. When we convert them to RAT parameters, the units will be converted to Angstroms.\n", - "\n", - "For example, the string `air | Ni 100 | SiO2 0.5 | Si` describes a 1000 angstrom nickel film backed by a 5 angstrom silicon oxide layer. The bulk-in and bulk-out are air and silicon respectively. The roughnesses and SLDs will be calculated or taken from the ORSO SLD database." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# create the RAT parameters and layers from this model\n", - "sample = ratapi.utils.orso.orso_model_to_rat(\"air | Ni 100 | SiO2 0.5 | Si\")\n", - "print(sample)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can also set `absorption=True` and the model will account for absorption. For example if we change the nickel film for a boron carbide film and want to account for its relatively high absorption, we can add it to the output:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sample = ratapi.utils.orso.orso_model_to_rat(\"vacuum | B4C 100 | SiO2 0.5 | Si\", absorption=True)\n", - "print(sample)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Finally, ORSO supports defining repeated layers using parentheses. For example, if we had a polarising multilayer of 5 repetitions of 70 angstrom silicon and 70 angstrom iron, we could represent it as `air | 5 ( Si 7 | Fe 7 ) | Si`.\n", - "\n", - "RAT will only create the number of layers and parameters necessary, but the `ORSOSample` object's `model` attribute will give a list of layer names with the structure of the model preserved, which can be given as the layer model for a Contrast." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sample = ratapi.utils.orso.orso_model_to_rat(\"air | 5 ( Si 7 | Fe 7 ) | Si\")\n", - "print(sample)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Reading in data and models from .ort files" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "RAT can also load both data and model information from an .ort file. This is done through the `ORSOProject` object, which takes a file path and can also optionally account for absorption.\n", - "\n", - "The example data file we use here is example data for an unknown film on deposited on silicon." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pathlib\n", - "data_path = pathlib.Path(\"../data\")\n", - "\n", - "orso_data = ratapi.utils.orso.ORSOProject(data_path / \"c_PLP0011859_q.ort\")\n", - "print(orso_data)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The `ORSOProject` object contains two lists: `ORSOProject.data` and `ORSOProject.samples`. The former is a list of Data objects with each dataset defined in the file, and the latter is a list of `ORSOSample` objects (like above) with model information. Note that if the .ort file does not define a model for a dataset, that index of `ORSOProject.samples` will be None.\n", - "\n", - "It's then easy to access this data to create a RAT `Project` that represents our data." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from ratapi.models import Background, Contrast, Parameter, Resolution\n", - "\n", - "dataset = orso_data.data[0]\n", - "sample = orso_data.samples[0]\n", - "\n", - "project = ratapi.Project(\n", - " name = \"Example Project\",\n", - " geometry = \"substrate/liquid\",\n", - " parameters = sample.parameters,\n", - " bulk_in = [sample.bulk_in],\n", - " bulk_out = [sample.bulk_out],\n", - " scalefactors = [Parameter(name=\"Scalefactor\", min=0, value=0.34, max=1.5)],\n", - " background_parameters = [Parameter(name=\"Background Parameter\", min=0, value=2e-6, max=1)],\n", - " backgrounds = [Background(name=\"Background\", type=\"constant\", source=\"Background Parameter\")],\n", - " resolutions = [Resolution(name=\"Data Resolution\", type=\"data\")],\n", - " data = [dataset],\n", - " layers = sample.layers,\n", - " contrasts = [Contrast(\n", - " name = \"prist4\",\n", - " data = dataset.name,\n", - " background = \"Background\",\n", - " bulk_in = sample.bulk_in.name,\n", - " bulk_out = sample.bulk_out.name,\n", - " scalefactor = \"Scalefactor\",\n", - " resolution = \"Data Resolution\",\n", - " model = sample.model,\n", - " )]\n", - ")\n", - "\n", - "controls = ratapi.Controls()\n", - "project, results = ratapi.run(project, controls)\n", - "ratapi.plotting.plot_ref_sld(project, results)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": ".venv", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.2" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/ratapi/inputs.py b/ratapi/inputs.py deleted file mode 100644 index bdfaddad..00000000 --- a/ratapi/inputs.py +++ /dev/null @@ -1,595 +0,0 @@ -"""Converts python models to the necessary inputs for the compiled RAT code.""" - -import importlib -import os -import pathlib -from collections.abc import Callable - -import numpy as np - -import ratapi -import ratapi.wrappers -from ratapi.rat_core import Checks, Control, NameStore, ProblemDefinition -from ratapi.utils.enums import Calculations, Languages, LayerModels, TypeOptions - -parameter_field = { - "parameters": "params", - "bulk_in": "bulkIns", - "bulk_out": "bulkOuts", - "scalefactors": "scalefactors", - "domain_ratios": "domainRatios", - "background_parameters": "backgroundParams", - "resolution_parameters": "resolutionParams", -} - - -def get_python_handle(file_name: str, function_name: str, path: str | pathlib.Path = "") -> Callable: - """Get the function handle from a function defined in a python module located anywhere within the filesystem. - - Parameters - ---------- - file_name : str - The name of the file containing the function of interest. - function_name : str - The name of the function we wish to obtain the handle for within the module. - path : str - The path to the file containing the function (default is "", which represent the working directory). - - Returns - ------- - handle : Callable - The handle of the function defined in the python module file. - - """ - spec = importlib.util.spec_from_file_location(pathlib.Path(file_name).stem, os.path.join(path, file_name)) - custom_module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(custom_module) - handle = getattr(custom_module, function_name) - return handle - - -class FileHandles: - """Class to defer creation of custom file handles. - - Parameters - ---------- - files : ClassList[CustomFile] - A list of custom file models. - - """ - - def __init__(self, files=None): - self.index = 0 - self.files = [] if files is None else [file.model_dump() for file in files] - - def __iter__(self): - self.index = 0 - return self - - def get_handle(self, index: int): - """Return file handle for a given custom file. - - Parameters - ---------- - index : int - The index of the custom file. - - """ - custom_file = self.files[index] - full_path = os.path.join(custom_file["path"], custom_file["filename"]) - - if not os.path.isfile(full_path): - raise FileNotFoundError(f"The custom file ({custom_file['name']}) does not have a valid path.") - - if not custom_file["function_name"] and custom_file["language"] != Languages.Matlab: - raise ValueError(f"The custom file ({custom_file['name']}) does not have a valid function name.") - - if custom_file["language"] == Languages.Python: - file_handle = get_python_handle(custom_file["filename"], custom_file["function_name"], custom_file["path"]) - elif custom_file["language"] == Languages.Matlab: - file_handle = ratapi.wrappers.MatlabWrapper(full_path).getHandle() - elif custom_file["language"] == Languages.Cpp: - file_handle = ratapi.wrappers.DylibWrapper(full_path, custom_file["function_name"]).getHandle() - - return file_handle - - def copy(self) -> "FileHandles": - """Create a copy of the FileHandles object. - - Returns - ------- - FileHandles - The copy of this FileHandles object. - - """ - handles = FileHandles() - handles.files = [file.copy() for file in self.files] - - return handles - - def __next__(self): - if self.index < len(self.files): - custom_file = self.get_handle(self.index) - self.index += 1 - return custom_file - else: - raise StopIteration - - def __len__(self): - return len(self.files) - - -def make_input(project: ratapi.Project, controls: ratapi.Controls) -> tuple[ProblemDefinition, Control]: - """Construct the inputs required for the compiled RAT code using the data defined in the input project and controls. - - Parameters - ---------- - project : RAT.Project - The project model, which defines the physical system under study. - controls : RAT.Controls - The controls model, which defines algorithmic properties. - - Returns - ------- - problem : RAT.rat_core.ProblemDefinition - The problem input used in the compiled RAT code. - cpp_controls : RAT.rat_core.Control - The controls object used in the compiled RAT code. - - """ - problem = make_problem(project) - cpp_controls = make_controls(controls) - - return problem, cpp_controls - - -def make_problem(project: ratapi.Project) -> ProblemDefinition: - """Construct the problem input required for the compiled RAT code. - - Parameters - ---------- - project : RAT.Project - The project model, which defines the physical system under study. - - Returns - ------- - problem : RAT.rat_core.ProblemDefinition - The problem input used in the compiled RAT code. - - """ - prior_id = {"uniform": 1, "gaussian": 2, "jeffreys": 3} - - # Ensure all contrast fields are properly defined - for contrast in project.contrasts: - contrast_fields = ["data", "background", "bulk_in", "bulk_out", "scalefactor", "resolution"] - - if project.calculation == Calculations.Domains: - contrast_fields.append("domain_ratio") - - for field in contrast_fields: - if getattr(contrast, field) == "": - raise ValueError( - f'In the input project, the "{field}" field of contrast "{contrast.name}" does not have a ' - f"value defined. A value must be supplied before running the project." - ) - - # Ensure backgrounds and resolutions have a source defined - background = project.backgrounds[contrast.background] - resolution = project.resolutions[contrast.resolution] - if background.source == "": - raise ValueError( - f"All backgrounds must have a source defined. For a {background.type} type background, " - f"the source must be defined in " - f'"{ratapi.project.values_defined_in[f"backgrounds.{background.type}.source"]}"' - ) - if resolution.source == "" and resolution.type != TypeOptions.Data: - raise ValueError( - f"Constant resolutions must have a source defined. The source must be defined in " - f'"{ratapi.project.values_defined_in[f"resolutions.{resolution.type}.source"]}"' - ) - - # Set contrast parameters according to model type - if project.model == LayerModels.StandardLayers: - if project.calculation == Calculations.Domains: - contrast_models = [ - [project.domain_contrasts.index(domain_contrast, True) for domain_contrast in contrast.model] - for contrast in project.contrasts - ] - else: - contrast_models = [ - [project.layers.index(layer, True) for layer in contrast.model] for contrast in project.contrasts - ] - else: - contrast_models = [[]] * len(project.contrasts) - - # Set contrast parameters according to model type - if project.model == LayerModels.StandardLayers: - contrast_custom_files = [float("NaN")] * len(project.contrasts) - else: - contrast_custom_files = [project.custom_files.index(contrast.model[0], True) for contrast in project.contrasts] - - # Get details of defined layers - layer_details = get_layer_details(project) - - contrast_background_params = [] - contrast_background_types = [] - all_data = [] - data_limits = [] - simulation_limits = [] - contrast_resolution_params = [] - contrast_resolution_types = [] - - # Set data, background and resolution for each contrast - for contrast in project.contrasts: - # Set data - data_index = project.data.index(contrast.data) - data = project.data[data_index].data - data_range = project.data[data_index].data_range - simulation_range = project.data[data_index].simulation_range - - if data_range: - data_limits.append(data_range) - else: - data_limits.append([0.0, 0.0]) - - if simulation_range: - simulation_limits.append(simulation_range) - else: - simulation_limits.append([0.0, 0.0]) - - # Set background parameters - background = project.backgrounds[contrast.background] - contrast_background_types.append(background.type) - contrast_background_param = [] - - if background.type == TypeOptions.Data: - contrast_background_param.append(project.data.index(background.source, True)) - if background.value_1 != "": - contrast_background_param.append(project.background_parameters.index(background.value_1)) - # If we are using a data background, we add the background data to the contrast data - data = append_data_background(data, project.data[background.source].data) - - elif background.type == TypeOptions.Function: - contrast_background_param.append(project.custom_files.index(background.source, True)) - contrast_background_param.extend( - [ - project.background_parameters.index(value, True) - for value in [ - background.value_1, - background.value_2, - background.value_3, - background.value_4, - background.value_5, - ] - if value != "" - ] - ) - - else: - contrast_background_param.append(project.background_parameters.index(background.source, True)) - - contrast_background_params.append(contrast_background_param) - - # Set resolution parameters - resolution = project.resolutions[contrast.resolution] - contrast_resolution_types.append(resolution.type) - contrast_resolution_param = [] - if resolution.type == TypeOptions.Function: - contrast_resolution_param.append(project.custom_files.index(resolution.source, True)) - contrast_resolution_param.extend( - [ - project.resolution_parameters.index(value, True) - for value in [ - resolution.value_1, - resolution.value_2, - resolution.value_3, - resolution.value_4, - resolution.value_5, - ] - if value != "" - ] - ) - - elif resolution.type == TypeOptions.Constant: - contrast_resolution_param.append(project.resolution_parameters.index(resolution.source, True)) - - contrast_resolution_params.append(contrast_resolution_param) - - # Contrast data has exactly six columns to include background data if relevant - all_data.append(np.column_stack((data, np.zeros((data.shape[0], 6 - data.shape[1]))))) - - problem = ProblemDefinition() - - problem.TF = project.calculation - problem.resample = make_resample(project) - problem.data = all_data - problem.dataPresent = make_data_present(project) - problem.dataLimits = data_limits - problem.simulationLimits = simulation_limits - problem.numberOfContrasts = len(project.contrasts) - problem.geometry = project.geometry - problem.useImaginary = project.absorption - problem.repeatLayers = [contrast.repeat_layers for contrast in project.contrasts] - problem.contrastBackgroundParams = contrast_background_params - problem.contrastBackgroundTypes = contrast_background_types - problem.contrastBackgroundActions = [contrast.background_action for contrast in project.contrasts] - problem.contrastScalefactors = [ - project.scalefactors.index(contrast.scalefactor, True) for contrast in project.contrasts - ] - problem.contrastBulkIns = [project.bulk_in.index(contrast.bulk_in, True) for contrast in project.contrasts] - problem.contrastBulkOuts = [project.bulk_out.index(contrast.bulk_out, True) for contrast in project.contrasts] - - problem.contrastResolutionParams = contrast_resolution_params - problem.contrastResolutionTypes = contrast_resolution_types - - problem.backgroundParams = [param.value for param in project.background_parameters] - problem.scalefactors = [param.value for param in project.scalefactors] - problem.bulkIns = [param.value for param in project.bulk_in] - problem.bulkOuts = [param.value for param in project.bulk_out] - problem.resolutionParams = [param.value for param in project.resolution_parameters] - problem.params = [param.value for param in project.parameters] - problem.numberOfLayers = len(project.layers) - problem.contrastLayers = [contrast_model if contrast_model else [] for contrast_model in contrast_models] - problem.layersDetails = layer_details if project.model == LayerModels.StandardLayers else [] - problem.customFiles = FileHandles(project.custom_files) - problem.modelType = project.model - problem.contrastCustomFiles = contrast_custom_files - - problem.contrastDomainRatios = [ - project.domain_ratios.index(contrast.domain_ratio, True) if hasattr(contrast, "domain_ratio") else 0 - for contrast in project.contrasts - ] - - problem.domainRatios = [param.value for param in project.domain_ratios] - problem.numberOfDomainContrasts = len(project.domain_contrasts) - - domain_contrast_models = [ - [project.layers.index(layer, True) for layer in domain_contrast.model] - for domain_contrast in project.domain_contrasts - ] - - problem.domainContrastLayers = [ - domain_contrast_model if domain_contrast_model else [] for domain_contrast_model in domain_contrast_models - ] - problem.fitParams = [ - param.value - for class_list in ratapi.project.parameter_class_lists - for param in getattr(project, class_list) - if param.fit - ] - problem.fitLimits = [ - [param.min, param.max] - for class_list in ratapi.project.parameter_class_lists - for param in getattr(project, class_list) - if param.fit - ] - problem.priorNames = [ - param.name for class_list in ratapi.project.parameter_class_lists for param in getattr(project, class_list) - ] - problem.priorValues = [ - [prior_id[param.prior_type], param.mu, param.sigma] - for class_list in ratapi.project.parameter_class_lists - for param in getattr(project, class_list) - ] - - # Names - problem.names = NameStore() - for class_list in ratapi.project.parameter_class_lists: - setattr(problem.names, parameter_field[class_list], [param.name for param in getattr(project, class_list)]) - problem.names.contrasts = [contrast.name for contrast in project.contrasts] - - # Checks - problem.checks = Checks() - for class_list in ratapi.project.parameter_class_lists: - setattr( - problem.checks, parameter_field[class_list], [int(element.fit) for element in getattr(project, class_list)] - ) - - check_indices(problem) - - return problem - - -def get_layer_details(project: ratapi.Project) -> list[int]: - """Get parameter indices for all layers defined in the project.""" - hydrate_id = {"bulk in": 0, "bulk out": 1} - layer_details = [] - - # Get the thickness, SLD, roughness fields from the appropriate model - if project.absorption: - layer_fields = list(ratapi.models.AbsorptionLayer.model_fields.keys())[1:-2] - else: - layer_fields = list(ratapi.models.Layer.model_fields.keys())[1:-2] - - for layer in project.layers: - for field in layer_fields: - if getattr(layer, field) == "": - raise ValueError( - f'In the input project, the "{field}" field of layer {layer.name} does not have a value ' - f"defined. A value must be supplied before running the project." - ) - - layer_params = [project.parameters.index(getattr(layer, attribute), True) for attribute in list(layer_fields)] - - layer_params.append(project.parameters.index(layer.hydration, True) if layer.hydration else float("NaN")) - layer_params.append(hydrate_id[layer.hydrate_with]) - - layer_details.append(layer_params) - - return layer_details - - -def make_resample(project: ratapi.Project) -> list[int]: - """Construct the "resample" field of the problem input required for the compiled RAT code. - - Parameters - ---------- - project : RAT.Project - The project model, which defines the physical system under study. - - Returns - ------- - list[int] - The "resample" field of the problem input used in the compiled RAT code. - - """ - return [contrast.resample for contrast in project.contrasts] - - -def make_data_present(project: ratapi.Project) -> list[int]: - """Construct the "dataPresent" field of the problem input required for the compiled RAT code. - - Parameters - ---------- - project : RAT.Project - The project model, which defines the physical system under study. - - Returns - ------- - list[int] - The "dataPresent" field of the problem input used in the compiled RAT code. - - """ - return [1 if project.data[contrast.data].data.size != 0 else 0 for contrast in project.contrasts] - - -def check_indices(problem: ProblemDefinition) -> None: - """Check the indices given in a problem's contrasts lie within the range of the corresponding parameter lists. - - Parameters - ---------- - problem : RAT.rat_core.ProblemDefinition - The problem input used in the compiled RAT code. - - """ - index_list = { - "scalefactors": "contrastScalefactors", - "bulkIns": "contrastBulkIns", - "bulkOuts": "contrastBulkOuts", - "domainRatios": "contrastDomainRatios", - } - - # Check the indices -- note we have switched to 1-based indexing at this point - for params in index_list: - param_list = getattr(problem, params) - if len(param_list) > 0: - elements = [ - element - for element in getattr(problem, index_list[params]) - if (element != -1) and not (0 < element <= len(param_list)) - ] - if elements: - raise IndexError( - f'The problem field "{index_list[params]}" contains: {", ".join(str(i) for i in elements)}' - f', which lie{"s" * (len(elements) == 1)} outside of the range of "{params}"', - ) - - # backgroundParams has a different structure, so is handled separately: - # it is of type list[list[int]], where each list[int] is the indices for - # source, value_1, value_2, value_3, value_4, value_5 where they are defined - # e.g. for a data background with offset it is [source value_1], for a function - # with 3 values it is [source value_1 value_2 value_3], etc. - - source_param_lists = { - "constant": "backgroundParams", - "data": "data", - "function": "customFiles", - } - - for i, background_data in enumerate(problem.contrastBackgroundParams): - background_type = problem.contrastBackgroundTypes[i] - - # check source param is in range of the relevant parameter list - param_list = getattr(problem, source_param_lists[background_type]) - source_index = background_data[0] - if not 0 < source_index <= len(param_list): - raise IndexError( - f'Entry {i} of contrastBackgroundParams has type "{background_type}" ' - f"and source index {source_index}, " - f'which is outside the range of "{source_param_lists[background_type]}".' - ) - - # check value params are in range for background params - if len(background_data) > 1: - elements = [element for element in background_data[1:] if not 0 < element <= len(problem.backgroundParams)] - if elements: - raise IndexError( - f"Entry {i} of contrastBackgroundParams contains: {', '.join(str(i) for i in elements)}" - f', which lie{"s" * (len(elements) == 1)} outside of the range of "backgroundParams"', - ) - - -def append_data_background(data: np.array, background: np.array) -> np.array: - """Append background data to contrast data. - - Parameters - ---------- - data : np.array - The contrast data to which we are appending a background. - background : np.array - The background data to append to the contrast. - - Returns - ------- - np.array - The contrast data with background data appended as two additional columns. - - """ - if not np.allclose(data[:, 0], background[:, 0]): - raise ValueError("The q-values of the data and background must be equal.") - - return np.hstack((data, np.zeros((data.shape[0], 4 - data.shape[1])), background[:, 1:])) - - -def make_controls(input_controls: ratapi.Controls) -> Control: - """Convert the controls object to the format required by the compiled RAT code. - - Parameters - ---------- - input_controls : RAT.Controls - The controls model, which defines algorithmic properties. - - Returns - ------- - controls : RAT.rat_core.Control - The controls object used in the compiled RAT code. - - """ - controls = Control() - - controls.procedure = input_controls.procedure - controls.parallel = input_controls.parallel - controls.numSimulationPoints = input_controls.numSimulationPoints - controls.resampleMinAngle = input_controls.resampleMinAngle - controls.resampleNPoints = input_controls.resampleNPoints - controls.display = input_controls.display - # Simplex - controls.xTolerance = input_controls.xTolerance - controls.funcTolerance = input_controls.funcTolerance - controls.maxFuncEvals = input_controls.maxFuncEvals - controls.maxIterations = input_controls.maxIterations - controls.updateFreq = input_controls.updateFreq - controls.updatePlotFreq = input_controls.updatePlotFreq - # DE - controls.populationSize = input_controls.populationSize - controls.fWeight = input_controls.fWeight - controls.crossoverProbability = input_controls.crossoverProbability - controls.strategy = int(input_controls.strategy) # RAT core expects strategy as an integer - controls.targetValue = input_controls.targetValue - controls.numGenerations = input_controls.numGenerations - # NS - controls.nLive = input_controls.nLive - controls.nMCMC = input_controls.nMCMC - controls.propScale = input_controls.propScale - controls.nsTolerance = input_controls.nsTolerance - # Dream - controls.nSamples = input_controls.nSamples - controls.nChains = input_controls.nChains - controls.jumpProbability = input_controls.jumpProbability - controls.pUnitGamma = input_controls.pUnitGamma - controls.boundHandling = input_controls.boundHandling - controls.adaptPCR = input_controls.adaptPCR - - controls.IPCFilePath = input_controls._IPCFilePath - - return controls diff --git a/ratapi/models.py b/ratapi/models.py deleted file mode 100644 index ba0a1e99..00000000 --- a/ratapi/models.py +++ /dev/null @@ -1,717 +0,0 @@ -"""The models module. Contains the pydantic models used by RAT to store project parameters.""" - -import pathlib -import warnings -from contextlib import suppress -from typing import Any - -import numpy as np -import prettytable -from pydantic import BaseModel, Field, ValidationInfo, field_validator, model_validator - -from ratapi.utils.enums import BackgroundActions, Hydration, Languages, Priors, TypeOptions - -try: - from enum import StrEnum -except ImportError: - from strenum import StrEnum - - -# Create a counter for each model -background_number = ["Background", 0] -contrast_number = ["Contrast", 0] -custom_file_number = ["Custom File", 0] -data_number = ["Data", 0] -domain_contrast_number = ["Domain Contrast", 0] -layer_number = ["Layer", 0] -parameter_number = ["Parameter", 0] -resolution_number = ["Resolution", 0] - -_model_counter = { - "Background": background_number, - "Contrast": contrast_number, - "ContrastWithRatio": contrast_number, - "CustomFile": custom_file_number, - "Data": data_number, - "DomainContrast": domain_contrast_number, - "Layer": layer_number, - "AbsorptionLayer": layer_number, - "Parameter": parameter_number, - "ProtectedParameter": parameter_number, - "Resolution": resolution_number, -} - - -def _model_name_factory(model_name: str) -> str: - """Generate a unique name for model using a global counter. - - Parameters - ---------- - model_name : str - The name of the model class. - """ - title, number = _model_counter[model_name] - _model_counter[model_name][1] += 1 - return f"New {title} {(number + 1)}" - - -class RATModel(BaseModel, validate_assignment=True, extra="forbid"): - """A BaseModel where enums are represented by their value.""" - - def __repr__(self): - fields_repr = ", ".join( - repr(v) if a is None else f"{a}={v.value!r}" if isinstance(v, StrEnum) else f"{a}={v!r}" - for a, v in self.__repr_args__() - ) - return f"{self.__repr_name__()}({fields_repr})" - - @field_validator("name", mode="after", check_fields=False) - @classmethod - def update_counter(cls, name: str) -> str: - """Update the auto name counter if a similar name is manually given. - - Parameters - ---------- - name : str - The name of the model. - """ - title, number = _model_counter[cls.__name__] - prefix = f"New {title} " - if name.startswith(prefix): - with suppress(ValueError): - new_number = int(name[len(prefix) :]) - if new_number > number: - _model_counter[cls.__name__][1] = new_number - return name - - def __str__(self): - table = prettytable.PrettyTable() - table.field_names = [key.replace("_", " ") for key in self.display_fields] - table.add_row(list(self.display_fields.values())) - return table.get_string() - - @property - def display_fields(self) -> dict: - """A dictionary of which fields should be displayed by this model and their values.""" - return self.__dict__ - - -class Signal(RATModel): - """Base model for background & resolution signals.""" - - name: str = Field(default="New Signal", min_length=1) - type: TypeOptions = TypeOptions.Constant - source: str = "" - value_1: str = "" - value_2: str = "" - value_3: str = "" - value_4: str = "" - value_5: str = "" - - def __setattr__(self, name, value): - if name == "type": - warnings.warn(f"Changing the type of {self.name} clears its source and value fields.", stacklevel=2) - for attr in ["source", "value_1", "value_2", "value_3", "value_4", "value_5"]: - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - super().__setattr__(attr, "") - - super().__setattr__(name, value) - - @property - def display_fields(self) -> dict: - """The fields which should be visible in a table and their values. - - Returns - ------- - dict - A dictionary of the fields which should be visible in a table and their values. - - """ - visible_fields = ["name", "type", "source"] - if self.type != TypeOptions.Constant: - visible_fields.append("value_1") - if self.type == TypeOptions.Function: - visible_fields.extend(["value_2", "value_3", "value_4", "value_5"]) - - return {f: getattr(self, f) for f in visible_fields} - - -class Background(Signal): - """A background signal. - - Parameters - ---------- - name : str - The name of the background. - type : TypeOptions - The type of background (constant, function or data) - source : str - The source of the background; - - - if type is 'constant', this should be the name of a background parameter. - - if type is 'data', this should be the name of a dataset defined in `Project.data`. - - if type is 'function', this should be the name of a custom function defined in `Project.custom_files`. - - value_1, value_2, value_3, value_4, value_5 : str - Values required by the background. - - - if type is 'constant', all values will be ignored. - - if type is 'data', value_1 may be the parameter name for an optional offset. Other values are ignored. - - if type is 'function', these values may be the names of up to 5 parameters which are passed to the function. - - """ - - name: str = Field(default_factory=lambda: _model_name_factory("Background"), min_length=1) - - @model_validator(mode="after") - def check_unsupported_parameters(self): - """Raise an error if the parameters given are not supported for the given type.""" - if self.type == TypeOptions.Constant: - expected_empty_fields = ["value_1", "value_2", "value_3", "value_4", "value_5"] - elif self.type == TypeOptions.Data: - expected_empty_fields = ["value_2", "value_3", "value_4", "value_5"] - else: - return self - - non_empty_fields = [v for v in expected_empty_fields if getattr(self, v) != ""] - if non_empty_fields: - raise ValueError( - f'The following values are not supported by the "{self.type}" Background type: ' - f"{', '.join(non_empty_fields)}" - ) - - return self - - -class Contrast(RATModel): - """A group of all of the components of a model. - - Parameters - ---------- - name : str - The name of the contrast. - data : str - The name of the dataset used by the contrast. - background : str - The name of the background for the contrast. - background_action : BackgroundActions - Whether the background should be added ('add') or subtracted ('subtract') from the data. - bulk_in : str - The name of the bulk-in parameter which defines the SLD of the interface between the - first layer and the environment. - bulk_out : str - The name of the bulk-out parameter which defines the SLD of the interface between the last - layer and the environment. - scalefactor : str - The name of the scalefactor which defines how much the data for this contrast should be scaled. - resolution : str - The name of the instrument resolution for this contrast. - resample : bool - Whether adaptive resampling should be used for interface microslicing. - repeat_layers : int - For standard layers, the number of times the set of layers defined in the model should be repeated. - model : list[str] - If this is a standard layers model, this should be a list of layer names - that make up the slab model for this contrast. - For custom models, this should be a list containing just the custom file name for the - custom model function. - - """ - - name: str = Field(default_factory=lambda: _model_name_factory("Contrast"), min_length=1) - data: str = "" - background: str = "" - background_action: BackgroundActions = BackgroundActions.Add - bulk_in: str = "" - bulk_out: str = "" - scalefactor: str = "" - resolution: str = "" - resample: bool = False - repeat_layers: int = Field(default=1, gt=0) - model: list[str] = [] - - @model_validator(mode="before") - @classmethod - def domain_ratio_error(cls, data: Any): - """If the extra input 'domain_ratio' is given, give a more descriptive error.""" - if isinstance(data, dict) and data.get("domain_ratio", False): - raise ValueError( - "The Contrast class does not support domain ratios. Use the ContrastWithRatio class instead." - ) - - return data - - def __str__(self): - table = prettytable.PrettyTable() - table.field_names = [key.replace("_", " ") for key in self.__dict__] - model_entry = "\n".join(element for element in self.model) - table.add_row( - [ - self.name, - self.data, - self.background, - self.background_action, - self.bulk_in, - self.bulk_out, - self.scalefactor, - self.resolution, - self.resample, - self.repeat_layers, - model_entry, - ] - ) - return table.get_string() - - -class ContrastWithRatio(RATModel): - """A group of all of the components of a model, including domain terms. - - Parameters - ---------- - name : str - The name of the contrast. - data : str - The name of the dataset used by the contrast. - background : str - The name of the background for the contrast. - background_action : BackgroundActions - Whether the background should be added ('add') or subtracted ('subtract') from the data. - bulk_in : str - The name of the bulk-in parameter which defines the SLD of the interface between the - first layer and the environment. - bulk_out : str - The name of the bulk-out parameter which defines the SLD of the interface between the last - layer and the environment. - scalefactor : str - resolution : str - The name of the instrument resolution for this contrast. - resample : bool - Whether adaptive resampling should be used for interface microslicing. - repeat_layers : int - For standard layers, the number of times the set of layers defined in the model should be repeated. - domain_ratio : str - The name of the domain ratio parameter describing how the first domain should be weighted - relative to the second. - model : list[str] - If this is a standard layers model, this should be a list of the names of the two domain contrasts - which make up the domain model for this contrast. - For custom models, this should be a list containing just the custom file name for the - custom model function. - - """ - - name: str = Field(default_factory=lambda: _model_name_factory("ContrastWithRatio"), min_length=1) - data: str = "" - background: str = "" - background_action: BackgroundActions = BackgroundActions.Add - bulk_in: str = "" - bulk_out: str = "" - scalefactor: str = "" - resolution: str = "" - resample: bool = False - repeat_layers: int = Field(default=1, gt=0) - domain_ratio: str = "" - model: list[str] = [] - - def __str__(self): - table = prettytable.PrettyTable() - table.field_names = [key.replace("_", " ") for key in self.__dict__] - model_entry = "\n".join(element for element in self.model) - table.add_row( - [ - self.name, - self.data, - self.background, - self.background_action, - self.bulk_in, - self.bulk_out, - self.scalefactor, - self.resolution, - self.resample, - self.repeat_layers, - self.domain_ratio, - model_entry, - ] - ) - return table.get_string() - - -class CustomFile(RATModel): - """A file containing functions to use for a custom model or function background. - - Parameters - ---------- - name : str - The name of this custom file object. - filename : str - The name of the file containing the custom function. - function_name : str - The name of the custom function within the file. - language : Languages - What language the custom function is written in: 'matlab', 'python', or 'cpp' (C++) - path : pathlib.Path - The path to the custom file. - - """ - - name: str = Field(default_factory=lambda: _model_name_factory("CustomFile"), min_length=1) - filename: str = "" - function_name: str = "" - language: Languages = Languages.Python - path: pathlib.Path = pathlib.Path(".") - - def model_post_init(self, __context: Any) -> None: - """Autogenerate the function name from the filename if not set. - - If a filename is supplied but the ``function_name`` field is not set, the ``function_name`` should be set to - the filename without the extension. - - """ - if "filename" in self.model_fields_set and "function_name" not in self.model_fields_set: - self.function_name = pathlib.Path(self.filename).stem - - @model_validator(mode="after") - def set_matlab_function_name(self): - """For a matlab custom function, ``function_name`` should be set to the filename without the extension.""" - if self.language == Languages.Matlab and self.function_name != pathlib.Path(self.filename).stem: - self.function_name = pathlib.Path(self.filename).stem - - return self - - -class Data(RATModel, arbitrary_types_allowed=True): - """A dataset required for a contrast. - - Parameters - ---------- - name : str - The name of this dataset. - data : np.ndarray[np.float64] - The (x, y, error) data for this dataset, given as a Numpy array of three columns. - data_range : list[float] - simulation_range : list[float] - - """ - - name: str = Field(default_factory=lambda: _model_name_factory("Data"), min_length=1) - data: np.ndarray = np.empty([0, 3]) - data_range: list[float] = Field(default=[], min_length=2, max_length=2) - simulation_range: list[float] = Field(default=[], min_length=2, max_length=2) - - @field_validator("data") - @classmethod - def check_data_dimension(cls, data: np.ndarray) -> np.ndarray: - """Ensure the data is be a two-dimensional array containing at least three columns.""" - try: - data.shape[1] - except IndexError: - raise ValueError('"data" must have at least two dimensions') from None - else: - if data.shape[1] < 3: - raise ValueError('"data" must have at least three columns') from None - return data - - @field_validator("data_range", "simulation_range") - @classmethod - def check_min_max(cls, limits: list[float], info: ValidationInfo) -> list[float]: - """Ensure the data range and simulation range maximum is greater than the minimum.""" - if limits[0] > limits[1]: - raise ValueError(f'{info.field_name} "min" value is greater than the "max" value') - return limits - - def model_post_init(self, __context: Any) -> None: - """Automatically generate ``data_range`` and ``simulation_range`` from the data. - - If the ``data_range`` and ``simulation_range`` fields are not set, but ``data`` is supplied, the ranges are - set to the min and max values of the first column (assumed to be q) of the supplied data. - """ - if self.data.shape[0] > 0: - data_min = float(np.min(self.data[:, 0])) - data_max = float(np.max(self.data[:, 0])) - for field in ["data_range", "simulation_range"]: - if field not in self.model_fields_set: - getattr(self, field).extend([data_min, data_max]) - - @model_validator(mode="after") - def check_ranges(self) -> "Data": - """Check that ``data_range`` is within the q-range of the data, and ``simulation_range`` is outside it. - - The limits of the "data_range" field must lie within the range of the supplied data, whilst the limits - of the "simulation_range" field must lie outside the range of the supplied data. - """ - if self.data.shape[0] > 0: - data_min = np.min(self.data[:, 0]) - data_max = np.max(self.data[:, 0]) - if "data_range" in self.model_fields_set and ( - self.data_range[0] < data_min or self.data_range[1] > data_max - ): - raise ValueError( - f"The data_range value of: {self.data_range} must lie within the min/max values of " - f"the data: [{data_min}, {data_max}]", - ) - if "simulation_range" in self.model_fields_set and ( - self.simulation_range[0] > data_min or self.simulation_range[1] < data_max - ): - raise ValueError( - f"The simulation_range value of: {self.simulation_range} must lie outside of the " - f"min/max values of the data: [{data_min}, {data_max}]", - ) - return self - - def __eq__(self, other: object) -> bool: - if isinstance(other, BaseModel): - # When comparing instances of generic types for equality, as long as all field values are equal, - # only require their generic origin types to be equal, rather than exact type equality. - # This prevents headaches like MyGeneric(x=1) != MyGeneric[Any](x=1). - self_type = self.__pydantic_generic_metadata__["origin"] or self.__class__ - other_type = other.__pydantic_generic_metadata__["origin"] or other.__class__ - - return ( - self_type == other_type - and self.name == other.name - and (self.data == other.data).all() - and self.data_range == other.data_range - and self.simulation_range == other.simulation_range - and self.__pydantic_private__ == other.__pydantic_private__ - and self.__pydantic_extra__ == other.__pydantic_extra__ - ) - else: - return NotImplemented # delegate to the other item in the comparison - - def __str__(self): - table = prettytable.PrettyTable() - table.field_names = [key.replace("_", " ") for key in self.__dict__] - array_entry = f"{'Data array: [' + ' x '.join(str(i) for i in self.data.shape) if self.data.size > 0 else '['}]" - table.add_row([self.name, array_entry, self.data_range, self.simulation_range]) - return table.get_string() - - -class DomainContrast(RATModel): - """A group of layers required for a domain. - - Parameters - ---------- - name : str - The name of this domain contrast. - model : list[str] - A list of layer names that make up the slab model for this contrast. - - """ - - name: str = Field(default_factory=lambda: _model_name_factory("DomainContrast"), min_length=1) - model: list[str] = [] - - def __str__(self): - table = prettytable.PrettyTable() - table.field_names = [key.replace("_", " ") for key in self.__dict__] - model_entry = "\n".join(element for element in self.model) - table.add_row([self.name, model_entry]) - return table.get_string() - - -class Layer(RATModel, populate_by_name=True): - """A slab model layer with given physical properties. - - Parameters - ---------- - name : str - The name of this layer. - thickness : str - The name of the parameter describing the thickness of this layer. - SLD : str - The name of the parameter describing the scattering length density - of this layer. - roughness : str - The name of the parameter describing the roughness of this layer. - hydration : str - hydrate_with : str - - """ - - name: str = Field(default_factory=lambda: _model_name_factory("Layer"), min_length=1) - thickness: str - SLD: str = Field(validation_alias="SLD_real") - roughness: str - hydration: str = "" - hydrate_with: Hydration = Hydration.BulkOut - - @model_validator(mode="before") - @classmethod - def sld_imaginary_error(cls, data: Any): - """If the extra input 'sld_imaginary' is given, give a more descriptive error.""" - if isinstance(data, dict) and data.get("SLD_imaginary", False): - raise ValueError("The Layer class does not support imaginary SLD. Use the AbsorptionLayer class instead.") - - return data - - -class AbsorptionLayer(RATModel, populate_by_name=True): - """A slab model layer with a non-negligible absorption term. - - Parameters - ---------- - name : str - The name of this layer. - thickness : str - The name of the parameter describing the thickness of this layer. - SLD_real : str - The name of the parameter describing the real (scattering) term - for the scattering length density of this layer. - SLD_imaginary : str - The name of the parameter describing the imaginary (absorption) term - for the scattering length density of this layer. - roughness : str - The name of the parameter describing the roughness of this layer. - hydration : str - hydrate_with : str - - """ - - name: str = Field(default_factory=lambda: _model_name_factory("AbsorptionLayer"), min_length=1) - thickness: str - SLD_real: str = Field(validation_alias="SLD") - SLD_imaginary: str - roughness: str - hydration: str = "" - hydrate_with: Hydration = Hydration.BulkOut - - -class Parameter(RATModel): - """A parameter needed to specify the model. - - Parameters - ---------- - name : str - The name of this parameter. - min : float - The minimum value that this parameter could take when fitted. - value : float - The value of this parameter. - max : float - The maximum value that this parameter could take when fitted. - fit : bool - Whether this parameter should be fitted in a calculation. - prior_type : Priors - For Bayesian calculations, whether the prior likelihood - is assumed to be 'uniform' or 'gaussian'. - mu, sigma : float - If the prior type is Gaussian, the mu and sigma values describing - the Gaussian function for the prior likelihood. - - """ - - name: str = Field(default_factory=lambda: _model_name_factory("Parameter"), min_length=1) - min: float = 0.0 - value: float = 0.0 - max: float = 0.0 - fit: bool = False - prior_type: Priors = Priors.Uniform - mu: float = 0.0 - sigma: float = np.inf - - show_priors: bool = False - - def model_post_init(self, __context: Any) -> None: - """Apply parameter value to limits if they are not set.""" - if "value" in self.model_fields_set: - if self.value > 0.0: - if "max" not in self.model_fields_set: - self.max = self.value - if "min" not in self.model_fields_set: - self.min = self.value - elif self.value < 0.0: - if "min" not in self.model_fields_set: - self.min = self.value - if "max" not in self.model_fields_set: - self.max = self.value - - @model_validator(mode="after") - def check_min_max(self) -> "Parameter": - """Ensure the maximum value of a parameter is greater than the minimum.""" - if self.min > self.max: - raise ValueError(f"The maximum value {self.max} must be greater than the minimum value {self.min}") - return self - - @model_validator(mode="after") - def check_value_in_range(self) -> "Parameter": - """Ensure the value of a parameter lies within its defined bounds.""" - if self.value < self.min or self.value > self.max: - raise ValueError(f"value {self.value} is not within the defined range: {self.min} <= value <= {self.max}") - return self - - @property - def display_fields(self) -> dict: - """Only display Prior information if ``show_priors`` is true.""" - visible_fields = ["name", "min", "value", "max", "fit"] - if self.show_priors: - visible_fields.append("prior_type") - if self.prior_type == Priors.Gaussian: - visible_fields.extend(["mu", "sigma"]) - - return {f: getattr(self, f) for f in visible_fields} - - -class ProtectedParameter(Parameter): - """A Parameter with a fixed name.""" - - name: str = Field(frozen=True, min_length=1) - - -class Resolution(Signal): - """An instrument resolution. - - Parameters - ---------- - name : str - The name of the resolution. - type : TypeOptions - The type of resolution: 'constant', 'data', or (NOT YET IMPLEMENTED) 'function'. - source : str - The source data for the resolution; - - - if type is 'constant', this should be the name of a background parameter. - - if type is 'data', this should be empty (resolution data is in the contrast data). - - if type is 'function' (NOT YET IMPLEMENTED), - this should be the name of a custom function defined in `Project.custom_files`. - - value_1, value_2, value_3, value_4, value_5 : str - Values required by the background. - - - if type is 'constant' or 'data', all values will be ignored. - - if type is 'function' (NOT YET IMPLEMENTED), - these values may be the names of up to 5 parameters which are passed to the function. - - """ - - name: str = Field(default_factory=lambda: _model_name_factory("Resolution"), min_length=1) - - @field_validator("type") - @classmethod - def validate_unimplemented_resolutions(cls, type: TypeOptions): - """Raise an error if currently unsupported function resolutions are used.""" - # when function resolutions are added, fix the commented-out parts of - # test_project.py::test_rename_models - # and test_project.py::test_allowed_resolutions - if type == TypeOptions.Function: - raise NotImplementedError("Function resolutions are not yet supported.") - return type - - @model_validator(mode="after") - def check_unsupported_parameters(self): - """Raise an error if the parameters given are not supported for the given type.""" - if self.type == TypeOptions.Constant: - expected_empty_fields = ["value_1", "value_2", "value_3", "value_4", "value_5"] - elif self.type == TypeOptions.Data: - expected_empty_fields = ["source", "value_1", "value_2", "value_3", "value_4", "value_5"] - else: - return self - - non_empty_fields = [v for v in expected_empty_fields if getattr(self, v) != ""] - if non_empty_fields: - raise ValueError( - f'The following values are not supported by the "{self.type}" Resolution type: ' - f"{', '.join(non_empty_fields)}" - ) - - return self diff --git a/ratapi/outputs.py b/ratapi/outputs.py deleted file mode 100644 index c1f5c0ed..00000000 --- a/ratapi/outputs.py +++ /dev/null @@ -1,821 +0,0 @@ -"""Converts results from the compiled RAT code to python dataclasses.""" - -import json -from dataclasses import dataclass -from pathlib import Path -from typing import Any, Union - -import numpy as np - -import ratapi.rat_core -from ratapi.utils.enums import Procedures - -bayes_results_subclasses = [ - "predictionIntervals", - "confidenceIntervals", - "dreamParams", - "dreamOutput", - "nestedSamplerOutput", -] - -bayes_results_fields = { - "param_fields": { - "predictionIntervals": [], - "confidenceIntervals": [], - "dreamParams": [ - "nParams", - "nChains", - "nGenerations", - "parallel", - "CPU", - "jumpProbability", - "pUnitGamma", - "nCR", - "delta", - "steps", - "zeta", - "outlier", - "adaptPCR", - "thinning", - "epsilon", - "ABC", - "IO", - "storeOutput", - ], - "dreamOutput": ["runtime", "iteration"], - "nestedSamplerOutput": ["logZ", "logZErr"], - }, - "list_fields": { - "predictionIntervals": ["reflectivity"], - "confidenceIntervals": [], - "dreamParams": [], - "dreamOutput": [], - "nestedSamplerOutput": [], - }, - "double_list_fields": { - "predictionIntervals": ["sld"], - "confidenceIntervals": [], - "dreamParams": [], - "dreamOutput": [], - "nestedSamplerOutput": [], - }, - "array_fields": { - "predictionIntervals": ["sampleChi"], - "confidenceIntervals": ["percentile65", "percentile95", "mean"], - "dreamParams": ["R"], - "dreamOutput": ["allChains", "outlierChains", "AR", "R_stat", "CR"], - "nestedSamplerOutput": ["nestSamples", "postSamples"], - }, -} - -results_fields = { - "list_fields": ["reflectivity", "simulation", "shiftedData", "backgrounds", "resolutions"], - "double_list_fields": ["sldProfiles", "layers", "resampledLayers"], -} - - -def get_field_string(field: str, value: Any, array_limit: int): - """Return a string representation of class fields where large arrays are represented by their shape. - - An array will be displayed as just its shape if it is multidimensional or 1D and longer than ``array_limit``. - - Parameters - ---------- - field : str - The name of the field in the RAT output class. - value : Any - The value of the given field in the RAT output class. - array_limit : int - The maximum length of 1D arrays which will be fully displayed. - - Returns - ------- - field_string : str - The string representation of the field in the RAT output class. - - Examples - -------- - >>> get_field_string("data", 130, 5) - "data = 130" - - >>> get_field_string("data", array([1, 2, 3, 4, 5]), 10) - "data = [1 2 3 4 5]" - - >>> get_field_string("data", array([1, 2, 3, 4, 5]), 3) - "data = Data array: [5]," - - >>> get_field_string("data", array([[1, 2, 3], [4, 5, 6]]), 10) - "data = Data array: [2 x 3]," - - """ - array_text = "Data array: " - if isinstance(value, list) and len(value) > 0: - if isinstance(value[0], np.ndarray): - array_strings = [f"{array_text}[{' x '.join(str(i) for i in array.shape)}]" for array in value] - field_string = f"{field} = [{', '.join(str(string) for string in array_strings)}],\n" - elif isinstance(value[0], list) and len(value[0]) > 0 and isinstance(value[0][0], np.ndarray): - array_strings = [ - [f"{array_text}[{' x '.join(str(i) for i in array.shape)}]" for array in sub_list] for sub_list in value - ] - list_strings = [f"[{', '.join(string for string in list_string)}]" for list_string in array_strings] - field_string = f"{field} = [{', '.join(list_strings)}],\n" - else: - field_string = f"{field} = {str(value)},\n" - elif isinstance(value, np.ndarray): - if value.ndim == 1 and value.size < array_limit: - field_string = f"{field} = {str(value) if value.size > 0 else '[]'},\n" - else: - field_string = f"{field} = {array_text}[{' x '.join(str(i) for i in value.shape)}],\n" - else: - field_string = f"{field} = {str(value)},\n" - - return field_string - - -class RATResult: - """A mixin class which truncates arrays when the class is displayed.""" - - def __str__(self): - output = f"{self.__class__.__name__}(\n" - for key, value in self.__dict__.items(): - output += "\t" + get_field_string(key, value, 100) - output += ")" - return output - - -@dataclass -class CalculationResults(RATResult): - """The goodness of fit from the Abeles calculation. - - Parameters - ---------- - chiValues : np.ndarray - The chi-squared value for each contrast. - sumChi : float - The sum of the chiValues array. - - """ - - chiValues: np.ndarray - sumChi: float - - -@dataclass -class ContrastParams(RATResult): - """The experimental parameters for each contrast. - - Parameters - ---------- - scalefactors : np.ndarray - The scalefactor values for each contrast. - bulkIn : np.ndarray - The bulk in values for each contrast. - bulkOut : np.ndarray - The bulk out values for each contrast. - subRoughs : np.ndarray - The substrate roughness values for each contrast. - resample : np.ndarray - An array containing whether each contrast was resampled. - - """ - - scalefactors: np.ndarray - bulkIn: np.ndarray - bulkOut: np.ndarray - subRoughs: np.ndarray - resample: np.ndarray - - -@dataclass -class Results: - """The results of a RAT calculation. - - Parameters - ---------- - reflectivity : list - The reflectivity curves for each contrast, - with the same range as the data - (``data_range`` in the contrast's ``Data`` object) - simulation : list - The reflectivity curves for each contrast, - which can be a wider range to allow extrapolation - (``simulation_range`` in the contrast's ``Data`` object). - shiftedData : list - The data with scalefactors and background corrections applied. - backgrounds : list - The background for each contrast defined over the simulation range. - resolutions : list - The resolution for each contrast defined over the simulation range. - sldProfiles : list - The SLD profiles for each contrast. - layers : list - The array of layer parameter values for each contrast. - resampledLayers : list - If resampling is used, the array of layer parameter values for each contrast after resampling has been - performed. - calculationResults : CalculationResults - The chi-squared fit results from the final calculation and fit. - contrastParams : ContrastParams - The experimental parameters for the contrasts. - fitParams : np.ndarray - The best fit value of the parameter with name ``fitNames[i]``. - fitNames : list[str] - The names of the fit parameters, where ``fitNames[i]`` is the name - of the parameter with value given in ``fitParams[i]``. - - """ - - reflectivity: list - simulation: list - shiftedData: list - backgrounds: list - resolutions: list - sldProfiles: list - layers: list - resampledLayers: list - calculationResults: CalculationResults - contrastParams: ContrastParams - fitParams: np.ndarray - fitNames: list[str] - - def __str__(self): - output = "" - for key, value in self.__dict__.items(): - output += get_field_string(key, value, 100) - return output - - def save(self, filepath: str | Path = "./results.json"): - """Save the Results object to a JSON file. - - Parameters - ---------- - filepath : str or Path - The path to where the results file will be written. - """ - filepath = Path(filepath).with_suffix(".json") - json_dict = write_core_results_fields(self) - - filepath.write_text(json.dumps(json_dict)) - - @classmethod - def load(cls, path: str | Path) -> Union["Results", "BayesResults"]: - """Load a Results object from file. - - Parameters - ---------- - path : str or Path - The path to the results json file. - """ - path = Path(path) - input_data = path.read_text() - results_dict = json.loads(input_data) - - results_dict = read_core_results_fields(results_dict) - - if all(key in results_dict for key in bayes_results_subclasses): - results_dict = read_bayes_results_fields(results_dict) - - return BayesResults( - reflectivity=results_dict["reflectivity"], - simulation=results_dict["simulation"], - shiftedData=results_dict["shiftedData"], - backgrounds=results_dict["backgrounds"], - resolutions=results_dict["resolutions"], - sldProfiles=results_dict["sldProfiles"], - layers=results_dict["layers"], - resampledLayers=results_dict["resampledLayers"], - calculationResults=CalculationResults(**results_dict["calculationResults"]), - contrastParams=ContrastParams(**results_dict["contrastParams"]), - fitParams=np.array(results_dict["fitParams"]), - fitNames=results_dict["fitNames"], - predictionIntervals=PredictionIntervals(**results_dict["predictionIntervals"]), - confidenceIntervals=ConfidenceIntervals(**results_dict["confidenceIntervals"]), - dreamParams=DreamParams(**results_dict["dreamParams"]), - dreamOutput=DreamOutput(**results_dict["dreamOutput"]), - nestedSamplerOutput=NestedSamplerOutput(**results_dict["nestedSamplerOutput"]), - chain=np.array(results_dict["chain"]), - ) - - else: - return Results( - reflectivity=results_dict["reflectivity"], - simulation=results_dict["simulation"], - shiftedData=results_dict["shiftedData"], - backgrounds=results_dict["backgrounds"], - resolutions=results_dict["resolutions"], - sldProfiles=results_dict["sldProfiles"], - layers=results_dict["layers"], - resampledLayers=results_dict["resampledLayers"], - calculationResults=CalculationResults(**results_dict["calculationResults"]), - contrastParams=ContrastParams(**results_dict["contrastParams"]), - fitParams=np.array(results_dict["fitParams"]), - fitNames=results_dict["fitNames"], - ) - - -@dataclass -class PredictionIntervals(RATResult): - """The Bayesian prediction intervals for 95% and 65% confidence. - - For ``reflectivity`` and ``sld``, each list item is an array - with five rows. The rows represent: - - - 0: the 5th percentile; - - 1: the 35th percentile; - - 2: the mean value of the interval; - - 3: the 65th percentile; - - 4: the 95th percentile. - - Parameters - ---------- - reflectivity : list - The prediction interval data for reflectivity of each contrast. - SLD : list - The prediction interval data for SLD of each contrast. - sampleChi : np.ndarray - The value of sumChi at each point of the Markov chain. - - """ - - reflectivity: list - sld: list - sampleChi: np.ndarray - - -@dataclass -class ConfidenceIntervals(RATResult): - """The 65% and 95% confidence intervals for the best fit results. - - Parameters - ---------- - percentile95 : np.ndarray - The 95% confidence intervals for each fit parameter. - percentile65 : np.ndarray - The 65% confidence intervals for each fit parameter. - mean : np.ndarray - The mean values for each fit parameter. - - """ - - percentile95: np.ndarray - percentile65: np.ndarray - mean: np.ndarray - - -@dataclass -class DreamParams(RATResult): - """The parameters used by the inner DREAM algorithm. - - Parameters - ---------- - nParams : float - The number of parameters used by the algorithm. - nChains : float - The number of MCMC chains used by the algorithm. - nGenerations : float - The number of DE generations calculated per iteration. - parallel : bool - Whether the algorithm should run chains in parallel. - CPU : float - The number of processor cores used for parallel chains. - jumpProbability : float - A probability range for the size of jumps when performing subspace sampling. - pUnitGamma : float - The probability that the scaling-down factor of jumps will be ignored - and a larger jump will be taken for one iteration. - nCR : float - The number of crossovers performed each iteration. - delta : float - The number of chain mutation pairs proposed each iteration. - steps : float - The number of MCMC steps to perform between conversion checks. - zeta : float - The ergodicity of the algorithm. - outlier : str - What test should be used to detect outliers. - adaptPCR : bool - Whether the crossover probability for differential evolution should be - adapted by the algorithm as it runs. - thinning : float - The thinning rate of each Markov chain (to reduce memory intensity) - epsilon : float - The cutoff threshold for Approximate Bayesian Computation (if used) - ABC : bool - Whether Approximate Bayesian Computation is used. - IO : bool - Whether the algorithm should perform IO writes of the model in parallel. - storeOutput : bool - Whether output model simulations are performed. - R : np.ndarray - An array where row ``i`` is the list of chains - with which chain ``i`` can mutate. - - """ - - nParams: float - nChains: float - nGenerations: float - parallel: bool - CPU: float - jumpProbability: float - pUnitGamma: float - nCR: float - delta: float - steps: float - zeta: float - outlier: str - adaptPCR: bool - thinning: float - epsilon: float - ABC: bool - IO: bool - storeOutput: bool - R: np.ndarray - - -@dataclass -class DreamOutput(RATResult): - """The diagnostic output information from DREAM. - - Parameters - ---------- - allChains : np.ndarray - An ``nGenerations`` x ``nParams + 2`` x ``nChains`` size array, - where ``chain_k = DreamOutput.allChains[:, :, k]`` - is the data of chain ``k`` in the final iteration; - for generation i of the final iteration, ``chain_k[i, j]`` represents: - - - the sampled value of parameter ``j`` for ``j in 0:nParams``; - - the associated log-prior for those sampled values for ``j = nParams + 1``; - - the associated log-likelihood for those sampled values for ``j = nParams + 2``. - - outlierChains : np.ndarray - A two-column array where ``DreamOutput.AR[i, 1]`` is the index of a chain - and ``DreamOutput.AR[i, 0]`` is the length of that chain when it was removed - for being an outlier. - runtime : float - The runtime of the DREAM algorithm in seconds. - iteration : float - The number of iterations performed. - AR : np.ndarray - A two-column array where ``DreamOutput.AR[i, 0]`` is an iteration number - and ``DreamOutput.AR[i, 1]`` is the average acceptance rate of chain step - proposals for that iteration. - R_stat : np.ndarray - An array where ``DreamOutput.R_stat[i, 0]`` is an iteration number and - ``DreamOutput.R_stat[i, j]`` is the convergence statistic for parameter ``j`` - at that iteration (where chains are indexed 1 to ``nParams`` inclusive). - CR : np.ndarray - A four-column array where ``DreamOutput.CR[i, 0]`` is an iteration number, - ``and DreamOutput.CR[i, j]`` is the selection probability of the ``j``'th crossover - value for that iteration. - - """ - - allChains: np.ndarray - outlierChains: np.ndarray - runtime: float - iteration: float - AR: np.ndarray - R_stat: np.ndarray - CR: np.ndarray - - -@dataclass -class NestedSamplerOutput(RATResult): - """The output information from the Nested Sampler (ns). - - Parameters - ---------- - logZ : float - The natural logarithm of the evidence Z for the parameter values. - logZErr : float - The estimated uncertainty in the final value of logZ. - nestSamples : np.ndarray - ``NestedSamplerOutput.nestSamples[i, j]`` represents the values - sampled at iteration ``i``, where this value is: - - - the value sampled for parameter ``j``, for ``j`` in ``0:nParams``, - - the minimum log-likelihood for ``j = nParams + 1``. - - postSamples : np.ndarray - The posterior values at the points sampled in ``NestedSamplerOutput.nestSamples``. - - """ - - logZ: float - logZErr: float - nestSamples: np.ndarray - postSamples: np.ndarray - - -@dataclass -class BayesResults(Results): - """The results of a Bayesian RAT calculation. - - Parameters - ---------- - predictionIntervals : PredictionIntervals - The prediction intervals. - confidenceIntervals : ConfidenceIntervals - The 65% and 95% confidence intervals for the best fit results. - dreamParams : DreamParams - The parameters used by DREAM, if relevant. - dreamOutput : DreamOutput - The output from DREAM if DREAM was used. - nestedSamplerOutput : NestedSamplerOutput - The output from nested sampling if ns was used. - chain : np.ndarray - The MCMC chains for each parameter. - The ``i``'th column of the array contains the chain for parameter ``fitNames[i]``. - - """ - - predictionIntervals: PredictionIntervals - confidenceIntervals: ConfidenceIntervals - dreamParams: DreamParams - dreamOutput: DreamOutput - nestedSamplerOutput: NestedSamplerOutput - chain: np.ndarray - - def from_procedure(self) -> Procedures: - """Return the procedure that created the result. - - Returns - ------- - procedure: Procedures - The procedure that created the result. - """ - samples = self.nestedSamplerOutput.nestSamples - if samples.shape == (1, 2) and not np.any(samples): - return Procedures.DREAM - return Procedures.NS - - def save(self, filepath: str | Path = "./results.json"): - """Save the BayesResults object to a JSON file. - - Parameters - ---------- - filepath : str or Path - The path to where the results file will be written. - """ - filepath = Path(filepath).with_suffix(".json") - json_dict = write_core_results_fields(self) - - # Take each of the subclasses in a BayesResults instance and switch the numpy arrays to lists - for subclass_name in bayes_results_subclasses: - subclass = getattr(self, subclass_name) - subclass_dict = {} - - for field in bayes_results_fields["param_fields"][subclass_name]: - subclass_dict[field] = getattr(subclass, field) - - for field in bayes_results_fields["list_fields"][subclass_name]: - subclass_dict[field] = [result_array.tolist() for result_array in getattr(subclass, field)] - - for field in bayes_results_fields["double_list_fields"][subclass_name]: - subclass_dict[field] = [ - [result_array.tolist() for result_array in inner_list] for inner_list in getattr(subclass, field) - ] - - for field in bayes_results_fields["array_fields"][subclass_name]: - subclass_dict[field] = getattr(subclass, field).tolist() - - json_dict[subclass_name] = subclass_dict - - json_dict["chain"] = self.chain.tolist() - filepath.write_text(json.dumps(json_dict)) - - -def write_core_results_fields(results: Results | BayesResults, json_dict: dict | None = None) -> dict: - """Modify the values of the fields that appear in both Results and BayesResults when saving to a json file. - - Parameters - ---------- - results: Union[Results, BayesResults] - The results or BayesResults object we are writing to json. - json_dict: Optional[dict] - The dictionary containing the json output. - - Returns - ------- - json_dict: dict - The output json dict updated with the fields that appear in both Results and BayesResults. - """ - if json_dict is None: - json_dict = {} - - for field in results_fields["list_fields"]: - json_dict[field] = [result_array.tolist() for result_array in getattr(results, field)] - - for field in results_fields["double_list_fields"]: - json_dict[field] = [ - [result_array.tolist() for result_array in inner_list] for inner_list in getattr(results, field) - ] - - json_dict["calculationResults"] = {} - json_dict["calculationResults"]["chiValues"] = results.calculationResults.chiValues.tolist() - json_dict["calculationResults"]["sumChi"] = results.calculationResults.sumChi - - json_dict["contrastParams"] = {} - for field in results.contrastParams.__dict__: - json_dict["contrastParams"][field] = getattr(results.contrastParams, field).tolist() - - json_dict["fitParams"] = results.fitParams.tolist() - json_dict["fitNames"] = results.fitNames - - return json_dict - - -def read_core_results_fields(results_dict: dict) -> dict: - """Modify the values of the fields that appear in both Results and BayesResults when loading a json file. - - Parameters - ---------- - results_dict: Optional[dict] - The dictionary containing the json input. - - Returns - ------- - results_dict: dict - The input json dict with the fields that appear in both Results and BayesResults converted to numpy arrays - where necessary. - """ - for field in results_fields["list_fields"]: - results_dict[field] = [np.array(result_array) for result_array in results_dict[field]] - - for field in results_fields["double_list_fields"]: - results_dict[field] = [ - [np.array(result_array) for result_array in inner_list] for inner_list in results_dict[field] - ] - - results_dict["calculationResults"]["chiValues"] = np.array(results_dict["calculationResults"]["chiValues"]) - - for field in results_dict["contrastParams"]: - results_dict["contrastParams"][field] = np.array(results_dict["contrastParams"][field]) - - return results_dict - - -def read_bayes_results_fields(results_dict: dict) -> dict: - """Modify the values of the fields that appear only in BayesResults when loading a json file. - - Parameters - ---------- - results_dict: Optional[dict] - The dictionary containing the json input. - - Returns - ------- - results_dict: dict - The input json dict with the fields that appear in both Results and BayesResults converted to numpy arrays - where necessary. - """ - for subclass_name in bayes_results_subclasses: - subclass_dict = {} - - for field in bayes_results_fields["param_fields"][subclass_name]: - subclass_dict[field] = results_dict[subclass_name][field] - - for field in bayes_results_fields["list_fields"][subclass_name]: - subclass_dict[field] = [np.array(result_array) for result_array in results_dict[subclass_name][field]] - - for field in bayes_results_fields["double_list_fields"][subclass_name]: - subclass_dict[field] = [ - [np.array(result_array) for result_array in inner_list] - for inner_list in results_dict[subclass_name][field] - ] - - for field in bayes_results_fields["array_fields"][subclass_name]: - subclass_dict[field] = np.array(results_dict[subclass_name][field]) - - results_dict[subclass_name] = subclass_dict - - return results_dict - - -def make_results( - procedure: Procedures, - output_results: ratapi.rat_core.OutputResult, - bayes_results: ratapi.rat_core.OutputBayesResult | None = None, -) -> Results | BayesResults: - """Initialise a python Results or BayesResults object using the outputs from a RAT calculation. - - Parameters - ---------- - procedure : Procedures - The procedure used by the calculation. - output_results : ratapi.rat_core.OutputResult - The C++ output results from the calculation. - bayes_results : Optional[ratapi.rat_core.OutputBayesResult] - The optional extra C++ Bayesian output results from a Bayesian calculation. - - Returns - ------- - Results or BayesResults - A result object containing the results of the calculation, of type - Results for non-Bayesian procedures and BayesResults for Bayesian procedures. - - """ - calculation_results = CalculationResults( - chiValues=output_results.calculationResults.chiValues, - sumChi=output_results.calculationResults.sumChi, - ) - contrast_params = ContrastParams( - scalefactors=output_results.contrastParams.scalefactors, - bulkIn=output_results.contrastParams.bulkIn, - bulkOut=output_results.contrastParams.bulkOut, - subRoughs=output_results.contrastParams.subRoughs, - resample=output_results.contrastParams.resample, - ) - - if procedure in [Procedures.NS, Procedures.DREAM]: - prediction_intervals = PredictionIntervals( - reflectivity=bayes_results.predictionIntervals.reflectivity, - sld=bayes_results.predictionIntervals.sld, - sampleChi=bayes_results.predictionIntervals.sampleChi, - ) - - confidence_intervals = ConfidenceIntervals( - percentile95=bayes_results.confidenceIntervals.percentile95, - percentile65=bayes_results.confidenceIntervals.percentile65, - mean=bayes_results.confidenceIntervals.mean, - ) - - dream_params = DreamParams( - nParams=bayes_results.dreamParams.nParams, - nChains=bayes_results.dreamParams.nChains, - nGenerations=bayes_results.dreamParams.nGenerations, - parallel=bool(bayes_results.dreamParams.parallel), - CPU=bayes_results.dreamParams.CPU, - jumpProbability=bayes_results.dreamParams.jumpProbability, - pUnitGamma=bayes_results.dreamParams.pUnitGamma, - nCR=bayes_results.dreamParams.nCR, - delta=bayes_results.dreamParams.delta, - steps=bayes_results.dreamParams.steps, - zeta=bayes_results.dreamParams.zeta, - outlier=bayes_results.dreamParams.outlier, - adaptPCR=bool(bayes_results.dreamParams.adaptPCR), - thinning=bayes_results.dreamParams.thinning, - epsilon=bayes_results.dreamParams.epsilon, - ABC=bool(bayes_results.dreamParams.ABC), - IO=bool(bayes_results.dreamParams.IO), - storeOutput=bool(bayes_results.dreamParams.storeOutput), - R=bayes_results.dreamParams.R, - ) - - dream_output = DreamOutput( - allChains=bayes_results.dreamOutput.allChains, - outlierChains=bayes_results.dreamOutput.outlierChains, - runtime=bayes_results.dreamOutput.runtime, - iteration=bayes_results.dreamOutput.iteration, - AR=bayes_results.dreamOutput.AR, - R_stat=bayes_results.dreamOutput.R_stat, - CR=bayes_results.dreamOutput.CR, - ) - - nested_sampler_output = NestedSamplerOutput( - logZ=bayes_results.nestedSamplerOutput.logZ, - logZErr=bayes_results.nestedSamplerOutput.logZErr, - nestSamples=bayes_results.nestedSamplerOutput.nestSamples, - postSamples=bayes_results.nestedSamplerOutput.postSamples, - ) - - results = BayesResults( - reflectivity=output_results.reflectivity, - simulation=output_results.simulation, - shiftedData=output_results.shiftedData, - backgrounds=output_results.backgrounds, - resolutions=output_results.resolutions, - sldProfiles=output_results.sldProfiles, - layers=output_results.layers, - resampledLayers=output_results.resampledLayers, - calculationResults=calculation_results, - contrastParams=contrast_params, - fitParams=output_results.fitParams, - fitNames=output_results.fitNames, - predictionIntervals=prediction_intervals, - confidenceIntervals=confidence_intervals, - dreamParams=dream_params, - dreamOutput=dream_output, - nestedSamplerOutput=nested_sampler_output, - chain=bayes_results.chain, - ) - - else: - results = Results( - reflectivity=output_results.reflectivity, - simulation=output_results.simulation, - shiftedData=output_results.shiftedData, - backgrounds=output_results.backgrounds, - resolutions=output_results.resolutions, - sldProfiles=output_results.sldProfiles, - layers=output_results.layers, - resampledLayers=output_results.resampledLayers, - calculationResults=calculation_results, - contrastParams=contrast_params, - fitParams=output_results.fitParams, - fitNames=output_results.fitNames, - ) - - return results diff --git a/ratapi/project.py b/ratapi/project.py deleted file mode 100644 index b8ca49f2..00000000 --- a/ratapi/project.py +++ /dev/null @@ -1,1080 +0,0 @@ -"""The project module. Defines and stores all the input data required for reflectivity calculations in RAT.""" - -import collections -import copy -import functools -import json -import warnings -from collections.abc import Callable -from enum import Enum -from pathlib import Path -from textwrap import indent -from typing import Annotated, Any, get_args, get_origin - -import numpy as np -from pydantic import ( - BaseModel, - Discriminator, - Field, - Tag, - ValidationError, - ValidationInfo, - field_validator, - model_validator, -) - -import ratapi.models -from ratapi.classlist import ClassList -from ratapi.utils.custom_errors import custom_pydantic_validation_error -from ratapi.utils.enums import Calculations, Geometries, LayerModels, Priors, TypeOptions - - -# note for these discriminators that the before-validator discriminate_ambiguous_dicts -# guarantees we don't run into the ambiguous case of a sequence of dicts -def discriminate_layers(layer_input): - """Union discriminator for layers.""" - if isinstance(layer_input, collections.abc.Sequence): - # if classlist is empty, just label it as no absorption and it'll get fixed in post_init - if len(layer_input) > 0 and isinstance(layer_input[0], ratapi.models.AbsorptionLayer): - return "abs" - return "no_abs" - - -def discriminate_contrasts(contrast_input): - """Union discriminator for contrasts.""" - if isinstance(contrast_input, collections.abc.Sequence): - # if classlist is empty, just label it as no ratio and it'll get fixed in post_init - if len(contrast_input) > 0 and isinstance(contrast_input[0], ratapi.models.ContrastWithRatio): - return "ratio" - return "no_ratio" - - -values_defined_in = { - "backgrounds.value_1": "background_parameters", - "backgrounds.value_2": "background_parameters", - "backgrounds.value_3": "background_parameters", - "backgrounds.value_4": "background_parameters", - "backgrounds.value_5": "background_parameters", - "backgrounds.constant.source": "background_parameters", - "backgrounds.data.source": "data", - "backgrounds.function.source": "custom_files", - "resolutions.value_1": "resolution_parameters", - "resolutions.value_2": "resolution_parameters", - "resolutions.value_3": "resolution_parameters", - "resolutions.value_4": "resolution_parameters", - "resolutions.value_5": "resolution_parameters", - "resolutions.constant.source": "resolution_parameters", - "resolutions.function.source": "custom_files", - "layers.thickness": "parameters", - "layers.SLD": "parameters", - "layers.SLD_real": "parameters", - "layers.SLD_imaginary": "parameters", - "layers.roughness": "parameters", - "contrasts.data": "data", - "contrasts.background": "backgrounds", - "contrasts.bulk_in": "bulk_in", - "contrasts.bulk_out": "bulk_out", - "contrasts.scalefactor": "scalefactors", - "contrasts.resolution": "resolutions", - "contrasts.domain_ratio": "domain_ratios", -} - -AllFields = collections.namedtuple("AllFields", ["attribute", "fields"]) -model_names_used_in = { - "background_parameters": [ - AllFields("backgrounds", ["source", "value_1", "value_2", "value_3", "value_4", "value_5"]) - ], - "resolution_parameters": [ - AllFields("resolutions", ["source", "value_1", "value_2", "value_3", "value_4", "value_5"]) - ], - "parameters": [AllFields("layers", ["thickness", "SLD", "SLD_real", "SLD_imaginary", "roughness", "hydration"])], - "data": [ - AllFields("contrasts", ["data"]), - AllFields("backgrounds", ["source"]), - ], - "custom_files": [AllFields("backgrounds", ["source"]), AllFields("resolutions", ["source"])], - "backgrounds": [AllFields("contrasts", ["background"])], - "bulk_in": [AllFields("contrasts", ["bulk_in"])], - "bulk_out": [AllFields("contrasts", ["bulk_out"])], - "scalefactors": [AllFields("contrasts", ["scalefactor"])], - "domain_ratios": [AllFields("contrasts", ["domain_ratio"])], - "resolutions": [AllFields("contrasts", ["resolution"])], -} - -# Note that the order of these parameters is hard-coded into RAT -parameter_class_lists = [ - "parameters", - "background_parameters", - "scalefactors", - "bulk_in", - "bulk_out", - "resolution_parameters", - "domain_ratios", -] -class_lists = [ - *parameter_class_lists, - "backgrounds", - "resolutions", - "custom_files", - "data", - "layers", - "domain_contrasts", - "contrasts", -] - - -class Project(BaseModel, validate_assignment=True, extra="forbid", use_attribute_docstrings=True): - """Defines the input data for a reflectivity calculation in RAT. - - This class combines the data defined in each of the pydantic models included in "models.py" into the full set of - inputs required for a reflectivity calculation. - """ - - name: str = "" - """The name of the project.""" - - calculation: Calculations = Calculations.Normal - """What calculation type should be used. Can be 'normal' or 'domains'.""" - - model: LayerModels = LayerModels.StandardLayers - """What layer model should be used. Can be 'standard layers', 'custom layers', or 'custom xy'.""" - - geometry: Geometries = Geometries.AirSubstrate - """What geometry should be used. Can be 'air/substrate' or 'substrate/liquid'""" - - absorption: bool = False - """Whether imaginary SLD (absorption) should be accounted for.""" - - parameters: ClassList[ratapi.models.Parameter] = ClassList() - """The list of parameters used in the layers of a model.""" - - bulk_in: ClassList[ratapi.models.Parameter] = ClassList( - ratapi.models.Parameter( - name="SLD Air", - min=0.0, - value=0.0, - max=0.0, - fit=False, - prior_type=Priors.Uniform, - mu=0.0, - sigma=np.inf, - ), - ) - """The list of parameters for SLD of the entry interfaces of a model.""" - - bulk_out: ClassList[ratapi.models.Parameter] = ClassList( - ratapi.models.Parameter( - name="SLD D2O", - min=6.2e-6, - value=6.35e-6, - max=6.35e-6, - fit=False, - prior_type=Priors.Uniform, - mu=0.0, - sigma=np.inf, - ), - ) - """The list of parameters for SLD of the exit interfaces of a model.""" - - scalefactors: ClassList[ratapi.models.Parameter] = ClassList( - ratapi.models.Parameter( - name="Scalefactor 1", - min=0.02, - value=0.23, - max=0.25, - fit=False, - prior_type=Priors.Uniform, - mu=0.0, - sigma=np.inf, - ), - ) - """The list of parameters for scale factors to handle systematic error in model data.""" - - domain_ratios: ClassList[ratapi.models.Parameter] = ClassList( - ratapi.models.Parameter( - name="Domain Ratio 1", - min=0.4, - value=0.5, - max=0.6, - fit=False, - prior_type=Priors.Uniform, - mu=0.0, - sigma=np.inf, - ), - ) - """The list of parameters for weighting between domains of a domains model.""" - - background_parameters: ClassList[ratapi.models.Parameter] = ClassList( - ratapi.models.Parameter( - name="Background Param 1", - min=1e-7, - value=1e-6, - max=1e-5, - fit=False, - prior_type=Priors.Uniform, - mu=0.0, - sigma=np.inf, - ), - ) - """The list of parameters for models of backgrounds.""" - - backgrounds: ClassList[ratapi.models.Background] = ClassList( - ratapi.models.Background(name="Background 1", type=TypeOptions.Constant, source="Background Param 1"), - ) - """The list of models for background noise in the project.""" - - resolution_parameters: ClassList[ratapi.models.Parameter] = ClassList( - ratapi.models.Parameter( - name="Resolution Param 1", - min=0.01, - value=0.03, - max=0.05, - fit=False, - prior_type=Priors.Uniform, - mu=0.0, - sigma=np.inf, - ), - ) - """The list of parameters for models of resolutions.""" - - resolutions: ClassList[ratapi.models.Resolution] = ClassList( - ratapi.models.Resolution(name="Resolution 1", type=TypeOptions.Constant, source="Resolution Param 1"), - ) - """The list of models for instrument resolution in the project.""" - - custom_files: ClassList[ratapi.models.CustomFile] = ClassList() - """Handles for custom files used by the project.""" - - data: ClassList[ratapi.models.Data] = ClassList() - """Experimental data for a model.""" - - layers: ( - Annotated[ClassList[ratapi.models.Layer], Tag("no_abs")] - | Annotated[ClassList[ratapi.models.AbsorptionLayer], Tag("abs")] - ) = Field( - default=ClassList(), - discriminator=Discriminator( - discriminate_layers, - custom_error_type="invalid_union_member", - custom_error_message="Input should be an instance of ClassList", - custom_error_context={"discriminator": "absorption_or_no"}, - ), - ) - """The layers of a standard layer model.""" - - domain_contrasts: ClassList[ratapi.models.DomainContrast] = ClassList() - """The groups of layers required by each domain in a domains model.""" - - contrasts: ( - Annotated[ClassList[ratapi.models.Contrast], Tag("no_ratio")] - | Annotated[ClassList[ratapi.models.ContrastWithRatio], Tag("ratio")] - ) = Field( - default=ClassList(), - discriminator=Discriminator( - discriminate_contrasts, - custom_error_type="invalid_union_member", - custom_error_message="Input should be an instance of ClassList.", - custom_error_context={"discriminator": "ratio_or_no_ratio"}, - ), - ) - """All groups of components used to define each model in the project.""" - - _all_names: dict - _contrast_model_field: str - _protected_parameters: dict - - @model_validator(mode="before") - @classmethod - def discriminate_ambiguous_dicts(cls, data: Any) -> Any: - """If layers or contrasts contain a dict, convert it to the relevant model.""" - # pydantic docs says data can be anything, but i can't see anywhere where it isn't a dict. - # if it's not a dict, just return and let the library handle it - if isinstance(data, dict): - layer_model = ratapi.models.AbsorptionLayer if data.get("absorption", False) else ratapi.models.Layer - if data.get("calculation", Calculations.Normal) == Calculations.Domains: - contrast_model = ratapi.models.ContrastWithRatio - else: - contrast_model = ratapi.models.Contrast - - # note we aren't modifying the layers and contrasts in-place: - # if a ClassList of dicts is passed, in-place conversion would make the ClassList heterogenous - # & it'd throw an error - if layers := data.get("layers", False): - new_layers = ClassList() - for layer in layers: - if isinstance(layer, dict): - layer = layer_model.model_validate(layer) - new_layers.append(layer) - data["layers"] = new_layers - - if contrasts := data.get("contrasts", False): - new_contrasts = ClassList() - for contrast in contrasts: - if isinstance(contrast, dict): - contrast = contrast_model.model_validate(contrast) - new_contrasts.append(contrast) - data["contrasts"] = new_contrasts - - return data - - @field_validator("layers") - @classmethod - def check_layers(cls, value: ClassList, info: ValidationInfo): - """Check that layers are AbsorptionLayers if doing absorption, and Layers otherwise.""" - if info.data["absorption"]: - model_name = "AbsorptionLayer" - other_model = "Layer" - else: - model_name = "Layer" - other_model = "AbsorptionLayer" - model = getattr(ratapi.models, model_name) - if not all(isinstance(element, model) for element in value): - raise ValueError( - f'"The layers attribute contains {other_model}s, ' - f"but the absorption parameter is {info.data['absorption']}. " - f'The attribute should be a ClassList of {model_name} instead."' - ) - - return value - - @field_validator("contrasts") - @classmethod - def check_contrasts(cls, value: ClassList, info: ValidationInfo): - """Check that contrasts are with ratio if calculating domains, and without otherwise.""" - if info.data["calculation"] == Calculations.Domains: - model_name = "ContrastWithRatio" - error_word = "without" - else: - model_name = "Contrast" - error_word = "with" - model = getattr(ratapi.models, model_name) - if not all(isinstance(element, model) for element in value): - raise ValueError( - f'"The contrasts attribute contains contrasts {error_word} ratio, ' - f'but the calculation is {str(info.data["calculation"])}", ' - f"The attribute should be a ClassList of {model_name} instead." - ) - - return value - - def model_post_init(self, __context: Any) -> None: - """Set up the Class to protect against disallowed modification. - - We initialise the class handle in the ClassLists for empty data fields, set protected parameters, get names of - all defined parameters, determine the contents of the "model" field in contrasts, and wrap ClassList routines - to control revalidation. - """ - # Ensure all ClassLists have the correct _class_handle defined - for field in (fields := Project.model_fields): - annotation = fields[field].annotation - if get_origin(annotation) == ClassList: - classlist = getattr(self, field) - if not hasattr(field, "_class_handle"): - classlist._class_handle = get_args(annotation)[0] - - layers_field = self.layers - if not hasattr(layers_field, "_class_handle"): - if self.absorption: - layers_field._class_handle = ratapi.models.AbsorptionLayer - else: - layers_field._class_handle = ratapi.models.Layer - - contrast_field = self.contrasts - if not hasattr(contrast_field, "_class_handle"): - if self.calculation == Calculations.Domains: - contrast_field._class_handle = ratapi.models.ContrastWithRatio - else: - contrast_field._class_handle = ratapi.models.Contrast - - if "Substrate Roughness" not in [name.title() for name in self.parameters.get_names()]: - self.parameters.insert( - 0, - ratapi.models.ProtectedParameter( - name="Substrate Roughness", - min=1.0, - value=3.0, - max=5.0, - fit=True, - prior_type=ratapi.models.Priors.Uniform, - mu=0.0, - sigma=np.inf, - ), - ) - elif "Substrate Roughness" not in [name.title() for name in self.get_all_protected_parameters()["parameters"]]: - # If substrate roughness is included as a standard parameter replace it with a protected parameter - substrate_roughness_values = self.parameters["Substrate Roughness"].model_dump() - self.parameters.remove("Substrate Roughness") - self.parameters.insert(0, ratapi.models.ProtectedParameter(**substrate_roughness_values)) - - if "Simulation" not in [name.title() for name in self.data.get_names()]: - self.data.insert(0, ratapi.models.Data(name="Simulation", simulation_range=[0.005, 0.7])) - - self._all_names = self.get_all_names() - self._contrast_model_field = self.get_contrast_model_field() - self._protected_parameters = self.get_all_protected_parameters() - - # Wrap ClassList routines - when any of these routines are called, the wrapper will force revalidation of the - # model, handle errors and reset previous values if necessary. - methods_to_wrap = [ - "_setitem", - "_delitem", - "_iadd", - "append", - "insert", - "pop", - "remove", - "clear", - "extend", - "set_fields", - ] - - for class_list in class_lists: - attribute = getattr(self, class_list) - for methodName in methods_to_wrap: - setattr(attribute, methodName, self._classlist_wrapper(attribute, getattr(attribute, methodName))) - - @model_validator(mode="after") - def set_domain_ratios(self) -> "Project": - """If we are not running a domains calculation, ensure the domain_ratios component of the model is empty.""" - if self.calculation != Calculations.Domains: - self.domain_ratios.data = [] - return self - - @model_validator(mode="after") - def set_domain_contrasts(self) -> "Project": - """Ensure ``domain_contrasts`` is empty if we are not running a standard layer domains calculation.""" - if not (self.calculation == Calculations.Domains and self.model == LayerModels.StandardLayers): - self.domain_contrasts.data = [] - return self - - @model_validator(mode="after") - def set_layers(self) -> "Project": - """If we are not using a standard layers model, ensure the layers component of the model is empty.""" - if self.model != LayerModels.StandardLayers: - self.layers.data = [] - return self - - @model_validator(mode="after") - def set_repeat_layers(self) -> "Project": - """If we are not using a standard layers model, warn that the repeat layers setting is not valid.""" - if self.model != LayerModels.StandardLayers: - for contrast in self.contrasts: - if "repeat_layers" in contrast.model_fields_set and contrast.repeat_layers != 1: - warnings.warn( - 'For a custom layers or custom XY calculation, the "repeat_layers" setting for each ' - "contrast is not valid - resetting to 1.", - stacklevel=2, - ) - contrast.repeat_layers = 1 - return self - - @model_validator(mode="after") - def set_resample(self) -> "Project": - """If we are using a custom XY model, warn that the resample setting for each contrast must always be True.""" - if self.model == LayerModels.CustomXY: - for contrast in self.contrasts: - if "resample" in contrast.model_fields_set and contrast.resample is False: - warnings.warn( - 'For a custom XY calculation, "resample" must be True for each contrast - resetting to True.', - stacklevel=2, - ) - contrast.resample = True - return self - - @model_validator(mode="after") - def set_calculation(self) -> "Project": - """Apply the calc setting to the project.""" - contrast_list = [] - handle = self.contrasts._class_handle.__name__ - if self.calculation == Calculations.Domains and handle == "Contrast": - for contrast in self.contrasts: - contrast_list.append(ratapi.models.ContrastWithRatio(**contrast.model_dump())) - self.contrasts.data = contrast_list - self.domain_ratios.data = [ - ratapi.models.Parameter( - name="Domain Ratio 1", - min=0.4, - value=0.5, - max=0.6, - fit=False, - prior_type=ratapi.models.Priors.Uniform, - mu=0.0, - sigma=np.inf, - ), - ] - self.contrasts._class_handle = ratapi.models.ContrastWithRatio - elif self.calculation != Calculations.Domains and handle == "ContrastWithRatio": - for contrast in self.contrasts: - contrast_params = contrast.model_dump() - del contrast_params["domain_ratio"] - contrast_list.append(ratapi.models.Contrast(**contrast_params)) - self.contrasts.data = contrast_list - self.contrasts._class_handle = ratapi.models.Contrast - return self - - @model_validator(mode="after") - def set_contrast_model_field(self) -> "Project": - """Clear the contrast models if ``calculation`` or ``model_type`` has changed. - - The contents of the "model" field of "contrasts" depend on the values of the "calculation" and "model_type" - defined in the project. - """ - model_field = self.get_contrast_model_field() - if model_field != self._contrast_model_field: - for contrast in self.contrasts: - contrast.model = [] - self._contrast_model_field = model_field - return self - - @model_validator(mode="after") - def check_contrast_model_length(self) -> "Project": - """Ensure the contrast model isn't too long for a domains, custom layers, or custom XY calculation. - - If a custom model is used, the ``model`` field of the contrast should just be one item long. For - a standard layers domain calculation, it should be exactly two items long. - """ - if self.model == LayerModels.StandardLayers and self.calculation == Calculations.Domains: - for contrast in self.contrasts: - if contrast.model and len(contrast.model) != 2: - raise ValueError( - 'For a standard layers domains calculation the "model" field of "contrasts" must ' - "contain exactly two values.", - ) - elif self.model != LayerModels.StandardLayers: - for contrast in self.contrasts: - if len(contrast.model) > 1: - raise ValueError( - 'For a custom model calculation the "model" field of "contrasts" cannot contain ' - "more than one value.", - ) - return self - - @model_validator(mode="after") - def set_absorption(self) -> "Project": - """Apply the absorption setting to the project.""" - layer_list = [] - handle = self.layers._class_handle.__name__ - if self.absorption and handle == "Layer": - for layer in self.layers: - layer_params = layer.model_dump() - layer_params["SLD_imaginary"] = "" - layer_list.append(ratapi.models.AbsorptionLayer(**layer_params)) - self.layers.data = layer_list - self.layers._class_handle = ratapi.models.AbsorptionLayer - elif not self.absorption and handle == "AbsorptionLayer": - for layer in self.layers: - layer_params = layer.model_dump() - del layer_params["SLD_imaginary"] - layer_list.append(ratapi.models.Layer(**layer_params)) - self.layers.data = layer_list - self.layers._class_handle = ratapi.models.Layer - return self - - @model_validator(mode="after") - def update_renamed_models(self) -> "Project": - """When models defined in the ClassLists are renamed, we need to update that name elsewhere in the project.""" - for class_list, fields_to_update in model_names_used_in.items(): - old_names = self._all_names[class_list] - new_names = getattr(self, class_list).get_names() - if len(old_names) == len(new_names): - name_diff = [(old, new) for (old, new) in zip(old_names, new_names, strict=False) if old != new] - for old_name, new_name in name_diff: - for field in fields_to_update: - project_field = getattr(self, field.attribute) - all_matches = project_field.get_all_matches(old_name) - params = field.fields - for index, param in all_matches: - if param in params: - setattr(project_field[index], param, new_name) - return self - - @model_validator(mode="after") - def cross_check_model_values(self) -> "Project": - """Certain model fields should contain values defined elsewhere in the project.""" - values = ["value_1", "value_2", "value_3", "value_4", "value_5"] - for field in ["backgrounds", "resolutions"]: - self.check_allowed_source(field) - self.check_allowed_values( - field, - values, - getattr(self, f"{field[:-1]}_parameters").get_names(), - self._all_names[f"{field[:-1]}_parameters"], - ) - - self.check_allowed_values( - "layers", - ["thickness", "SLD", "SLD_real", "SLD_imaginary", "roughness"], - self.parameters.get_names(), - self._all_names["parameters"], - ) - - self.check_allowed_values("contrasts", ["data"], self.data.get_names(), self._all_names["data"]) - self.check_allowed_values( - "contrasts", ["background"], self.backgrounds.get_names(), self._all_names["backgrounds"] - ) - self.check_allowed_values("contrasts", ["bulk_in"], self.bulk_in.get_names(), self._all_names["bulk_in"]) - self.check_allowed_values("contrasts", ["bulk_out"], self.bulk_out.get_names(), self._all_names["bulk_out"]) - self.check_allowed_values( - "contrasts", ["scalefactor"], self.scalefactors.get_names(), self._all_names["scalefactors"] - ) - self.check_allowed_values( - "contrasts", ["resolution"], self.resolutions.get_names(), self._all_names["resolutions"] - ) - self.check_allowed_values( - "contrasts", ["domain_ratio"], self.domain_ratios.get_names(), self._all_names["domain_ratios"] - ) - - self.check_contrast_model_allowed_values( - "contrasts", - getattr(self, self._contrast_model_field).get_names(), - self._all_names[self._contrast_model_field], - self._contrast_model_field, - ) - self.check_contrast_model_allowed_values( - "domain_contrasts", self.layers.get_names(), self._all_names["layers"], "layers" - ) - return self - - @model_validator(mode="after") - def check_protected_parameters(self) -> "Project": - """Protected parameters should not be deleted. If this is attempted, raise an error.""" - for class_list in parameter_class_lists: - protected_parameters = [ - param.name for param in getattr(self, class_list) if isinstance(param, ratapi.models.ProtectedParameter) - ] - # All previously existing protected parameters should be present in new list - if not all(element in protected_parameters for element in self._protected_parameters[class_list]): - removed_params = [ - param for param in self._protected_parameters[class_list] if param not in protected_parameters - ] - raise ValueError(f"Can't delete the protected parameters: {', '.join(str(i) for i in removed_params)}") - self._protected_parameters = self.get_all_protected_parameters() - return self - - @model_validator(mode="after") - def update_names(self) -> "Project": - """Following validation, update the list of all parameter names.""" - self._all_names = self.get_all_names() - return self - - def __str__(self): - output = "" - for key, value in self.__dict__.items(): - if value: - output += f"{key.replace('_', ' ').title() + ': ':-<100}\n\n" - try: - output += value.value + "\n\n" # For enums - except AttributeError: - output += str(value) + "\n\n" - return output - - def get_all_names(self): - """Record the names of all models defined in the project.""" - return {class_list: getattr(self, class_list).get_names() for class_list in class_lists} - - def get_all_protected_parameters(self): - """Record the protected parameters defined in the project.""" - return { - class_list: [ - param.name for param in getattr(self, class_list) if isinstance(param, ratapi.models.ProtectedParameter) - ] - for class_list in parameter_class_lists - } - - def check_allowed_values( - self, attribute: str, field_list: list[str], allowed_values: list[str], previous_values: list[str] - ) -> None: - """Check the values of the given fields in the given model are in the supplied list of allowed values. - - Parameters - ---------- - attribute : str - The attribute of Project being validated. - field_list : list [str] - The fields of the attribute to be checked for valid values. - allowed_values : list [str] - The list of allowed values for the fields given in field_list. - previous_values : list [str] - The list of allowed values for the fields given in field_list after the previous validation. - - Raises - ------ - ValueError - Raised if any field in field_list has a value not specified in allowed_values. - - """ - class_list = getattr(self, attribute) - for index, model in enumerate(class_list): - for field in field_list: - value = getattr(model, field, "") - if value and value not in allowed_values: - if value in previous_values: - raise ValueError( - f'The value "{value}" used in the "{field}" field of {attribute}[{index}] must be defined ' - f'in "{values_defined_in[f"{attribute}.{field}"]}". Please remove "{value}" from ' - f'"{attribute}[{index}].{field}" before attempting to delete it.', - ) - else: - raise ValueError( - f'The value "{value}" used in the "{field}" field of {attribute}[{index}] must be defined ' - f'in "{values_defined_in[f"{attribute}.{field}"]}". Please add "{value}" to ' - f'"{values_defined_in[f"{attribute}.{field}"]}" before including it in "{attribute}".', - ) - - def check_allowed_source(self, attribute: str) -> None: - """Check that the source of a background or resolution is defined in the relevant field for its type. - - - A constant background or resolution source should be defined in - `background_parameters` or `resolution_parameters` respectively; - - A data background source should be defined in `data` - - A function background source should be defined in `custom_files` - - Parameters - ---------- - attribute : str - The attribute of Project being validated. - - Raises - ------ - ValueError - Raised if any field in field_list has a value not specified in allowed_constants or allowed_data as - appropriate. - - """ - class_list = getattr(self, attribute) - for index, model in enumerate(class_list): - if model.type == TypeOptions.Constant: - allowed_values = getattr(self, f"{attribute[:-1]}_parameters").get_names() - previous_values = self._all_names[f"{attribute[:-1]}_parameters"] - elif model.type == TypeOptions.Data: - allowed_values = self.data.get_names() - previous_values = self._all_names["data"] - else: - allowed_values = self.custom_files.get_names() - previous_values = self._all_names["custom_files"] - - if (value := model.source) != "" and value not in allowed_values: - if value in previous_values: - raise ValueError( - f'The value "{value}" used in the "source" field of {attribute}[{index}] must be defined in ' - f'"{values_defined_in[f"{attribute}.{model.type}.source"]}". Please remove "{value}" from ' - f'"{attribute}[{index}].source" before attempting to delete it.', - ) - else: - raise ValueError( - f'The value "{value}" used in the "source" field of {attribute}[{index}] must be defined in ' - f'"{values_defined_in[f"{attribute}.{model.type}.source"]}". Please add "{value}" to ' - f'"{values_defined_in[f"{attribute}.{model.type}.source"]}" before including it in ' - f'"{attribute}".', - ) - - def check_contrast_model_allowed_values( - self, - contrast_attribute: str, - allowed_values: list[str], - previous_values: list[str], - allowed_field: str, - ) -> None: - """Ensure the contents of the ``model`` for a contrast or domain contrast exist in the required project fields. - - Parameters - ---------- - contrast_attribute : str - The specific contrast attribute of Project being validated (either "contrasts" or "domain_contrasts"). - allowed_values : list [str] - The list of allowed values for the model of the contrast_attribute. - previous_values : list [str] - The list of allowed values for the model of the contrast_attribute after the previous validation. - allowed_field : str - The name of the field in the project in which the allowed_values are defined. - - Raises - ------ - ValueError - Raised if any model in contrast_attribute has a value not specified in allowed_values. - - """ - class_list = getattr(self, contrast_attribute) - for index, contrast in enumerate(class_list): - if (model_values := contrast.model) and (missing_values := list(set(model_values) - set(allowed_values))): - if all(value in previous_values for value in model_values): - raise ValueError( - f"The value{'s' if len(missing_values) > 1 else ''}: " - f'"{", ".join(str(i) for i in missing_values)}" used in the "model" field of ' - f'{contrast_attribute}[{index}] must be defined in "{allowed_field}". Please remove all ' - f'unnecessary values from "model" before attempting to delete them.', - ) - else: - raise ValueError( - f"The value{'s' if len(missing_values) > 1 else ''}: " - f'"{", ".join(str(i) for i in missing_values)}" used in the "model" field of ' - f'{contrast_attribute}[{index}] must be defined in "{allowed_field}". Please add all ' - f'required values to "{allowed_field}" before including them in "{contrast_attribute}".', - ) - - def get_contrast_model_field(self): - """Get the field used to define the contents of the "model" field in contrasts. - - Returns - ------- - model_field : str - The name of the field used to define the contrasts' model field. - - """ - if self.model == LayerModels.StandardLayers: - if self.calculation == Calculations.Domains: - model_field = "domain_contrasts" - else: - model_field = "layers" - else: - model_field = "custom_files" - return model_field - - def set_prior_visibility(self, priors_visible: bool): - """Set whether priors are visible or invisible for all parameters. - - Parameters - ---------- - priors_visible : bool - Whether priors should be shown. - - """ - for classlist_name in parameter_class_lists: - classlist = getattr(self, classlist_name) - for i in range(0, len(classlist)): - classlist[i].show_priors = priors_visible - - def show_priors(self): - """Show priors for all parameters in the model.""" - # convenience function from set_prior_visibility - self.set_prior_visibility(True) - - def hide_priors(self): - """Hide priors for all parameters in the model.""" - # convenience function from set_prior_visibility - self.set_prior_visibility(False) - - def write_script(self, obj_name: str = "problem", script: str = "project_script.py"): - """Write a python script that can be run to reproduce this project object. - - Parameters - ---------- - obj_name : str, optional - The name given to the project object under construction (default is "problem"). - script : str, optional - The filepath of the generated script (default is "project_script.py"). - - """ - # Need to ensure correct format for script name - script_path = Path(script) - if script_path.suffix == "": - script_path = script_path.with_suffix(".py") - elif script_path.suffix != ".py": - raise ValueError('The script name provided to "write_script" must use the ".py" format') - - def write_item(item): - """Write a model item as a string of a dictionary.""" - if isinstance(item, ratapi.models.Data): - item_str = "{" + f"'name': '{item.name}'," - if not np.any(item.data): # if array is empty, e.g. in simulation data - item_str += "'data': empty([0, 3]), " - else: - item_str += f"'data': {repr(item.data)}, " - if len(item.data_range) != 0: - item_str += f"'data_range': {item.data_range}, " - if len(item.simulation_range) != 0: - item_str += f"'simulation_range': {item.simulation_range}" - item_str += "}" - return item_str - - if isinstance(item, ratapi.models.CustomFile): - # convert file paths to strings because pathlib gets too specific - item_str = ( - "{" - + f"'name': '{item.name}', " - + f"'filename': '{item.filename}', " - + f"'function_name': '{item.function_name}', " - + f"'language': '{str(item.language)}', " - # Raw string to ensure backslash is not interpreted as escape - + f"'path': r'{str(try_relative_to(item.path, script_path.parent))}'" - + "}" - ) - return item_str - # converting a dict to a string doesn't automatically convert StrEnums to str :( - return str({key: str(value) if isinstance(value, Enum) else value for key, value in dict(item).items()}) - - def classlist_script(name, classlist): - """Write a classlist as a script.""" - return f"{name}=[\n " + "\n ".join([write_item(item) + "," for item in classlist.data]) + "]," - - script_path.write_text( - f"""# THIS FILE IS GENERATED FROM RAT VIA THE "WRITE_SCRIPT" ROUTINE. IT IS NOT PART OF THE RAT CODE. - -import ratapi -from numpy import array, empty, inf - -{obj_name} = ratapi.Project( - name="{self.name}", - calculation="{self.calculation}", - model="{self.model}", - geometry="{self.geometry}", - absorption="{self.absorption}", -""" - + indent( - "\n".join([classlist_script(class_list, getattr(self, class_list)) for class_list in class_lists]), - " " * 4, - ) - + "\n)" - ) - - def save(self, filepath: str | Path = "./project.json"): - """Save a project to a JSON file. - - Parameters - ---------- - filepath : str or Path - The path to where the project file will be written. - """ - filepath = Path(filepath).with_suffix(".json") - - json_dict = {} - for field in self.model_fields: - attr = getattr(self, field) - - if field == "data": - - def make_data_dict(item): - return { - "name": item.name, - "data": item.data.tolist(), - "data_range": item.data_range, - "simulation_range": item.simulation_range, - } - - json_dict["data"] = [make_data_dict(data) for data in attr] - - elif field == "custom_files": - - def make_custom_file_dict(item): - file_dict = { - "name": item.name, - "filename": item.filename, - "language": item.language, - "path": try_relative_to(item.path, filepath.parent), - } - if item.name != item.function_name: - file_dict["function_name"] = item.function_name - - return file_dict - - json_dict["custom_files"] = [make_custom_file_dict(file) for file in attr] - - elif isinstance(attr, ClassList): - json_dict[field] = [item.model_dump() for item in attr] - else: - json_dict[field] = attr - - filepath.write_text(json.dumps(json_dict)) - - @classmethod - def load(cls, path: str | Path) -> "Project": - """Load a project from file. - - Parameters - ---------- - path : str or Path - The path to the project file. - - """ - path = Path(path) - input_data = path.read_text() - model_dict = json.loads(input_data) - for dataset in model_dict["data"]: - if dataset["name"] == "Simulation": - dataset["data"] = np.empty([0, 3]) - del dataset["data_range"] - else: - data = dataset["data"] - dataset["data"] = np.array(data) - - # file paths are saved as relative to the project directory - for file in model_dict["custom_files"]: - if not Path(file["path"]).is_absolute(): - file["path"] = Path(path.parent, file["path"]).resolve() - - return cls.model_validate(model_dict) - - def _classlist_wrapper(self, class_list: ClassList, func: Callable): - """Define the function used to wrap around ClassList routines to force revalidation. - - Parameters - ---------- - class_list : ClassList - The ClassList defined in the "Project" model that is being modified. - func : Callable - The routine being wrapped. - - Returns - ------- - wrapped_func : Callable - The wrapped routine. - - """ - - @functools.wraps(func) - def wrapped_func(*args, **kwargs): - """Run the given function and then revalidate the "Project" model. - - If any exception is raised, restore the previous state of the given ClassList - and report details of the exception. - - """ - previous_state = copy.deepcopy(class_list.data) - return_value = None - try: - return_value = func(*args, **kwargs) - Project.model_validate(self) - except ValidationError as exc: - class_list.data = previous_state - custom_error_list = custom_pydantic_validation_error(exc.errors(include_url=False)) - raise ValidationError.from_exception_data(exc.title, custom_error_list, hide_input=True) from None - except (TypeError, ValueError): - class_list.data = previous_state - raise - finally: - del previous_state - return return_value - - return wrapped_func - - -def try_relative_to(path: Path, relative_to: Path) -> str: - """Attempt to create a relative path and warn the user if it isn't possible. - - Parameters - ---------- - path : Path - The path to try to find a relative path for. - relative_to: Path - The path to which we find a relative path for ``path``. - - Returns - ------- - str - The relative path if successful, else the absolute path. - - """ - path = Path(path) - relative_to = Path(relative_to) - if not path.is_absolute(): - return str(path) - elif path.is_relative_to(relative_to): - return str(path.relative_to(relative_to)) - else: - warnings.warn( - "Could not write custom file path as relative to the project directory, " - "which means that it may not work on other devices. If you would like to share your project, " - "make sure your custom files are in a subfolder of the project save location.", - stacklevel=2, - ) - return str(path.resolve()) diff --git a/ratapi/run.py b/ratapi/run.py deleted file mode 100644 index d973d068..00000000 --- a/ratapi/run.py +++ /dev/null @@ -1,140 +0,0 @@ -"""The function used to run a RAT algorithm for a given project and controls.""" - -import time - -from tqdm.auto import tqdm - -import ratapi.rat_core -from ratapi.inputs import make_input -from ratapi.outputs import make_results -from ratapi.utils.enums import Display - - -class ProgressBar: - """Create a progress bar that gets updates from the progress event during a calculation. - - Parameters - ---------- - display : bool, default True - Indicates if displaying is allowed - - """ - - def __init__(self, display=True): - self.pbar = None - self.display = display - self.tqdm_kwargs = {"total": 100, "desc": "", "bar_format": "{l_bar}{bar}", "disable": not self.display} - # Determine if the auto tqdm is standard or notebook - from tqdm.asyncio import tqdm as asyncio_tqdm - - if tqdm == asyncio_tqdm: - self.tqdm_kwargs.update({"ncols": 90}) - - def __enter__(self): - if self.display: - ratapi.events.register(ratapi.events.EventTypes.Progress, self.updateProgress) - - return self - - def updateProgress(self, event): - """Update the progress bar with progress event data. - - Parameters - ---------- - event: ProgressEventData - The progress event data. - - """ - if self.pbar is None: - self.pbar = tqdm(**self.tqdm_kwargs) - value = event.percent * 100 - self.pbar.desc = event.message - self.pbar.update(value - self.pbar.n) - - def __exit__(self, _exc_type, _exc_val, _traceback): - if self.pbar is not None: - self.pbar.close() - print("") # Print new line after bar - - if self.display: - ratapi.events.clear(ratapi.events.EventTypes.Progress, self.updateProgress) - - -class TextOutput: - """Context manager to pipe message events to stdout. - - Parameters - ---------- - display : bool, default: True - Indicates if displaying is allowed - - """ - - def __init__(self, display=True): - self.display = display - - def __enter__(self): - if self.display: - ratapi.events.register(ratapi.events.EventTypes.Message, self.printMessage) - - return self - - def printMessage(self, msg): - """Print an event message. - - Parameters - ---------- - msg: str - The event message. - - """ - print(msg, end="") - - def __exit__(self, _exc_type, _exc_val, _traceback): - if self.display: - ratapi.events.clear(ratapi.events.EventTypes.Message, self.printMessage) - - -def run(project, controls): - """Run RAT for the given project and controls inputs.""" - parameter_field = { - "parameters": "params", - "bulk_in": "bulkIns", - "bulk_out": "bulkOuts", - "scalefactors": "scalefactors", - "domain_ratios": "domainRatios", - "background_parameters": "backgroundParams", - "resolution_parameters": "resolutionParams", - } - - horizontal_line = "\u2500" * 107 + "\n" - display_on = controls.display != Display.Off - problem_definition, cpp_controls = make_input(project, controls) - - if display_on: - print("Starting RAT " + horizontal_line) - - start = time.time() - with ProgressBar(display=display_on), TextOutput(display=display_on): - problem_definition, output_results, bayes_results = ratapi.rat_core.RATMain( - problem_definition, - cpp_controls, - ) - end = time.time() - - if display_on: - print(f"Elapsed time is {end - start:.3f} seconds\n") - - results = make_results(controls.procedure, output_results, bayes_results) - - # Update parameter values in project - for class_list in ratapi.project.parameter_class_lists: - for index, value in enumerate(getattr(problem_definition, parameter_field[class_list])): - getattr(project, class_list)[index].value = value - - controls.delete_IPC() - - if display_on: - print("Finished RAT " + horizontal_line) - - return project, results diff --git a/ratapi/utils/__init__.py b/ratapi/utils/__init__.py deleted file mode 100644 index 56b312d4..00000000 --- a/ratapi/utils/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Additional utilities for ratapi.""" diff --git a/ratapi/utils/convert.py b/ratapi/utils/convert.py deleted file mode 100644 index 7b3a44f7..00000000 --- a/ratapi/utils/convert.py +++ /dev/null @@ -1,570 +0,0 @@ -"""Utilities for converting input files to Python `Project`s.""" - -import warnings -from collections.abc import Iterable -from os import PathLike -from pathlib import Path - -from numpy import array, empty, ndarray -from scipy.io.matlab import MatlabOpaque, loadmat - -from ratapi import Project, wrappers -from ratapi.classlist import ClassList -from ratapi.models import Background, Contrast, CustomFile, Data, Layer, Parameter, Resolution -from ratapi.utils.enums import Geometries, Languages, LayerModels - - -def r1_to_project(filename: str | PathLike) -> Project: - """Read a RasCAL1 project struct as a Python `Project`. - - Parameters - ---------- - filename : str, PathLike - The path to a .mat file containing project data. - - Returns - ------- - Project - A RAT `Project` equivalent to the RasCAL1 project struct. - - """ - mat_project = loadmat(str(filename), simplify_cells=True)["problem"] - - mat_module = mat_project["module"] - if mat_module["experiment_type"] == "Air / Liquid (or solid)": - geom = Geometries.AirSubstrate - else: - geom = Geometries.SubstrateLiquid - - # R1 uses a different name for custom xy layer model - layer_model = mat_module["type"] - if layer_model.lower() == "custom xy profile": - layer_model = LayerModels.CustomXY - layer_model = LayerModels(layer_model) - - def zip_if_several(*params) -> tuple | list[tuple]: - """Zips parameters if necessary, but can handle single-item parameters. - - Examples - -------- - zip_if_several([1, 2], [3, 4]) = [(1, 3), (2, 4)] - zip_if_several(1, 2, 3) = [(1, 2, 3)] - - Parameters - ---------- - *params - Any number of parameters. - - Returns - ------- - tuple or list of tuple - If any parameter is a single item, returns a list just containing the tuple of parameters. - Otherwise, returns the same as zip(*params). - - """ - if all(isinstance(param, Iterable) and not isinstance(param, str) for param in params): - return zip(*params, strict=False) - return [params] - - def read_param(names, constrs, values, fits): - """Read in a parameter list from the relevant keys, and fix constraints for non-fit parameters. - - Parameters - ---------- - names, constrs, values, fits : str - The keys for names, constraints, values - and whether to fit for a type of parameter. - - Returns - ------- - ClassList - A list of all relevant parameters. - - """ - - def fix_invalid_constraints(name: str, constrs: tuple[float, float], value: float) -> tuple[float, float]: - """Check that constraints are valid and fix them if they aren't. - - RasCAL-1 allowed the constraints of non-fit parameters to be invalid, which means - we need to fix them here so that the project is valid. - - Parameters - ---------- - name: str - The name of the parameter. - constrs : tuple[float, float] - The constraints of the parameter (min and max, respectively) - value : float - The value of the parameter. - - Returns - ------- - tuple[float, float] - The adjusted constraints (identical to constrs if constraints were valid) - - """ - new_constrs = (min(constrs[0], value), max(constrs[1], value)) - if new_constrs[0] != constrs[0] or new_constrs[1] != constrs[1]: - warnings.warn( - f"The parameter {name} has invalid constraints," - " these have been adjusted to satisfy the current value of the parameter.", - stacklevel=2, - ) - return new_constrs - - # adjust invalid constraints - # if just one item in the classlist, these objects won't be in lists - if not isinstance(fit := mat_project[fits], Iterable): - if not fit: - mat_project[constrs] = fix_invalid_constraints( - mat_project[names], mat_project[constrs], mat_project[values] - ) - # else they will be iterable - else: - for i, fit in enumerate(mat_project[fits]): - if not fit: - mat_project[constrs][i] = fix_invalid_constraints( - mat_project[names][i], mat_project[constrs][i], mat_project[values][i] - ) - - return ClassList( - [ - Parameter( - name=name, - min=constr[0], - value=val, - max=constr[1], - fit=fitbool, - ) - for name, constr, val, fitbool in zip_if_several( - mat_project[names], - mat_project[constrs], - mat_project[values], - mat_project[fits], - ) - ] - ) - - # we add these as new attributes of the mat project dict so we can feed them into read_param better - if mat_project["numberOfBacks"] == 1: - mat_project["back_param_names"] = "Background parameter 1" - else: - mat_project["back_param_names"] = [ - f"Background parameter {i}" for i in range(1, mat_project["numberOfBacks"] + 1) - ] - - # sometimes numberOfResolutions isn't defined: in all these cases there's only one resolution - # maybe from before multiple resolutions were possible? - if getattr(mat_project, "numberOfResolutions", 1) == 1: - mat_project["res_param_names"] = "Resolution parameter 1" - else: - mat_project["res_param_names"] = [ - f"Resolution parameter {i}" for i in range(1, mat_project["numberOfBacks"] + 1) - ] - - params = read_param("paramnames", "constr", "params", "fityesno") - back_params = read_param("back_param_names", "backs_constr", "backs", "backgrounds_fityesno") - res_params = read_param("res_param_names", "resolution_constr", "resolution", "resolution_fityesno") - bulk_ins = read_param("nbaNames", "nbairs_constr", "nba", "nbairs_fityesno") - bulk_outs = read_param("nbsNames", "nbsubs_constr", "nbs", "nbsubs_fityesno") - scale_facs = read_param("scalesNames", "scale_constr", "scalefac", "scalefac_fityesno") - - # if just one background, backsNames and back_param_names are strings; fix that here - # and mutatis mutandis for resolution - if isinstance(mat_project["back_param_names"], str): - mat_project["back_param_names"] = [mat_project["back_param_names"]] - if isinstance(mat_project["backsNames"], str): - mat_project["backsNames"] = [mat_project["backsNames"]] - if isinstance(mat_project["res_param_names"], str): - mat_project["res_param_names"] = [mat_project["res_param_names"]] - if isinstance(mat_project["resolNames"], str): - mat_project["resolNames"] = [mat_project["resolNames"]] - - # create backgrounds and resolutions from parameters - backs = ClassList( - [ - Background(name=back_name, type="constant", source=mat_project["back_param_names"][i]) - for i, back_name in enumerate(mat_project["backsNames"]) - ] - ) - res = ClassList( - [ - Resolution(name=res_name, type="constant", source=mat_project["res_param_names"][i]) - for i, res_name in enumerate(mat_project["resolNames"]) - ] - ) - - data = ClassList( - [ - Data( - name=Path(name).stem, - data=data, - data_range=data_range, - simulation_range=sim_range, - ) - for name, data, data_range, sim_range in zip_if_several( - mat_project["contrastFiles"], - mat_project["data"], - mat_project["dataLimits"], - mat_project["simLimits"], - ) - ] - ) - - # contrast names may be java strings (unsure why, maybe GUI input?): convert to Python str - # the java string is presented in Python as a MatlabOpaque object in a 1-item array (hence index [0]) - # which are given as a 1-item array with 4 entries. the fourth is the actual data (index [3]), - # which is given as the byte data of a Java string; this consists of 7 metadata bytes (ignored) - # and then the actual string characters (index [7:]) in ascii format (.decode("ascii")) - if len(mat_project["contrastNames"]) == 1 and isinstance(mat_project["contrastNames"], MatlabOpaque): - mat_project["contrastNames"] = bytes(mat_project["contrastNames"][0][3][7:]).decode("ascii") - else: - for i, contrast_name in enumerate(mat_project["contrastNames"]): - if isinstance(contrast_name, MatlabOpaque): - mat_project["contrastNames"][i] = bytes(contrast_name[0][3][7:]).decode("ascii") - - # if just one contrast, resolNames is a string; fix that here - if isinstance(mat_project["resolNames"], str): - mat_project["resolNames"] = [mat_project["resolNames"]] - - if isinstance(mat_project["contrastNames"], (ndarray, list)) and len( - dict.fromkeys(mat_project["contrastNames"]) - ) != len(mat_project["contrastNames"]): - # contrast names are not unique so create unique ones - mat_project["contrastNames"] = [f"Contrast {i + 1}" for i in range(len(mat_project["contrastNames"]))] - - contrasts = ClassList( - [ - Contrast( - name=name, - background=backs[int(back) - 1].name, - resolution=mat_project["resolNames"][int(res) - 1], - scalefactor=scale_facs[int(scale) - 1].name, - bulk_in=bulk_ins[int(bulk_in) - 1].name, - bulk_out=bulk_outs[int(bulk_out) - 1].name, - data=data[i].name, - ) - for i, (name, back, res, scale, bulk_in, bulk_out) in enumerate( - zip_if_several( - mat_project["contrastNames"], - mat_project["contrastBacks"], - mat_project["contrastResolutions"], - mat_project["contrastScales"], - mat_project["contrastNbas"], - mat_project["contrastNbss"], - ) - ) - ] - ) - - # set model for each contrast and add custom files - if layer_model == LayerModels.StandardLayers: - custom_file = ClassList() - layers = ClassList( - [ - Layer( - name=name, - thickness=params[int(thickness) - 1].name, - SLD=params[int(sld) - 1].name, - roughness=params[int(roughness) - 1].name, - # if hydration is not set, it is an empty numpy array, else it is a string representing a number - hydration=params[int(hydration) - 1].name if getattr(hydration, "size", 1) > 0 else "", - hydrate_with=hydrate_with, - ) - # R1 layers are 6-item arrays, unpack into a Layer object - for thickness, sld, roughness, hydration, name, hydrate_with in mat_project["layersDetails"] - ] - ) - - for i, contrast in enumerate(contrasts): - # if there is only one layer, contrastsNumberOfLayers is an int; otherwise it is a list - if ( - isinstance(mat_project["contrastsNumberOfLayers"], int) - and mat_project["contrastsNumberOfLayers"] == 0 - or isinstance(mat_project["contrastsNumberOfLayers"], list) - and mat_project["contrastsNumberOfLayers"][i] == 0 - ): - continue - # contrastLayers is not an array, but rather a string with commas between entries - contrast_layers = mat_project["contrastLayers"][i].split(",") - contrast_layers = [ - int(x) - 1 for x in contrast_layers if x != "" - ] # remove empty string from hanging commas - contrast.model = [layers[i].name for i in contrast_layers] - - else: - custom_filepath = mat_module["name"] - if Path(custom_filepath).suffix != ".m": - custom_filepath += ".m" - model_name = Path(custom_filepath).stem - # Assume the custom file is in the same directory as the mat file - custom_file = ClassList( - [ - CustomFile( - name=model_name, filename=custom_filepath, language=Languages.Matlab, path=Path(filename).parent - ) - ] - ) - layers = ClassList() - for contrast in contrasts: - contrast.model = [model_name] - - project = Project( - name=mat_project.get("name", ""), - model=layer_model, - geometry=geom, - parameters=params, - backgrounds=backs, - background_parameters=back_params, - resolutions=res, - resolution_parameters=res_params, - bulk_in=bulk_ins, - bulk_out=bulk_outs, - scalefactors=scale_facs, - data=data, - layers=layers, - contrasts=contrasts, - custom_files=custom_file, - ) - - return project - - -def project_to_r1( - project: Project, filename: str | PathLike = "RAT_project", return_struct: bool = False -) -> dict | None: - """Convert a RAT Project to a RasCAL1 project struct. - - Parameters - ---------- - project : Project - The RAT Project to convert. - filename : str or PathLike, default "RAT_project" - If given, saves as a .mat file with the given filename. - return_struct : bool, default False - If True, do not save and instead return the R1 struct. - - Returns - ------- - dict or None - If `return_struct` is True, return the r1 struct. Else, return nothing. - - """ - - def convert_parameters( - params: ClassList[Parameter], name: str, value: str, constr: str, fit: str, number: str = "" - ): - """Convert a list of parameters to r1 data fields. - - Parameters - ---------- - params: ClassList - A list of parameter type from the Project. - name, constr, value, fit : str - The keys for names, constraints, values - and whether to fit for a type of parameter. - number : str, optional, default "" - Key for the length of the parameter list if not blank. - - Returns - ------- - dict - A dict of the relevant struct fields. - - """ - output = { - name: [p.name for p in params], - value: [p.value for p in params], - constr: [[p.min, p.max] for p in params], - fit: [int(p.fit) for p in params], - } - if number: - output[number] = len(params) - - return output - - # translate RAT geometries into R1 experiment types - r1_geoms_dict = {Geometries.AirSubstrate: "Air / Liquid (or solid)", Geometries.SubstrateLiquid: "Solid / Liquid"} - - r1 = { - # set name, type, experiment type - "name": project.name, - "module": { - "type": str(project.model), - "experiment_type": r1_geoms_dict[project.geometry], - }, - } - # parameter names, values, constraints, fits - r1.update( - convert_parameters( - project.parameters, - "paramnames", - "params", - "constr", - "fityesno", - ) - ) - # scalefactors names, values, constraints, fit, and number - r1.update( - convert_parameters( - project.scalefactors, - "scalesNames", - "scalefac", - "scale_constr", - "scalefac_fityesno", - "numberOfScales", - ) - ) - # bulk in names, values, constraints, fit, and number - r1.update( - convert_parameters( - project.bulk_in, - "nbaNames", - "nba", - "nbairs_constr", - "nbairs_fityesno", - "numberOfNbas", - ) - ) - # bulk out names, values, constraints, fit, and number - r1.update( - convert_parameters( - project.bulk_out, - "nbsNames", - "nbs", - "nbsubs_constr", - "nbsubs_fityesno", - "numberOfNbss", - ) - ) - - shifts = { - "numberOfShifts": 1, - "shiftsNames": "Shift 1", - "shifts_horisontal": 0, - "shifts_fityesno": 0, - "shifts_constr": [-1e-4, 1e-4], - } - r1.update(shifts) - - resolutions = { - "resolNames": [r.name for r in project.resolutions], - "resolution": [project.resolution_parameters[r.source].value for r in project.resolutions], - "resolution_constr": [ - [project.resolution_parameters[r.source].min, project.resolution_parameters[r.source].max] - for r in project.resolutions - ], - "resolution_fityesno": [int(project.resolution_parameters[r.source].fit) for r in project.resolutions], - "numberOfResolutions": len(project.resolutions), - } - r1.update(resolutions) - - backgrounds = { - "backsNames": [b.name for b in project.backgrounds], - "backs": [project.background_parameters[b.source].value for b in project.backgrounds], - "backs_constr": [ - [project.background_parameters[b.source].min, project.background_parameters[b.source].max] - for b in project.backgrounds - ], - "backgrounds_fityesno": [int(project.background_parameters[b.source].fit) for b in project.backgrounds], - "numberOfBacks": len(project.backgrounds), - } - r1.update(backgrounds) - - if project.model == LayerModels.StandardLayers: - layer_info = { - "numberOfLayers": len(project.layers), - "layersDetails": [ - [ - project.parameters.index(layer.thickness, True), - project.parameters.index(layer.SLD, True), - project.parameters.index(layer.roughness, True), - project.parameters.index(layer.hydration, True) if layer.hydration else empty(shape=(0, 0)), - layer.name, - str(layer.hydrate_with), - ] - for layer in project.layers - ], - } - r1["module"]["name"] = "" - else: - layer_info = {"numberOfLayers": 0, "layersDetails": []} - # note R1 only supports one custom file! - r1["module"]["name"] = project.custom_files[0].name - r1.update(layer_info) - - contrasts = { - "contrastNames": [c.name for c in project.contrasts], - "contrastNbas": [project.bulk_in.index(c.bulk_in, True) for c in project.contrasts], - "contrastNbss": [project.bulk_out.index(c.bulk_out, True) for c in project.contrasts], - "contrastScales": [project.scalefactors.index(c.scalefactor, True) for c in project.contrasts], - "data": [project.data[c.data].data for c in project.contrasts], - "simLimits": [project.data[c.data].simulation_range for c in project.contrasts], - "dataLimits": [project.data[c.data].data_range for c in project.contrasts], - "fitlowrange": [project.data[c.data].data_range[0] for c in project.contrasts], - "fithirange": [project.data[c.data].data_range[1] for c in project.contrasts], - "contrastRepeatSLDs": [[0, 1] for _ in project.contrasts], - "contrastFiles": [project.data[c.data].name for c in project.contrasts], - # some of the data is a bit complex for a (readable) list comp; create empty lists and append below - "contrastResolutions": [], - "contrastBacks": [], - "dataPresent": [], - "include_data": [], - "dataTypes": [], - "contrastLayers": [], - "contrastsNumberOfLayers": [], - } - for contrast in project.contrasts: - # R1 stores contrast resolutions and background by the index of the relevant parameter - resolution = project.resolutions[contrast.resolution] - contrasts["contrastResolutions"].append(project.resolution_parameters.index(resolution.source, True)) - - background = project.backgrounds[contrast.background] - contrasts["contrastBacks"].append(project.background_parameters.index(background.source, True)) - - data = project.data[contrast.data] - if "simulation" in data.name: - contrasts["dataPresent"].append(0) - contrasts["include_data"].append(0) - contrasts["dataTypes"].append("Simulation") - else: - contrasts["dataPresent"].append(1) - contrasts["include_data"].append(1) - contrasts["dataTypes"].append("Ascii File") - - if project.model == LayerModels.StandardLayers: - model = contrast.model - contrasts["contrastsNumberOfLayers"].append(len(model)) - contrasts["contrastLayers"].append(",".join(str(project.layers.index(layer) + 1) for layer in model)) - else: - contrasts["contrastsNumberOfLayers"].append(0) - contrasts["contrastLayers"].append("") - - r1.update(contrasts) - - # some final processing: - # .mat files just contain the item for any single-item list, so process and fix that - # also, `savemat` will only write cells instead of matrices for object-type ndarrays. convert lists to those - for key, value in r1.items(): - if isinstance(value, list): - if len(value) == 1: - r1[key] = value[0] - else: - if not all(isinstance(x, type(r1[key][0])) for x in r1[key]): - r1[key] = array(value, dtype="object") - - if return_struct: - return r1 - - if Path(filename).suffix != ".mat": - filename += ".mat" - # scipy.io.savemat doesn't do cells properly: - # https://github.com/scipy/scipy/issues/3756 - # rather than fiddling we just use matlab - loader = wrappers.MatlabWrapper.loader - if loader is None: - raise ImportError("matlabengine is not installed.") - eng = loader.result() - eng.workspace["problem"] = r1 - eng.save(str(filename), "problem", nargout=0) - return None diff --git a/ratapi/utils/custom_errors.py b/ratapi/utils/custom_errors.py deleted file mode 100644 index 83bf084f..00000000 --- a/ratapi/utils/custom_errors.py +++ /dev/null @@ -1,40 +0,0 @@ -"""Defines routines for custom error handling in RAT.""" - -import pydantic_core - - -def custom_pydantic_validation_error( - error_list: list[pydantic_core.ErrorDetails], - custom_error_msgs: dict[str, str] | None = None, -) -> list[pydantic_core.ErrorDetails]: - """Give Pydantic errors a better custom message with extraneous information removed. - - We substitute the standard error for a PydanticCustomError for a given set of error types. - For errors that do not have a custom error message defined, - we redefine them using a PydanticCustomError to remove the url from the error message. - - Parameters - ---------- - error_list : list[pydantic_core.ErrorDetails] - A list of errors produced by pydantic.ValidationError.errors(). - custom_error_msgs: dict[str, str], optional - A dict of custom error messages for given error types. - - Returns - ------- - new_error : list[pydantic_core.ErrorDetails] - A list of errors including PydanticCustomErrors in place of the error types in custom_errors. - - """ - if custom_error_msgs is None: - custom_error_msgs = {} - custom_error_list = [] - for error in error_list: - if error["type"] in custom_error_msgs: - custom_error = pydantic_core.PydanticCustomError(error["type"], custom_error_msgs[error["type"]]) - else: - custom_error = pydantic_core.PydanticCustomError(error["type"], error["msg"]) - error["type"] = custom_error - custom_error_list.append(error) - - return custom_error_list diff --git a/ratapi/utils/enums.py b/ratapi/utils/enums.py deleted file mode 100644 index 313f04c7..00000000 --- a/ratapi/utils/enums.py +++ /dev/null @@ -1,204 +0,0 @@ -"""The Enum values used in the parameters of various ratapi classes and functions.""" - -try: - from enum import StrEnum -except ImportError: - from strenum import StrEnum - - -class RATEnum(StrEnum): - """A subclass of StrEnum with some adjustments for variable spellings.""" - - @classmethod - def _missing_(cls, value: str): - value = value.lower() - - # Replace common alternative spellings - value = value.replace("-", " ").replace("_", " ").replace("++", "pp").replace("polarized", "polarised") - - for member in cls: - if member.value.lower() == value: - return member - return None - - -# Controls -class Procedures(RATEnum): - """The available options for procedures.""" - - Calculate = "calculate" - """Run an Abelès reflectivity calculation and calculate chi-squared to the data.""" - - Simplex = "simplex" - """Run a Nelder-Mead simplex optimisation over the fit parameters.""" - - DE = "de" - """Run a Differential Evolution optimisation over the fit parameters.""" - - NS = "ns" - """Run Bayesian Nested Sampling over the fit parameters.""" - - DREAM = "dream" - """Run the Bayesian DREAM algorithm over the fit parameters.""" - - -class Parallel(RATEnum): - """The available options for parallelisation.""" - - Single = "single" - """Do not parallelise.""" - - Points = "points" - """Split all contrasts into groups of points, and assign a process to each group.""" - - Contrasts = "contrasts" - """Assign one process to each contrast.""" - - -class Display(RATEnum): - """The available options for terminal output.""" - - Off = "off" - Iter = "iter" - Notify = "notify" - Final = "final" - - -class Strategies(RATEnum): - """The available strategies for generating base vectors in differential evolution.""" - - Random = "random" - """The base vector is random.""" - - LocalToBest = "local to best" - """The base vector is a combination of one randomly-selected local solution - and the best solution of the previous iteration.""" - - BestWithJitter = "best jitter" - """The base vector is the best solution of the previous iteration, with a small random perturbation applied.""" - - RandomWithPerVectorDither = "vector dither" - """The base vector is random, with a random scaling factor applied to each mutant. - This scaling factor is different for each mutant.""" - - RandomWithPerGenerationDither = "generation dither" - """The base vector is random, with a random scaling factor applied to each mutant. - This scaling factor is the same for every mutant, and randomised every generation.""" - - RandomEitherOrAlgorithm = "either or" - """The base vector is randomly chosen from either a pure random mutation, - or a pure recombination of parent parameter values.""" - - @classmethod - def _missing_(cls, value: int | str): - # legacy compatibility with strategies being 1-indexed ints under the hood - if isinstance(value, int): - if value < 1 or value > 6: - raise IndexError("Strategy indices must be between 1 and 6.") - return list(cls)[value - 1] - return super()._missing_(value) - - def __int__(self): - """Convert the DE strategy to its hardcoded index in the internal code. - - RAT core expects strategy to be an integer, as this is how it is given to - the internal DE algorithm. - """ - return list(Strategies).index(self) + 1 - - -class BoundHandling(RATEnum): - """The available options for bound handling in DREAM.""" - - Off = "off" - """Allow points to be sampled out of the parameter bounds.""" - - Reflect = "reflect" - """If a step passes a boundary, reflect it back across the boundary.""" - - Bound = "bound" - """If a step passes a boundary, set it equal to the nearest point on the boundary.""" - - Fold = "fold" - """Treat the boundary as periodic and ‘wrap the step around’ to the other side of the space.""" - - -# Models -class TypeOptions(RATEnum): - """The types of signal (``Background`` and ``Resolution``).""" - - Constant = "constant" - """A uniform constant signal given by a parameter.""" - - Data = "data" - """A signal for each q-value given by a dataset.""" - - Function = "function" - """A signal defined by a custom function.""" - - -class BackgroundActions(RATEnum): - """Ways that the background can be applied to the model.""" - - Add = "add" - Subtract = "subtract" - - -class Languages(RATEnum): - """Language options for custom files.""" - - Cpp = "cpp" - Python = "python" - Matlab = "matlab" - - -class Hydration(RATEnum): - """Options for the 'hydrate with' parameter of a Layer.""" - - BulkIn = "bulk in" - BulkOut = "bulk out" - - -class Priors(RATEnum): - """Prior distributions for parameters.""" - - Uniform = "uniform" - """A uniform distribution over the parameter range.""" - - Gaussian = "gaussian" - """A Gaussian distribution centred on the parameter value, - with shape defined by ``mu`` and ``sigma`` for the parameter.""" - - Jeffreys = "jeffreys" - """A Jeffreys' prior distribution over the parameter range.""" - - -# Project -class Calculations(RATEnum): - """Types of calculations that can be performed by RAT.""" - - Normal = "normal" - Domains = "domains" - - -class LayerModels(RATEnum): - """Types of layer model supported by RAT.""" - - CustomLayers = "custom layers" - """The layer model is given by a custom function.""" - - CustomXY = "custom xy" - """The continuous SLD of the layer model is given by a custom function.""" - - StandardLayers = "standard layers" - """The layer model is given by a list of ``Layer``s or ``DomainContrast``s.""" - - -class Geometries(RATEnum): - """Where the substrate roughness is placed.""" - - AirSubstrate = "air/substrate" - """The substrate roughness is placed at the end of the stack.""" - - SubstrateLiquid = "substrate/liquid" - """The substrate roughness is placed at the beginning of the stack.""" diff --git a/ratapi/utils/orso.py b/ratapi/utils/orso.py deleted file mode 100644 index 2d0345fc..00000000 --- a/ratapi/utils/orso.py +++ /dev/null @@ -1,247 +0,0 @@ -"""Readers from file formats.""" - -from dataclasses import dataclass -from itertools import count -from pathlib import Path -from textwrap import shorten - -import orsopy -import prettytable -from orsopy.fileio import load_orso - -from ratapi import ClassList -from ratapi.models import AbsorptionLayer, Data, Layer, Parameter - - -class ORSOProject: - """A class to encapsulate model information and data from an .ort file. - - Parameters - ---------- - filepath : str or Path - The path to the .ort file. - absorption : bool, default None - Whether to account for absorption in the model data. - - """ - - def __init__(self, filepath: str | Path, absorption: bool = False): - ort_data = load_orso(filepath) - datasets = [Data(name=dataset.info.data_source.sample.name, data=dataset.data) for dataset in ort_data] - # orso datasets in the same file can have repeated names! - # but classlists do not allow this - # use this dict to keep track of counts for repeated names - name_counts = {d.name: count(1) for d in datasets} - names = [d.name for d in datasets] - if len(names) > len(list(set(names))): - for i, data in enumerate(datasets): - if data.name in names[:i]: - data.name += f"-{next(name_counts[data.name])}" - self.data = ClassList(datasets) - self.samples = [ - orso_model_to_rat(dataset.info.data_source.sample.model, absorption=absorption) for dataset in ort_data - ] - - def __str__(self): - data_str = f"Data:\n{str(self.data)}\n\n" - if len(self.samples) == 1: - samples_str = f"Sample:\n{str(self.samples[0])}" - else: - table = prettytable.PrettyTable() - table.field_names = ["index", "bulk in", "bulk out", "parameters", "layers", "model"] - for index, sample in enumerate(self.samples): - if sample is None: - row = [index, "", "", "", "", ""] - else: - row = [ - index, - sample.bulk_in.name, - sample.bulk_out.name, - shorten(", ".join([p.name for p in sample.parameters]), width=20, placeholder="..."), - shorten(", ".join([layer.name for layer in sample.layers]), width=20, placeholder="..."), - shorten(str(sample.model), width=20, placeholder="..."), - ] - table.add_row(row) - samples_str = table.get_string() - - return data_str + samples_str - - -@dataclass -class ORSOSample: - """The stack data from an ORSO SampleModel, in RAT models.""" - - bulk_in: Parameter - bulk_out: Parameter - parameters: ClassList[Parameter] - layers: ClassList[Layer] | ClassList[AbsorptionLayer] - model: list[str] - - def __str__(self): - return ( - "Bulk in:\n" - f"{str(self.bulk_in)}\n\n" - "Bulk out:\n" - f"{str(self.bulk_out)}\n\n" - "Parameters:\n" - f"{str(self.parameters)}\n\n" - "Layers:\n" - f"{str(self.layers)}\n\n" - "Model:\n" - f"{self.model}" - ) - - -def orso_model_to_rat( - model: orsopy.fileio.model_language.SampleModel | str, absorption: bool = False -) -> ORSOSample | None: - """Get information from an ORSO SampleModel object. - - Parameters - ---------- - model : orsopy.fileio.model_language.SampleModel or str - The sample model to turn into a RAT data. If given as a string, - the string is interpreted as a layer stack in ORSO model language. - absorption : bool, default False - Whether to account for absorption in the model. - - Returns - ------- - ORSOSample - A dataclass containing the sample data, or None if the model is None. - - """ - if model is None: - return None - - if isinstance(model, str): - model = orsopy.fileio.model_language.SampleModel(stack=model) - - stack = model.resolve_to_layers() - # if bulk in or out is air, it has SLD predefined - # else we need to grab it from SLDDB - if bulk_in_sld := stack[0].material.sld is None: - bulk_in_sld = stack[0].material.get_sld() - - # resolve_to_layers loses the name of bulk in and out - bulk_in_name = model.stack.split("|")[0].strip() - bulk_in = Parameter( - name=f"{bulk_in_name} SLD", - min=bulk_in_sld.real, - value=bulk_in_sld.real, - max=bulk_in_sld.real, - fit=False, - ) - - if bulk_out_sld := stack[-1].material.sld is None: - bulk_out_sld = stack[-1].material.get_sld() - - bulk_out_name = model.stack.split("|")[-1].strip() - bulk_out = Parameter( - name=f"{bulk_out_name} SLD", - min=bulk_out_sld.real, - value=bulk_out_sld.real, - max=bulk_out_sld.real, - fit=False, - ) - - parameters = ClassList() - layers = ClassList() - contrast_model = [] - - for orso_layer in stack[1:-1]: - name = get_material_name(orso_layer.material, model) - contrast_model.append(name) - layer_params, layer = orso_layer_to_rat_layer(orso_layer, name, absorption) - parameters.union(layer_params) - layers.union(layer) - - return ORSOSample( - bulk_in=bulk_in, - bulk_out=bulk_out, - parameters=parameters, - layers=layers, - model=contrast_model, - ) - - -def orso_layer_to_rat_layer( - layer: orsopy.fileio.model_language.Layer, name: str, absorption: bool = False -) -> tuple[ClassList[Parameter], Layer]: - """Convert an ``orsopy`` layer to a RAT layer. - - Parameters - ---------- - layer : orsopy.fileio.model_language.Layer - An ``orsopy`` Layer. - name : str - The name of the material in the layer. - absorption : bool, default True - Whether absorption should be accounted for in the layer. - - Returns - ------- - ClassList[Parameter], Layer - The parameters required for the RAT layer and the layer itself. - - """ - thickness = layer.thickness.as_unit("angstrom") - roughness = layer.roughness.as_unit("angstrom") - sld = layer.material.get_sld() - - params = ClassList( - [ - Parameter(name=f"{name} Thickness", min=thickness, value=thickness, max=thickness, fit=False), - Parameter(name=f"{name} Roughness", min=roughness, value=roughness, max=roughness, fit=False), - Parameter(name=f"{name} SLD", min=sld.real, value=sld.real, max=sld.real, fit=False), - ] - ) - if absorption: - params.append(Parameter(name=f"{name} SLD imaginary", min=sld.imag, value=sld.imag, max=sld.imag, fit=False)) - layer = AbsorptionLayer( - name=name, - thickness=f"{name} Thickness", - roughness=f"{name} Roughness", - SLD_real=f"{name} SLD", - SLD_imaginary=f"{name} SLD imaginary", - ) - else: - layer = Layer( - name=name, - thickness=f"{name} Thickness", - roughness=f"{name} Roughness", - SLD=f"{name} SLD", - ) - - return params, layer - - -def get_material_name( - material: orsopy.fileio.model_language.Material, model: orsopy.fileio.model_language.SampleModel -) -> str: - """Get the name of a material in the model. - - Layers with custom property definitions may not have a formula, so this adjusts the name for that. - - Parameters - ---------- - material : Material - The material to get the name of. - model : SampleModel - The sample model from which the material came. - - Returns - ------- - str - The name of the material. - - """ - if material.formula is not None: - return material.formula - else: - matching_materials = [k for k, v in model.materials.items() if v == material] - if matching_materials: - return matching_materials[0] - else: - # orsopy should catch that this is the case before we get here, but just in case... - raise ValueError("ORSO model contains layers with undefined materials!") diff --git a/ratapi/utils/plotting.py b/ratapi/utils/plotting.py deleted file mode 100644 index 6f9debb7..00000000 --- a/ratapi/utils/plotting.py +++ /dev/null @@ -1,1235 +0,0 @@ -"""Plot results using the matplotlib library.""" - -import copy -import types -from collections.abc import Callable -from functools import partial, wraps -from math import ceil, floor, sqrt -from statistics import stdev -from typing import Literal - -import matplotlib -import matplotlib.figure -import matplotlib.pyplot as plt -import matplotlib.transforms as mtransforms -import numpy as np -from matplotlib.axes._axes import Axes -from scipy.ndimage import gaussian_filter1d -from scipy.stats import gaussian_kde, lognorm, norm - -import ratapi -import ratapi.inputs -import ratapi.outputs -from ratapi.rat_core import PlotEventData, makeSLDProfile - - -def _extract_plot_data(event_data: PlotEventData, q4: bool, show_error_bar: bool, shift_value: float): - """Extract the plot data for the sld, ref, error plot lines. - - Parameters - ---------- - event_data : PlotEventData - The plot event data that contains all the information - to generate the ref and sld plots - q4 : bool, default: False - Controls whether Q^4 is plotted on the reflectivity plot - show_error_bar : bool, default: True - Controls whether the error bars are shown - shift_value : float - A value between 0 and 100 that controls the spacing between the reflectivity plots for each of the contrasts - - Returns - ------- - plot_values : dict - A dict containing the data for the sld, ref, error plot lines. - - """ - results = {"ref": [], "error": [], "sld": [], "sld_resample": []} - - if shift_value < 0 or shift_value > 100: - raise ValueError("Parameter `shift_value` must be between 0 and 100") - - for i, (r, data, sld) in enumerate( - zip(event_data.reflectivity, event_data.shiftedData, event_data.sldProfiles, strict=False) - ): - # Calculate the divisor - div = 10 ** (i / 100 * shift_value) - q4_data = 1 if not q4 or not event_data.dataPresent[i] else data[:, 0] ** 4 - mult = q4_data / div - - # Plot the reflectivity on plot (1,1) - results["ref"].append([r[:, 0], r[:, 1] * mult]) - - if event_data.dataPresent[i]: - sd_x = data[:, 0] - sd_y, sd_e = map(lambda x: x * mult, (data[:, 1], data[:, 2])) - errors = np.zeros(len(sd_e)) - - if show_error_bar: - valid = sd_y - sd_e >= 0 - errors[valid] = sd_e[valid] - valid |= sd_y < 0 - else: - valid = np.ones(len(sd_e)).astype(bool) - sd_e = errors - - results["error"].append([sd_x[valid], sd_y[valid], sd_e[valid]]) - - results["sld"].append([]) - for j in range(len(sld)): - results["sld"][-1].append([sld[j][:, 0], sld[j][:, 1]]) - - results["sld_resample"].append([]) - if event_data.resample[i] == 1 or event_data.modelType == "custom xy": - layers = event_data.resampledLayers[i][0] - for j in range(len(event_data.resampledLayers[i])): - layer = event_data.resampledLayers[i][j] - if layers.shape[1] == 4: - layer = np.delete(layer, 2, 1) - new_profile = makeSLDProfile( - layers[0, 1], # Bulk In - layers[-1, 1], # Bulk Out - layer, - event_data.subRoughs[i], # roughness - 1, - ) - - results["sld_resample"][-1].append([new_profile[:, 0] - 49, new_profile[:, 1]]) - - return results - - -def plot_ref_sld_helper( - data: PlotEventData, - fig: matplotlib.figure.Figure, - delay: bool = True, - confidence_intervals: dict | None = None, - linear_x: bool = False, - q4: bool = False, - show_error_bar: bool = True, - show_grid: bool = False, - show_legend: bool = True, - shift_value: float = 100, - animated=False, -): - """Clear the previous plots and updates the ref and SLD plots. - - Parameters - ---------- - data : PlotEventData - The plot event data that contains all the information - to generate the ref and sld plots - fig : matplotlib.figure.Figure - The figure object that has two subplots - delay : bool, default: True - Controls whether to delay 0.005s after plot is created - confidence_intervals : dict or None, default None - The Bayesian confidence intervals for reflectivity and SLD. - Only relevant if the procedure used is Bayesian (NS or DREAM) - linear_x : bool, default: False - Controls whether the x-axis on reflectivity plot uses the linear scale - q4 : bool, default: False - Controls whether Q^4 is plotted on the reflectivity plot - show_error_bar : bool, default: True - Controls whether the error bars are shown - show_grid : bool, default: False - Controls whether the grid is shown - show_legend : bool, default: True - Controls whether the legend is shown - shift_value : float, default: 100 - A value between 0 and 100 that controls the spacing between the reflectivity plots for each of the contrasts - animated : bool, default: False - Controls whether the animated property of foreground plot elements should be set. - - """ - preserve_zoom = False - - if len(fig.axes) != 2: - fig.clf() - fig.subplots(1, 2) - - fig.subplots_adjust(wspace=0.3, hspace=0) - - ref_plot: plt.Axes = fig.axes[0] - sld_plot: plt.Axes = fig.axes[1] - if ref_plot.lines and fig.canvas.toolbar is not None: - preserve_zoom = True - fig.canvas.toolbar.push_current() - - # Clears the previous plots - ref_plot.cla() - sld_plot.cla() - - plot_data = _extract_plot_data(data, q4, show_error_bar, shift_value) - for i, name in enumerate(data.contrastNames): - ref_plot.plot(plot_data["ref"][i][0], plot_data["ref"][i][1], label=name, linewidth=1, animated=animated) - color = ref_plot.get_lines()[-1].get_color() - - # Plot confidence intervals if required - if confidence_intervals is not None: - # Calculate the divisor - div = 10 ** (i / 100 * shift_value) - ref_min, ref_max = confidence_intervals["reflectivity"][i] - mult = (1 if not q4 else plot_data["ref"][i][0] ** 4) / div - ref_plot.fill_between(plot_data["ref"][i][0], ref_min * mult, ref_max * mult, alpha=0.6, color="grey") - - if data.dataPresent[i]: - # Plot the errorbars - ref_plot.errorbar( - x=plot_data["error"][i][0], - y=plot_data["error"][i][1], - yerr=plot_data["error"][i][2], - elinewidth=1, - ecolor=color, - marker=".", - markersize=3, - linestyle="none", - color=color, - capsize=0, - animated=animated, - ) - - # Plot the slds on plot (1,2) - for j in range(len(plot_data["sld"][i])): - label = name if len(plot_data["sld"][i]) == 1 else f"{name} Domain {j + 1}" - sld_plot.plot( - plot_data["sld"][i][j][0], plot_data["sld"][i][j][1], label=label, linewidth=1, animated=animated - ) - - # Plot confidence intervals if required - if confidence_intervals is not None: - sld_min, sld_max = confidence_intervals["sld"][i][j] - sld_plot.fill_between(plot_data["sld"][i][j][0], sld_min, sld_max, alpha=0.6, color="grey") - - for j in range(len(plot_data["sld_resample"][i])): - sld_plot.plot( - plot_data["sld_resample"][i][j][0], - plot_data["sld_resample"][i][j][1], - color=color, - linewidth=1, - animated=animated, - ) - - # Format the axis - ref_plot.set_yscale("log") - if not linear_x: - ref_plot.set_xscale("log") - ref_plot.set_xlabel("$Q_{z} (\u00c5^{-1})$") - ref_plot.set_ylabel("Reflectivity") - - sld_plot.set_xlabel("$Z (\u00c5)$") - sld_plot.set_ylabel("$SLD (\u00c5^{-2})$", labelpad=1) - - if show_legend: - ref_plot.legend() - sld_plot.legend() - - if show_grid: - ref_plot.grid() - sld_plot.grid() - - if preserve_zoom: - fig.canvas.toolbar.back() - if delay: - plt.pause(0.005) - - -def plot_ref_sld( - project: ratapi.Project, - results: ratapi.outputs.Results | ratapi.outputs.BayesResults, - block: bool = False, - fig: matplotlib.figure.Figure | None = None, - return_fig: bool = False, - bayes: Literal[65, 95, None] = None, - linear_x: bool = False, - q4: bool = False, - show_error_bar: bool = True, - show_grid: bool = False, - show_legend: bool = True, - shift_value: float = 100, -) -> plt.Figure | None: - """Plot the reflectivity and SLD profiles. - - Parameters - ---------- - project : Project - An instance of the Project class - results : Union[Results, BayesResults] - The result from the calculation - block : bool, default: False - Indicates the plot should block until it is closed - fig : matplotlib.figure.Figure, optional - The figure object that has two subplots - return_fig : bool, default False - If True, return the figure instead of displaying it. - bayes : 65, 95 or None, default None - Whether to shade Bayesian confidence intervals. Can be `None` - (if no intervals), `65` to show 65% confidence intervals, - and `95` to show 95% confidence intervals. - linear_x : bool, default: False - Controls whether the x-axis on reflectivity plot uses the linear scale - q4 : bool, default: False - Controls whether Q^4 is plotted on the reflectivity plot - show_error_bar : bool, default: True - Controls whether the error bars are shown - show_grid : bool, default: False - Controls whether the grid is shown - show_legend : bool, default: True - Controls whether the legend is shown - shift_value : float, default: 100 - A value between 0 and 100 that controls the spacing between the reflectivity plots for each of the contrasts - - Returns - ------- - Figure or None - Returns Figure if `return_fig` is True, else returns nothing. - - """ - data = PlotEventData() - - # We need to take a copy of reflectivity and SLD in case we are plotting a - # shaded plot and will therefore change the plotted data to that from the - # centre of the Bayesian distribution - data.modelType = project.model - data.reflectivity = copy.deepcopy(results.reflectivity) - data.shiftedData = results.shiftedData - data.sldProfiles = copy.deepcopy(results.sldProfiles) - data.resampledLayers = results.resampledLayers - data.dataPresent = ratapi.inputs.make_data_present(project) - data.subRoughs = results.contrastParams.subRoughs - data.resample = ratapi.inputs.make_resample(project) - data.contrastNames = [contrast.name for contrast in project.contrasts] - - if bayes: - if isinstance(results, ratapi.outputs.BayesResults): - # the predictionIntervals data consists of 5 rows: - # row 0: min with 95% confidence - # row 1: min with 65% confidence - # row 2: mean - # row 3: max with 65% confidence - # row 4: max with 95% confidence - if bayes == 95: - interval = [0, 4] - elif bayes == 65: - interval = [1, 3] - else: - raise ValueError("Parameter `bayes` must be 95, 65 or None") - confidence_intervals = { - "reflectivity": [ - (ref_inter[interval[0]], ref_inter[interval[1]]) - for ref_inter in results.predictionIntervals.reflectivity - ], - "sld": [ - [(sld_inter[interval[0]], sld_inter[interval[1]]) for sld_inter in sld] - for sld in results.predictionIntervals.sld - ], - } - # For a shaded plot, use the mean values from predictionIntervals - for reflectivity, mean_reflectivity in zip( - data.reflectivity, results.predictionIntervals.reflectivity, strict=False - ): - reflectivity[:, 1] = mean_reflectivity[2] - for sldProfile, mean_sld_profile in zip(data.sldProfiles, results.predictionIntervals.sld, strict=False): - for sld, mean_sld in zip(sldProfile, mean_sld_profile, strict=False): - sld[:, 1] = mean_sld[2] - else: - raise ValueError( - "Shaded confidence intervals are only available for the results of Bayesian analysis (NS or DREAM)" - ) - else: - confidence_intervals = None - - if fig is None: - fig = plt.subplots(1, 2)[0] - elif len(fig.axes) != 2: - fig.clf() - fig.subplots(1, 2) - - plot_ref_sld_helper( - data, - fig, - confidence_intervals=confidence_intervals, - linear_x=linear_x, - q4=q4, - show_error_bar=show_error_bar, - show_grid=show_grid, - show_legend=show_legend, - shift_value=shift_value, - ) - - if return_fig: - return fig - - plt.show(block=block) - - -class BlittingSupport: - """Create a SLD plot that uses blitting to get faster draws. - - The blit plot stores the background from an - initial draw then updates the foreground (lines and error bars) if the background is not changed. - - Parameters - ---------- - data : PlotEventData - The plot event data that contains all the information - to generate the ref and sld plots - fig : matplotlib.figure.Figure, optional - The figure class that has two subplots - linear_x : bool, default: False - Controls whether the x-axis on reflectivity plot uses the linear scale - q4 : bool, default: False - Controls whether Q^4 is plotted on the reflectivity plot - show_error_bar : bool, default: True - Controls whether the error bars are shown - show_grid : bool, default: False - Controls whether the grid is shown - show_legend : bool, default: True - Controls whether the legend is shown - shift_value : float, default: 100 - A value between 0 and 100 that controls the spacing between the reflectivity plots for each of the contrasts - """ - - def __init__( - self, - data, - fig=None, - linear_x: bool = False, - q4: bool = False, - show_error_bar: bool = True, - show_grid: bool = False, - show_legend: bool = True, - shift_value: float = 100, - ): - self.figure = fig - self.linear_x = linear_x - self.q4 = q4 - self.show_error_bar = show_error_bar - self.show_grid = show_grid - self.show_legend = show_legend - self.shift_value = shift_value - self.update_plot(data) - self.event_id = self.figure.canvas.mpl_connect("resize_event", self.resizeEvent) - - def __del__(self): - self.figure.canvas.mpl_disconnect(self.event_id) - - def resizeEvent(self, _event): - """Ensure the background is updated after a resize event.""" - self.__background_changed = True - - def update(self, data): - """Update the foreground, if background has not changed otherwise it updates full plot. - - Parameters - ---------- - data : PlotEventData - The plot event data that contains all the information - to generate the ref and sld plots - """ - if self.__background_changed: - self.update_plot(data) - else: - self.update_foreground(data) - - def __setattr__(self, name, value): - old_value = getattr(self, name, None) - if value == old_value: - return - - super().__setattr__(name, value) - if name in ["figure", "linear_x", "q4", "show_error_bar", "show_grid", "show_legend", "shift_value"]: - self.__background_changed = True - - def set_animated(self, is_animated: bool): - """Set the animated property of foreground plot elements. - - Parameters - ---------- - is_animated : bool - Indicates if the animated property should be set. - """ - for line in self.figure.axes[0].lines: - line.set_animated(is_animated) - for line in self.figure.axes[1].lines: - line.set_animated(is_animated) - for container in self.figure.axes[0].containers: - container[2][0].set_animated(is_animated) - - def adjust_error_bar(self, error_bar_container, x, y, y_error): - """Adjust the error bar data. - - Parameters - ---------- - error_bar_container : Tuple - Tuple containing the artist of the errorbar i.e. (data line, cap lines, bar lines) - x : np.ndarray - The shifted data x axis data - y : np.ndarray - The shifted data y axis data - y_error : np.ndarray - The shifted data y axis error data - """ - line, _, (bars_y,) = error_bar_container - - line.set_data(x, y) - x_base = x - y_base = y - - y_error_top = y_base + y_error - y_error_bottom = y_base - y_error - - new_segments_y = [ - np.array([[x, yt], [x, yb]]) for x, yt, yb in zip(x_base, y_error_top, y_error_bottom, strict=False) - ] - bars_y.set_segments(new_segments_y) - - def update_plot(self, data): - """Update the full plot. - - Parameters - ---------- - data : PlotEventData - The plot event data that contains all the information - to generate the ref and sld plots - """ - if self.figure is not None: - self.figure.clf() - - self.figure.tight_layout() - plot_ref_sld_helper( - data, - self.figure, - linear_x=self.linear_x, - q4=self.q4, - show_error_bar=self.show_error_bar, - show_grid=self.show_grid, - show_legend=self.show_legend, - shift_value=self.shift_value, - animated=True, - ) - self.figure.canvas.draw() - self.bg = self.figure.canvas.copy_from_bbox(self.figure.bbox) - for line in self.figure.axes[0].lines: - self.figure.axes[0].draw_artist(line) - for line in self.figure.axes[1].lines: - self.figure.axes[1].draw_artist(line) - for container in self.figure.axes[0].containers: - self.figure.axes[0].draw_artist(container[2][0]) - self.figure.canvas.blit(self.figure.bbox) - self.set_animated(False) - self.__background_changed = False - - def update_foreground(self, data): - """Update the plot foreground only. - - Parameters - ---------- - data : PlotEventData - The plot event data that contains all the information - to generate the ref and sld plots - """ - self.set_animated(True) - self.figure.canvas.restore_region(self.bg) - plot_data = _extract_plot_data(data, self.q4, self.show_error_bar, self.shift_value) - - offset = 2 - for i in range( - 0, - len(self.figure.axes[0].lines), - ): - self.figure.axes[0].lines[i].set_data(plot_data["ref"][i // offset][0], plot_data["ref"][i // offset][1]) - self.figure.axes[0].draw_artist(self.figure.axes[0].lines[i]) - - i = 0 - for j in range(len(plot_data["sld"])): - for sld in plot_data["sld"][j]: - self.figure.axes[1].lines[i].set_data(sld[0], sld[1]) - self.figure.axes[1].draw_artist(self.figure.axes[1].lines[i]) - i += 1 - - for resampled in plot_data["sld_resample"][j]: - self.figure.axes[1].lines[i].set_data(resampled[0], resampled[1]) - self.figure.axes[1].draw_artist(self.figure.axes[1].lines[i]) - i += 1 - - for i, container in enumerate(self.figure.axes[0].containers): - self.adjust_error_bar( - container, plot_data["error"][i][0], plot_data["error"][i][1], plot_data["error"][i][2] - ) - self.figure.axes[0].draw_artist(container[2][0]) - self.figure.axes[0].draw_artist(container[0]) - - self.figure.canvas.blit(self.figure.bbox) - self.figure.canvas.flush_events() - self.set_animated(False) - - -class LivePlot: - """Create a plot that gets updates from the plot event during a calculation. - - Parameters - ---------- - block : bool, default: False - Indicates the plot should block until it is closed - - """ - - def __init__(self, block=False): - self.block = block - self.closed = False - self.blit_plot = None - - def __enter__(self): - self.figure = plt.subplots(1, 2)[0] - self.figure.canvas.mpl_connect("close_event", self._setCloseState) - self.figure.show() - ratapi.events.register(ratapi.events.EventTypes.Plot, self.plotEvent) - - return self.figure - - def _setCloseState(self, _): - """Close event handler.""" - self.closed = True - - def plotEvent(self, event): - """Plot the figure from plot event data. - - This is a callback for the plot event. - - Parameters - ---------- - event: PlotEventData - The plot event data. - - """ - if not self.closed and self.figure.number in plt.get_fignums(): - if self.blit_plot is None: - self.blit_plot = BlittingSupport(event, self.figure) - else: - self.blit_plot.update(event) - - def __exit__(self, _exc_type, _exc_val, _traceback): - ratapi.events.clear(ratapi.events.EventTypes.Plot, self.plotEvent) - if not self.closed and self.figure.number in plt.get_fignums(): - plt.show(block=self.block) - - -def assert_bayesian(name: str): - """Ensure the results passed to a function are Bayesian. - - This is a decorator. - - Parameters - ---------- - name : str - The name of the plot for the error message. - - """ - - def decorator(func: Callable): - @wraps(func) - def inner(results, *args, **kwargs): - if isinstance(results, ratapi.outputs.BayesResults): - return func(results, *args, **kwargs) - raise ValueError(f"{name} plots are only available for the results of Bayesian analysis (NS or DREAM)") - - return inner - - return decorator - - -def name_to_index(param: str | int, names: list[str]): - """Convert parameter names to indices.""" - if isinstance(param, str): - if param not in names: - raise ValueError(f"Parameter {param} is not in this analysis.") - param = names.index(param) - elif isinstance(param, int): - if param > len(names) or param < 0: - raise IndexError(f"Index {param} has been given, but indices must be between zero and {len(names)}.") - else: - raise ValueError(f"Parameters must be given as indices or names, not {type(param)}.") - return param - - -@assert_bayesian("Corner") -def plot_corner( - results: ratapi.outputs.BayesResults, - params: list[int | str] | None = None, - smooth: bool = True, - block: bool = False, - fig: matplotlib.figure.Figure | None = None, - return_fig: bool = False, - hist_kwargs: dict | None = None, - hist2d_kwargs: dict | None = None, - progress_callback: Callable[[int, int], None] | None = None, -): - """Create a corner plot from a Bayesian analysis. - - Parameters - ---------- - results : BayesResults - The results from a Bayesian calculation. - params : list[int or str], default None - The indices or names of a subset of parameters if required. - If None, uses all indices. - smooth : bool, default True - Whether to apply Gaussian smoothing to the corner plot. - block : bool, default False - Whether Python should block until the plot is closed. - fig : matplotlib.figure.Figure, optional - The figure object to use for plot. - return_fig: bool, default False - If True, return the figure as an object instead of showing it. - hist_kwargs : dict - Extra keyword arguments to pass to the 1d histograms. - Default is {'density': True, 'bins': 25} - hist2d_kwargs : dict - Extra keyword arguments to pass to the 2d histograms. - Default is {'density': True, 'bins': 25} - progress_callback: Union[Callable[[int, int], None], None] - Callback function for providing progress during plot creation - First argument is current completed sub plot and second is total number of sub plots - - Returns - ------- - Figure or None - If `return_fig` is True, return the figure - otherwise, return nothing. - - """ - fitname_to_index = partial(name_to_index, names=results.fitNames) - - if params is None: - params = range(0, len(results.fitNames)) - else: - params = list(map(fitname_to_index, params)) - - # defaults are applied inside each function - just pass blank dicts for now - if hist_kwargs is None: - hist_kwargs = {} - if hist2d_kwargs is None: - hist2d_kwargs = {} - - num_params = len(params) - total_count = num_params + (num_params**2 - num_params) // 2 - - if fig is None: - fig, axes = plt.subplots(num_params, num_params, figsize=(11, 10), subplot_kw={"visible": False}) - else: - fig.clf() - axes = fig.subplots(num_params, num_params, subplot_kw={"visible": False}) - - # i is row, j is column - current_count = 0 - for i in range(num_params): - for j in range(i + 1): - row_param = params[i] - col_param = params[j] - current_axes: Axes = axes if isinstance(axes, matplotlib.axes.Axes) else axes[i][j] - current_axes.tick_params(which="both", labelsize="medium") - current_axes.xaxis.offsetText.set_fontsize("small") - current_axes.yaxis.offsetText.set_fontsize("small") - current_axes.set_visible(True) - if i == j: # diagonal: histograms - plot_one_hist(results, param=row_param, smooth=smooth, axes=current_axes, **hist_kwargs) - elif i > j: # lower triangle: 2d histograms - plot_contour( - results, x_param=col_param, y_param=row_param, smooth=smooth, axes=current_axes, **hist2d_kwargs - ) - - # remove label if on inside of corner plot - if j != 0: - current_axes.get_yaxis().set_visible(False) - if i != len(params) - 1: - current_axes.get_xaxis().set_visible(False) - # make labels invisible as titles cover that - current_axes.yaxis._update_offset_text_position = types.MethodType( - _y_update_offset_text_position, current_axes.yaxis - ) - current_axes.yaxis.offset_text_position = "center" - current_axes.set_ylabel("") - current_axes.set_xlabel("") - if progress_callback is not None: - current_count += 1 - progress_callback(current_count, total_count) - if return_fig: - return fig - plt.show(block=block) - - -@assert_bayesian("Histogram") -def plot_one_hist( - results: ratapi.outputs.BayesResults, - param: int | str, - smooth: bool = True, - sigma: float | None = None, - estimated_density: Literal["normal", "lognor", "kernel", None] = None, - axes: Axes | None = None, - block: bool = False, - return_fig: bool = False, - **hist_settings, -): - """Plot the marginalised posterior for a parameter of a Bayesian analysis. - - Parameters - ---------- - results : BayesResults - The results from a Bayesian calculation. - param : Union[int, str] - Either the index or name of a parameter. - block : bool, default False - Whether Python should block until the plot is closed. - smooth : bool, default True - Whether to apply Gaussian smoothing to the histogram. - Defaults to True. - sigma: float or None, default None - If given, is used as the sigma-parameter for the Gaussian smoothing. - If None, the default (1/3rd of parameter chain standard deviation) is used. - estimated_density : 'normal', 'lognor', 'kernel' or None, default None - If None (default), ignore. Else, add an estimated density - of the given form on top of the histogram by the following estimations: - 'normal': normal Gaussian. - 'lognor': Log-normal probability density. - 'kernel': kernel density estimation. - axes: Axes or None, default None - If provided, plot on the given Axes object. - block : bool, default False - Whether Python should block until the plot is closed. - return_fig: bool, default False - If True, return the figure as an object instead of showing it. - **hist_settings : - Settings passed to `np.histogram`. By default, the settings - passed are `bins = 25` and `density = True`. - - Returns - ------- - Figure or None - If `return_fig` is True, return the figure - otherwise, return nothing. - - """ - chain = results.chain - param = name_to_index(param, results.fitNames) - - if axes is None: - fig, axes = plt.subplots(1, 1) - else: - fig = None - - # apply default settings if not set by user - default_settings = {"bins": 25, "density": True} - hist_settings = {**default_settings, **hist_settings} - - parameter_chain = chain[:, param] - counts, bins = np.histogram(parameter_chain, **hist_settings) - mean_y = np.mean(parameter_chain) - sd_y = np.std(parameter_chain) - - if smooth: - if sigma is None: - sigma = sd_y / 2 - counts = gaussian_filter1d(counts, sigma) - axes.hist( - bins[:-1], - bins, - weights=counts, - edgecolor="black", - linewidth=1.2, - color="white", - ) - - axes.set_title(results.fitNames[param], loc="left", fontsize="medium") - - if estimated_density: - dx = bins[1] - bins[0] - if estimated_density == "normal": - t = np.linspace(mean_y - 3.5 * sd_y, mean_y + 3.5 * sd_y) - axes.plot(t, norm.pdf(t, loc=mean_y, scale=sd_y**2)) - elif estimated_density == "lognor": - t = np.linspace(bins[0] - 0.5 * dx, bins[-1] + 2 * dx) - axes.plot(t, lognorm.pdf(t, np.mean(np.log(parameter_chain)), np.std(np.log(parameter_chain)))) - elif estimated_density == "kernel": - t = np.linspace(bins[0] - 2 * dx, bins[-1] + 2 * dx, 200) - kde = gaussian_kde(parameter_chain) - axes.plot(t, kde.evaluate(t)) - else: - raise ValueError( - f"{estimated_density} is not a supported estimated density function." - " Supported functions are 'normal' 'lognor' or 'kernel'." - ) - - # adding the estimated density extends the figure range - reset it to histogram range - x_range = hist_settings.get("range", (parameter_chain.min(), parameter_chain.max())) - axes.set_xlim(x_range) - - if fig is not None: - if return_fig: - return fig - plt.show(block=block) - - -def _y_update_offset_text_position(axis, _bboxes, bboxes2): - """Update the position of the Y axis offset text using the provided bounding boxes. - - Adapted from https://github.com/matplotlib/matplotlib/issues/4476#issuecomment-105627334. - - Parameters - ---------- - axis : matplotlib.axis.YAxis - Y axis to update. - _bboxes : List - list of bounding boxes - bboxes2 : List - list of bounding boxes - """ - x, y = axis.offsetText.get_position() - - if axis.offset_text_position == "left": - # y in axes coords, x in display coords - axis.offsetText.set_transform( - mtransforms.blended_transform_factory(axis.axes.transAxes, mtransforms.IdentityTransform()) - ) - - top = axis.axes.bbox.ymax - y = top + axis.OFFSETTEXTPAD * axis.figure.dpi / 72.0 - - else: - # x & y in display coords - axis.offsetText.set_transform(mtransforms.IdentityTransform()) - - # Northwest of upper-right corner of right-hand extent of tick labels - if bboxes2: - bbox = mtransforms.Bbox.union(bboxes2) - else: - bbox = axis.axes.bbox - center = bbox.ymin + (bbox.ymax - bbox.ymin) / 2 - x = bbox.xmin - axis.OFFSETTEXTPAD * axis.figure.dpi / 72.0 - y = center - x_offset = 110 - axis.offsetText.set_position((x - x_offset, y)) - - -@assert_bayesian("Contour") -def plot_contour( - results: ratapi.outputs.BayesResults, - x_param: int | str, - y_param: int | str, - smooth: bool = True, - sigma: tuple[float] | None = None, - axes: Axes | None = None, - block: bool = False, - return_fig: bool = False, - **hist2d_settings, -): - """Plot a 2D histogram of two indexed chain parameters, with contours. - - Parameters - ---------- - results : ratapi.outputs.BayesResults - The results of a Bayesian analysis. - x_param : int - The index or name of the parameter on the x-axis. - y_param : int - The index or name ofthe parameter on the y-axis. - smooth : bool, default True - If True, apply Gaussian smoothing to the histogram. - sigma : tuple[float] or None, default None - If given, is used as parameters for Gaussian smoothing in x and y direction respectively. - If None, defaults to the standard deviation of the parameter chain in either direction. - axes: Axes or None, default None - If provided, plot on the given Axes object. - block : bool, default False - Whether Python should block until the plot is closed. - return_fig: bool, default False - If True, return the figure as an object instead of showing it. - **hist2d_settings: - Settings passed to `np.histogram2d`. - Default settings are `bins = 25` and `density = True`. - - Returns - ------- - Figure or None - If `return_fig` is True, return the figure - otherwise, return nothing. - - """ - if axes is None: - fig, axes = plt.subplots(1, 1) - else: - fig = None - x_param = name_to_index(x_param, results.fitNames) - y_param = name_to_index(y_param, results.fitNames) - - default_settings = {"bins": 25, "density": True} - hist2d_settings = {**default_settings, **hist2d_settings} - - counts, x_bins, y_bins = np.histogram2d(results.chain[:, x_param], results.chain[:, y_param], **hist2d_settings) - if smooth: - if sigma is None: - sigma_x = stdev(results.chain[:, x_param]) / 2 - sigma_y = stdev(results.chain[:, y_param]) / 2 - else: - sigma_x, sigma_y = sigma - # perform a 1d smooth along both axes - counts = gaussian_filter1d(counts, axis=0, sigma=sigma_x) - counts = gaussian_filter1d(counts, axis=1, sigma=sigma_y) - - axes.pcolormesh(x_bins, y_bins, counts.max() - counts, cmap=matplotlib.colormaps["Greys"].reversed()) - axes.contour(x_bins[:-1], y_bins[:-1], counts.max() - counts, colors="black") - axes.set_xlabel(results.fitNames[x_param]) - axes.set_ylabel(results.fitNames[y_param]) - - if fig is not None: - if return_fig: - return fig - plt.show(block=block) - - -def panel_plot_helper( - plot_func: Callable, - indices: list[int], - fig: matplotlib.figure.Figure | None = None, - progress_callback: Callable[[int, int], None] | None = None, -) -> matplotlib.figure.Figure: - """Generate a panel-based plot from a single plot function. - - Parameters - ---------- - plot_func : Callable - A function which plots one parameter on an Axes object, given its index. - indices : list[int] - The list of indices to pass into ``plot_func``. - fig : matplotlib.figure.Figure, optional - The figure object to use for plot. - progress_callback: Union[Callable[[int, int], None], None] - Callback function for providing progress during plot creation - First argument is current completed sub plot and second is total number of sub plots - - Returns - ------- - matplotlib.figure.Figure - A figure containing a grid of plots over the indices in `indices`. - - """ - nplots = len(indices) - nrows, ncols = ceil(sqrt(nplots)), round(sqrt(nplots)) - - if fig is None: - fig = plt.subplots(nrows, ncols, figsize=(11, 10), subplot_kw={"visible": False})[0] - else: - fig.clf() - fig.subplots(nrows, ncols, subplot_kw={"visible": False}) - axs = fig.get_axes() - for index, plot_num in enumerate(indices): - axs[index].tick_params(which="both", labelsize="medium") - axs[index].xaxis.offsetText.set_fontsize("small") - axs[index].yaxis.offsetText.set_fontsize("small") - axs[index].set_visible(True) - plot_func(axs[index], plot_num) - if progress_callback is not None: - progress_callback(index, nplots) - - fig.tight_layout() - return fig - - -@assert_bayesian("Histogram") -def plot_hists( - results: ratapi.outputs.BayesResults, - params: list[int | str] | None = None, - smooth: bool = True, - sigma: float | None = None, - estimated_density: dict[Literal["normal", "lognor", "kernel", None]] - | Literal["normal", "lognor", "kernel", None] = None, - block: bool = False, - fig: matplotlib.figure.Figure | None = None, - return_fig: bool = False, - progress_callback: Callable[[int, int], None] | None = None, - **hist_settings, -): - """Plot marginalised posteriors for several parameters from a Bayesian analysis. - - Parameters - ---------- - results : BayesResults - The results from a Bayesian calculation. - params : list[int], default None - The indices or names of a subset of parameters if required. - If None, uses all indices. - smooth : bool, default True - Whether to apply a Gaussian smoothing to the histogram. - Defaults to True. - sigma: float or None, default None - If given, is used as the sigma-parameter for the Gaussian smoothing. - If None, the default (1/3rd of parameter chain standard deviation) is used. - estimated_density : dict, default None - If None (default), ignore. - Can also be a string 'normal', 'lognor' or 'kernel' to apply the same estimated density to all parameters. - Else, a dictionary where the keys are - indices or names of parameters, and values denote an estimated density - of the given form on top of the histogram: - None : do not plot estimated density for this parameter. - 'normal': normal Gaussian. - 'lognor': Log-normal probability density. - 'kernel': kernel density estimation. - To provide a default estimated density function to all parameters that haven't been specifically set, - pass the 'default' key, - e.g. to apply 'normal' to all unset parameters, set `estimated_density = {'default': 'normal'}`. - block : bool, default False - Whether Python should block until the plot is closed. - fig : matplotlib.figure.Figure, optional - The figure object to use for plot. - return_fig: bool, default False - If True, return the figure as an object instead of showing it. - progress_callback: Union[Callable[[int, int], None], None] - Callback function for providing progress during plot creation - First argument is current completed sub plot and second is total number of sub plots - hist_settings : - Settings passed to `np.histogram`. By default, the settings - passed are `bins = 25` and `density = True`. - - Returns - ------- - Figure or None - If `return_fig` is True, return the figure - otherwise, return nothing. - - """ - # first convert names to indices if given - fitname_to_index = partial(name_to_index, names=results.fitNames) - - if params is None: - params = range(0, len(results.fitNames)) - else: - params = list(map(fitname_to_index, params)) - - if estimated_density is not None: - - def validate_dens_type(dens_type: str | None, param: str): - """Check estimated density is a supported type.""" - if dens_type not in [None, "normal", "lognor", "kernel"]: - raise ValueError( - f"Parameter {param} has estimated density function {dens_type}," - " which is not supported. Supported estimated density functions" - " are 'normal', 'lognor', and 'kernel'." - ) - return dens_type - - if isinstance(estimated_density, str): - validate_dens_type(estimated_density, "default") - estimated_density = {fitname_to_index(param): estimated_density for param in params} - else: - default = estimated_density.pop("default", None) - validate_dens_type(default, "default") - default_density = {fitname_to_index(param): default for param in params} - # convert names to indices and ensure density types given are correct - estimated_density = { - name_to_index(k, results.fitNames): validate_dens_type(v, k) for k, v in estimated_density.items() - } - # merge other estimated densities into default dict - estimated_density = {**default_density, **estimated_density} - else: - estimated_density = {} - - fig = panel_plot_helper( - lambda ax, i: plot_one_hist( - results, - i, - smooth=smooth, - sigma=sigma, - estimated_density=estimated_density.get(i), - axes=ax, - **hist_settings, - ), - params, - fig, - progress_callback, - ) - if return_fig: - return fig - plt.show(block=block) - - -@assert_bayesian("Chain") -def plot_chain( - results: ratapi.outputs.BayesResults, - params: list[int | str] | None = None, - maxpoints: int = 15000, - block: bool = False, - fig: matplotlib.figure.Figure | None = None, - return_fig: bool = False, - progress_callback: Callable[[int, int], None] | None = None, -): - """Plot the MCMC chain for each parameter of a Bayesian analysis. - - Parameters - ---------- - results : ratapi.outputs.BayesResults - The results of a Bayesian analysis. - params : list[int], default None - The indices or names of a subset of parameters if required. - If None, uses all indices. - maxpoints : int - The maximum number of points to plot for each parameter. - block : bool, default False - Whether Python should block until the plot is closed. - fig : matplotlib.figure.Figure, optional - The figure object to use for plot. - return_fig: bool, default False - If True, return the figure as an object instead of showing it. - progress_callback: Union[Callable[[int, int], None], None] - Callback function for providing progress during plot creation - First argument is current completed sub plot and second is total number of sub plots - - Returns - ------- - Figure or None - If `return_fig` is True, return the figure - otherwise, return nothing. - - """ - chain = results.chain - nsimulations, _ = chain.shape - # skip is to evenly distribute points plotted - # all points will be plotted if maxpoints < nsimulations - skip = max(floor(nsimulations / maxpoints), 1) - - # convert names to indices if given - fitname_to_index = partial(name_to_index, names=results.fitNames) - - if params is None: - params = range(0, len(results.fitNames)) - else: - params = list(map(fitname_to_index, params)) - - def plot_one_chain(axes: Axes, i: int): - axes.plot(range(0, nsimulations, skip), chain[:, i][0:nsimulations:skip]) - axes.set_title(results.fitNames[i], fontsize="small") - - fig = panel_plot_helper(plot_one_chain, params, fig, progress_callback) - if return_fig: - return fig - plt.show(block=block) - - -def plot_bayes(project: ratapi.Project, results: ratapi.outputs.BayesResults): - """Plot the results of a Bayesian analysis with confidence information. - - This produces an unshaded reflectivity/SLD plot, a reflectivity/SLD plot with shaded 95% confidence - intervals, a grid of histograms giving probability density for each parameter, and a corner plot for - all parameters. - - Parameters - ---------- - project : Project - An instance of the Project class - results : Union[Results, BayesResults] - The result from the calculation - block : bool, default: False - Indicates the plot should block until it is closed - - """ - if isinstance(results, ratapi.outputs.BayesResults): - plot_ref_sld(project, results) - plot_ref_sld(project, results, bayes=95) - plot_hists(results) - plot_corner(results) - else: - raise ValueError("Bayes plots are only available for the results of Bayesian analysis (NS or DREAM)") diff --git a/ratapi/wrappers.py b/ratapi/wrappers.py deleted file mode 100644 index 38f276ac..00000000 --- a/ratapi/wrappers.py +++ /dev/null @@ -1,147 +0,0 @@ -"""Wrappers for the interface between ratapi and MATLAB custom files.""" - -import os -import pathlib -from collections.abc import Callable -from contextlib import suppress - -import numpy as np -from numpy.typing import ArrayLike - -import ratapi.rat_core - - -def start_matlab(): - """Start MATLAB asynchronously and returns a future to retrieve the engine later. - - Returns - ------- - future : matlab.engine.futureresult.FutureResult - A future used to get the actual matlab engine. - - """ - future = None - if os.environ.get("DELAY_MATLAB_START", "0") == "0": - with suppress(ImportError): - import atexit - - import matlab.engine - - future = matlab.engine.start_matlab(background=True) - atexit.register(lambda: future.result()) - - return future - - -class MatlabWrapper: - """Creates a python callback for a MATLAB function. - - Parameters - ---------- - filename : string - The path of the file containing MATLAB function - - """ - - loader = start_matlab() - loader_error_message = "matlabengine is required to use MatlabWrapper" - - def __init__(self, filename: str) -> None: - if self.loader is None: - raise ImportError(self.loader_error_message) from None - - self.engine = self.loader.result() - path = pathlib.Path(filename) - self.engine.cd(str(path.parent), nargout=0) - self.function_name = path.stem - - def getHandle(self) -> Callable[[ArrayLike, ArrayLike, ArrayLike, int, int], tuple[ArrayLike, float]]: - """Return a wrapper for the custom MATLAB function. - - Returns - ------- - wrapper : Callable[[ArrayLike, ArrayLike, ArrayLike, int, int], tuple[ArrayLike, float]] - The wrapper function for the MATLAB callback - - """ - - def handle(*args): - if len(args) == 2: - output = getattr(self.engine, self.function_name)( - np.array(args[0], "float"), # xdata - np.array(args[1], "float"), # params - nargout=1, - ) - return np.array(output, "float").tolist() - else: - matlab_args = [ - np.array(args[0], "float"), # params - np.array(args[1], "float"), # bulk in - np.array(args[2], "float"), # bulk out - float(args[3]), # contrast - ] - if len(args) > 4: - matlab_args.append(float(args[4])) # domain number - - output, sub_rough = getattr(self.engine, self.function_name)( - *matlab_args, - nargout=2, - ) - return np.array(output, "float").tolist(), float(sub_rough) - - return handle - - -def use_shared_matlab(name, custom_error_message): - """Connect asynchronously to shared MATLAB engine instance with the given name. - - Parameters - ---------- - name : str - The name of shared MATLAB engine instance - custom_error_message : str - The custom error message in case of failed connection - - Returns - ------- - future : matlab.engine.futureresult.FutureResult - A future used to get the actual matlab engine. - - """ - with suppress(ImportError): - import matlab.engine - - MatlabWrapper.loader = matlab.engine.connect_matlab(name, background=True) - MatlabWrapper.loader_error_message = custom_error_message - return MatlabWrapper.loader - - -class DylibWrapper: - """Creates a python callback for a function in dynamic library. - - Parameters - ---------- - filename : str - The path of the dynamic library - function_name : str - The name of the function to call - - """ - - def __init__(self, filename, function_name) -> None: - self.engine = ratapi.rat_core.DylibEngine(filename, function_name) - - def getHandle(self) -> Callable[[ArrayLike, ArrayLike, ArrayLike, int, int], tuple[ArrayLike, float]]: - """Return a wrapper for the custom dynamic library function. - - Returns - ------- - wrapper : Callable[[ArrayLike, ArrayLike, ArrayLike, int, int], tuple[ArrayLike, float]] - The wrapper function for the dynamic library callback - - """ - - def handle(*args): - return self.engine.invoke(*args) - - return handle diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..83550d52 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +numpy +pybind11 +matlabengine diff --git a/setup.py b/setup.py index 9f70ff77..8449e2fa 100644 --- a/setup.py +++ b/setup.py @@ -1,33 +1,31 @@ -import platform -import sys from glob import glob from pathlib import Path - +import platform +import sys import pybind11 -from setuptools import Extension, find_packages, setup -from setuptools.command.build_clib import build_clib +from setuptools import setup, Extension from setuptools.command.build_ext import build_ext +from setuptools.command.build_clib import build_clib -PACKAGE_NAME = "ratapi" -with open("README.md") as f: - LONG_DESCRIPTION = f.read() +__version__ = '0.0.0' -libevent = ("eventManager", {"sources": ["cpp/RAT/events/eventManager.cpp"], "include_dirs": ["cpp/RAT/events/"]}) + +libevent = ('eventManager', {'sources': ['cpp/RAT/events/eventManager.cpp'], + 'include_dirs': ['cpp/RAT/events/']}) ext_modules = [ Extension( - "ratapi.rat_core", - sources=["cpp/rat.cpp", *glob("cpp/RAT/*.c*")], + 'rat.rat_core', + sources=['cpp/rat.cpp', *glob('cpp/RAT/*.c*')], include_dirs=[ # Path to pybind11 headers pybind11.get_include(), pybind11.get_include(True), - "cpp/RAT/", - "cpp/includes/", + 'cpp/RAT/', ], - language="c++", + language='c++' ), ] @@ -35,11 +33,9 @@ # check whether compiler supports a flag def has_flag(compiler, flagname): import tempfile - from setuptools.errors import CompileError - - with tempfile.NamedTemporaryFile("w", suffix=".cpp") as f: - f.write("int main (int argc, char **argv) { return 0; }") + with tempfile.NamedTemporaryFile('w', suffix='.cpp') as f: + f.write('int main (int argc, char **argv) { return 0; }') try: compiler.compile([f.name], extra_postargs=[flagname]) except CompileError: @@ -48,114 +44,129 @@ def has_flag(compiler, flagname): def get_shared_object_name(lib_name): - if platform.system() == "Windows": - return f"{lib_name}.dll" - elif platform.system() == "Darwin": - return f"{lib_name}.dylib" + if platform.system() == 'Windows': + return f'{lib_name}.dll' + elif platform.system() == 'Darwin': + return f'{lib_name}.dylib' else: - return f"{lib_name}.so" + return f'{lib_name}.so' class BuildExt(build_ext): """A custom build extension for adding compiler-specific options.""" - c_opts = { - "msvc": ["/O2", "/EHsc", "/openmp"], - "unix": ["-O2", "-fopenmp", "-std=c++11"], + 'msvc': ['/EHsc'], + 'unix': ['-fopenmp', '-std=c++11'], } l_opts = { - "msvc": [], - "unix": ["-fopenmp"], + 'msvc': [], + 'unix': ['-fopenmp'], } - if sys.platform == "darwin": - darwin_opts = ["-stdlib=libc++"] - c_opts["unix"] = [*darwin_opts, "-fopenmp", "-O2"] - l_opts["unix"] = [*darwin_opts, "-lomp"] + if sys.platform == 'darwin': + darwin_opts = ['-stdlib=libc++', '-mmacosx-version-min=10.9'] + c_opts['unix'] = [*darwin_opts, '-fopenmp'] + l_opts['unix'] = [*darwin_opts, '-lomp'] def build_extensions(self): ct = self.compiler.compiler_type opts = self.c_opts.get(ct, []) link_opts = self.l_opts.get(ct, []) - if ct == "unix": - if "-Wstrict-prototypes" in self.compiler.compiler_so: - self.compiler.compiler_so.remove("-Wstrict-prototypes") - - opts.append(f'-DVERSION_INFO="{self.distribution.get_version()}"') - if has_flag(self.compiler, "-fvisibility=hidden"): - opts.append("-fvisibility=hidden") - elif ct == "msvc": - opts.append(f'/DVERSION_INFO=\\"{self.distribution.get_version()}\\"') + if ct == 'unix': + if '-Wstrict-prototypes' in self.compiler.compiler_so: + self.compiler.compiler_so.remove('-Wstrict-prototypes') + + opts.append('-DVERSION_INFO="%s"' % self.distribution.get_version()) + if has_flag(self.compiler, '-fvisibility=hidden'): + opts.append('-fvisibility=hidden') + elif ct == 'msvc': + opts.append('/DVERSION_INFO=\\"%s\\"' % self.distribution.get_version()) for ext in self.extensions: ext.extra_compile_args = opts ext.extra_link_args = link_opts build_ext.build_extensions(self) - + def run(self): super().run() - build_py = self.get_finalized_command("build_py") - package_dir = f"{build_py.build_lib}/{PACKAGE_NAME}/" + build_py = self.get_finalized_command('build_py') + package_dir = f'{build_py.build_lib}/rat/' for p in Path(package_dir).glob("**/*"): if p.suffix in {".exp", ".a", ".lib"}: - p.unlink() - + p.unlink() + if self.inplace: obj_name = get_shared_object_name(libevent[0]) - src = f"{build_py.build_lib}/{PACKAGE_NAME}/{obj_name}" - dest = f"{build_py.get_package_dir(PACKAGE_NAME)}/{obj_name}" + src = f'{build_py.build_lib}/rat/{obj_name}' + dest = f'{build_py.get_package_dir("rat")}/{obj_name}' build_py.copy_file(src, dest) class BuildClib(build_clib): def initialize_options(self): super().initialize_options() - build_py = self.get_finalized_command("build_py") - self.build_clib = f"{build_py.build_lib}/{PACKAGE_NAME}" + build_py = self.get_finalized_command('build_py') + self.build_clib = f'{build_py.build_lib}/rat' def build_libraries(self, libraries): # bug in distutils: flag not valid for c++ - flag = "-Wstrict-prototypes" - if hasattr(self.compiler, "compiler_so") and flag in self.compiler.compiler_so: + flag = '-Wstrict-prototypes' + if (hasattr(self.compiler, 'compiler_so') + and flag in self.compiler.compiler_so): self.compiler.compiler_so.remove(flag) compiler_type = self.compiler.compiler_type - if compiler_type == "msvc": - compile_args = ["/EHsc", "/LD", "-D_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR"] + if compiler_type == 'msvc': + compile_args = ['/EHsc', '/LD'] else: - compile_args = ["-std=c++11", "-fPIC"] - - for lib_name, build_info in libraries: - build_info["cflags"] = compile_args - macros = build_info.get("macros") - include_dirs = build_info.get("include_dirs") - cflags = build_info.get("cflags") - sources = list(build_info.get("sources")) + compile_args = ['-std=c++11', '-fPIC'] + + for (lib_name, build_info) in libraries: + build_info['cflags'] = compile_args + macros = build_info.get('macros') + include_dirs = build_info.get('include_dirs') + cflags = build_info.get('cflags') + sources = list(build_info.get('sources')) objects = self.compiler.compile( - sources, - output_dir=self.build_temp, - macros=macros, - include_dirs=include_dirs, - extra_postargs=cflags, - debug=self.debug, - ) + sources, + output_dir=self.build_temp, + macros=macros, + include_dirs=include_dirs, + extra_postargs=cflags, + debug=self.debug + ) language = self.compiler.detect_language(sources) self.compiler.link_shared_object( - objects, + objects, get_shared_object_name(lib_name), - output_dir=self.build_clib, - target_lang=language, - ) + output_dir=self.build_clib, + target_lang=language + ) super().build_libraries(libraries) - + setup( - name=PACKAGE_NAME, - packages=find_packages(exclude=("tests",)), + name='rat', + version=__version__, + author='demo', + author_email='demo@gmail.com', + url='https://github.com/RascalSoftware/python-RAT', + description='Python extension for the Reflectivity Analysis Toolbox (RAT)', + long_description='', + packages=['rat'], include_package_data=True, - package_data={"": [get_shared_object_name(libevent[0])], "ratapi.examples": ["data/*.dat"]}, - cmdclass={"build_clib": BuildClib, "build_ext": BuildExt}, + package_data={'': [get_shared_object_name(libevent[0])]}, libraries=[libevent], ext_modules=ext_modules, + install_requires=['numpy'], + python_requires='>=3.9', + cmdclass={'build_clib': BuildClib, 'build_ext': BuildExt}, + extras_require={"Matlab_latest": ["matlabengine"], + "Matlab_2023b": ["matlabengine==23.2.1"], + "Matlab_2023a": ["matlabengine==9.14.3"], + "Matlab-2022b": ["matlabengine==9.13.9"], + "Matlab_2022a": ["matlabengine==9.12.19"], + "Matlab_2021b": ["matlabengine==9.11.21"], + "Matlab_2021a": ["matlabengine==9.10.3"]}, zip_safe=False, ) diff --git a/tests/conftest.py b/tests/conftest.py deleted file mode 100644 index 0f3b3569..00000000 --- a/tests/conftest.py +++ /dev/null @@ -1,8547 +0,0 @@ -import shutil -import tempfile -from pathlib import Path - -import matplotlib - -matplotlib.use("Agg") -import numpy as np -import pytest - -import ratapi -import ratapi.classlist -import ratapi.outputs -import ratapi.rat_core - - -@pytest.fixture -def temp_dir(): - path = tempfile.mkdtemp() - yield path - shutil.rmtree(path) - - -@pytest.fixture -def input_project(): - """A cut-down version of the input Project object for a reflectivity calculation set out in - "DSPC_standard_layers.py". - """ - project = ratapi.Project( - name="original_dspc_bilayer", - calculation="normal", - model="standard layers", - geometry="substrate/liquid", - absorption=False, - ) - - # Set up the relevant parameters - project.parameters.append( - name="Oxide Thickness", - min=5.0, - value=19.54, - max=60.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - project.parameters.append( - name="Oxide SLD", - min=3.39e-06, - value=3.39e-06, - max=3.41e-06, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - project.parameters.append( - name="SAM Tails Thickness", - min=15.0, - value=22.66, - max=40.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - project.parameters.append( - name="SAM Tails SLD", - min=-5e-07, - value=-4.01e-07, - max=-3e-07, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - project.parameters.append( - name="SAM Tails Hydration", - min=1.0, - value=5.252, - max=50.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - project.parameters.append( - name="SAM Roughness", - min=1.0, - value=5.64, - max=15.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - project.parameters.append( - name="CW Thickness", - min=10.0, - value=17.12, - max=28.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - project.parameters.append( - name="CW SLD", - min=0.0, - value=0.0, - max=1e-09, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - project.parameters.append( - name="SAM Heads Thickness", - min=5.0, - value=8.56, - max=17.0, - fit=True, - prior_type="gaussian", - mu=10.0, - sigma=2.0, - ) - project.parameters.append( - name="SAM Heads SLD", - min=1.0e-07, - value=1.75e-06, - max=2.0e-06, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - project.parameters.append( - name="SAM Heads Hydration", - min=10.0, - value=45.45, - max=50.0, - fit=True, - prior_type="uniform", - mu=30.0, - sigma=3.0, - ) - project.parameters.append( - name="Bilayer Heads Thickness", - min=7.0, - value=10.7, - max=17.0, - fit=True, - prior_type="gaussian", - mu=10.0, - sigma=2.0, - ) - project.parameters.append( - name="Bilayer Heads SLD", - min=5.0e-07, - value=1.47e-06, - max=1.5e-06, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - project.parameters.append( - name="Bilayer Roughness", - min=2.0, - value=6.014, - max=15.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - project.parameters.append( - name="Bilayer Tails Thickness", - min=14.0, - value=17.82, - max=22.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - project.parameters.append( - name="Bilayer Tails SLD", - min=-5.0e-07, - value=-4.61e-07, - max=0.0, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - project.parameters.append( - name="Bilayer Tails Hydration", - min=10.0, - value=17.64, - max=50.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - project.parameters.append( - name="Bilayer Heads Hydration", - min=10.0, - value=36.15, - max=50.0, - fit=True, - prior_type="gaussian", - mu=30.0, - sigma=3.0, - ) - project.parameters.append( - name="CW Hydration", - min=99.9, - value=100.0, - max=100.0, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - project.parameters.append( - name="Oxide Hydration", - min=0.0, - value=23.61, - max=60.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - - project.parameters.set_fields(0, max=10) - - del project.bulk_in[0] - project.bulk_in.append(name="Silicon", min=2.0e-06, value=2.073e-06, max=2.1e-06, fit=False) - - del project.bulk_out[0] - project.bulk_out.append(name="D2O", min=5.50e-06, value=5.98e-06, max=6.4e-06, fit=True) - project.bulk_out.append(name="SMW", min=1.0e-06, value=2.21e-06, max=4.99e-06, fit=True) - - del project.scalefactors[0] - project.scalefactors.append(name="Scalefactor 1", min=0.05, value=0.10, max=0.2, fit=False) - project.scalefactors.append(name="Scalefactor 2", min=0.05, value=0.15, max=0.2, fit=False) - - del project.backgrounds[0] - del project.background_parameters[0] - project.background_parameters.append( - name="Background parameter D2O", - min=5.0e-10, - value=2.23e-06, - max=7.0e-06, - fit=True, - ) - project.background_parameters.append( - name="Background parameter SMW", - min=1.0e-10, - value=3.38e-06, - max=4.99e-06, - fit=True, - ) - - return project - - -@pytest.fixture -def reflectivity_calculation_output_results(): - """The C++ results object for a reflectivity calculation of the project set out in "DSPC_standard_layers.py".""" - results = ratapi.rat_core.OutputResult() - results.reflectivity = [ - np.array( - [ - [1.14030000e-02, 1.00000223e00], - [1.38610000e-02, 1.00000223e00], - [1.68480000e-02, 6.42692703e-02], - [2.04790000e-02, 1.69530247e-02], - [2.48920000e-02, 6.18815370e-03], - [3.02560000e-02, 2.99474163e-03], - [3.67770000e-02, 1.73558265e-03], - [4.47020000e-02, 1.03290554e-03], - [5.43360000e-02, 6.45645642e-04], - [6.60450000e-02, 5.57949197e-04], - [8.02790000e-02, 5.58974858e-04], - [9.75790000e-02, 3.49803750e-04], - [1.18610000e-01, 8.89485853e-05], - [1.44170000e-01, 4.04713900e-05], - [1.75240000e-01, 6.98590391e-06], - [2.13000000e-01, 3.60410795e-06], - [2.58910000e-01, 2.41835671e-06], - [3.14700000e-01, 2.26496635e-06], - [3.82520000e-01, 2.26396064e-06], - [4.64960000e-01, 2.24609517e-06], - [5.65160000e-01, 2.23162115e-06], - ], - ), - np.array( - [ - [1.14030000e-02, 1.53247324e-02], - [1.38610000e-02, 9.89602164e-03], - [1.68480000e-02, 6.26868663e-03], - [2.04790000e-02, 3.83918877e-03], - [2.48920000e-02, 2.21818017e-03], - [3.02560000e-02, 1.15473774e-03], - [3.67770000e-02, 4.92469653e-04], - [4.47020000e-02, 1.37287345e-04], - [5.43360000e-02, 2.28561535e-05], - [6.60450000e-02, 6.63620782e-05], - [8.02790000e-02, 1.36790069e-04], - [9.75790000e-02, 1.15354200e-04], - [1.18610000e-01, 3.73063683e-05], - [1.44170000e-01, 1.21263573e-05], - [1.75240000e-01, 6.59103452e-06], - [2.13000000e-01, 4.38321947e-06], - [2.58910000e-01, 3.40797246e-06], - [3.14700000e-01, 3.41625063e-06], - [3.82520000e-01, 3.40076933e-06], - [4.64960000e-01, 3.38892224e-06], - [5.65160000e-01, 3.38103236e-06], - ], - ), - ] - results.simulation = [ - np.array( - [ - [1.14030000e-02, 1.00000223e00], - [1.38610000e-02, 1.00000223e00], - [1.68480000e-02, 6.42692703e-02], - [2.04790000e-02, 1.69530247e-02], - [2.48920000e-02, 6.18815370e-03], - [3.02560000e-02, 2.99474163e-03], - [3.67770000e-02, 1.73558265e-03], - [4.47020000e-02, 1.03290554e-03], - [5.43360000e-02, 6.45645642e-04], - [6.60450000e-02, 5.57949197e-04], - [8.02790000e-02, 5.58974858e-04], - [9.75790000e-02, 3.49803750e-04], - [1.18610000e-01, 8.89485853e-05], - [1.44170000e-01, 4.04713900e-05], - [1.75240000e-01, 6.98590391e-06], - [2.13000000e-01, 3.60410795e-06], - [2.58910000e-01, 2.41835671e-06], - [3.14700000e-01, 2.26496635e-06], - [3.82520000e-01, 2.26396064e-06], - [4.64960000e-01, 2.24609517e-06], - [5.65160000e-01, 2.23162115e-06], - ], - ), - np.array( - [ - [1.14030000e-02, 1.53247324e-02], - [1.38610000e-02, 9.89602164e-03], - [1.68480000e-02, 6.26868663e-03], - [2.04790000e-02, 3.83918877e-03], - [2.48920000e-02, 2.21818017e-03], - [3.02560000e-02, 1.15473774e-03], - [3.67770000e-02, 4.92469653e-04], - [4.47020000e-02, 1.37287345e-04], - [5.43360000e-02, 2.28561535e-05], - [6.60450000e-02, 6.63620782e-05], - [8.02790000e-02, 1.36790069e-04], - [9.75790000e-02, 1.15354200e-04], - [1.18610000e-01, 3.73063683e-05], - [1.44170000e-01, 1.21263573e-05], - [1.75240000e-01, 6.59103452e-06], - [2.13000000e-01, 4.38321947e-06], - [2.58910000e-01, 3.40797246e-06], - [3.14700000e-01, 3.41625063e-06], - [3.82520000e-01, 3.40076933e-06], - [4.64960000e-01, 3.38892224e-06], - [5.65160000e-01, 3.38103236e-06], - ], - ), - ] - results.shiftedData = [ - np.array( - [ - [1.1403e-02, 1.0063e00, 1.9003e-02], - [1.3861e-02, 9.0118e-01, 1.1774e-02], - [1.6848e-02, 7.0455e-02, 1.3083e-03], - [2.0479e-02, 1.7544e-02, 5.1254e-04], - [2.4892e-02, 6.4257e-03, 2.6236e-04], - [3.0256e-02, 2.7746e-03, 8.5758e-05], - [3.6777e-02, 1.8591e-03, 4.9391e-05], - [4.4702e-02, 1.1002e-03, 3.2644e-05], - [5.4336e-02, 6.6691e-04, 2.1365e-05], - [6.6045e-02, 6.0729e-04, 1.1791e-05], - [8.0279e-02, 5.8755e-04, 1.5569e-05], - [9.7579e-02, 3.2700e-04, 6.5280e-06], - [1.1861e-01, 7.8205e-05, 2.5881e-06], - [1.4417e-01, 3.3455e-05, 1.5143e-06], - [1.7524e-01, 4.9313e-06, 5.6663e-07], - [2.1300e-01, 4.1948e-06, 6.8549e-07], - [2.5891e-01, 3.9863e-06, 8.2061e-07], - [3.1470e-01, 2.0861e-06, 6.1379e-07], - [3.8252e-01, 2.1154e-06, 6.3084e-07], - [4.6496e-01, 1.9906e-06, 6.0793e-07], - [5.6516e-01, 2.3816e-06, 7.0610e-07], - ], - ), - np.array( - [ - [1.14030000e-02, 1.20493333e-02, 7.32200000e-04], - [1.38610000e-02, 6.71800000e-03, 3.71853333e-04], - [1.68480000e-02, 4.10506667e-03, 2.23106667e-04], - [2.04790000e-02, 2.43306667e-03, 1.46873333e-04], - [2.48920000e-02, 1.40940000e-03, 9.59200000e-05], - [3.02560000e-02, 7.43400000e-04, 3.50226667e-05], - [3.67770000e-02, 3.51466667e-04, 1.59573333e-05], - [4.47020000e-02, 9.80666667e-05, 7.29466667e-06], - [5.43360000e-02, 1.73500000e-05, 2.59200000e-06], - [6.60450000e-02, 4.86286667e-05, 2.46453333e-06], - [8.02790000e-02, 9.71733333e-05, 4.68166667e-06], - [9.75790000e-02, 7.06533333e-05, 2.32180000e-06], - [1.18610000e-01, 1.93046667e-05, 1.00813333e-06], - [1.44170000e-01, 6.61193333e-06, 5.29773333e-07], - [1.75240000e-01, 3.23726667e-06, 3.65933333e-07], - [2.13000000e-01, 3.29920000e-06, 4.74273333e-07], - [2.58910000e-01, 1.71180000e-06, 4.24720000e-07], - [3.14700000e-01, 2.24020000e-06, 5.08946667e-07], - [3.82520000e-01, 2.73306667e-06, 5.71513333e-07], - [4.64960000e-01, 2.36153333e-06, 5.24806667e-07], - [5.65160000e-01, 2.17460000e-06, 5.31346667e-07], - ], - ), - ] - results.backgrounds = [ - np.array( - [ - [1.1403e-02, 2.2300e-06, 0.0000e00], - [1.1973e-02, 2.2300e-06, 0.0000e00], - [1.2572e-02, 2.2300e-06, 0.0000e00], - [1.3201e-02, 2.2300e-06, 0.0000e00], - [1.3861e-02, 2.2300e-06, 0.0000e00], - [1.4554e-02, 2.2300e-06, 0.0000e00], - [1.5281e-02, 2.2300e-06, 0.0000e00], - [1.6045e-02, 2.2300e-06, 0.0000e00], - [1.6848e-02, 2.2300e-06, 0.0000e00], - [1.7690e-02, 2.2300e-06, 0.0000e00], - [1.8575e-02, 2.2300e-06, 0.0000e00], - [1.9503e-02, 2.2300e-06, 0.0000e00], - [2.0479e-02, 2.2300e-06, 0.0000e00], - [2.1502e-02, 2.2300e-06, 0.0000e00], - [2.2578e-02, 2.2300e-06, 0.0000e00], - [2.3706e-02, 2.2300e-06, 0.0000e00], - [2.4892e-02, 2.2300e-06, 0.0000e00], - [2.6136e-02, 2.2300e-06, 0.0000e00], - [2.7443e-02, 2.2300e-06, 0.0000e00], - [2.8815e-02, 2.2300e-06, 0.0000e00], - [3.0256e-02, 2.2300e-06, 0.0000e00], - [3.1769e-02, 2.2300e-06, 0.0000e00], - [3.3357e-02, 2.2300e-06, 0.0000e00], - [3.5025e-02, 2.2300e-06, 0.0000e00], - [3.6777e-02, 2.2300e-06, 0.0000e00], - [3.8615e-02, 2.2300e-06, 0.0000e00], - [4.0546e-02, 2.2300e-06, 0.0000e00], - [4.2573e-02, 2.2300e-06, 0.0000e00], - [4.4702e-02, 2.2300e-06, 0.0000e00], - [4.6937e-02, 2.2300e-06, 0.0000e00], - [4.9284e-02, 2.2300e-06, 0.0000e00], - [5.1748e-02, 2.2300e-06, 0.0000e00], - [5.4336e-02, 2.2300e-06, 0.0000e00], - [5.7052e-02, 2.2300e-06, 0.0000e00], - [5.9905e-02, 2.2300e-06, 0.0000e00], - [6.2900e-02, 2.2300e-06, 0.0000e00], - [6.6045e-02, 2.2300e-06, 0.0000e00], - [6.9348e-02, 2.2300e-06, 0.0000e00], - [7.2815e-02, 2.2300e-06, 0.0000e00], - [7.6456e-02, 2.2300e-06, 0.0000e00], - [8.0279e-02, 2.2300e-06, 0.0000e00], - [8.4292e-02, 2.2300e-06, 0.0000e00], - [8.8507e-02, 2.2300e-06, 0.0000e00], - [9.2932e-02, 2.2300e-06, 0.0000e00], - [9.7579e-02, 2.2300e-06, 0.0000e00], - [1.0246e-01, 2.2300e-06, 0.0000e00], - [1.0758e-01, 2.2300e-06, 0.0000e00], - [1.1296e-01, 2.2300e-06, 0.0000e00], - [1.1861e-01, 2.2300e-06, 0.0000e00], - [1.2454e-01, 2.2300e-06, 0.0000e00], - [1.3077e-01, 2.2300e-06, 0.0000e00], - [1.3730e-01, 2.2300e-06, 0.0000e00], - [1.4417e-01, 2.2300e-06, 0.0000e00], - [1.5138e-01, 2.2300e-06, 0.0000e00], - [1.5895e-01, 2.2300e-06, 0.0000e00], - [1.6689e-01, 2.2300e-06, 0.0000e00], - [1.7524e-01, 2.2300e-06, 0.0000e00], - [1.8400e-01, 2.2300e-06, 0.0000e00], - [1.9320e-01, 2.2300e-06, 0.0000e00], - [2.0286e-01, 2.2300e-06, 0.0000e00], - [2.1300e-01, 2.2300e-06, 0.0000e00], - [2.2365e-01, 2.2300e-06, 0.0000e00], - [2.3484e-01, 2.2300e-06, 0.0000e00], - [2.4658e-01, 2.2300e-06, 0.0000e00], - [2.5891e-01, 2.2300e-06, 0.0000e00], - [2.7185e-01, 2.2300e-06, 0.0000e00], - [2.8544e-01, 2.2300e-06, 0.0000e00], - [2.9972e-01, 2.2300e-06, 0.0000e00], - [3.1470e-01, 2.2300e-06, 0.0000e00], - [3.3044e-01, 2.2300e-06, 0.0000e00], - [3.4696e-01, 2.2300e-06, 0.0000e00], - [3.6431e-01, 2.2300e-06, 0.0000e00], - [3.8252e-01, 2.2300e-06, 0.0000e00], - [4.0165e-01, 2.2300e-06, 0.0000e00], - [4.2173e-01, 2.2300e-06, 0.0000e00], - [4.4282e-01, 2.2300e-06, 0.0000e00], - [4.6496e-01, 2.2300e-06, 0.0000e00], - [4.8821e-01, 2.2300e-06, 0.0000e00], - [5.1262e-01, 2.2300e-06, 0.0000e00], - [5.3825e-01, 2.2300e-06, 0.0000e00], - [5.6516e-01, 2.2300e-06, 0.0000e00], - [5.9342e-01, 2.2300e-06, 0.0000e00], - ] - ), - np.array( - [ - [1.1403e-02, 3.3800e-06, 0.0000e00], - [1.1973e-02, 3.3800e-06, 0.0000e00], - [1.2572e-02, 3.3800e-06, 0.0000e00], - [1.3201e-02, 3.3800e-06, 0.0000e00], - [1.3861e-02, 3.3800e-06, 0.0000e00], - [1.4554e-02, 3.3800e-06, 0.0000e00], - [1.5281e-02, 3.3800e-06, 0.0000e00], - [1.6045e-02, 3.3800e-06, 0.0000e00], - [1.6848e-02, 3.3800e-06, 0.0000e00], - [1.7690e-02, 3.3800e-06, 0.0000e00], - [1.8575e-02, 3.3800e-06, 0.0000e00], - [1.9503e-02, 3.3800e-06, 0.0000e00], - [2.0479e-02, 3.3800e-06, 0.0000e00], - [2.1502e-02, 3.3800e-06, 0.0000e00], - [2.2578e-02, 3.3800e-06, 0.0000e00], - [2.3706e-02, 3.3800e-06, 0.0000e00], - [2.4892e-02, 3.3800e-06, 0.0000e00], - [2.6136e-02, 3.3800e-06, 0.0000e00], - [2.7443e-02, 3.3800e-06, 0.0000e00], - [2.8815e-02, 3.3800e-06, 0.0000e00], - [3.0256e-02, 3.3800e-06, 0.0000e00], - [3.1769e-02, 3.3800e-06, 0.0000e00], - [3.3357e-02, 3.3800e-06, 0.0000e00], - [3.5025e-02, 3.3800e-06, 0.0000e00], - [3.6777e-02, 3.3800e-06, 0.0000e00], - [3.8615e-02, 3.3800e-06, 0.0000e00], - [4.0546e-02, 3.3800e-06, 0.0000e00], - [4.2573e-02, 3.3800e-06, 0.0000e00], - [4.4702e-02, 3.3800e-06, 0.0000e00], - [4.6937e-02, 3.3800e-06, 0.0000e00], - [4.9284e-02, 3.3800e-06, 0.0000e00], - [5.1748e-02, 3.3800e-06, 0.0000e00], - [5.4336e-02, 3.3800e-06, 0.0000e00], - [5.7052e-02, 3.3800e-06, 0.0000e00], - [5.9905e-02, 3.3800e-06, 0.0000e00], - [6.2900e-02, 3.3800e-06, 0.0000e00], - [6.6045e-02, 3.3800e-06, 0.0000e00], - [6.9348e-02, 3.3800e-06, 0.0000e00], - [7.2815e-02, 3.3800e-06, 0.0000e00], - [7.6456e-02, 3.3800e-06, 0.0000e00], - [8.0279e-02, 3.3800e-06, 0.0000e00], - [8.4292e-02, 3.3800e-06, 0.0000e00], - [8.8507e-02, 3.3800e-06, 0.0000e00], - [9.2932e-02, 3.3800e-06, 0.0000e00], - [9.7579e-02, 3.3800e-06, 0.0000e00], - [1.0246e-01, 3.3800e-06, 0.0000e00], - [1.0758e-01, 3.3800e-06, 0.0000e00], - [1.1296e-01, 3.3800e-06, 0.0000e00], - [1.1861e-01, 3.3800e-06, 0.0000e00], - [1.2454e-01, 3.3800e-06, 0.0000e00], - [1.3077e-01, 3.3800e-06, 0.0000e00], - [1.3730e-01, 3.3800e-06, 0.0000e00], - [1.4417e-01, 3.3800e-06, 0.0000e00], - [1.5138e-01, 3.3800e-06, 0.0000e00], - [1.5895e-01, 3.3800e-06, 0.0000e00], - [1.6689e-01, 3.3800e-06, 0.0000e00], - [1.7524e-01, 3.3800e-06, 0.0000e00], - [1.8400e-01, 3.3800e-06, 0.0000e00], - [1.9320e-01, 3.3800e-06, 0.0000e00], - [2.0286e-01, 3.3800e-06, 0.0000e00], - [2.1300e-01, 3.3800e-06, 0.0000e00], - [2.2365e-01, 3.3800e-06, 0.0000e00], - [2.3484e-01, 3.3800e-06, 0.0000e00], - [2.4658e-01, 3.3800e-06, 0.0000e00], - [2.5891e-01, 3.3800e-06, 0.0000e00], - [2.7185e-01, 3.3800e-06, 0.0000e00], - [2.8544e-01, 3.3800e-06, 0.0000e00], - [2.9972e-01, 3.3800e-06, 0.0000e00], - [3.1470e-01, 3.3800e-06, 0.0000e00], - [3.3044e-01, 3.3800e-06, 0.0000e00], - [3.4696e-01, 3.3800e-06, 0.0000e00], - [3.6431e-01, 3.3800e-06, 0.0000e00], - [3.8252e-01, 3.3800e-06, 0.0000e00], - [4.0165e-01, 3.3800e-06, 0.0000e00], - [4.2173e-01, 3.3800e-06, 0.0000e00], - [4.4282e-01, 3.3800e-06, 0.0000e00], - [4.6496e-01, 3.3800e-06, 0.0000e00], - [4.8821e-01, 3.3800e-06, 0.0000e00], - [5.1262e-01, 3.3800e-06, 0.0000e00], - [5.3825e-01, 3.3800e-06, 0.0000e00], - [5.6516e-01, 3.3800e-06, 0.0000e00], - [5.9342e-01, 3.3800e-06, 0.0000e00], - ] - ), - ] - results.resolutions = [ - np.array( - [ - [0.011403, 0.03], - [0.011973, 0.03], - [0.012572, 0.03], - [0.013201, 0.03], - [0.013861, 0.03], - [0.014554, 0.03], - [0.015281, 0.03], - [0.016045, 0.03], - [0.016848, 0.03], - [0.01769, 0.03], - [0.018575, 0.03], - [0.019503, 0.03], - [0.020479, 0.03], - [0.021502, 0.03], - [0.022578, 0.03], - [0.023706, 0.03], - [0.024892, 0.03], - [0.026136, 0.03], - [0.027443, 0.03], - [0.028815, 0.03], - [0.030256, 0.03], - [0.031769, 0.03], - [0.033357, 0.03], - [0.035025, 0.03], - [0.036777, 0.03], - [0.038615, 0.03], - [0.040546, 0.03], - [0.042573, 0.03], - [0.044702, 0.03], - [0.046937, 0.03], - [0.049284, 0.03], - [0.051748, 0.03], - [0.054336, 0.03], - [0.057052, 0.03], - [0.059905, 0.03], - [0.0629, 0.03], - [0.066045, 0.03], - [0.069348, 0.03], - [0.072815, 0.03], - [0.076456, 0.03], - [0.080279, 0.03], - [0.084292, 0.03], - [0.088507, 0.03], - [0.092932, 0.03], - [0.097579, 0.03], - [0.10246, 0.03], - [0.10758, 0.03], - [0.11296, 0.03], - [0.11861, 0.03], - [0.12454, 0.03], - [0.13077, 0.03], - [0.1373, 0.03], - [0.14417, 0.03], - [0.15138, 0.03], - [0.15895, 0.03], - [0.16689, 0.03], - [0.17524, 0.03], - [0.184, 0.03], - [0.1932, 0.03], - [0.20286, 0.03], - [0.213, 0.03], - [0.22365, 0.03], - [0.23484, 0.03], - [0.24658, 0.03], - [0.25891, 0.03], - [0.27185, 0.03], - [0.28544, 0.03], - [0.29972, 0.03], - [0.3147, 0.03], - [0.33044, 0.03], - [0.34696, 0.03], - [0.36431, 0.03], - [0.38252, 0.03], - [0.40165, 0.03], - [0.42173, 0.03], - [0.44282, 0.03], - [0.46496, 0.03], - [0.48821, 0.03], - [0.51262, 0.03], - [0.53825, 0.03], - [0.56516, 0.03], - [0.59342, 0.03], - ] - ), - np.array( - [ - [0.011403, 0.03], - [0.011973, 0.03], - [0.012572, 0.03], - [0.013201, 0.03], - [0.013861, 0.03], - [0.014554, 0.03], - [0.015281, 0.03], - [0.016045, 0.03], - [0.016848, 0.03], - [0.01769, 0.03], - [0.018575, 0.03], - [0.019503, 0.03], - [0.020479, 0.03], - [0.021502, 0.03], - [0.022578, 0.03], - [0.023706, 0.03], - [0.024892, 0.03], - [0.026136, 0.03], - [0.027443, 0.03], - [0.028815, 0.03], - [0.030256, 0.03], - [0.031769, 0.03], - [0.033357, 0.03], - [0.035025, 0.03], - [0.036777, 0.03], - [0.038615, 0.03], - [0.040546, 0.03], - [0.042573, 0.03], - [0.044702, 0.03], - [0.046937, 0.03], - [0.049284, 0.03], - [0.051748, 0.03], - [0.054336, 0.03], - [0.057052, 0.03], - [0.059905, 0.03], - [0.0629, 0.03], - [0.066045, 0.03], - [0.069348, 0.03], - [0.072815, 0.03], - [0.076456, 0.03], - [0.080279, 0.03], - [0.084292, 0.03], - [0.088507, 0.03], - [0.092932, 0.03], - [0.097579, 0.03], - [0.10246, 0.03], - [0.10758, 0.03], - [0.11296, 0.03], - [0.11861, 0.03], - [0.12454, 0.03], - [0.13077, 0.03], - [0.1373, 0.03], - [0.14417, 0.03], - [0.15138, 0.03], - [0.15895, 0.03], - [0.16689, 0.03], - [0.17524, 0.03], - [0.184, 0.03], - [0.1932, 0.03], - [0.20286, 0.03], - [0.213, 0.03], - [0.22365, 0.03], - [0.23484, 0.03], - [0.24658, 0.03], - [0.25891, 0.03], - [0.27185, 0.03], - [0.28544, 0.03], - [0.29972, 0.03], - [0.3147, 0.03], - [0.33044, 0.03], - [0.34696, 0.03], - [0.36431, 0.03], - [0.38252, 0.03], - [0.40165, 0.03], - [0.42173, 0.03], - [0.44282, 0.03], - [0.46496, 0.03], - [0.48821, 0.03], - [0.51262, 0.03], - [0.53825, 0.03], - [0.56516, 0.03], - [0.59342, 0.03], - ] - ), - ] - results.sldProfiles = [ - [ - np.array( - [ - [0.00000000e00, 2.07300000e-06], - [1.10000000e01, 2.07300000e-06], - [2.20000000e01, 2.07300000e-06], - [3.30000000e01, 2.07300001e-06], - [4.40000000e01, 2.11687361e-06], - [5.50000000e01, 3.90933280e-06], - [6.60000000e01, 3.51748792e-06], - [7.70000000e01, -2.64615370e-08], - [8.80000000e01, 8.14665196e-07], - [9.90000000e01, 4.11508879e-06], - [1.10000000e02, 5.58392432e-06], - [1.21000000e02, 3.71785214e-06], - [1.32000000e02, 1.39304140e-06], - [1.43000000e02, 6.95745588e-07], - [1.54000000e02, 7.84170141e-07], - [1.65000000e02, 2.15552213e-06], - [1.76000000e02, 4.68458332e-06], - [1.87000000e02, 5.91563638e-06], - [1.98000000e02, 5.97982117e-06], - [2.09000000e02, 5.97999998e-06], - [2.20000000e02, 5.98000000e-06], - [2.31000000e02, 5.98000000e-06], - [2.42000000e02, 5.98000000e-06], - [2.53000000e02, 5.98000000e-06], - [2.64000000e02, 5.98000000e-06], - ], - ), - np.array( - [ - [0.00000000e00, 2.07300000e-06], - [1.10000000e01, 2.07300000e-06], - [2.20000000e01, 2.07300000e-06], - [3.30000000e01, 2.07300001e-06], - [4.40000000e01, 2.09662378e-06], - [5.50000000e01, 3.06177428e-06], - [6.60000000e01, 2.70974796e-06], - [7.70000000e01, -2.34283042e-07], - [8.80000000e01, 2.46446429e-07], - [9.90000000e01, 1.80004279e-06], - [1.10000000e02, 2.14886270e-06], - [1.21000000e02, 1.70090192e-06], - [1.32000000e02, 5.06554250e-07], - [1.43000000e02, 2.47801381e-08], - [1.54000000e02, 8.73866316e-08], - [1.65000000e02, 9.86362863e-07], - [1.76000000e02, 1.96411923e-06], - [1.87000000e02, 2.19933821e-06], - [1.98000000e02, 2.20997064e-06], - [2.09000000e02, 2.21000000e-06], - [2.20000000e02, 2.21000000e-06], - [2.31000000e02, 2.21000000e-06], - [2.42000000e02, 2.21000000e-06], - [2.53000000e02, 2.21000000e-06], - [2.64000000e02, 2.21000000e-06], - ], - ), - ], - ] - results.layers = [ - [ - np.array( - [ - [1.954000e01, 4.001499e-06, 3.000000e00], - [2.266000e01, -6.586988e-08, 3.000000e00], - [8.560000e00, 3.672535e-06, 5.640000e00], - [1.712000e01, 5.980000e-06, 5.640000e00], - [1.070000e01, 3.100365e-06, 6.014000e00], - [1.782000e01, 6.751924e-07, 6.014000e00], - [1.782000e01, 6.751924e-07, 6.014000e00], - [1.070000e01, 3.100365e-06, 6.014000e00], - ], - ), - ], - [ - np.array( - [ - [1.9540000e01, 3.1114020e-06, 3.0000000e00], - [2.2660000e01, -2.6387028e-07, 3.0000000e00], - [8.5600000e00, 1.9590700e-06, 5.6400000e00], - [1.7120000e01, 2.2100000e-06, 5.6400000e00], - [1.0700000e01, 1.7375100e-06, 6.0140000e00], - [1.7820000e01, 1.0164400e-08, 6.0140000e00], - [1.7820000e01, 1.0164400e-08, 6.0140000e00], - [1.0700000e01, 1.7375100e-06, 6.0140000e00], - ], - ), - ], - ] - results.resampledLayers = [[np.array([[0.0, 0.0, 0.0]])], [np.array([[0.0, 0.0, 0.0]])]] - results.calculationResults = ratapi.rat_core.Calculation() - results.calculationResults.chiValues = np.array([202.83057377, 1641.4024969]) - results.calculationResults.sumChi = 1844.2330706690975 - results.contrastParams = ratapi.rat_core.ContrastParams() - results.contrastParams.scalefactors = np.array([0.1, 0.15]) - results.contrastParams.bulkIn = np.array([2.073e-06, 2.073e-06]) - results.contrastParams.bulkOut = np.array([5.98e-06, 2.21e-06]) - results.contrastParams.subRoughs = np.array([3.0, 3.0]) - results.contrastParams.resample = np.array([0.0, 0.0]) - results.fitParams = np.array( - [ - 3.000e00, - 1.954e01, - 2.266e01, - 5.252e00, - 5.640e00, - 1.712e01, - 8.560e00, - 4.545e01, - 1.070e01, - 6.014e00, - 1.782e01, - 1.764e01, - 3.615e01, - 2.361e01, - 2.230e-06, - 3.380e-06, - 5.980e-06, - 2.210e-06, - ], - ) - results.fitNames = [ - "Substrate Roughness", - "Oxide Thickness", - "SAM Tails Thickness", - "SAM Tails Hydration", - "SAM Roughness", - "CW Thickness", - "SAM Heads Thickness", - "SAM Heads Hydration", - "Bilayer Heads Thickness", - "Bilayer Roughness", - "Bilayer Tails Thickness", - "Bilayer Tails Hydration", - "Bilayer Heads Hydration", - "Oxide Hydration", - "Background parameter D2O", - "Background parameter SMW", - "D2O", - "SMW", - ] - - return results - - -@pytest.fixture -def reflectivity_calculation_results(): - """The python results object for a reflectivity calculation of the project set out in "DSPC_standard_layers.py".""" - return ratapi.outputs.Results( - reflectivity=[ - np.array( - [ - [1.14030000e-02, 1.00000223e00], - [1.38610000e-02, 1.00000223e00], - [1.68480000e-02, 6.42692703e-02], - [2.04790000e-02, 1.69530247e-02], - [2.48920000e-02, 6.18815370e-03], - [3.02560000e-02, 2.99474163e-03], - [3.67770000e-02, 1.73558265e-03], - [4.47020000e-02, 1.03290554e-03], - [5.43360000e-02, 6.45645642e-04], - [6.60450000e-02, 5.57949197e-04], - [8.02790000e-02, 5.58974858e-04], - [9.75790000e-02, 3.49803750e-04], - [1.18610000e-01, 8.89485853e-05], - [1.44170000e-01, 4.04713900e-05], - [1.75240000e-01, 6.98590391e-06], - [2.13000000e-01, 3.60410795e-06], - [2.58910000e-01, 2.41835671e-06], - [3.14700000e-01, 2.26496635e-06], - [3.82520000e-01, 2.26396064e-06], - [4.64960000e-01, 2.24609517e-06], - [5.65160000e-01, 2.23162115e-06], - ], - ), - np.array( - [ - [1.14030000e-02, 1.53247324e-02], - [1.38610000e-02, 9.89602164e-03], - [1.68480000e-02, 6.26868663e-03], - [2.04790000e-02, 3.83918877e-03], - [2.48920000e-02, 2.21818017e-03], - [3.02560000e-02, 1.15473774e-03], - [3.67770000e-02, 4.92469653e-04], - [4.47020000e-02, 1.37287345e-04], - [5.43360000e-02, 2.28561535e-05], - [6.60450000e-02, 6.63620782e-05], - [8.02790000e-02, 1.36790069e-04], - [9.75790000e-02, 1.15354200e-04], - [1.18610000e-01, 3.73063683e-05], - [1.44170000e-01, 1.21263573e-05], - [1.75240000e-01, 6.59103452e-06], - [2.13000000e-01, 4.38321947e-06], - [2.58910000e-01, 3.40797246e-06], - [3.14700000e-01, 3.41625063e-06], - [3.82520000e-01, 3.40076933e-06], - [4.64960000e-01, 3.38892224e-06], - [5.65160000e-01, 3.38103236e-06], - ], - ), - ], - simulation=[ - np.array( - [ - [1.14030000e-02, 1.00000223e00], - [1.38610000e-02, 1.00000223e00], - [1.68480000e-02, 6.42692703e-02], - [2.04790000e-02, 1.69530247e-02], - [2.48920000e-02, 6.18815370e-03], - [3.02560000e-02, 2.99474163e-03], - [3.67770000e-02, 1.73558265e-03], - [4.47020000e-02, 1.03290554e-03], - [5.43360000e-02, 6.45645642e-04], - [6.60450000e-02, 5.57949197e-04], - [8.02790000e-02, 5.58974858e-04], - [9.75790000e-02, 3.49803750e-04], - [1.18610000e-01, 8.89485853e-05], - [1.44170000e-01, 4.04713900e-05], - [1.75240000e-01, 6.98590391e-06], - [2.13000000e-01, 3.60410795e-06], - [2.58910000e-01, 2.41835671e-06], - [3.14700000e-01, 2.26496635e-06], - [3.82520000e-01, 2.26396064e-06], - [4.64960000e-01, 2.24609517e-06], - [5.65160000e-01, 2.23162115e-06], - ], - ), - np.array( - [ - [1.14030000e-02, 1.53247324e-02], - [1.38610000e-02, 9.89602164e-03], - [1.68480000e-02, 6.26868663e-03], - [2.04790000e-02, 3.83918877e-03], - [2.48920000e-02, 2.21818017e-03], - [3.02560000e-02, 1.15473774e-03], - [3.67770000e-02, 4.92469653e-04], - [4.47020000e-02, 1.37287345e-04], - [5.43360000e-02, 2.28561535e-05], - [6.60450000e-02, 6.63620782e-05], - [8.02790000e-02, 1.36790069e-04], - [9.75790000e-02, 1.15354200e-04], - [1.18610000e-01, 3.73063683e-05], - [1.44170000e-01, 1.21263573e-05], - [1.75240000e-01, 6.59103452e-06], - [2.13000000e-01, 4.38321947e-06], - [2.58910000e-01, 3.40797246e-06], - [3.14700000e-01, 3.41625063e-06], - [3.82520000e-01, 3.40076933e-06], - [4.64960000e-01, 3.38892224e-06], - [5.65160000e-01, 3.38103236e-06], - ], - ), - ], - shiftedData=[ - np.array( - [ - [1.1403e-02, 1.0063e00, 1.9003e-02], - [1.3861e-02, 9.0118e-01, 1.1774e-02], - [1.6848e-02, 7.0455e-02, 1.3083e-03], - [2.0479e-02, 1.7544e-02, 5.1254e-04], - [2.4892e-02, 6.4257e-03, 2.6236e-04], - [3.0256e-02, 2.7746e-03, 8.5758e-05], - [3.6777e-02, 1.8591e-03, 4.9391e-05], - [4.4702e-02, 1.1002e-03, 3.2644e-05], - [5.4336e-02, 6.6691e-04, 2.1365e-05], - [6.6045e-02, 6.0729e-04, 1.1791e-05], - [8.0279e-02, 5.8755e-04, 1.5569e-05], - [9.7579e-02, 3.2700e-04, 6.5280e-06], - [1.1861e-01, 7.8205e-05, 2.5881e-06], - [1.4417e-01, 3.3455e-05, 1.5143e-06], - [1.7524e-01, 4.9313e-06, 5.6663e-07], - [2.1300e-01, 4.1948e-06, 6.8549e-07], - [2.5891e-01, 3.9863e-06, 8.2061e-07], - [3.1470e-01, 2.0861e-06, 6.1379e-07], - [3.8252e-01, 2.1154e-06, 6.3084e-07], - [4.6496e-01, 1.9906e-06, 6.0793e-07], - [5.6516e-01, 2.3816e-06, 7.0610e-07], - ], - ), - np.array( - [ - [1.14030000e-02, 1.20493333e-02, 7.32200000e-04], - [1.38610000e-02, 6.71800000e-03, 3.71853333e-04], - [1.68480000e-02, 4.10506667e-03, 2.23106667e-04], - [2.04790000e-02, 2.43306667e-03, 1.46873333e-04], - [2.48920000e-02, 1.40940000e-03, 9.59200000e-05], - [3.02560000e-02, 7.43400000e-04, 3.50226667e-05], - [3.67770000e-02, 3.51466667e-04, 1.59573333e-05], - [4.47020000e-02, 9.80666667e-05, 7.29466667e-06], - [5.43360000e-02, 1.73500000e-05, 2.59200000e-06], - [6.60450000e-02, 4.86286667e-05, 2.46453333e-06], - [8.02790000e-02, 9.71733333e-05, 4.68166667e-06], - [9.75790000e-02, 7.06533333e-05, 2.32180000e-06], - [1.18610000e-01, 1.93046667e-05, 1.00813333e-06], - [1.44170000e-01, 6.61193333e-06, 5.29773333e-07], - [1.75240000e-01, 3.23726667e-06, 3.65933333e-07], - [2.13000000e-01, 3.29920000e-06, 4.74273333e-07], - [2.58910000e-01, 1.71180000e-06, 4.24720000e-07], - [3.14700000e-01, 2.24020000e-06, 5.08946667e-07], - [3.82520000e-01, 2.73306667e-06, 5.71513333e-07], - [4.64960000e-01, 2.36153333e-06, 5.24806667e-07], - [5.65160000e-01, 2.17460000e-06, 5.31346667e-07], - ], - ), - ], - backgrounds=[ - np.array( - [ - [1.1403e-02, 2.2300e-06, 0.0000e00], - [1.1973e-02, 2.2300e-06, 0.0000e00], - [1.2572e-02, 2.2300e-06, 0.0000e00], - [1.3201e-02, 2.2300e-06, 0.0000e00], - [1.3861e-02, 2.2300e-06, 0.0000e00], - [1.4554e-02, 2.2300e-06, 0.0000e00], - [1.5281e-02, 2.2300e-06, 0.0000e00], - [1.6045e-02, 2.2300e-06, 0.0000e00], - [1.6848e-02, 2.2300e-06, 0.0000e00], - [1.7690e-02, 2.2300e-06, 0.0000e00], - [1.8575e-02, 2.2300e-06, 0.0000e00], - [1.9503e-02, 2.2300e-06, 0.0000e00], - [2.0479e-02, 2.2300e-06, 0.0000e00], - [2.1502e-02, 2.2300e-06, 0.0000e00], - [2.2578e-02, 2.2300e-06, 0.0000e00], - [2.3706e-02, 2.2300e-06, 0.0000e00], - [2.4892e-02, 2.2300e-06, 0.0000e00], - [2.6136e-02, 2.2300e-06, 0.0000e00], - [2.7443e-02, 2.2300e-06, 0.0000e00], - [2.8815e-02, 2.2300e-06, 0.0000e00], - [3.0256e-02, 2.2300e-06, 0.0000e00], - [3.1769e-02, 2.2300e-06, 0.0000e00], - [3.3357e-02, 2.2300e-06, 0.0000e00], - [3.5025e-02, 2.2300e-06, 0.0000e00], - [3.6777e-02, 2.2300e-06, 0.0000e00], - [3.8615e-02, 2.2300e-06, 0.0000e00], - [4.0546e-02, 2.2300e-06, 0.0000e00], - [4.2573e-02, 2.2300e-06, 0.0000e00], - [4.4702e-02, 2.2300e-06, 0.0000e00], - [4.6937e-02, 2.2300e-06, 0.0000e00], - [4.9284e-02, 2.2300e-06, 0.0000e00], - [5.1748e-02, 2.2300e-06, 0.0000e00], - [5.4336e-02, 2.2300e-06, 0.0000e00], - [5.7052e-02, 2.2300e-06, 0.0000e00], - [5.9905e-02, 2.2300e-06, 0.0000e00], - [6.2900e-02, 2.2300e-06, 0.0000e00], - [6.6045e-02, 2.2300e-06, 0.0000e00], - [6.9348e-02, 2.2300e-06, 0.0000e00], - [7.2815e-02, 2.2300e-06, 0.0000e00], - [7.6456e-02, 2.2300e-06, 0.0000e00], - [8.0279e-02, 2.2300e-06, 0.0000e00], - [8.4292e-02, 2.2300e-06, 0.0000e00], - [8.8507e-02, 2.2300e-06, 0.0000e00], - [9.2932e-02, 2.2300e-06, 0.0000e00], - [9.7579e-02, 2.2300e-06, 0.0000e00], - [1.0246e-01, 2.2300e-06, 0.0000e00], - [1.0758e-01, 2.2300e-06, 0.0000e00], - [1.1296e-01, 2.2300e-06, 0.0000e00], - [1.1861e-01, 2.2300e-06, 0.0000e00], - [1.2454e-01, 2.2300e-06, 0.0000e00], - [1.3077e-01, 2.2300e-06, 0.0000e00], - [1.3730e-01, 2.2300e-06, 0.0000e00], - [1.4417e-01, 2.2300e-06, 0.0000e00], - [1.5138e-01, 2.2300e-06, 0.0000e00], - [1.5895e-01, 2.2300e-06, 0.0000e00], - [1.6689e-01, 2.2300e-06, 0.0000e00], - [1.7524e-01, 2.2300e-06, 0.0000e00], - [1.8400e-01, 2.2300e-06, 0.0000e00], - [1.9320e-01, 2.2300e-06, 0.0000e00], - [2.0286e-01, 2.2300e-06, 0.0000e00], - [2.1300e-01, 2.2300e-06, 0.0000e00], - [2.2365e-01, 2.2300e-06, 0.0000e00], - [2.3484e-01, 2.2300e-06, 0.0000e00], - [2.4658e-01, 2.2300e-06, 0.0000e00], - [2.5891e-01, 2.2300e-06, 0.0000e00], - [2.7185e-01, 2.2300e-06, 0.0000e00], - [2.8544e-01, 2.2300e-06, 0.0000e00], - [2.9972e-01, 2.2300e-06, 0.0000e00], - [3.1470e-01, 2.2300e-06, 0.0000e00], - [3.3044e-01, 2.2300e-06, 0.0000e00], - [3.4696e-01, 2.2300e-06, 0.0000e00], - [3.6431e-01, 2.2300e-06, 0.0000e00], - [3.8252e-01, 2.2300e-06, 0.0000e00], - [4.0165e-01, 2.2300e-06, 0.0000e00], - [4.2173e-01, 2.2300e-06, 0.0000e00], - [4.4282e-01, 2.2300e-06, 0.0000e00], - [4.6496e-01, 2.2300e-06, 0.0000e00], - [4.8821e-01, 2.2300e-06, 0.0000e00], - [5.1262e-01, 2.2300e-06, 0.0000e00], - [5.3825e-01, 2.2300e-06, 0.0000e00], - [5.6516e-01, 2.2300e-06, 0.0000e00], - [5.9342e-01, 2.2300e-06, 0.0000e00], - ] - ), - np.array( - [ - [1.1403e-02, 3.3800e-06, 0.0000e00], - [1.1973e-02, 3.3800e-06, 0.0000e00], - [1.2572e-02, 3.3800e-06, 0.0000e00], - [1.3201e-02, 3.3800e-06, 0.0000e00], - [1.3861e-02, 3.3800e-06, 0.0000e00], - [1.4554e-02, 3.3800e-06, 0.0000e00], - [1.5281e-02, 3.3800e-06, 0.0000e00], - [1.6045e-02, 3.3800e-06, 0.0000e00], - [1.6848e-02, 3.3800e-06, 0.0000e00], - [1.7690e-02, 3.3800e-06, 0.0000e00], - [1.8575e-02, 3.3800e-06, 0.0000e00], - [1.9503e-02, 3.3800e-06, 0.0000e00], - [2.0479e-02, 3.3800e-06, 0.0000e00], - [2.1502e-02, 3.3800e-06, 0.0000e00], - [2.2578e-02, 3.3800e-06, 0.0000e00], - [2.3706e-02, 3.3800e-06, 0.0000e00], - [2.4892e-02, 3.3800e-06, 0.0000e00], - [2.6136e-02, 3.3800e-06, 0.0000e00], - [2.7443e-02, 3.3800e-06, 0.0000e00], - [2.8815e-02, 3.3800e-06, 0.0000e00], - [3.0256e-02, 3.3800e-06, 0.0000e00], - [3.1769e-02, 3.3800e-06, 0.0000e00], - [3.3357e-02, 3.3800e-06, 0.0000e00], - [3.5025e-02, 3.3800e-06, 0.0000e00], - [3.6777e-02, 3.3800e-06, 0.0000e00], - [3.8615e-02, 3.3800e-06, 0.0000e00], - [4.0546e-02, 3.3800e-06, 0.0000e00], - [4.2573e-02, 3.3800e-06, 0.0000e00], - [4.4702e-02, 3.3800e-06, 0.0000e00], - [4.6937e-02, 3.3800e-06, 0.0000e00], - [4.9284e-02, 3.3800e-06, 0.0000e00], - [5.1748e-02, 3.3800e-06, 0.0000e00], - [5.4336e-02, 3.3800e-06, 0.0000e00], - [5.7052e-02, 3.3800e-06, 0.0000e00], - [5.9905e-02, 3.3800e-06, 0.0000e00], - [6.2900e-02, 3.3800e-06, 0.0000e00], - [6.6045e-02, 3.3800e-06, 0.0000e00], - [6.9348e-02, 3.3800e-06, 0.0000e00], - [7.2815e-02, 3.3800e-06, 0.0000e00], - [7.6456e-02, 3.3800e-06, 0.0000e00], - [8.0279e-02, 3.3800e-06, 0.0000e00], - [8.4292e-02, 3.3800e-06, 0.0000e00], - [8.8507e-02, 3.3800e-06, 0.0000e00], - [9.2932e-02, 3.3800e-06, 0.0000e00], - [9.7579e-02, 3.3800e-06, 0.0000e00], - [1.0246e-01, 3.3800e-06, 0.0000e00], - [1.0758e-01, 3.3800e-06, 0.0000e00], - [1.1296e-01, 3.3800e-06, 0.0000e00], - [1.1861e-01, 3.3800e-06, 0.0000e00], - [1.2454e-01, 3.3800e-06, 0.0000e00], - [1.3077e-01, 3.3800e-06, 0.0000e00], - [1.3730e-01, 3.3800e-06, 0.0000e00], - [1.4417e-01, 3.3800e-06, 0.0000e00], - [1.5138e-01, 3.3800e-06, 0.0000e00], - [1.5895e-01, 3.3800e-06, 0.0000e00], - [1.6689e-01, 3.3800e-06, 0.0000e00], - [1.7524e-01, 3.3800e-06, 0.0000e00], - [1.8400e-01, 3.3800e-06, 0.0000e00], - [1.9320e-01, 3.3800e-06, 0.0000e00], - [2.0286e-01, 3.3800e-06, 0.0000e00], - [2.1300e-01, 3.3800e-06, 0.0000e00], - [2.2365e-01, 3.3800e-06, 0.0000e00], - [2.3484e-01, 3.3800e-06, 0.0000e00], - [2.4658e-01, 3.3800e-06, 0.0000e00], - [2.5891e-01, 3.3800e-06, 0.0000e00], - [2.7185e-01, 3.3800e-06, 0.0000e00], - [2.8544e-01, 3.3800e-06, 0.0000e00], - [2.9972e-01, 3.3800e-06, 0.0000e00], - [3.1470e-01, 3.3800e-06, 0.0000e00], - [3.3044e-01, 3.3800e-06, 0.0000e00], - [3.4696e-01, 3.3800e-06, 0.0000e00], - [3.6431e-01, 3.3800e-06, 0.0000e00], - [3.8252e-01, 3.3800e-06, 0.0000e00], - [4.0165e-01, 3.3800e-06, 0.0000e00], - [4.2173e-01, 3.3800e-06, 0.0000e00], - [4.4282e-01, 3.3800e-06, 0.0000e00], - [4.6496e-01, 3.3800e-06, 0.0000e00], - [4.8821e-01, 3.3800e-06, 0.0000e00], - [5.1262e-01, 3.3800e-06, 0.0000e00], - [5.3825e-01, 3.3800e-06, 0.0000e00], - [5.6516e-01, 3.3800e-06, 0.0000e00], - [5.9342e-01, 3.3800e-06, 0.0000e00], - ] - ), - ], - resolutions=[ - np.array( - [ - [0.011403, 0.03], - [0.011973, 0.03], - [0.012572, 0.03], - [0.013201, 0.03], - [0.013861, 0.03], - [0.014554, 0.03], - [0.015281, 0.03], - [0.016045, 0.03], - [0.016848, 0.03], - [0.01769, 0.03], - [0.018575, 0.03], - [0.019503, 0.03], - [0.020479, 0.03], - [0.021502, 0.03], - [0.022578, 0.03], - [0.023706, 0.03], - [0.024892, 0.03], - [0.026136, 0.03], - [0.027443, 0.03], - [0.028815, 0.03], - [0.030256, 0.03], - [0.031769, 0.03], - [0.033357, 0.03], - [0.035025, 0.03], - [0.036777, 0.03], - [0.038615, 0.03], - [0.040546, 0.03], - [0.042573, 0.03], - [0.044702, 0.03], - [0.046937, 0.03], - [0.049284, 0.03], - [0.051748, 0.03], - [0.054336, 0.03], - [0.057052, 0.03], - [0.059905, 0.03], - [0.0629, 0.03], - [0.066045, 0.03], - [0.069348, 0.03], - [0.072815, 0.03], - [0.076456, 0.03], - [0.080279, 0.03], - [0.084292, 0.03], - [0.088507, 0.03], - [0.092932, 0.03], - [0.097579, 0.03], - [0.10246, 0.03], - [0.10758, 0.03], - [0.11296, 0.03], - [0.11861, 0.03], - [0.12454, 0.03], - [0.13077, 0.03], - [0.1373, 0.03], - [0.14417, 0.03], - [0.15138, 0.03], - [0.15895, 0.03], - [0.16689, 0.03], - [0.17524, 0.03], - [0.184, 0.03], - [0.1932, 0.03], - [0.20286, 0.03], - [0.213, 0.03], - [0.22365, 0.03], - [0.23484, 0.03], - [0.24658, 0.03], - [0.25891, 0.03], - [0.27185, 0.03], - [0.28544, 0.03], - [0.29972, 0.03], - [0.3147, 0.03], - [0.33044, 0.03], - [0.34696, 0.03], - [0.36431, 0.03], - [0.38252, 0.03], - [0.40165, 0.03], - [0.42173, 0.03], - [0.44282, 0.03], - [0.46496, 0.03], - [0.48821, 0.03], - [0.51262, 0.03], - [0.53825, 0.03], - [0.56516, 0.03], - [0.59342, 0.03], - ] - ), - np.array( - [ - [0.011403, 0.03], - [0.011973, 0.03], - [0.012572, 0.03], - [0.013201, 0.03], - [0.013861, 0.03], - [0.014554, 0.03], - [0.015281, 0.03], - [0.016045, 0.03], - [0.016848, 0.03], - [0.01769, 0.03], - [0.018575, 0.03], - [0.019503, 0.03], - [0.020479, 0.03], - [0.021502, 0.03], - [0.022578, 0.03], - [0.023706, 0.03], - [0.024892, 0.03], - [0.026136, 0.03], - [0.027443, 0.03], - [0.028815, 0.03], - [0.030256, 0.03], - [0.031769, 0.03], - [0.033357, 0.03], - [0.035025, 0.03], - [0.036777, 0.03], - [0.038615, 0.03], - [0.040546, 0.03], - [0.042573, 0.03], - [0.044702, 0.03], - [0.046937, 0.03], - [0.049284, 0.03], - [0.051748, 0.03], - [0.054336, 0.03], - [0.057052, 0.03], - [0.059905, 0.03], - [0.0629, 0.03], - [0.066045, 0.03], - [0.069348, 0.03], - [0.072815, 0.03], - [0.076456, 0.03], - [0.080279, 0.03], - [0.084292, 0.03], - [0.088507, 0.03], - [0.092932, 0.03], - [0.097579, 0.03], - [0.10246, 0.03], - [0.10758, 0.03], - [0.11296, 0.03], - [0.11861, 0.03], - [0.12454, 0.03], - [0.13077, 0.03], - [0.1373, 0.03], - [0.14417, 0.03], - [0.15138, 0.03], - [0.15895, 0.03], - [0.16689, 0.03], - [0.17524, 0.03], - [0.184, 0.03], - [0.1932, 0.03], - [0.20286, 0.03], - [0.213, 0.03], - [0.22365, 0.03], - [0.23484, 0.03], - [0.24658, 0.03], - [0.25891, 0.03], - [0.27185, 0.03], - [0.28544, 0.03], - [0.29972, 0.03], - [0.3147, 0.03], - [0.33044, 0.03], - [0.34696, 0.03], - [0.36431, 0.03], - [0.38252, 0.03], - [0.40165, 0.03], - [0.42173, 0.03], - [0.44282, 0.03], - [0.46496, 0.03], - [0.48821, 0.03], - [0.51262, 0.03], - [0.53825, 0.03], - [0.56516, 0.03], - [0.59342, 0.03], - ] - ), - ], - sldProfiles=[ - [ - np.array( - [ - [0.00000000e00, 2.07300000e-06], - [1.10000000e01, 2.07300000e-06], - [2.20000000e01, 2.07300000e-06], - [3.30000000e01, 2.07300001e-06], - [4.40000000e01, 2.11687361e-06], - [5.50000000e01, 3.90933280e-06], - [6.60000000e01, 3.51748792e-06], - [7.70000000e01, -2.64615370e-08], - [8.80000000e01, 8.14665196e-07], - [9.90000000e01, 4.11508879e-06], - [1.10000000e02, 5.58392432e-06], - [1.21000000e02, 3.71785214e-06], - [1.32000000e02, 1.39304140e-06], - [1.43000000e02, 6.95745588e-07], - [1.54000000e02, 7.84170141e-07], - [1.65000000e02, 2.15552213e-06], - [1.76000000e02, 4.68458332e-06], - [1.87000000e02, 5.91563638e-06], - [1.98000000e02, 5.97982117e-06], - [2.09000000e02, 5.97999998e-06], - [2.20000000e02, 5.98000000e-06], - [2.31000000e02, 5.98000000e-06], - [2.42000000e02, 5.98000000e-06], - [2.53000000e02, 5.98000000e-06], - [2.64000000e02, 5.98000000e-06], - ], - ), - np.array( - [ - [0.00000000e00, 2.07300000e-06], - [1.10000000e01, 2.07300000e-06], - [2.20000000e01, 2.07300000e-06], - [3.30000000e01, 2.07300001e-06], - [4.40000000e01, 2.09662378e-06], - [5.50000000e01, 3.06177428e-06], - [6.60000000e01, 2.70974796e-06], - [7.70000000e01, -2.34283042e-07], - [8.80000000e01, 2.46446429e-07], - [9.90000000e01, 1.80004279e-06], - [1.10000000e02, 2.14886270e-06], - [1.21000000e02, 1.70090192e-06], - [1.32000000e02, 5.06554250e-07], - [1.43000000e02, 2.47801381e-08], - [1.54000000e02, 8.73866316e-08], - [1.65000000e02, 9.86362863e-07], - [1.76000000e02, 1.96411923e-06], - [1.87000000e02, 2.19933821e-06], - [1.98000000e02, 2.20997064e-06], - [2.09000000e02, 2.21000000e-06], - [2.20000000e02, 2.21000000e-06], - [2.31000000e02, 2.21000000e-06], - [2.42000000e02, 2.21000000e-06], - [2.53000000e02, 2.21000000e-06], - [2.64000000e02, 2.21000000e-06], - ], - ), - ], - ], - layers=[ - [ - np.array( - [ - [1.954000e01, 4.001499e-06, 3.000000e00], - [2.266000e01, -6.586988e-08, 3.000000e00], - [8.560000e00, 3.672535e-06, 5.640000e00], - [1.712000e01, 5.980000e-06, 5.640000e00], - [1.070000e01, 3.100365e-06, 6.014000e00], - [1.782000e01, 6.751924e-07, 6.014000e00], - [1.782000e01, 6.751924e-07, 6.014000e00], - [1.070000e01, 3.100365e-06, 6.014000e00], - ], - ), - ], - [ - np.array( - [ - [1.9540000e01, 3.1114020e-06, 3.0000000e00], - [2.2660000e01, -2.6387028e-07, 3.0000000e00], - [8.5600000e00, 1.9590700e-06, 5.6400000e00], - [1.7120000e01, 2.2100000e-06, 5.6400000e00], - [1.0700000e01, 1.7375100e-06, 6.0140000e00], - [1.7820000e01, 1.0164400e-08, 6.0140000e00], - [1.7820000e01, 1.0164400e-08, 6.0140000e00], - [1.0700000e01, 1.7375100e-06, 6.0140000e00], - ], - ), - ], - ], - resampledLayers=[[np.array([[0.0, 0.0, 0.0]])], [np.array([[0.0, 0.0, 0.0]])]], - calculationResults=ratapi.outputs.CalculationResults( - chiValues=np.array([202.83057377, 1641.4024969]), - sumChi=1844.2330706690975, - ), - contrastParams=ratapi.outputs.ContrastParams( - scalefactors=np.array([0.1, 0.15]), - bulkIn=np.array([2.073e-06, 2.073e-06]), - bulkOut=np.array([5.98e-06, 2.21e-06]), - subRoughs=np.array([3.0, 3.0]), - resample=np.array([0.0, 0.0]), - ), - fitParams=np.array( - [ - 3.000e00, - 1.954e01, - 2.266e01, - 5.252e00, - 5.640e00, - 1.712e01, - 8.560e00, - 4.545e01, - 1.070e01, - 6.014e00, - 1.782e01, - 1.764e01, - 3.615e01, - 2.361e01, - 2.230e-06, - 3.380e-06, - 5.980e-06, - 2.210e-06, - ], - ), - fitNames=[ - "Substrate Roughness", - "Oxide Thickness", - "SAM Tails Thickness", - "SAM Tails Hydration", - "SAM Roughness", - "CW Thickness", - "SAM Heads Thickness", - "SAM Heads Hydration", - "Bilayer Heads Thickness", - "Bilayer Roughness", - "Bilayer Tails Thickness", - "Bilayer Tails Hydration", - "Bilayer Heads Hydration", - "Oxide Hydration", - "Background parameter D2O", - "Background parameter SMW", - "D2O", - "SMW", - ], - ) - - -@pytest.fixture -def dream_output_results(): - """The C++ results object for a Dream optimisation of the project set out in "DSPC_standard_layers.py". - - This optimisation used the parameters: nSamples=1, nChains=1. However, the calculationResults, contrastParams, - and fitParams are taken from an optimisation with the parameters: nSamples=50000, nChains=10. - """ - results = ratapi.rat_core.OutputResult() - results.reflectivity = [ - np.array( - [ - [1.14030000e-02, 1.45891447e01], - [1.38610000e-02, 1.45739839e01], - [1.68480000e-02, 1.45684725e01], - [2.04790000e-02, 1.45658452e01], - [2.48920000e-02, 1.45641513e01], - [3.02560000e-02, 1.45628311e01], - [3.67770000e-02, 1.45618510e01], - [4.47020000e-02, 1.45613427e01], - [5.43360000e-02, 1.45612940e01], - [6.60450000e-02, 1.45613971e01], - [8.02790000e-02, 1.45613678e01], - [9.75790000e-02, 1.45612960e01], - [1.18610000e-01, 1.45612799e01], - [1.44170000e-01, 1.45612749e01], - [1.75240000e-01, 1.45612726e01], - [2.13000000e-01, 1.45612723e01], - [2.58910000e-01, 1.45612724e01], - [3.14700000e-01, 1.45612723e01], - [3.82520000e-01, 1.45612723e01], - [4.64960000e-01, 1.45612723e01], - [5.65160000e-01, 1.45612723e01], - ], - ), - np.array( - [ - [1.14030000e-02, 1.00000316e00], - [1.38610000e-02, 1.21238320e-01], - [1.68480000e-02, 2.13433068e-02], - [2.04790000e-02, 8.71162144e-03], - [2.48920000e-02, 5.72807902e-03], - [3.02560000e-02, 3.71827525e-03], - [3.67770000e-02, 1.72067772e-03], - [4.47020000e-02, 3.51471141e-04], - [5.43360000e-02, 2.03975460e-05], - [6.60450000e-02, 1.89221181e-04], - [8.02790000e-02, 1.49280488e-04], - [9.75790000e-02, 3.86439083e-05], - [1.18610000e-01, 1.63612094e-05], - [1.44170000e-01, 6.75770325e-06], - [1.75240000e-01, 3.45955607e-06], - [2.13000000e-01, 3.20880782e-06], - [2.58910000e-01, 3.32068345e-06], - [3.14700000e-01, 3.21671807e-06], - [3.82520000e-01, 3.15612021e-06], - [4.64960000e-01, 3.15645546e-06], - [5.65160000e-01, 3.15511510e-06], - ], - ), - ] - results.simulation = [ - np.array( - [ - [1.14030000e-02, 1.45891447e01], - [1.38610000e-02, 1.45739839e01], - [1.68480000e-02, 1.45684725e01], - [2.04790000e-02, 1.45658452e01], - [2.48920000e-02, 1.45641513e01], - [3.02560000e-02, 1.45628311e01], - [3.67770000e-02, 1.45618510e01], - [4.47020000e-02, 1.45613427e01], - [5.43360000e-02, 1.45612940e01], - [6.60450000e-02, 1.45613971e01], - [8.02790000e-02, 1.45613678e01], - [9.75790000e-02, 1.45612960e01], - [1.18610000e-01, 1.45612799e01], - [1.44170000e-01, 1.45612749e01], - [1.75240000e-01, 1.45612726e01], - [2.13000000e-01, 1.45612723e01], - [2.58910000e-01, 1.45612724e01], - [3.14700000e-01, 1.45612723e01], - [3.82520000e-01, 1.45612723e01], - [4.64960000e-01, 1.45612723e01], - [5.65160000e-01, 1.45612723e01], - ], - ), - np.array( - [ - [1.14030000e-02, 1.00000316e00], - [1.38610000e-02, 1.21238320e-01], - [1.68480000e-02, 2.13433068e-02], - [2.04790000e-02, 8.71162144e-03], - [2.48920000e-02, 5.72807902e-03], - [3.02560000e-02, 3.71827525e-03], - [3.67770000e-02, 1.72067772e-03], - [4.47020000e-02, 3.51471141e-04], - [5.43360000e-02, 2.03975460e-05], - [6.60450000e-02, 1.89221181e-04], - [8.02790000e-02, 1.49280488e-04], - [9.75790000e-02, 3.86439083e-05], - [1.18610000e-01, 1.63612094e-05], - [1.44170000e-01, 6.75770325e-06], - [1.75240000e-01, 3.45955607e-06], - [2.13000000e-01, 3.20880782e-06], - [2.58910000e-01, 3.32068345e-06], - [3.14700000e-01, 3.21671807e-06], - [3.82520000e-01, 3.15612021e-06], - [4.64960000e-01, 3.15645546e-06], - [5.65160000e-01, 3.15511510e-06], - ], - ), - ] - results.shiftedData = [ - np.array( - [ - [1.1403e-02, 1.0063e00, 1.9003e-02], - [1.3861e-02, 9.0118e-01, 1.1774e-02], - [1.6848e-02, 7.0455e-02, 1.3083e-03], - [2.0479e-02, 1.7544e-02, 5.1254e-04], - [2.4892e-02, 6.4257e-03, 2.6236e-04], - [3.0256e-02, 2.7746e-03, 8.5758e-05], - [3.6777e-02, 1.8591e-03, 4.9391e-05], - [4.4702e-02, 1.1002e-03, 3.2644e-05], - [5.4336e-02, 6.6691e-04, 2.1365e-05], - [6.6045e-02, 6.0729e-04, 1.1791e-05], - [8.0279e-02, 5.8755e-04, 1.5569e-05], - [9.7579e-02, 3.2700e-04, 6.5280e-06], - [1.1861e-01, 7.8205e-05, 2.5881e-06], - [1.4417e-01, 3.3455e-05, 1.5143e-06], - [1.7524e-01, 4.9313e-06, 5.6663e-07], - [2.1300e-01, 4.1948e-06, 6.8549e-07], - [2.5891e-01, 3.9863e-06, 8.2061e-07], - [3.1470e-01, 2.0861e-06, 6.1379e-07], - [3.8252e-01, 2.1154e-06, 6.3084e-07], - [4.6496e-01, 1.9906e-06, 6.0793e-07], - [5.6516e-01, 2.3816e-06, 7.0610e-07], - ], - ), - np.array( - [ - [1.14030000e-02, 1.20493333e-02, 7.32200000e-04], - [1.38610000e-02, 6.71800000e-03, 3.71853333e-04], - [1.68480000e-02, 4.10506667e-03, 2.23106667e-04], - [2.04790000e-02, 2.43306667e-03, 1.46873333e-04], - [2.48920000e-02, 1.40940000e-03, 9.59200000e-05], - [3.02560000e-02, 7.43400000e-04, 3.50226667e-05], - [3.67770000e-02, 3.51466667e-04, 1.59573333e-05], - [4.47020000e-02, 9.80666667e-05, 7.29466667e-06], - [5.43360000e-02, 1.73500000e-05, 2.59200000e-06], - [6.60450000e-02, 4.86286667e-05, 2.46453333e-06], - [8.02790000e-02, 9.71733333e-05, 4.68166667e-06], - [9.75790000e-02, 7.06533333e-05, 2.32180000e-06], - [1.18610000e-01, 1.93046667e-05, 1.00813333e-06], - [1.44170000e-01, 6.61193333e-06, 5.29773333e-07], - [1.75240000e-01, 3.23726667e-06, 3.65933333e-07], - [2.13000000e-01, 3.29920000e-06, 4.74273333e-07], - [2.58910000e-01, 1.71180000e-06, 4.24720000e-07], - [3.14700000e-01, 2.24020000e-06, 5.08946667e-07], - [3.82520000e-01, 2.73306667e-06, 5.71513333e-07], - [4.64960000e-01, 2.36153333e-06, 5.24806667e-07], - [5.65160000e-01, 2.17460000e-06, 5.31346667e-07], - ], - ), - ] - results.backgrounds = [ - np.array( - [ - [1.14030000e-02, 2.37401704e-06, 0.00000000e00], - [1.19730000e-02, 2.37401704e-06, 0.00000000e00], - [1.25720000e-02, 2.37401704e-06, 0.00000000e00], - [1.32010000e-02, 2.37401704e-06, 0.00000000e00], - [1.38610000e-02, 2.37401704e-06, 0.00000000e00], - [1.45540000e-02, 2.37401704e-06, 0.00000000e00], - [1.52810000e-02, 2.37401704e-06, 0.00000000e00], - [1.60450000e-02, 2.37401704e-06, 0.00000000e00], - [1.68480000e-02, 2.37401704e-06, 0.00000000e00], - [1.76900000e-02, 2.37401704e-06, 0.00000000e00], - [1.85750000e-02, 2.37401704e-06, 0.00000000e00], - [1.95030000e-02, 2.37401704e-06, 0.00000000e00], - [2.04790000e-02, 2.37401704e-06, 0.00000000e00], - [2.15020000e-02, 2.37401704e-06, 0.00000000e00], - [2.25780000e-02, 2.37401704e-06, 0.00000000e00], - [2.37060000e-02, 2.37401704e-06, 0.00000000e00], - [2.48920000e-02, 2.37401704e-06, 0.00000000e00], - [2.61360000e-02, 2.37401704e-06, 0.00000000e00], - [2.74430000e-02, 2.37401704e-06, 0.00000000e00], - [2.88150000e-02, 2.37401704e-06, 0.00000000e00], - [3.02560000e-02, 2.37401704e-06, 0.00000000e00], - [3.17690000e-02, 2.37401704e-06, 0.00000000e00], - [3.33570000e-02, 2.37401704e-06, 0.00000000e00], - [3.50250000e-02, 2.37401704e-06, 0.00000000e00], - [3.67770000e-02, 2.37401704e-06, 0.00000000e00], - [3.86150000e-02, 2.37401704e-06, 0.00000000e00], - [4.05460000e-02, 2.37401704e-06, 0.00000000e00], - [4.25730000e-02, 2.37401704e-06, 0.00000000e00], - [4.47020000e-02, 2.37401704e-06, 0.00000000e00], - [4.69370000e-02, 2.37401704e-06, 0.00000000e00], - [4.92840000e-02, 2.37401704e-06, 0.00000000e00], - [5.17480000e-02, 2.37401704e-06, 0.00000000e00], - [5.43360000e-02, 2.37401704e-06, 0.00000000e00], - [5.70520000e-02, 2.37401704e-06, 0.00000000e00], - [5.99050000e-02, 2.37401704e-06, 0.00000000e00], - [6.29000000e-02, 2.37401704e-06, 0.00000000e00], - [6.60450000e-02, 2.37401704e-06, 0.00000000e00], - [6.93480000e-02, 2.37401704e-06, 0.00000000e00], - [7.28150000e-02, 2.37401704e-06, 0.00000000e00], - [7.64560000e-02, 2.37401704e-06, 0.00000000e00], - [8.02790000e-02, 2.37401704e-06, 0.00000000e00], - [8.42920000e-02, 2.37401704e-06, 0.00000000e00], - [8.85070000e-02, 2.37401704e-06, 0.00000000e00], - [9.29320000e-02, 2.37401704e-06, 0.00000000e00], - [9.75790000e-02, 2.37401704e-06, 0.00000000e00], - [1.02460000e-01, 2.37401704e-06, 0.00000000e00], - [1.07580000e-01, 2.37401704e-06, 0.00000000e00], - [1.12960000e-01, 2.37401704e-06, 0.00000000e00], - [1.18610000e-01, 2.37401704e-06, 0.00000000e00], - [1.24540000e-01, 2.37401704e-06, 0.00000000e00], - [1.30770000e-01, 2.37401704e-06, 0.00000000e00], - [1.37300000e-01, 2.37401704e-06, 0.00000000e00], - [1.44170000e-01, 2.37401704e-06, 0.00000000e00], - [1.51380000e-01, 2.37401704e-06, 0.00000000e00], - [1.58950000e-01, 2.37401704e-06, 0.00000000e00], - [1.66890000e-01, 2.37401704e-06, 0.00000000e00], - [1.75240000e-01, 2.37401704e-06, 0.00000000e00], - [1.84000000e-01, 2.37401704e-06, 0.00000000e00], - [1.93200000e-01, 2.37401704e-06, 0.00000000e00], - [2.02860000e-01, 2.37401704e-06, 0.00000000e00], - [2.13000000e-01, 2.37401704e-06, 0.00000000e00], - [2.23650000e-01, 2.37401704e-06, 0.00000000e00], - [2.34840000e-01, 2.37401704e-06, 0.00000000e00], - [2.46580000e-01, 2.37401704e-06, 0.00000000e00], - [2.58910000e-01, 2.37401704e-06, 0.00000000e00], - [2.71850000e-01, 2.37401704e-06, 0.00000000e00], - [2.85440000e-01, 2.37401704e-06, 0.00000000e00], - [2.99720000e-01, 2.37401704e-06, 0.00000000e00], - [3.14700000e-01, 2.37401704e-06, 0.00000000e00], - [3.30440000e-01, 2.37401704e-06, 0.00000000e00], - [3.46960000e-01, 2.37401704e-06, 0.00000000e00], - [3.64310000e-01, 2.37401704e-06, 0.00000000e00], - [3.82520000e-01, 2.37401704e-06, 0.00000000e00], - [4.01650000e-01, 2.37401704e-06, 0.00000000e00], - [4.21730000e-01, 2.37401704e-06, 0.00000000e00], - [4.42820000e-01, 2.37401704e-06, 0.00000000e00], - [4.64960000e-01, 2.37401704e-06, 0.00000000e00], - [4.88210000e-01, 2.37401704e-06, 0.00000000e00], - [5.12620000e-01, 2.37401704e-06, 0.00000000e00], - [5.38250000e-01, 2.37401704e-06, 0.00000000e00], - [5.65160000e-01, 2.37401704e-06, 0.00000000e00], - [5.93420000e-01, 2.37401704e-06, 0.00000000e00], - ] - ), - np.array( - [ - [1.14030000e-02, 2.19553929e-06, 0.00000000e00], - [1.19730000e-02, 2.19553929e-06, 0.00000000e00], - [1.25720000e-02, 2.19553929e-06, 0.00000000e00], - [1.32010000e-02, 2.19553929e-06, 0.00000000e00], - [1.38610000e-02, 2.19553929e-06, 0.00000000e00], - [1.45540000e-02, 2.19553929e-06, 0.00000000e00], - [1.52810000e-02, 2.19553929e-06, 0.00000000e00], - [1.60450000e-02, 2.19553929e-06, 0.00000000e00], - [1.68480000e-02, 2.19553929e-06, 0.00000000e00], - [1.76900000e-02, 2.19553929e-06, 0.00000000e00], - [1.85750000e-02, 2.19553929e-06, 0.00000000e00], - [1.95030000e-02, 2.19553929e-06, 0.00000000e00], - [2.04790000e-02, 2.19553929e-06, 0.00000000e00], - [2.15020000e-02, 2.19553929e-06, 0.00000000e00], - [2.25780000e-02, 2.19553929e-06, 0.00000000e00], - [2.37060000e-02, 2.19553929e-06, 0.00000000e00], - [2.48920000e-02, 2.19553929e-06, 0.00000000e00], - [2.61360000e-02, 2.19553929e-06, 0.00000000e00], - [2.74430000e-02, 2.19553929e-06, 0.00000000e00], - [2.88150000e-02, 2.19553929e-06, 0.00000000e00], - [3.02560000e-02, 2.19553929e-06, 0.00000000e00], - [3.17690000e-02, 2.19553929e-06, 0.00000000e00], - [3.33570000e-02, 2.19553929e-06, 0.00000000e00], - [3.50250000e-02, 2.19553929e-06, 0.00000000e00], - [3.67770000e-02, 2.19553929e-06, 0.00000000e00], - [3.86150000e-02, 2.19553929e-06, 0.00000000e00], - [4.05460000e-02, 2.19553929e-06, 0.00000000e00], - [4.25730000e-02, 2.19553929e-06, 0.00000000e00], - [4.47020000e-02, 2.19553929e-06, 0.00000000e00], - [4.69370000e-02, 2.19553929e-06, 0.00000000e00], - [4.92840000e-02, 2.19553929e-06, 0.00000000e00], - [5.17480000e-02, 2.19553929e-06, 0.00000000e00], - [5.43360000e-02, 2.19553929e-06, 0.00000000e00], - [5.70520000e-02, 2.19553929e-06, 0.00000000e00], - [5.99050000e-02, 2.19553929e-06, 0.00000000e00], - [6.29000000e-02, 2.19553929e-06, 0.00000000e00], - [6.60450000e-02, 2.19553929e-06, 0.00000000e00], - [6.93480000e-02, 2.19553929e-06, 0.00000000e00], - [7.28150000e-02, 2.19553929e-06, 0.00000000e00], - [7.64560000e-02, 2.19553929e-06, 0.00000000e00], - [8.02790000e-02, 2.19553929e-06, 0.00000000e00], - [8.42920000e-02, 2.19553929e-06, 0.00000000e00], - [8.85070000e-02, 2.19553929e-06, 0.00000000e00], - [9.29320000e-02, 2.19553929e-06, 0.00000000e00], - [9.75790000e-02, 2.19553929e-06, 0.00000000e00], - [1.02460000e-01, 2.19553929e-06, 0.00000000e00], - [1.07580000e-01, 2.19553929e-06, 0.00000000e00], - [1.12960000e-01, 2.19553929e-06, 0.00000000e00], - [1.18610000e-01, 2.19553929e-06, 0.00000000e00], - [1.24540000e-01, 2.19553929e-06, 0.00000000e00], - [1.30770000e-01, 2.19553929e-06, 0.00000000e00], - [1.37300000e-01, 2.19553929e-06, 0.00000000e00], - [1.44170000e-01, 2.19553929e-06, 0.00000000e00], - [1.51380000e-01, 2.19553929e-06, 0.00000000e00], - [1.58950000e-01, 2.19553929e-06, 0.00000000e00], - [1.66890000e-01, 2.19553929e-06, 0.00000000e00], - [1.75240000e-01, 2.19553929e-06, 0.00000000e00], - [1.84000000e-01, 2.19553929e-06, 0.00000000e00], - [1.93200000e-01, 2.19553929e-06, 0.00000000e00], - [2.02860000e-01, 2.19553929e-06, 0.00000000e00], - [2.13000000e-01, 2.19553929e-06, 0.00000000e00], - [2.23650000e-01, 2.19553929e-06, 0.00000000e00], - [2.34840000e-01, 2.19553929e-06, 0.00000000e00], - [2.46580000e-01, 2.19553929e-06, 0.00000000e00], - [2.58910000e-01, 2.19553929e-06, 0.00000000e00], - [2.71850000e-01, 2.19553929e-06, 0.00000000e00], - [2.85440000e-01, 2.19553929e-06, 0.00000000e00], - [2.99720000e-01, 2.19553929e-06, 0.00000000e00], - [3.14700000e-01, 2.19553929e-06, 0.00000000e00], - [3.30440000e-01, 2.19553929e-06, 0.00000000e00], - [3.46960000e-01, 2.19553929e-06, 0.00000000e00], - [3.64310000e-01, 2.19553929e-06, 0.00000000e00], - [3.82520000e-01, 2.19553929e-06, 0.00000000e00], - [4.01650000e-01, 2.19553929e-06, 0.00000000e00], - [4.21730000e-01, 2.19553929e-06, 0.00000000e00], - [4.42820000e-01, 2.19553929e-06, 0.00000000e00], - [4.64960000e-01, 2.19553929e-06, 0.00000000e00], - [4.88210000e-01, 2.19553929e-06, 0.00000000e00], - [5.12620000e-01, 2.19553929e-06, 0.00000000e00], - [5.38250000e-01, 2.19553929e-06, 0.00000000e00], - [5.65160000e-01, 2.19553929e-06, 0.00000000e00], - [5.93420000e-01, 2.19553929e-06, 0.00000000e00], - ] - ), - ] - results.resolutions = [ - np.array( - [ - [0.011403, 0.03], - [0.011973, 0.03], - [0.012572, 0.03], - [0.013201, 0.03], - [0.013861, 0.03], - [0.014554, 0.03], - [0.015281, 0.03], - [0.016045, 0.03], - [0.016848, 0.03], - [0.01769, 0.03], - [0.018575, 0.03], - [0.019503, 0.03], - [0.020479, 0.03], - [0.021502, 0.03], - [0.022578, 0.03], - [0.023706, 0.03], - [0.024892, 0.03], - [0.026136, 0.03], - [0.027443, 0.03], - [0.028815, 0.03], - [0.030256, 0.03], - [0.031769, 0.03], - [0.033357, 0.03], - [0.035025, 0.03], - [0.036777, 0.03], - [0.038615, 0.03], - [0.040546, 0.03], - [0.042573, 0.03], - [0.044702, 0.03], - [0.046937, 0.03], - [0.049284, 0.03], - [0.051748, 0.03], - [0.054336, 0.03], - [0.057052, 0.03], - [0.059905, 0.03], - [0.0629, 0.03], - [0.066045, 0.03], - [0.069348, 0.03], - [0.072815, 0.03], - [0.076456, 0.03], - [0.080279, 0.03], - [0.084292, 0.03], - [0.088507, 0.03], - [0.092932, 0.03], - [0.097579, 0.03], - [0.10246, 0.03], - [0.10758, 0.03], - [0.11296, 0.03], - [0.11861, 0.03], - [0.12454, 0.03], - [0.13077, 0.03], - [0.1373, 0.03], - [0.14417, 0.03], - [0.15138, 0.03], - [0.15895, 0.03], - [0.16689, 0.03], - [0.17524, 0.03], - [0.184, 0.03], - [0.1932, 0.03], - [0.20286, 0.03], - [0.213, 0.03], - [0.22365, 0.03], - [0.23484, 0.03], - [0.24658, 0.03], - [0.25891, 0.03], - [0.27185, 0.03], - [0.28544, 0.03], - [0.29972, 0.03], - [0.3147, 0.03], - [0.33044, 0.03], - [0.34696, 0.03], - [0.36431, 0.03], - [0.38252, 0.03], - [0.40165, 0.03], - [0.42173, 0.03], - [0.44282, 0.03], - [0.46496, 0.03], - [0.48821, 0.03], - [0.51262, 0.03], - [0.53825, 0.03], - [0.56516, 0.03], - [0.59342, 0.03], - ] - ), - np.array( - [ - [0.011403, 0.03], - [0.011973, 0.03], - [0.012572, 0.03], - [0.013201, 0.03], - [0.013861, 0.03], - [0.014554, 0.03], - [0.015281, 0.03], - [0.016045, 0.03], - [0.016848, 0.03], - [0.01769, 0.03], - [0.018575, 0.03], - [0.019503, 0.03], - [0.020479, 0.03], - [0.021502, 0.03], - [0.022578, 0.03], - [0.023706, 0.03], - [0.024892, 0.03], - [0.026136, 0.03], - [0.027443, 0.03], - [0.028815, 0.03], - [0.030256, 0.03], - [0.031769, 0.03], - [0.033357, 0.03], - [0.035025, 0.03], - [0.036777, 0.03], - [0.038615, 0.03], - [0.040546, 0.03], - [0.042573, 0.03], - [0.044702, 0.03], - [0.046937, 0.03], - [0.049284, 0.03], - [0.051748, 0.03], - [0.054336, 0.03], - [0.057052, 0.03], - [0.059905, 0.03], - [0.0629, 0.03], - [0.066045, 0.03], - [0.069348, 0.03], - [0.072815, 0.03], - [0.076456, 0.03], - [0.080279, 0.03], - [0.084292, 0.03], - [0.088507, 0.03], - [0.092932, 0.03], - [0.097579, 0.03], - [0.10246, 0.03], - [0.10758, 0.03], - [0.11296, 0.03], - [0.11861, 0.03], - [0.12454, 0.03], - [0.13077, 0.03], - [0.1373, 0.03], - [0.14417, 0.03], - [0.15138, 0.03], - [0.15895, 0.03], - [0.16689, 0.03], - [0.17524, 0.03], - [0.184, 0.03], - [0.1932, 0.03], - [0.20286, 0.03], - [0.213, 0.03], - [0.22365, 0.03], - [0.23484, 0.03], - [0.24658, 0.03], - [0.25891, 0.03], - [0.27185, 0.03], - [0.28544, 0.03], - [0.29972, 0.03], - [0.3147, 0.03], - [0.33044, 0.03], - [0.34696, 0.03], - [0.36431, 0.03], - [0.38252, 0.03], - [0.40165, 0.03], - [0.42173, 0.03], - [0.44282, 0.03], - [0.46496, 0.03], - [0.48821, 0.03], - [0.51262, 0.03], - [0.53825, 0.03], - [0.56516, 0.03], - [0.59342, 0.03], - ] - ), - ] - results.sldProfiles = [ - [ - np.array( - [ - [0.00000000e00, 2.07301741e-06], - [1.10000000e01, 2.07309604e-06], - [2.20000000e01, 2.07345780e-06], - [3.30000000e01, 2.07491687e-06], - [4.40000000e01, 2.17562259e-06], - [5.50000000e01, 3.22650495e-06], - [6.60000000e01, 3.40913848e-06], - [7.70000000e01, 3.13506253e-06], - [8.80000000e01, 1.20456289e-06], - [9.90000000e01, 1.27138002e-06], - [1.10000000e02, 1.56285495e-06], - [1.21000000e02, 1.84518709e-06], - [1.32000000e02, 2.00498449e-06], - [1.43000000e02, 1.96260665e-06], - [1.54000000e02, 1.71966879e-06], - [1.65000000e02, 1.39383267e-06], - [1.76000000e02, 1.22970195e-06], - [1.87000000e02, 1.41565526e-06], - [1.98000000e02, 1.88172657e-06], - [2.09000000e02, 2.40655867e-06], - [2.20000000e02, 2.83570420e-06], - [2.31000000e02, 3.11210082e-06], - [2.42000000e02, 3.24277802e-06], - [2.53000000e02, 3.28427452e-06], - [2.64000000e02, 3.29268847e-06], - [2.75000000e02, 3.29375418e-06], - [2.86000000e02, 3.29383773e-06], - [2.97000000e02, 3.29384178e-06], - [3.08000000e02, 3.29384190e-06], - ], - ), - np.array( - [ - [0.00000000e00, 2.07301819e-06], - [1.10000000e01, 2.07310296e-06], - [2.20000000e01, 2.07350415e-06], - [3.30000000e01, 2.07518460e-06], - [4.40000000e01, 2.23394767e-06], - [5.50000000e01, 3.90646736e-06], - [6.60000000e01, 4.18619279e-06], - [7.70000000e01, 3.91675004e-06], - [8.80000000e01, 1.92451547e-06], - [9.90000000e01, 2.06988861e-06], - [1.10000000e02, 2.47614934e-06], - [1.21000000e02, 2.84889288e-06], - [1.32000000e02, 3.00529286e-06], - [1.43000000e02, 2.86310144e-06], - [1.54000000e02, 2.49967205e-06], - [1.65000000e02, 2.09673058e-06], - [1.76000000e02, 1.92431424e-06], - [1.87000000e02, 2.18829605e-06], - [1.98000000e02, 2.83032190e-06], - [2.09000000e02, 3.62584708e-06], - [2.20000000e02, 4.36871153e-06], - [2.31000000e02, 4.89806866e-06], - [2.42000000e02, 5.16145928e-06], - [2.53000000e02, 5.24684298e-06], - [2.64000000e02, 5.26428707e-06], - [2.75000000e02, 5.26650242e-06], - [2.86000000e02, 5.26667628e-06], - [2.97000000e02, 5.26668469e-06], - [3.08000000e02, 5.26668495e-06], - ], - ), - ], - ] - results.layers = [ - [ - np.array( - [ - [3.15755349e01, 3.35278238e-06, 4.16625659e00], - [3.61791464e01, 7.68327921e-07, 4.16625659e00], - [1.00488530e01, 2.06044530e-06, 2.78042232e01], - [1.08043784e01, 3.29384190e-06, 2.78042232e01], - [2.42251646e01, 2.35556998e-06, 1.55593097e01], - [1.49022278e01, 7.42138004e-07, 1.55593097e01], - [1.49022278e01, 7.42138004e-07, 1.55593097e01], - [2.42251646e01, 2.35556998e-06, 1.55593097e01], - ], - ), - ], - [ - np.array( - [ - [3.15755349e01, 4.11636356e-06, 4.16625659e00], - [3.61791464e01, 1.39268494e-06, 4.16625659e00], - [1.00488530e01, 2.45715680e-06, 2.78042232e01], - [1.08043784e01, 5.26668495e-06, 2.78042232e01], - [2.42251646e01, 3.31348777e-06, 1.55593097e01], - [1.49022278e01, 1.37428245e-06, 1.55593097e01], - [1.49022278e01, 1.37428245e-06, 1.55593097e01], - [2.42251646e01, 3.31348777e-06, 1.55593097e01], - ], - ), - ], - ] - results.resampledLayers = [[np.array([[0.0, 0.0, 0.0]])], [np.array([[0.0, 0.0, 0.0]])]] - results.calculationResults = ratapi.rat_core.Calculation() - results.calculationResults.chiValues = (np.array([4.6077885, 7.00028098]),) - results.calculationResults.sumChi = 11.608069475997699 - results.contrastParams = ratapi.rat_core.ContrastParams() - results.contrastParams.scalefactors = np.array([0.1, 0.15]) - results.contrastParams.bulkIn = np.array([2.073e-06, 2.073e-06]) - results.contrastParams.bulkOut = np.array([6.01489149e-06, 1.59371685e-06]) - results.contrastParams.subRoughs = np.array([6.19503045, 6.19503045]) - results.contrastParams.resample = np.array([0.0, 0.0]) - results.fitParams = np.array( - [ - 6.19503045e00, - 1.84420960e01, - 2.11039621e01, - 8.75538121e00, - 3.72292994e00, - 1.84624551e01, - 1.02316734e01, - 2.31156093e01, - 1.09906265e01, - 5.71005361e00, - 1.67933822e01, - 1.72009856e01, - 3.00260126e01, - 2.94448999e01, - 2.37113128e-06, - 1.99006694e-06, - 6.01489149e-06, - 1.59371685e-06, - ], - ) - results.fitNames = [ - "Substrate Roughness", - "Oxide Thickness", - "SAM Tails Thickness", - "SAM Tails Hydration", - "SAM Roughness", - "CW Thickness", - "SAM Heads Thickness", - "SAM Heads Hydration", - "Bilayer Heads Thickness", - "Bilayer Roughness", - "Bilayer Tails Thickness", - "Bilayer Tails Hydration", - "Bilayer Heads Hydration", - "Oxide Hydration", - "Background parameter D2O", - "Background parameter SMW", - "D2O", - "SMW", - ] - - return results - - -@pytest.fixture -def dream_bayes(): - """The C++ BayesResults object for a dream optimisation of the project set out in "DSPC_standard_layers.py". - - This optimisation used the parameters: nSamples=1, nChains=1. - """ - bayes = ratapi.rat_core.OutputBayesResult() - bayes.predictionIntervals = ratapi.rat_core.PredictionIntervals() - bayes.predictionIntervals.reflectivity = [ - np.array( - [ - [ - 1.00000560e00, - 7.07687612e-01, - 2.08315160e-02, - 2.40787966e-03, - 2.17627660e-03, - 2.54301700e-03, - 1.76309827e-03, - 6.15269679e-04, - 3.43679710e-05, - 7.93625275e-05, - 1.27760549e-04, - 3.35799941e-05, - 6.75048751e-06, - 7.64258431e-06, - 6.05800395e-06, - 5.60288298e-06, - 5.60333677e-06, - 5.60223341e-06, - 5.60206667e-06, - 5.60206314e-06, - 5.60206314e-06, - ], - [ - 1.00000560e00, - 7.07687612e-01, - 2.08315160e-02, - 2.40787966e-03, - 2.17627660e-03, - 2.54301700e-03, - 1.76309827e-03, - 6.15269679e-04, - 3.43679710e-05, - 7.93625275e-05, - 1.27760549e-04, - 3.35799941e-05, - 6.75048751e-06, - 7.64258431e-06, - 6.05800395e-06, - 5.60288298e-06, - 5.60333677e-06, - 5.60223341e-06, - 5.60206667e-06, - 5.60206314e-06, - 5.60206314e-06, - ], - [ - 1.55201098e01, - 1.53748894e01, - 1.50402011e01, - 1.50299478e01, - 1.50290525e01, - 1.50287935e01, - 1.50282126e01, - 1.50276044e01, - 1.50273248e01, - 1.50273185e01, - 1.50272997e01, - 1.50272498e01, - 1.50272364e01, - 1.50272347e01, - 1.50272335e01, - 1.50272330e01, - 1.50272329e01, - 1.50272328e01, - 1.50272328e01, - 1.50272328e01, - 1.50272328e01, - ], - [ - 2.91397425e01, - 2.91324974e01, - 2.91281368e01, - 2.91255472e01, - 2.91240295e01, - 2.91231836e01, - 2.91227893e01, - 2.91226872e01, - 2.91226902e01, - 2.91226359e01, - 2.91225541e01, - 2.91225457e01, - 2.91225448e01, - 2.91225407e01, - 2.91225398e01, - 2.91225393e01, - 2.91225391e01, - 2.91225390e01, - 2.91225390e01, - 2.91225389e01, - 2.91225389e01, - ], - [ - 2.91397425e01, - 2.91324974e01, - 2.91281368e01, - 2.91255472e01, - 2.91240295e01, - 2.91231836e01, - 2.91227893e01, - 2.91226872e01, - 2.91226902e01, - 2.91226359e01, - 2.91225541e01, - 2.91225457e01, - 2.91225448e01, - 2.91225407e01, - 2.91225398e01, - 2.91225393e01, - 2.91225391e01, - 2.91225390e01, - 2.91225390e01, - 2.91225389e01, - 2.91225389e01, - ], - ], - ), - np.array( - [ - [ - 7.82198834e-01, - 2.84434275e-02, - 3.42472318e-03, - 1.45801296e-03, - 2.02213149e-03, - 2.00826891e-03, - 1.27577246e-03, - 4.27099544e-04, - 2.07304219e-05, - 4.88683542e-05, - 4.14000873e-05, - 1.57801531e-05, - 2.08705254e-06, - 2.27936213e-06, - 1.09950377e-06, - 7.09021331e-07, - 7.09539552e-07, - 7.08228574e-07, - 7.08101644e-07, - 7.08098642e-07, - 7.08098641e-07, - ], - [ - 7.82198834e-01, - 2.84434275e-02, - 3.42472318e-03, - 1.45801296e-03, - 2.02213149e-03, - 2.00826891e-03, - 1.27577246e-03, - 4.27099544e-04, - 2.07304219e-05, - 4.88683542e-05, - 4.14000873e-05, - 1.57801531e-05, - 2.08705254e-06, - 2.27936213e-06, - 1.09950377e-06, - 7.09021331e-07, - 7.09539552e-07, - 7.08228574e-07, - 7.08101644e-07, - 7.08098642e-07, - 7.08098641e-07, - ], - [ - 8.94587126e-01, - 4.07514176e-01, - 3.66355642e-02, - 1.22207690e-02, - 5.91350591e-03, - 3.17495745e-03, - 1.50593011e-03, - 5.80889579e-04, - 2.44654124e-04, - 1.40925782e-04, - 6.26965047e-05, - 1.91064075e-05, - 9.45189755e-06, - 6.16421495e-06, - 5.17046678e-06, - 4.24101973e-06, - 3.82067554e-06, - 3.55352666e-06, - 3.38981154e-06, - 3.29631224e-06, - 3.25061722e-06, - ], - [ - 1.00000560e00, - 7.63076662e-01, - 6.77868181e-02, - 2.23160672e-02, - 9.56355479e-03, - 4.26929321e-03, - 1.72181442e-03, - 7.25142247e-04, - 4.54691084e-04, - 2.27274223e-04, - 8.54009496e-05, - 2.26525796e-05, - 1.63600080e-05, - 9.80814666e-06, - 8.98896697e-06, - 7.55397947e-06, - 6.73887287e-06, - 6.22237216e-06, - 5.90521384e-06, - 5.72401646e-06, - 5.63546023e-06, - ], - [ - 1.00000560e00, - 7.63076662e-01, - 6.77868181e-02, - 2.23160672e-02, - 9.56355479e-03, - 4.26929321e-03, - 1.72181442e-03, - 7.25142247e-04, - 4.54691084e-04, - 2.27274223e-04, - 8.54009496e-05, - 2.26525796e-05, - 1.63600080e-05, - 9.80814666e-06, - 8.98896697e-06, - 7.55397947e-06, - 6.73887287e-06, - 6.22237216e-06, - 5.90521384e-06, - 5.72401646e-06, - 5.63546023e-06, - ], - ], - ), - ] - bayes.predictionIntervals.sld = [ - [ - np.array( - [ - [ - -2.26996619e-06, - -2.26166520e-06, - -2.24783719e-06, - -2.22613645e-06, - -2.19406176e-06, - -2.17142372e-06, - 1.88515086e-07, - 2.60653226e-07, - 3.44976651e-07, - 4.40965268e-07, - 5.53846231e-07, - 6.92263150e-07, - 8.41189317e-07, - 9.28611746e-07, - 8.59850711e-07, - 6.40672491e-07, - 4.45129915e-07, - 4.69261576e-07, - 7.08570915e-07, - 9.66403060e-07, - 1.08031232e-06, - 1.05528544e-06, - 9.86455522e-07, - 9.38980618e-07, - 9.20228966e-07, - 9.15507876e-07, - 9.14706158e-07, - 9.14597081e-07, - 9.14576711e-07, - ], - [ - -2.26996619e-06, - -2.26166520e-06, - -2.24783719e-06, - -2.22613645e-06, - -2.19406176e-06, - -2.17142372e-06, - 1.88515086e-07, - 2.60653226e-07, - 3.44976651e-07, - 4.40965268e-07, - 5.53846231e-07, - 6.92263150e-07, - 8.41189317e-07, - 9.28611746e-07, - 8.59850711e-07, - 6.40672491e-07, - 4.45129915e-07, - 4.69261576e-07, - 7.08570915e-07, - 9.66403060e-07, - 1.08031232e-06, - 1.05528544e-06, - 9.86455522e-07, - 9.38980618e-07, - 9.20228966e-07, - 9.15507876e-07, - 9.14706158e-07, - 9.14597081e-07, - 9.14576711e-07, - ], - [ - -1.50598689e-07, - -1.46347158e-07, - -1.38880755e-07, - -1.07564801e-07, - 1.23182525e-07, - 6.23089296e-07, - 2.07733185e-06, - 2.14065378e-06, - 2.16728982e-06, - 2.04144854e-06, - 1.74466846e-06, - 1.85390758e-06, - 2.36094420e-06, - 2.55768452e-06, - 2.25381054e-06, - 1.86530516e-06, - 1.68664783e-06, - 1.84743812e-06, - 2.30954159e-06, - 2.85224030e-06, - 3.22454811e-06, - 3.35997774e-06, - 3.36663861e-06, - 3.34928647e-06, - 3.34035624e-06, - 3.33797637e-06, - 3.33756709e-06, - 3.33751126e-06, - 3.33750083e-06, - ], - [ - 2.07300000e-06, - 2.07300292e-06, - 2.07379485e-06, - 2.11519890e-06, - 2.55438964e-06, - 3.55503738e-06, - 4.05904125e-06, - 4.11311338e-06, - 4.07922495e-06, - 3.72064411e-06, - 2.99405572e-06, - 3.07268206e-06, - 3.95544112e-06, - 4.26687563e-06, - 3.71632577e-06, - 3.15016567e-06, - 2.98922400e-06, - 3.29339384e-06, - 3.98924852e-06, - 4.83082363e-06, - 5.47423812e-06, - 5.77801555e-06, - 5.86387989e-06, - 5.87813196e-06, - 5.87950617e-06, - 5.87958266e-06, - 5.87958511e-06, - 5.87958515e-06, - 5.87958515e-06, - ], - [ - 2.07300000e-06, - 2.07300292e-06, - 2.07379485e-06, - 2.11519890e-06, - 2.55438964e-06, - 3.55503738e-06, - 4.05904125e-06, - 4.11311338e-06, - 4.07922495e-06, - 3.72064411e-06, - 2.99405572e-06, - 3.07268206e-06, - 3.95544112e-06, - 4.26687563e-06, - 3.71632577e-06, - 3.15016567e-06, - 2.98922400e-06, - 3.29339384e-06, - 3.98924852e-06, - 4.83082363e-06, - 5.47423812e-06, - 5.77801555e-06, - 5.86387989e-06, - 5.87813196e-06, - 5.87950617e-06, - 5.87958266e-06, - 5.87958511e-06, - 5.87958515e-06, - 5.87958515e-06, - ], - ], - ), - np.array( - [ - [ - -1.35107208e-06, - -1.33036284e-06, - -1.29371078e-06, - -1.23241324e-06, - -1.13554244e-06, - -3.51002390e-06, - 5.85600156e-07, - 8.57236782e-07, - 1.19525576e-06, - 1.57378055e-06, - 1.91426623e-06, - 2.08784412e-06, - 2.00936631e-06, - 1.71439287e-06, - 1.27066669e-06, - 7.62973092e-07, - 4.60666931e-07, - 6.93493469e-07, - 1.45652624e-06, - 2.42477950e-06, - 3.34626572e-06, - 4.13683755e-06, - 4.64240264e-06, - 4.65273375e-06, - 4.65372768e-06, - 4.65378295e-06, - 4.65378471e-06, - 4.65378475e-06, - 4.65378475e-06, - ], - [ - -1.35107208e-06, - -1.33036284e-06, - -1.29371078e-06, - -1.23241324e-06, - -1.13554244e-06, - -3.51002390e-06, - 5.85600156e-07, - 8.57236782e-07, - 1.19525576e-06, - 1.57378055e-06, - 1.91426623e-06, - 2.08784412e-06, - 2.00936631e-06, - 1.71439287e-06, - 1.27066669e-06, - 7.62973092e-07, - 4.60666931e-07, - 6.93493469e-07, - 1.45652624e-06, - 2.42477950e-06, - 3.34626572e-06, - 4.13683755e-06, - 4.64240264e-06, - 4.65273375e-06, - 4.65372768e-06, - 4.65378295e-06, - 4.65378471e-06, - 4.65378475e-06, - 4.65378475e-06, - ], - [ - 3.19875093e-07, - 3.30479403e-07, - 3.49564160e-07, - 3.97621442e-07, - 6.24076436e-07, - -1.88708544e-07, - 2.11120725e-06, - 2.27195959e-06, - 2.42630375e-06, - 2.42402196e-06, - 2.19947507e-06, - 2.28976268e-06, - 2.60261209e-06, - 2.56234446e-06, - 2.11162563e-06, - 1.61774868e-06, - 1.39431387e-06, - 1.64217088e-06, - 2.31360784e-06, - 3.13090619e-06, - 3.83908225e-06, - 4.35302731e-06, - 4.67870504e-06, - 4.84354637e-06, - 4.90376869e-06, - 4.91908875e-06, - 4.92196879e-06, - 4.92248720e-06, - 4.92261931e-06, - ], - [ - 2.07300000e-06, - 2.07300241e-06, - 2.07365590e-06, - 2.10782176e-06, - 2.47023394e-06, - 3.29595019e-06, - 3.71184421e-06, - 3.75625892e-06, - 3.71789509e-06, - 3.31607852e-06, - 2.49871058e-06, - 2.50161165e-06, - 3.22503390e-06, - 3.45199857e-06, - 2.99394321e-06, - 2.51456240e-06, - 2.37387787e-06, - 2.63750456e-06, - 3.21284100e-06, - 3.87176041e-06, - 4.35613565e-06, - 4.57984935e-06, - 4.71330577e-06, - 5.02541464e-06, - 5.14208904e-06, - 5.17195834e-06, - 5.17758173e-06, - 5.17859423e-06, - 5.17885226e-06, - ], - [ - 2.07300000e-06, - 2.07300241e-06, - 2.07365590e-06, - 2.10782176e-06, - 2.47023394e-06, - 3.29595019e-06, - 3.71184421e-06, - 3.75625892e-06, - 3.71789509e-06, - 3.31607852e-06, - 2.49871058e-06, - 2.50161165e-06, - 3.22503390e-06, - 3.45199857e-06, - 2.99394321e-06, - 2.51456240e-06, - 2.37387787e-06, - 2.63750456e-06, - 3.21284100e-06, - 3.87176041e-06, - 4.35613565e-06, - 4.57984935e-06, - 4.71330577e-06, - 5.02541464e-06, - 5.14208904e-06, - 5.17195834e-06, - 5.17758173e-06, - 5.17859423e-06, - 5.17885226e-06, - ], - ], - ), - ], - ] - bayes.predictionIntervals.sampleChi = np.array( - [ - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - ], - ) - bayes.confidenceIntervals = ratapi.rat_core.ConfidenceIntervals() - bayes.confidenceIntervals.percentile65 = np.array( - [ - [ - -1.29074586e-231, - 8.33251318e000, - 1.75397363e001, - 1.75397363e001, - 9.85302945e000, - 9.85302945e000, - 8.34197863e000, - 8.34197863e000, - 1.65750684e001, - 1.45435510e001, - 1.45435510e001, - 1.52609047e001, - 4.82866779e001, - 2.91225389e001, - 5.60206314e-006, - 7.08098641e-007, - 7.08098641e-007, - 4.65378475e-006, - ], - [ - 8.33251318e000, - 5.48185565e001, - 5.48185565e001, - 4.57554170e001, - 4.57554170e001, - 1.17557273e001, - 1.17557273e001, - 3.18752608e001, - 3.18752608e001, - 1.65750684e001, - 1.52609047e001, - 4.88237113e001, - 4.88237113e001, - 4.82866779e001, - 2.91225389e001, - 5.60206314e-006, - 5.87958515e-006, - 5.87958515e-006, - ], - ], - ) - bayes.confidenceIntervals.percentile95 = np.array( - [ - [ - -1.29074586e-231, - 8.33251318e000, - 1.75397363e001, - 1.75397363e001, - 9.85302945e000, - 9.85302945e000, - 8.34197863e000, - 8.34197863e000, - 1.65750684e001, - 1.45435510e001, - 1.45435510e001, - 1.52609047e001, - 4.82866779e001, - 2.91225389e001, - 5.60206314e-006, - 7.08098641e-007, - 7.08098641e-007, - 4.65378475e-006, - ], - [ - 8.33251318e000, - 5.48185565e001, - 5.48185565e001, - 4.57554170e001, - 4.57554170e001, - 1.17557273e001, - 1.17557273e001, - 3.18752608e001, - 3.18752608e001, - 1.65750684e001, - 1.52609047e001, - 4.88237113e001, - 4.88237113e001, - 4.82866779e001, - 2.91225389e001, - 5.60206314e-006, - 5.87958515e-006, - 5.87958515e-006, - ], - ], - ) - bayes.confidenceIntervals.mean = np.array( - [ - [ - 4.16625659e00, - 3.15755349e01, - 3.61791464e01, - 3.16475766e01, - 2.78042232e01, - 1.08043784e01, - 1.00488530e01, - 2.01086197e01, - 2.42251646e01, - 1.55593097e01, - 1.49022278e01, - 3.20423080e01, - 4.85551946e01, - 3.87046084e01, - 1.45612723e01, - 3.15508089e-06, - 3.29384190e-06, - 5.26668495e-06, - ], - ], - ) - bayes.dreamParams = ratapi.rat_core.DreamParams() - bayes.dreamParams.nParams = 18.0 - bayes.dreamParams.nChains = 1.0 - bayes.dreamParams.nGenerations = 1.0 - bayes.dreamParams.parallel = 0 - bayes.dreamParams.CPU = 1.0 - bayes.dreamParams.jumpProbability = 0.5 - bayes.dreamParams.pUnitGamma = 0.2 - bayes.dreamParams.nCR = 3.0 - bayes.dreamParams.delta = 3.0 - bayes.dreamParams.steps = 50.0 - bayes.dreamParams.zeta = 1e-12 - bayes.dreamParams.outlier = "iqr" - bayes.dreamParams.adaptPCR = 0 - bayes.dreamParams.thinning = 1.0 - bayes.dreamParams.epsilon = 0.025 - bayes.dreamParams.ABC = 0 - bayes.dreamParams.IO = 0 - bayes.dreamParams.storeOutput = 0 - bayes.dreamParams.R = np.array([[0.0]]) - bayes.dreamOutput = ratapi.rat_core.DreamOutput() - bayes.dreamOutput.allChains = np.array( - [ - [ - [8.33251318e00], - [5.48185565e01], - [1.75397363e01], - [4.57554170e01], - [9.85302945e00], - [1.17557273e01], - [8.34197863e00], - [3.18752608e01], - [1.65750684e01], - [1.45435510e01], - [1.52609047e01], - [4.88237113e01], - [4.82866779e01], - [2.91225389e01], - [5.60206314e-06], - [7.08098641e-07], - [5.87958515e-06], - [4.65378475e-06], - [-4.86509830e01], - [-5.63741277e05], - ], - ], - ) - bayes.dreamOutput.outlierChains = np.array([[0.0, 0.0]]) - bayes.dreamOutput.runtime = 2.6e-06 - bayes.dreamOutput.iteration = 2.0 - bayes.dreamOutput.AR = np.array([[1.0, np.nan]]) - bayes.dreamOutput.R_stat = np.array( - [ - [ - 1.0, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - ], - ], - ) - bayes.dreamOutput.CR = np.array([[1.00000000, 0.33333333, 0.33333333, 0.33333333]]) - bayes.nestedSamplerOutput = ratapi.rat_core.NestedSamplerOutput() - bayes.nestedSamplerOutput.logZ = 0.0 - bayes.nestedSamplerOutput.nestSamples = np.array([[0.0, 0.0]]) - bayes.nestedSamplerOutput.postSamples = np.array([[0.0, 0.0]]) - bayes.chain = np.array( - [ - [ - -1.29231905e-231, - 8.33251318e000, - 5.48185565e001, - 1.75397363e001, - 4.57554170e001, - 9.85302945e000, - 1.17557273e001, - 8.34197863e000, - 3.18752608e001, - 1.65750684e001, - 1.45435510e001, - 1.52609047e001, - 4.88237113e001, - 4.82866779e001, - 2.91225389e001, - 5.60206314e-006, - 7.08098641e-007, - 5.87958515e-006, - ], - [ - 8.33251318e000, - 5.48185565e001, - 1.75397363e001, - 4.57554170e001, - 9.85302945e000, - 1.17557273e001, - 8.34197863e000, - 3.18752608e001, - 1.65750684e001, - 1.45435510e001, - 1.52609047e001, - 4.88237113e001, - 4.82866779e001, - 2.91225389e001, - 5.60206314e-006, - 7.08098641e-007, - 5.87958515e-006, - 4.65378475e-006, - ], - ], - ) - - return bayes - - -@pytest.fixture -def dream_results(): - """The python BayesResults object for a Dream optimisation of the project set out in "DSPC_standard_layers.py". - - This optimisation used the parameters: nSamples=1, nChains=1. However, the calculationResults, contrastParams, - and fitParams are taken from an optimisation with the parameters: nSamples=50000, nChains=10. - """ - return ratapi.outputs.BayesResults( - reflectivity=[ - np.array( - [ - [1.14030000e-02, 1.45891447e01], - [1.38610000e-02, 1.45739839e01], - [1.68480000e-02, 1.45684725e01], - [2.04790000e-02, 1.45658452e01], - [2.48920000e-02, 1.45641513e01], - [3.02560000e-02, 1.45628311e01], - [3.67770000e-02, 1.45618510e01], - [4.47020000e-02, 1.45613427e01], - [5.43360000e-02, 1.45612940e01], - [6.60450000e-02, 1.45613971e01], - [8.02790000e-02, 1.45613678e01], - [9.75790000e-02, 1.45612960e01], - [1.18610000e-01, 1.45612799e01], - [1.44170000e-01, 1.45612749e01], - [1.75240000e-01, 1.45612726e01], - [2.13000000e-01, 1.45612723e01], - [2.58910000e-01, 1.45612724e01], - [3.14700000e-01, 1.45612723e01], - [3.82520000e-01, 1.45612723e01], - [4.64960000e-01, 1.45612723e01], - [5.65160000e-01, 1.45612723e01], - ], - ), - np.array( - [ - [1.14030000e-02, 1.00000316e00], - [1.38610000e-02, 1.21238320e-01], - [1.68480000e-02, 2.13433068e-02], - [2.04790000e-02, 8.71162144e-03], - [2.48920000e-02, 5.72807902e-03], - [3.02560000e-02, 3.71827525e-03], - [3.67770000e-02, 1.72067772e-03], - [4.47020000e-02, 3.51471141e-04], - [5.43360000e-02, 2.03975460e-05], - [6.60450000e-02, 1.89221181e-04], - [8.02790000e-02, 1.49280488e-04], - [9.75790000e-02, 3.86439083e-05], - [1.18610000e-01, 1.63612094e-05], - [1.44170000e-01, 6.75770325e-06], - [1.75240000e-01, 3.45955607e-06], - [2.13000000e-01, 3.20880782e-06], - [2.58910000e-01, 3.32068345e-06], - [3.14700000e-01, 3.21671807e-06], - [3.82520000e-01, 3.15612021e-06], - [4.64960000e-01, 3.15645546e-06], - [5.65160000e-01, 3.15511510e-06], - ], - ), - ], - simulation=[ - np.array( - [ - [1.14030000e-02, 1.45891447e01], - [1.38610000e-02, 1.45739839e01], - [1.68480000e-02, 1.45684725e01], - [2.04790000e-02, 1.45658452e01], - [2.48920000e-02, 1.45641513e01], - [3.02560000e-02, 1.45628311e01], - [3.67770000e-02, 1.45618510e01], - [4.47020000e-02, 1.45613427e01], - [5.43360000e-02, 1.45612940e01], - [6.60450000e-02, 1.45613971e01], - [8.02790000e-02, 1.45613678e01], - [9.75790000e-02, 1.45612960e01], - [1.18610000e-01, 1.45612799e01], - [1.44170000e-01, 1.45612749e01], - [1.75240000e-01, 1.45612726e01], - [2.13000000e-01, 1.45612723e01], - [2.58910000e-01, 1.45612724e01], - [3.14700000e-01, 1.45612723e01], - [3.82520000e-01, 1.45612723e01], - [4.64960000e-01, 1.45612723e01], - [5.65160000e-01, 1.45612723e01], - ], - ), - np.array( - [ - [1.14030000e-02, 1.00000316e00], - [1.38610000e-02, 1.21238320e-01], - [1.68480000e-02, 2.13433068e-02], - [2.04790000e-02, 8.71162144e-03], - [2.48920000e-02, 5.72807902e-03], - [3.02560000e-02, 3.71827525e-03], - [3.67770000e-02, 1.72067772e-03], - [4.47020000e-02, 3.51471141e-04], - [5.43360000e-02, 2.03975460e-05], - [6.60450000e-02, 1.89221181e-04], - [8.02790000e-02, 1.49280488e-04], - [9.75790000e-02, 3.86439083e-05], - [1.18610000e-01, 1.63612094e-05], - [1.44170000e-01, 6.75770325e-06], - [1.75240000e-01, 3.45955607e-06], - [2.13000000e-01, 3.20880782e-06], - [2.58910000e-01, 3.32068345e-06], - [3.14700000e-01, 3.21671807e-06], - [3.82520000e-01, 3.15612021e-06], - [4.64960000e-01, 3.15645546e-06], - [5.65160000e-01, 3.15511510e-06], - ], - ), - ], - shiftedData=[ - np.array( - [ - [1.1403e-02, 1.0063e00, 1.9003e-02], - [1.3861e-02, 9.0118e-01, 1.1774e-02], - [1.6848e-02, 7.0455e-02, 1.3083e-03], - [2.0479e-02, 1.7544e-02, 5.1254e-04], - [2.4892e-02, 6.4257e-03, 2.6236e-04], - [3.0256e-02, 2.7746e-03, 8.5758e-05], - [3.6777e-02, 1.8591e-03, 4.9391e-05], - [4.4702e-02, 1.1002e-03, 3.2644e-05], - [5.4336e-02, 6.6691e-04, 2.1365e-05], - [6.6045e-02, 6.0729e-04, 1.1791e-05], - [8.0279e-02, 5.8755e-04, 1.5569e-05], - [9.7579e-02, 3.2700e-04, 6.5280e-06], - [1.1861e-01, 7.8205e-05, 2.5881e-06], - [1.4417e-01, 3.3455e-05, 1.5143e-06], - [1.7524e-01, 4.9313e-06, 5.6663e-07], - [2.1300e-01, 4.1948e-06, 6.8549e-07], - [2.5891e-01, 3.9863e-06, 8.2061e-07], - [3.1470e-01, 2.0861e-06, 6.1379e-07], - [3.8252e-01, 2.1154e-06, 6.3084e-07], - [4.6496e-01, 1.9906e-06, 6.0793e-07], - [5.6516e-01, 2.3816e-06, 7.0610e-07], - ], - ), - np.array( - [ - [1.14030000e-02, 1.20493333e-02, 7.32200000e-04], - [1.38610000e-02, 6.71800000e-03, 3.71853333e-04], - [1.68480000e-02, 4.10506667e-03, 2.23106667e-04], - [2.04790000e-02, 2.43306667e-03, 1.46873333e-04], - [2.48920000e-02, 1.40940000e-03, 9.59200000e-05], - [3.02560000e-02, 7.43400000e-04, 3.50226667e-05], - [3.67770000e-02, 3.51466667e-04, 1.59573333e-05], - [4.47020000e-02, 9.80666667e-05, 7.29466667e-06], - [5.43360000e-02, 1.73500000e-05, 2.59200000e-06], - [6.60450000e-02, 4.86286667e-05, 2.46453333e-06], - [8.02790000e-02, 9.71733333e-05, 4.68166667e-06], - [9.75790000e-02, 7.06533333e-05, 2.32180000e-06], - [1.18610000e-01, 1.93046667e-05, 1.00813333e-06], - [1.44170000e-01, 6.61193333e-06, 5.29773333e-07], - [1.75240000e-01, 3.23726667e-06, 3.65933333e-07], - [2.13000000e-01, 3.29920000e-06, 4.74273333e-07], - [2.58910000e-01, 1.71180000e-06, 4.24720000e-07], - [3.14700000e-01, 2.24020000e-06, 5.08946667e-07], - [3.82520000e-01, 2.73306667e-06, 5.71513333e-07], - [4.64960000e-01, 2.36153333e-06, 5.24806667e-07], - [5.65160000e-01, 2.17460000e-06, 5.31346667e-07], - ], - ), - ], - backgrounds=[ - np.array( - [ - [1.14030000e-02, 2.37401704e-06, 0.00000000e00], - [1.19730000e-02, 2.37401704e-06, 0.00000000e00], - [1.25720000e-02, 2.37401704e-06, 0.00000000e00], - [1.32010000e-02, 2.37401704e-06, 0.00000000e00], - [1.38610000e-02, 2.37401704e-06, 0.00000000e00], - [1.45540000e-02, 2.37401704e-06, 0.00000000e00], - [1.52810000e-02, 2.37401704e-06, 0.00000000e00], - [1.60450000e-02, 2.37401704e-06, 0.00000000e00], - [1.68480000e-02, 2.37401704e-06, 0.00000000e00], - [1.76900000e-02, 2.37401704e-06, 0.00000000e00], - [1.85750000e-02, 2.37401704e-06, 0.00000000e00], - [1.95030000e-02, 2.37401704e-06, 0.00000000e00], - [2.04790000e-02, 2.37401704e-06, 0.00000000e00], - [2.15020000e-02, 2.37401704e-06, 0.00000000e00], - [2.25780000e-02, 2.37401704e-06, 0.00000000e00], - [2.37060000e-02, 2.37401704e-06, 0.00000000e00], - [2.48920000e-02, 2.37401704e-06, 0.00000000e00], - [2.61360000e-02, 2.37401704e-06, 0.00000000e00], - [2.74430000e-02, 2.37401704e-06, 0.00000000e00], - [2.88150000e-02, 2.37401704e-06, 0.00000000e00], - [3.02560000e-02, 2.37401704e-06, 0.00000000e00], - [3.17690000e-02, 2.37401704e-06, 0.00000000e00], - [3.33570000e-02, 2.37401704e-06, 0.00000000e00], - [3.50250000e-02, 2.37401704e-06, 0.00000000e00], - [3.67770000e-02, 2.37401704e-06, 0.00000000e00], - [3.86150000e-02, 2.37401704e-06, 0.00000000e00], - [4.05460000e-02, 2.37401704e-06, 0.00000000e00], - [4.25730000e-02, 2.37401704e-06, 0.00000000e00], - [4.47020000e-02, 2.37401704e-06, 0.00000000e00], - [4.69370000e-02, 2.37401704e-06, 0.00000000e00], - [4.92840000e-02, 2.37401704e-06, 0.00000000e00], - [5.17480000e-02, 2.37401704e-06, 0.00000000e00], - [5.43360000e-02, 2.37401704e-06, 0.00000000e00], - [5.70520000e-02, 2.37401704e-06, 0.00000000e00], - [5.99050000e-02, 2.37401704e-06, 0.00000000e00], - [6.29000000e-02, 2.37401704e-06, 0.00000000e00], - [6.60450000e-02, 2.37401704e-06, 0.00000000e00], - [6.93480000e-02, 2.37401704e-06, 0.00000000e00], - [7.28150000e-02, 2.37401704e-06, 0.00000000e00], - [7.64560000e-02, 2.37401704e-06, 0.00000000e00], - [8.02790000e-02, 2.37401704e-06, 0.00000000e00], - [8.42920000e-02, 2.37401704e-06, 0.00000000e00], - [8.85070000e-02, 2.37401704e-06, 0.00000000e00], - [9.29320000e-02, 2.37401704e-06, 0.00000000e00], - [9.75790000e-02, 2.37401704e-06, 0.00000000e00], - [1.02460000e-01, 2.37401704e-06, 0.00000000e00], - [1.07580000e-01, 2.37401704e-06, 0.00000000e00], - [1.12960000e-01, 2.37401704e-06, 0.00000000e00], - [1.18610000e-01, 2.37401704e-06, 0.00000000e00], - [1.24540000e-01, 2.37401704e-06, 0.00000000e00], - [1.30770000e-01, 2.37401704e-06, 0.00000000e00], - [1.37300000e-01, 2.37401704e-06, 0.00000000e00], - [1.44170000e-01, 2.37401704e-06, 0.00000000e00], - [1.51380000e-01, 2.37401704e-06, 0.00000000e00], - [1.58950000e-01, 2.37401704e-06, 0.00000000e00], - [1.66890000e-01, 2.37401704e-06, 0.00000000e00], - [1.75240000e-01, 2.37401704e-06, 0.00000000e00], - [1.84000000e-01, 2.37401704e-06, 0.00000000e00], - [1.93200000e-01, 2.37401704e-06, 0.00000000e00], - [2.02860000e-01, 2.37401704e-06, 0.00000000e00], - [2.13000000e-01, 2.37401704e-06, 0.00000000e00], - [2.23650000e-01, 2.37401704e-06, 0.00000000e00], - [2.34840000e-01, 2.37401704e-06, 0.00000000e00], - [2.46580000e-01, 2.37401704e-06, 0.00000000e00], - [2.58910000e-01, 2.37401704e-06, 0.00000000e00], - [2.71850000e-01, 2.37401704e-06, 0.00000000e00], - [2.85440000e-01, 2.37401704e-06, 0.00000000e00], - [2.99720000e-01, 2.37401704e-06, 0.00000000e00], - [3.14700000e-01, 2.37401704e-06, 0.00000000e00], - [3.30440000e-01, 2.37401704e-06, 0.00000000e00], - [3.46960000e-01, 2.37401704e-06, 0.00000000e00], - [3.64310000e-01, 2.37401704e-06, 0.00000000e00], - [3.82520000e-01, 2.37401704e-06, 0.00000000e00], - [4.01650000e-01, 2.37401704e-06, 0.00000000e00], - [4.21730000e-01, 2.37401704e-06, 0.00000000e00], - [4.42820000e-01, 2.37401704e-06, 0.00000000e00], - [4.64960000e-01, 2.37401704e-06, 0.00000000e00], - [4.88210000e-01, 2.37401704e-06, 0.00000000e00], - [5.12620000e-01, 2.37401704e-06, 0.00000000e00], - [5.38250000e-01, 2.37401704e-06, 0.00000000e00], - [5.65160000e-01, 2.37401704e-06, 0.00000000e00], - [5.93420000e-01, 2.37401704e-06, 0.00000000e00], - ] - ), - np.array( - [ - [1.14030000e-02, 2.19553929e-06, 0.00000000e00], - [1.19730000e-02, 2.19553929e-06, 0.00000000e00], - [1.25720000e-02, 2.19553929e-06, 0.00000000e00], - [1.32010000e-02, 2.19553929e-06, 0.00000000e00], - [1.38610000e-02, 2.19553929e-06, 0.00000000e00], - [1.45540000e-02, 2.19553929e-06, 0.00000000e00], - [1.52810000e-02, 2.19553929e-06, 0.00000000e00], - [1.60450000e-02, 2.19553929e-06, 0.00000000e00], - [1.68480000e-02, 2.19553929e-06, 0.00000000e00], - [1.76900000e-02, 2.19553929e-06, 0.00000000e00], - [1.85750000e-02, 2.19553929e-06, 0.00000000e00], - [1.95030000e-02, 2.19553929e-06, 0.00000000e00], - [2.04790000e-02, 2.19553929e-06, 0.00000000e00], - [2.15020000e-02, 2.19553929e-06, 0.00000000e00], - [2.25780000e-02, 2.19553929e-06, 0.00000000e00], - [2.37060000e-02, 2.19553929e-06, 0.00000000e00], - [2.48920000e-02, 2.19553929e-06, 0.00000000e00], - [2.61360000e-02, 2.19553929e-06, 0.00000000e00], - [2.74430000e-02, 2.19553929e-06, 0.00000000e00], - [2.88150000e-02, 2.19553929e-06, 0.00000000e00], - [3.02560000e-02, 2.19553929e-06, 0.00000000e00], - [3.17690000e-02, 2.19553929e-06, 0.00000000e00], - [3.33570000e-02, 2.19553929e-06, 0.00000000e00], - [3.50250000e-02, 2.19553929e-06, 0.00000000e00], - [3.67770000e-02, 2.19553929e-06, 0.00000000e00], - [3.86150000e-02, 2.19553929e-06, 0.00000000e00], - [4.05460000e-02, 2.19553929e-06, 0.00000000e00], - [4.25730000e-02, 2.19553929e-06, 0.00000000e00], - [4.47020000e-02, 2.19553929e-06, 0.00000000e00], - [4.69370000e-02, 2.19553929e-06, 0.00000000e00], - [4.92840000e-02, 2.19553929e-06, 0.00000000e00], - [5.17480000e-02, 2.19553929e-06, 0.00000000e00], - [5.43360000e-02, 2.19553929e-06, 0.00000000e00], - [5.70520000e-02, 2.19553929e-06, 0.00000000e00], - [5.99050000e-02, 2.19553929e-06, 0.00000000e00], - [6.29000000e-02, 2.19553929e-06, 0.00000000e00], - [6.60450000e-02, 2.19553929e-06, 0.00000000e00], - [6.93480000e-02, 2.19553929e-06, 0.00000000e00], - [7.28150000e-02, 2.19553929e-06, 0.00000000e00], - [7.64560000e-02, 2.19553929e-06, 0.00000000e00], - [8.02790000e-02, 2.19553929e-06, 0.00000000e00], - [8.42920000e-02, 2.19553929e-06, 0.00000000e00], - [8.85070000e-02, 2.19553929e-06, 0.00000000e00], - [9.29320000e-02, 2.19553929e-06, 0.00000000e00], - [9.75790000e-02, 2.19553929e-06, 0.00000000e00], - [1.02460000e-01, 2.19553929e-06, 0.00000000e00], - [1.07580000e-01, 2.19553929e-06, 0.00000000e00], - [1.12960000e-01, 2.19553929e-06, 0.00000000e00], - [1.18610000e-01, 2.19553929e-06, 0.00000000e00], - [1.24540000e-01, 2.19553929e-06, 0.00000000e00], - [1.30770000e-01, 2.19553929e-06, 0.00000000e00], - [1.37300000e-01, 2.19553929e-06, 0.00000000e00], - [1.44170000e-01, 2.19553929e-06, 0.00000000e00], - [1.51380000e-01, 2.19553929e-06, 0.00000000e00], - [1.58950000e-01, 2.19553929e-06, 0.00000000e00], - [1.66890000e-01, 2.19553929e-06, 0.00000000e00], - [1.75240000e-01, 2.19553929e-06, 0.00000000e00], - [1.84000000e-01, 2.19553929e-06, 0.00000000e00], - [1.93200000e-01, 2.19553929e-06, 0.00000000e00], - [2.02860000e-01, 2.19553929e-06, 0.00000000e00], - [2.13000000e-01, 2.19553929e-06, 0.00000000e00], - [2.23650000e-01, 2.19553929e-06, 0.00000000e00], - [2.34840000e-01, 2.19553929e-06, 0.00000000e00], - [2.46580000e-01, 2.19553929e-06, 0.00000000e00], - [2.58910000e-01, 2.19553929e-06, 0.00000000e00], - [2.71850000e-01, 2.19553929e-06, 0.00000000e00], - [2.85440000e-01, 2.19553929e-06, 0.00000000e00], - [2.99720000e-01, 2.19553929e-06, 0.00000000e00], - [3.14700000e-01, 2.19553929e-06, 0.00000000e00], - [3.30440000e-01, 2.19553929e-06, 0.00000000e00], - [3.46960000e-01, 2.19553929e-06, 0.00000000e00], - [3.64310000e-01, 2.19553929e-06, 0.00000000e00], - [3.82520000e-01, 2.19553929e-06, 0.00000000e00], - [4.01650000e-01, 2.19553929e-06, 0.00000000e00], - [4.21730000e-01, 2.19553929e-06, 0.00000000e00], - [4.42820000e-01, 2.19553929e-06, 0.00000000e00], - [4.64960000e-01, 2.19553929e-06, 0.00000000e00], - [4.88210000e-01, 2.19553929e-06, 0.00000000e00], - [5.12620000e-01, 2.19553929e-06, 0.00000000e00], - [5.38250000e-01, 2.19553929e-06, 0.00000000e00], - [5.65160000e-01, 2.19553929e-06, 0.00000000e00], - [5.93420000e-01, 2.19553929e-06, 0.00000000e00], - ] - ), - ], - resolutions=[ - np.array( - [ - [0.011403, 0.03], - [0.011973, 0.03], - [0.012572, 0.03], - [0.013201, 0.03], - [0.013861, 0.03], - [0.014554, 0.03], - [0.015281, 0.03], - [0.016045, 0.03], - [0.016848, 0.03], - [0.01769, 0.03], - [0.018575, 0.03], - [0.019503, 0.03], - [0.020479, 0.03], - [0.021502, 0.03], - [0.022578, 0.03], - [0.023706, 0.03], - [0.024892, 0.03], - [0.026136, 0.03], - [0.027443, 0.03], - [0.028815, 0.03], - [0.030256, 0.03], - [0.031769, 0.03], - [0.033357, 0.03], - [0.035025, 0.03], - [0.036777, 0.03], - [0.038615, 0.03], - [0.040546, 0.03], - [0.042573, 0.03], - [0.044702, 0.03], - [0.046937, 0.03], - [0.049284, 0.03], - [0.051748, 0.03], - [0.054336, 0.03], - [0.057052, 0.03], - [0.059905, 0.03], - [0.0629, 0.03], - [0.066045, 0.03], - [0.069348, 0.03], - [0.072815, 0.03], - [0.076456, 0.03], - [0.080279, 0.03], - [0.084292, 0.03], - [0.088507, 0.03], - [0.092932, 0.03], - [0.097579, 0.03], - [0.10246, 0.03], - [0.10758, 0.03], - [0.11296, 0.03], - [0.11861, 0.03], - [0.12454, 0.03], - [0.13077, 0.03], - [0.1373, 0.03], - [0.14417, 0.03], - [0.15138, 0.03], - [0.15895, 0.03], - [0.16689, 0.03], - [0.17524, 0.03], - [0.184, 0.03], - [0.1932, 0.03], - [0.20286, 0.03], - [0.213, 0.03], - [0.22365, 0.03], - [0.23484, 0.03], - [0.24658, 0.03], - [0.25891, 0.03], - [0.27185, 0.03], - [0.28544, 0.03], - [0.29972, 0.03], - [0.3147, 0.03], - [0.33044, 0.03], - [0.34696, 0.03], - [0.36431, 0.03], - [0.38252, 0.03], - [0.40165, 0.03], - [0.42173, 0.03], - [0.44282, 0.03], - [0.46496, 0.03], - [0.48821, 0.03], - [0.51262, 0.03], - [0.53825, 0.03], - [0.56516, 0.03], - [0.59342, 0.03], - ] - ), - np.array( - [ - [0.011403, 0.03], - [0.011973, 0.03], - [0.012572, 0.03], - [0.013201, 0.03], - [0.013861, 0.03], - [0.014554, 0.03], - [0.015281, 0.03], - [0.016045, 0.03], - [0.016848, 0.03], - [0.01769, 0.03], - [0.018575, 0.03], - [0.019503, 0.03], - [0.020479, 0.03], - [0.021502, 0.03], - [0.022578, 0.03], - [0.023706, 0.03], - [0.024892, 0.03], - [0.026136, 0.03], - [0.027443, 0.03], - [0.028815, 0.03], - [0.030256, 0.03], - [0.031769, 0.03], - [0.033357, 0.03], - [0.035025, 0.03], - [0.036777, 0.03], - [0.038615, 0.03], - [0.040546, 0.03], - [0.042573, 0.03], - [0.044702, 0.03], - [0.046937, 0.03], - [0.049284, 0.03], - [0.051748, 0.03], - [0.054336, 0.03], - [0.057052, 0.03], - [0.059905, 0.03], - [0.0629, 0.03], - [0.066045, 0.03], - [0.069348, 0.03], - [0.072815, 0.03], - [0.076456, 0.03], - [0.080279, 0.03], - [0.084292, 0.03], - [0.088507, 0.03], - [0.092932, 0.03], - [0.097579, 0.03], - [0.10246, 0.03], - [0.10758, 0.03], - [0.11296, 0.03], - [0.11861, 0.03], - [0.12454, 0.03], - [0.13077, 0.03], - [0.1373, 0.03], - [0.14417, 0.03], - [0.15138, 0.03], - [0.15895, 0.03], - [0.16689, 0.03], - [0.17524, 0.03], - [0.184, 0.03], - [0.1932, 0.03], - [0.20286, 0.03], - [0.213, 0.03], - [0.22365, 0.03], - [0.23484, 0.03], - [0.24658, 0.03], - [0.25891, 0.03], - [0.27185, 0.03], - [0.28544, 0.03], - [0.29972, 0.03], - [0.3147, 0.03], - [0.33044, 0.03], - [0.34696, 0.03], - [0.36431, 0.03], - [0.38252, 0.03], - [0.40165, 0.03], - [0.42173, 0.03], - [0.44282, 0.03], - [0.46496, 0.03], - [0.48821, 0.03], - [0.51262, 0.03], - [0.53825, 0.03], - [0.56516, 0.03], - [0.59342, 0.03], - ] - ), - ], - sldProfiles=[ - [ - np.array( - [ - [0.00000000e00, 2.07301741e-06], - [1.10000000e01, 2.07309604e-06], - [2.20000000e01, 2.07345780e-06], - [3.30000000e01, 2.07491687e-06], - [4.40000000e01, 2.17562259e-06], - [5.50000000e01, 3.22650495e-06], - [6.60000000e01, 3.40913848e-06], - [7.70000000e01, 3.13506253e-06], - [8.80000000e01, 1.20456289e-06], - [9.90000000e01, 1.27138002e-06], - [1.10000000e02, 1.56285495e-06], - [1.21000000e02, 1.84518709e-06], - [1.32000000e02, 2.00498449e-06], - [1.43000000e02, 1.96260665e-06], - [1.54000000e02, 1.71966879e-06], - [1.65000000e02, 1.39383267e-06], - [1.76000000e02, 1.22970195e-06], - [1.87000000e02, 1.41565526e-06], - [1.98000000e02, 1.88172657e-06], - [2.09000000e02, 2.40655867e-06], - [2.20000000e02, 2.83570420e-06], - [2.31000000e02, 3.11210082e-06], - [2.42000000e02, 3.24277802e-06], - [2.53000000e02, 3.28427452e-06], - [2.64000000e02, 3.29268847e-06], - [2.75000000e02, 3.29375418e-06], - [2.86000000e02, 3.29383773e-06], - [2.97000000e02, 3.29384178e-06], - [3.08000000e02, 3.29384190e-06], - ], - ), - np.array( - [ - [0.00000000e00, 2.07301819e-06], - [1.10000000e01, 2.07310296e-06], - [2.20000000e01, 2.07350415e-06], - [3.30000000e01, 2.07518460e-06], - [4.40000000e01, 2.23394767e-06], - [5.50000000e01, 3.90646736e-06], - [6.60000000e01, 4.18619279e-06], - [7.70000000e01, 3.91675004e-06], - [8.80000000e01, 1.92451547e-06], - [9.90000000e01, 2.06988861e-06], - [1.10000000e02, 2.47614934e-06], - [1.21000000e02, 2.84889288e-06], - [1.32000000e02, 3.00529286e-06], - [1.43000000e02, 2.86310144e-06], - [1.54000000e02, 2.49967205e-06], - [1.65000000e02, 2.09673058e-06], - [1.76000000e02, 1.92431424e-06], - [1.87000000e02, 2.18829605e-06], - [1.98000000e02, 2.83032190e-06], - [2.09000000e02, 3.62584708e-06], - [2.20000000e02, 4.36871153e-06], - [2.31000000e02, 4.89806866e-06], - [2.42000000e02, 5.16145928e-06], - [2.53000000e02, 5.24684298e-06], - [2.64000000e02, 5.26428707e-06], - [2.75000000e02, 5.26650242e-06], - [2.86000000e02, 5.26667628e-06], - [2.97000000e02, 5.26668469e-06], - [3.08000000e02, 5.26668495e-06], - ], - ), - ], - ], - layers=[ - [ - np.array( - [ - [3.15755349e01, 3.35278238e-06, 4.16625659e00], - [3.61791464e01, 7.68327921e-07, 4.16625659e00], - [1.00488530e01, 2.06044530e-06, 2.78042232e01], - [1.08043784e01, 3.29384190e-06, 2.78042232e01], - [2.42251646e01, 2.35556998e-06, 1.55593097e01], - [1.49022278e01, 7.42138004e-07, 1.55593097e01], - [1.49022278e01, 7.42138004e-07, 1.55593097e01], - [2.42251646e01, 2.35556998e-06, 1.55593097e01], - ], - ), - ], - [ - np.array( - [ - [3.15755349e01, 4.11636356e-06, 4.16625659e00], - [3.61791464e01, 1.39268494e-06, 4.16625659e00], - [1.00488530e01, 2.45715680e-06, 2.78042232e01], - [1.08043784e01, 5.26668495e-06, 2.78042232e01], - [2.42251646e01, 3.31348777e-06, 1.55593097e01], - [1.49022278e01, 1.37428245e-06, 1.55593097e01], - [1.49022278e01, 1.37428245e-06, 1.55593097e01], - [2.42251646e01, 3.31348777e-06, 1.55593097e01], - ], - ), - ], - ], - resampledLayers=[[np.array([[0.0, 0.0, 0.0]])], [np.array([[0.0, 0.0, 0.0]])]], - calculationResults=ratapi.outputs.CalculationResults( - chiValues=np.array([4.6077885, 7.00028098]), - sumChi=11.608069475997699, - ), - contrastParams=ratapi.outputs.ContrastParams( - scalefactors=np.array([0.1, 0.15]), - bulkIn=np.array([2.073e-06, 2.073e-06]), - bulkOut=np.array([6.01489149e-06, 1.59371685e-06]), - subRoughs=np.array([6.19503045, 6.19503045]), - resample=np.array([0.0, 0.0]), - ), - fitParams=np.array( - [ - 6.19503045e00, - 1.84420960e01, - 2.11039621e01, - 8.75538121e00, - 3.72292994e00, - 1.84624551e01, - 1.02316734e01, - 2.31156093e01, - 1.09906265e01, - 5.71005361e00, - 1.67933822e01, - 1.72009856e01, - 3.00260126e01, - 2.94448999e01, - 2.37113128e-06, - 1.99006694e-06, - 6.01489149e-06, - 1.59371685e-06, - ], - ), - fitNames=[ - "Substrate Roughness", - "Oxide Thickness", - "SAM Tails Thickness", - "SAM Tails Hydration", - "SAM Roughness", - "CW Thickness", - "SAM Heads Thickness", - "SAM Heads Hydration", - "Bilayer Heads Thickness", - "Bilayer Roughness", - "Bilayer Tails Thickness", - "Bilayer Tails Hydration", - "Bilayer Heads Hydration", - "Oxide Hydration", - "Background parameter D2O", - "Background parameter SMW", - "D2O", - "SMW", - ], - predictionIntervals=ratapi.outputs.PredictionIntervals( - reflectivity=[ - np.array( - [ - [ - 1.00000560e00, - 7.07687612e-01, - 2.08315160e-02, - 2.40787966e-03, - 2.17627660e-03, - 2.54301700e-03, - 1.76309827e-03, - 6.15269679e-04, - 3.43679710e-05, - 7.93625275e-05, - 1.27760549e-04, - 3.35799941e-05, - 6.75048751e-06, - 7.64258431e-06, - 6.05800395e-06, - 5.60288298e-06, - 5.60333677e-06, - 5.60223341e-06, - 5.60206667e-06, - 5.60206314e-06, - 5.60206314e-06, - ], - [ - 1.00000560e00, - 7.07687612e-01, - 2.08315160e-02, - 2.40787966e-03, - 2.17627660e-03, - 2.54301700e-03, - 1.76309827e-03, - 6.15269679e-04, - 3.43679710e-05, - 7.93625275e-05, - 1.27760549e-04, - 3.35799941e-05, - 6.75048751e-06, - 7.64258431e-06, - 6.05800395e-06, - 5.60288298e-06, - 5.60333677e-06, - 5.60223341e-06, - 5.60206667e-06, - 5.60206314e-06, - 5.60206314e-06, - ], - [ - 1.55201098e01, - 1.53748894e01, - 1.50402011e01, - 1.50299478e01, - 1.50290525e01, - 1.50287935e01, - 1.50282126e01, - 1.50276044e01, - 1.50273248e01, - 1.50273185e01, - 1.50272997e01, - 1.50272498e01, - 1.50272364e01, - 1.50272347e01, - 1.50272335e01, - 1.50272330e01, - 1.50272329e01, - 1.50272328e01, - 1.50272328e01, - 1.50272328e01, - 1.50272328e01, - ], - [ - 2.91397425e01, - 2.91324974e01, - 2.91281368e01, - 2.91255472e01, - 2.91240295e01, - 2.91231836e01, - 2.91227893e01, - 2.91226872e01, - 2.91226902e01, - 2.91226359e01, - 2.91225541e01, - 2.91225457e01, - 2.91225448e01, - 2.91225407e01, - 2.91225398e01, - 2.91225393e01, - 2.91225391e01, - 2.91225390e01, - 2.91225390e01, - 2.91225389e01, - 2.91225389e01, - ], - [ - 2.91397425e01, - 2.91324974e01, - 2.91281368e01, - 2.91255472e01, - 2.91240295e01, - 2.91231836e01, - 2.91227893e01, - 2.91226872e01, - 2.91226902e01, - 2.91226359e01, - 2.91225541e01, - 2.91225457e01, - 2.91225448e01, - 2.91225407e01, - 2.91225398e01, - 2.91225393e01, - 2.91225391e01, - 2.91225390e01, - 2.91225390e01, - 2.91225389e01, - 2.91225389e01, - ], - ], - ), - np.array( - [ - [ - 7.82198834e-01, - 2.84434275e-02, - 3.42472318e-03, - 1.45801296e-03, - 2.02213149e-03, - 2.00826891e-03, - 1.27577246e-03, - 4.27099544e-04, - 2.07304219e-05, - 4.88683542e-05, - 4.14000873e-05, - 1.57801531e-05, - 2.08705254e-06, - 2.27936213e-06, - 1.09950377e-06, - 7.09021331e-07, - 7.09539552e-07, - 7.08228574e-07, - 7.08101644e-07, - 7.08098642e-07, - 7.08098641e-07, - ], - [ - 7.82198834e-01, - 2.84434275e-02, - 3.42472318e-03, - 1.45801296e-03, - 2.02213149e-03, - 2.00826891e-03, - 1.27577246e-03, - 4.27099544e-04, - 2.07304219e-05, - 4.88683542e-05, - 4.14000873e-05, - 1.57801531e-05, - 2.08705254e-06, - 2.27936213e-06, - 1.09950377e-06, - 7.09021331e-07, - 7.09539552e-07, - 7.08228574e-07, - 7.08101644e-07, - 7.08098642e-07, - 7.08098641e-07, - ], - [ - 8.94587126e-01, - 4.07514176e-01, - 3.66355642e-02, - 1.22207690e-02, - 5.91350591e-03, - 3.17495745e-03, - 1.50593011e-03, - 5.80889579e-04, - 2.44654124e-04, - 1.40925782e-04, - 6.26965047e-05, - 1.91064075e-05, - 9.45189755e-06, - 6.16421495e-06, - 5.17046678e-06, - 4.24101973e-06, - 3.82067554e-06, - 3.55352666e-06, - 3.38981154e-06, - 3.29631224e-06, - 3.25061722e-06, - ], - [ - 1.00000560e00, - 7.63076662e-01, - 6.77868181e-02, - 2.23160672e-02, - 9.56355479e-03, - 4.26929321e-03, - 1.72181442e-03, - 7.25142247e-04, - 4.54691084e-04, - 2.27274223e-04, - 8.54009496e-05, - 2.26525796e-05, - 1.63600080e-05, - 9.80814666e-06, - 8.98896697e-06, - 7.55397947e-06, - 6.73887287e-06, - 6.22237216e-06, - 5.90521384e-06, - 5.72401646e-06, - 5.63546023e-06, - ], - [ - 1.00000560e00, - 7.63076662e-01, - 6.77868181e-02, - 2.23160672e-02, - 9.56355479e-03, - 4.26929321e-03, - 1.72181442e-03, - 7.25142247e-04, - 4.54691084e-04, - 2.27274223e-04, - 8.54009496e-05, - 2.26525796e-05, - 1.63600080e-05, - 9.80814666e-06, - 8.98896697e-06, - 7.55397947e-06, - 6.73887287e-06, - 6.22237216e-06, - 5.90521384e-06, - 5.72401646e-06, - 5.63546023e-06, - ], - ], - ), - ], - sld=[ - [ - np.array( - [ - [ - -2.26996619e-06, - -2.26166520e-06, - -2.24783719e-06, - -2.22613645e-06, - -2.19406176e-06, - -2.17142372e-06, - 1.88515086e-07, - 2.60653226e-07, - 3.44976651e-07, - 4.40965268e-07, - 5.53846231e-07, - 6.92263150e-07, - 8.41189317e-07, - 9.28611746e-07, - 8.59850711e-07, - 6.40672491e-07, - 4.45129915e-07, - 4.69261576e-07, - 7.08570915e-07, - 9.66403060e-07, - 1.08031232e-06, - 1.05528544e-06, - 9.86455522e-07, - 9.38980618e-07, - 9.20228966e-07, - 9.15507876e-07, - 9.14706158e-07, - 9.14597081e-07, - 9.14576711e-07, - ], - [ - -2.26996619e-06, - -2.26166520e-06, - -2.24783719e-06, - -2.22613645e-06, - -2.19406176e-06, - -2.17142372e-06, - 1.88515086e-07, - 2.60653226e-07, - 3.44976651e-07, - 4.40965268e-07, - 5.53846231e-07, - 6.92263150e-07, - 8.41189317e-07, - 9.28611746e-07, - 8.59850711e-07, - 6.40672491e-07, - 4.45129915e-07, - 4.69261576e-07, - 7.08570915e-07, - 9.66403060e-07, - 1.08031232e-06, - 1.05528544e-06, - 9.86455522e-07, - 9.38980618e-07, - 9.20228966e-07, - 9.15507876e-07, - 9.14706158e-07, - 9.14597081e-07, - 9.14576711e-07, - ], - [ - -1.50598689e-07, - -1.46347158e-07, - -1.38880755e-07, - -1.07564801e-07, - 1.23182525e-07, - 6.23089296e-07, - 2.07733185e-06, - 2.14065378e-06, - 2.16728982e-06, - 2.04144854e-06, - 1.74466846e-06, - 1.85390758e-06, - 2.36094420e-06, - 2.55768452e-06, - 2.25381054e-06, - 1.86530516e-06, - 1.68664783e-06, - 1.84743812e-06, - 2.30954159e-06, - 2.85224030e-06, - 3.22454811e-06, - 3.35997774e-06, - 3.36663861e-06, - 3.34928647e-06, - 3.34035624e-06, - 3.33797637e-06, - 3.33756709e-06, - 3.33751126e-06, - 3.33750083e-06, - ], - [ - 2.07300000e-06, - 2.07300292e-06, - 2.07379485e-06, - 2.11519890e-06, - 2.55438964e-06, - 3.55503738e-06, - 4.05904125e-06, - 4.11311338e-06, - 4.07922495e-06, - 3.72064411e-06, - 2.99405572e-06, - 3.07268206e-06, - 3.95544112e-06, - 4.26687563e-06, - 3.71632577e-06, - 3.15016567e-06, - 2.98922400e-06, - 3.29339384e-06, - 3.98924852e-06, - 4.83082363e-06, - 5.47423812e-06, - 5.77801555e-06, - 5.86387989e-06, - 5.87813196e-06, - 5.87950617e-06, - 5.87958266e-06, - 5.87958511e-06, - 5.87958515e-06, - 5.87958515e-06, - ], - [ - 2.07300000e-06, - 2.07300292e-06, - 2.07379485e-06, - 2.11519890e-06, - 2.55438964e-06, - 3.55503738e-06, - 4.05904125e-06, - 4.11311338e-06, - 4.07922495e-06, - 3.72064411e-06, - 2.99405572e-06, - 3.07268206e-06, - 3.95544112e-06, - 4.26687563e-06, - 3.71632577e-06, - 3.15016567e-06, - 2.98922400e-06, - 3.29339384e-06, - 3.98924852e-06, - 4.83082363e-06, - 5.47423812e-06, - 5.77801555e-06, - 5.86387989e-06, - 5.87813196e-06, - 5.87950617e-06, - 5.87958266e-06, - 5.87958511e-06, - 5.87958515e-06, - 5.87958515e-06, - ], - ] - ), - np.array( - [ - [ - -1.35107208e-06, - -1.33036284e-06, - -1.29371078e-06, - -1.23241324e-06, - -1.13554244e-06, - -3.51002390e-06, - 5.85600156e-07, - 8.57236782e-07, - 1.19525576e-06, - 1.57378055e-06, - 1.91426623e-06, - 2.08784412e-06, - 2.00936631e-06, - 1.71439287e-06, - 1.27066669e-06, - 7.62973092e-07, - 4.60666931e-07, - 6.93493469e-07, - 1.45652624e-06, - 2.42477950e-06, - 3.34626572e-06, - 4.13683755e-06, - 4.64240264e-06, - 4.65273375e-06, - 4.65372768e-06, - 4.65378295e-06, - 4.65378471e-06, - 4.65378475e-06, - 4.65378475e-06, - ], - [ - -1.35107208e-06, - -1.33036284e-06, - -1.29371078e-06, - -1.23241324e-06, - -1.13554244e-06, - -3.51002390e-06, - 5.85600156e-07, - 8.57236782e-07, - 1.19525576e-06, - 1.57378055e-06, - 1.91426623e-06, - 2.08784412e-06, - 2.00936631e-06, - 1.71439287e-06, - 1.27066669e-06, - 7.62973092e-07, - 4.60666931e-07, - 6.93493469e-07, - 1.45652624e-06, - 2.42477950e-06, - 3.34626572e-06, - 4.13683755e-06, - 4.64240264e-06, - 4.65273375e-06, - 4.65372768e-06, - 4.65378295e-06, - 4.65378471e-06, - 4.65378475e-06, - 4.65378475e-06, - ], - [ - 3.19875093e-07, - 3.30479403e-07, - 3.49564160e-07, - 3.97621442e-07, - 6.24076436e-07, - -1.88708544e-07, - 2.11120725e-06, - 2.27195959e-06, - 2.42630375e-06, - 2.42402196e-06, - 2.19947507e-06, - 2.28976268e-06, - 2.60261209e-06, - 2.56234446e-06, - 2.11162563e-06, - 1.61774868e-06, - 1.39431387e-06, - 1.64217088e-06, - 2.31360784e-06, - 3.13090619e-06, - 3.83908225e-06, - 4.35302731e-06, - 4.67870504e-06, - 4.84354637e-06, - 4.90376869e-06, - 4.91908875e-06, - 4.92196879e-06, - 4.92248720e-06, - 4.92261931e-06, - ], - [ - 2.07300000e-06, - 2.07300241e-06, - 2.07365590e-06, - 2.10782176e-06, - 2.47023394e-06, - 3.29595019e-06, - 3.71184421e-06, - 3.75625892e-06, - 3.71789509e-06, - 3.31607852e-06, - 2.49871058e-06, - 2.50161165e-06, - 3.22503390e-06, - 3.45199857e-06, - 2.99394321e-06, - 2.51456240e-06, - 2.37387787e-06, - 2.63750456e-06, - 3.21284100e-06, - 3.87176041e-06, - 4.35613565e-06, - 4.57984935e-06, - 4.71330577e-06, - 5.02541464e-06, - 5.14208904e-06, - 5.17195834e-06, - 5.17758173e-06, - 5.17859423e-06, - 5.17885226e-06, - ], - [ - 2.07300000e-06, - 2.07300241e-06, - 2.07365590e-06, - 2.10782176e-06, - 2.47023394e-06, - 3.29595019e-06, - 3.71184421e-06, - 3.75625892e-06, - 3.71789509e-06, - 3.31607852e-06, - 2.49871058e-06, - 2.50161165e-06, - 3.22503390e-06, - 3.45199857e-06, - 2.99394321e-06, - 2.51456240e-06, - 2.37387787e-06, - 2.63750456e-06, - 3.21284100e-06, - 3.87176041e-06, - 4.35613565e-06, - 4.57984935e-06, - 4.71330577e-06, - 5.02541464e-06, - 5.14208904e-06, - 5.17195834e-06, - 5.17758173e-06, - 5.17859423e-06, - 5.17885226e-06, - ], - ] - ), - ] - ], - sampleChi=np.array( - [ - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.46133559e16, - 1.12748255e06, - 1.12748255e06, - 1.46133559e16, - ], - ), - ), - confidenceIntervals=ratapi.outputs.ConfidenceIntervals( - percentile65=np.array( - [ - [ - -1.29074586e-231, - 8.33251318e000, - 1.75397363e001, - 1.75397363e001, - 9.85302945e000, - 9.85302945e000, - 8.34197863e000, - 8.34197863e000, - 1.65750684e001, - 1.45435510e001, - 1.45435510e001, - 1.52609047e001, - 4.82866779e001, - 2.91225389e001, - 5.60206314e-006, - 7.08098641e-007, - 7.08098641e-007, - 4.65378475e-006, - ], - [ - 8.33251318e000, - 5.48185565e001, - 5.48185565e001, - 4.57554170e001, - 4.57554170e001, - 1.17557273e001, - 1.17557273e001, - 3.18752608e001, - 3.18752608e001, - 1.65750684e001, - 1.52609047e001, - 4.88237113e001, - 4.88237113e001, - 4.82866779e001, - 2.91225389e001, - 5.60206314e-006, - 5.87958515e-006, - 5.87958515e-006, - ], - ], - ), - percentile95=np.array( - [ - [ - -1.29074586e-231, - 8.33251318e000, - 1.75397363e001, - 1.75397363e001, - 9.85302945e000, - 9.85302945e000, - 8.34197863e000, - 8.34197863e000, - 1.65750684e001, - 1.45435510e001, - 1.45435510e001, - 1.52609047e001, - 4.82866779e001, - 2.91225389e001, - 5.60206314e-006, - 7.08098641e-007, - 7.08098641e-007, - 4.65378475e-006, - ], - [ - 8.33251318e000, - 5.48185565e001, - 5.48185565e001, - 4.57554170e001, - 4.57554170e001, - 1.17557273e001, - 1.17557273e001, - 3.18752608e001, - 3.18752608e001, - 1.65750684e001, - 1.52609047e001, - 4.88237113e001, - 4.88237113e001, - 4.82866779e001, - 2.91225389e001, - 5.60206314e-006, - 5.87958515e-006, - 5.87958515e-006, - ], - ], - ), - mean=np.array( - [ - [ - 4.16625659e00, - 3.15755349e01, - 3.61791464e01, - 3.16475766e01, - 2.78042232e01, - 1.08043784e01, - 1.00488530e01, - 2.01086197e01, - 2.42251646e01, - 1.55593097e01, - 1.49022278e01, - 3.20423080e01, - 4.85551946e01, - 3.87046084e01, - 1.45612723e01, - 3.15508089e-06, - 3.29384190e-06, - 5.26668495e-06, - ], - ], - ), - ), - dreamParams=ratapi.outputs.DreamParams( - nParams=18.0, - nChains=1.0, - nGenerations=1.0, - parallel=False, - CPU=1.0, - jumpProbability=0.5, - pUnitGamma=0.2, - nCR=3.0, - delta=3.0, - steps=50.0, - zeta=1e-12, - outlier="iqr", - adaptPCR=False, - thinning=1.0, - epsilon=0.025, - ABC=False, - IO=False, - storeOutput=False, - R=np.array([[0.0]]), - ), - dreamOutput=ratapi.outputs.DreamOutput( - allChains=np.array( - [ - [ - [8.33251318e00], - [5.48185565e01], - [1.75397363e01], - [4.57554170e01], - [9.85302945e00], - [1.17557273e01], - [8.34197863e00], - [3.18752608e01], - [1.65750684e01], - [1.45435510e01], - [1.52609047e01], - [4.88237113e01], - [4.82866779e01], - [2.91225389e01], - [5.60206314e-06], - [7.08098641e-07], - [5.87958515e-06], - [4.65378475e-06], - [-4.86509830e01], - [-5.63741277e05], - ], - ], - ), - outlierChains=np.array([[0.0, 0.0]]), - runtime=2.6e-06, - iteration=2.0, - AR=np.array([[1.0, np.nan]]), - R_stat=np.array( - [ - [ - 1.0, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - np.nan, - ], - ], - ), - CR=np.array([[1.0, 0.33333333, 0.33333333, 0.33333333]]), - ), - nestedSamplerOutput=ratapi.outputs.NestedSamplerOutput( - logZ=0.0, - logZErr=0.0, - nestSamples=np.array([[0.0, 0.0]]), - postSamples=np.array([[0.0, 0.0]]), - ), - chain=np.array( - [ - [ - -1.29231905e-231, - 8.33251318e000, - 5.48185565e001, - 1.75397363e001, - 4.57554170e001, - 9.85302945e000, - 1.17557273e001, - 8.34197863e000, - 3.18752608e001, - 1.65750684e001, - 1.45435510e001, - 1.52609047e001, - 4.88237113e001, - 4.82866779e001, - 2.91225389e001, - 5.60206314e-006, - 7.08098641e-007, - 5.87958515e-006, - ], - [ - 8.33251318e000, - 5.48185565e001, - 1.75397363e001, - 4.57554170e001, - 9.85302945e000, - 1.17557273e001, - 8.34197863e000, - 3.18752608e001, - 1.65750684e001, - 1.45435510e001, - 1.52609047e001, - 4.88237113e001, - 4.82866779e001, - 2.91225389e001, - 5.60206314e-006, - 7.08098641e-007, - 5.87958515e-006, - 4.65378475e-006, - ], - ], - ), - ) - - -@pytest.fixture -def nested_sampler_results(dream_results): - results = dream_results - results.nestedSamplerOutput = ratapi.outputs.NestedSamplerOutput( - logZ=-28.99992503667041, - logZErr=0.3391187711291207, - nestSamples=np.ones((100, 9)), - postSamples=np.ones((100, 10)), - ) - return results - - -@pytest.fixture -def r1_default_project(): - """The Project corresponding to the data in R1defaultProject.mat.""" - project = ratapi.Project( - name="defaultProject", - calculation="normal", - model="standard layers", - geometry="air/substrate", - absorption=False, - parameters=ratapi.ClassList( - ratapi.models.Parameter( - name="Substrate Roughness", - min=3.0, - value=4.844363132849221, - max=8.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - ), - bulk_in=ratapi.ClassList( - ratapi.models.Parameter( - name="Air", - min=0.0, - value=0.0, - max=0.0, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - ), - bulk_out=ratapi.ClassList( - ratapi.models.Parameter( - name="D2O", - min=6.3e-06, - value=6.35e-06, - max=6.4e-06, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - ), - scalefactors=ratapi.ClassList( - ratapi.models.Parameter( - name="Scalefactor 1", - min=0.009999999776482582, - value=0.10141560336360426, - max=0.3, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - ), - backgrounds=ratapi.ClassList( - ratapi.models.Background(name="Background 1", type="constant", source="Background parameter 1") - ), - background_parameters=ratapi.ClassList( - ratapi.models.Parameter( - name="Background parameter 1", - min=5e-08, - value=3.069003361230152e-06, - max=7e-06, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - ), - resolutions=ratapi.ClassList( - ratapi.models.Resolution(name="Resolution 1", type="constant", source="Resolution parameter 1") - ), - resolution_parameters=ratapi.ClassList( - ratapi.models.Parameter( - name="Resolution parameter 1", - min=0.01, - value=0.03, - max=0.05, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - ), - ) - project.data.append( - name="f82395c", - data=np.array( - [ - [4.8866e-02, 1.2343e-04, 1.3213e-06], - [5.1309e-02, 1.0063e-04, 1.0803e-06], - [5.3874e-02, 8.2165e-05, 8.8779e-07], - [5.6568e-02, 6.4993e-05, 7.2018e-07], - [5.9396e-02, 5.3958e-05, 6.0015e-07], - [6.2366e-02, 4.3590e-05, 5.0129e-07], - [6.5485e-02, 3.5780e-05, 4.1957e-07], - [6.8759e-02, 2.9130e-05, 3.5171e-07], - [7.2197e-02, 2.3481e-05, 3.0586e-07], - [7.5807e-02, 1.8906e-05, 2.6344e-07], - [7.9597e-02, 1.4642e-05, 2.2314e-07], - [8.3577e-02, 1.1589e-05, 1.8938e-07], - [8.7756e-02, 9.5418e-06, 1.6220e-07], - [9.2143e-02, 7.5694e-06, 1.3809e-07], - [9.6751e-02, 6.3831e-06, 1.2097e-07], - [1.0159e-01, 5.0708e-06, 1.0333e-07], - [1.0667e-01, 4.1041e-06, 8.9548e-08], - [1.1200e-01, 3.4253e-06, 7.9830e-08], - [1.1760e-01, 2.8116e-06, 7.1554e-08], - [1.2348e-01, 2.3767e-06, 6.3738e-08], - [1.2966e-01, 1.9241e-06, 5.6586e-08], - [1.3614e-01, 1.5642e-06, 5.2778e-08], - [1.4294e-01, 1.2922e-06, 4.9730e-08], - [1.5009e-01, 1.1694e-06, 5.1175e-08], - [1.5760e-01, 9.7837e-07, 5.0755e-08], - [1.6548e-01, 8.9138e-07, 5.3542e-08], - [1.7375e-01, 7.9420e-07, 5.4857e-08], - [1.8244e-01, 7.9131e-07, 5.8067e-08], - [1.9156e-01, 6.5358e-07, 5.7717e-08], - [2.0114e-01, 6.2970e-07, 5.7951e-08], - [2.1119e-01, 5.0130e-07, 5.5262e-08], - [2.2175e-01, 5.0218e-07, 5.6461e-08], - [2.3284e-01, 3.9299e-07, 5.0685e-08], - [2.4448e-01, 3.5324e-07, 5.0194e-08], - [2.5671e-01, 4.4475e-07, 5.6485e-08], - [2.6954e-01, 5.1338e-07, 6.2247e-08], - [2.8302e-01, 3.4918e-07, 4.9745e-08], - [2.9717e-01, 4.3037e-07, 5.5488e-08], - [3.1203e-01, 4.0099e-07, 5.3591e-08], - [3.2763e-01, 3.8397e-07, 5.1303e-08], - [3.4401e-01, 3.0995e-07, 4.5965e-08], - [3.6121e-01, 3.9357e-07, 5.0135e-08], - [3.7927e-01, 3.0997e-07, 4.3680e-08], - [3.9824e-01, 2.9656e-07, 4.2432e-08], - [4.1815e-01, 2.1909e-07, 3.6117e-08], - [4.3906e-01, 2.3153e-07, 3.6307e-08], - [4.6101e-01, 3.3428e-07, 4.3874e-08], - [4.8406e-01, 2.3441e-07, 3.7488e-08], - [5.0826e-01, 1.5496e-07, 3.0585e-08], - [5.3368e-01, 2.4708e-07, 3.9376e-08], - [5.6036e-01, 2.2157e-07, 3.8258e-08], - [5.8838e-01, 2.2798e-07, 4.6976e-08], - [6.1169e-01, 6.0272e-07, 2.3239e-07], - ] - ), - data_range=[0.048866, 0.61169], - simulation_range=[0.048866, 0.61169], - ) - project.contrasts.append( - name="Chain-d, acmw", - data="f82395c", - background="Background 1", - background_action="add", - bulk_in="Air", - bulk_out="D2O", - scalefactor="Scalefactor 1", - resolution="Resolution 1", - resample=False, - model=[], - ) - return project - - -@pytest.fixture -def r1_monolayer(): - """The Project file corresponding to the data in R1monolayerVolumeModel.mat.""" - project = ratapi.Project( - name="monolayerVolumeModel", - calculation="normal", - model="custom layers", - geometry="air/substrate", - absorption=False, - parameters=ratapi.ClassList( - [ - ratapi.models.Parameter( - name="Substrate Roughness", - min=1.0, - value=2.9979642781948908, - max=8.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ratapi.models.Parameter( - name="Area per molecule", - min=47.0, - value=53.052680457664785, - max=100.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ratapi.models.Parameter( - name="Head Thickness", - min=7.0, - value=12.276333836779942, - max=20.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ratapi.models.Parameter( - name="Theta", - min=0.0, - value=28.870541049836262, - max=50.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ] - ), - bulk_in=ratapi.ClassList( - ratapi.models.Parameter( - name="Air", - min=0.0, - value=0.0, - max=0.0, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - ), - bulk_out=( - ratapi.ClassList( - [ - ratapi.models.Parameter( - name="D2O", - min=6.3e-06, - value=6.35e-06, - max=6.4e-06, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ratapi.models.Parameter( - name="ACMW", - min=-5e-07, - value=0.0, - max=5e-07, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ] - ) - ), - scalefactors=ratapi.ClassList( - ratapi.models.Parameter( - name="Scalefactor 1", - min=0.1, - value=0.2272676786810902, - max=0.4, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - ), - backgrounds=ratapi.ClassList( - [ - ratapi.models.Background(name="Background D2O", type="constant", source="Background parameter 1"), - ratapi.models.Background(name="Background ACMW", type="constant", source="Background parameter 2"), - ] - ), - background_parameters=ratapi.ClassList( - [ - ratapi.models.Parameter( - name="Background parameter 1", - min=1e-07, - value=2.2653463958223856e-06, - max=7e-06, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ratapi.models.Parameter( - name="Background parameter 2", - min=1e-07, - value=5.7431759430575025e-06, - max=7e-06, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ] - ), - resolutions=ratapi.ClassList( - ratapi.models.Resolution(name="Resolution 1", type="constant", source="Resolution parameter 1") - ), - resolution_parameters=ratapi.ClassList( - ratapi.models.Parameter( - name="Resolution parameter 1", - min=0.01, - value=0.03, - max=0.05, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - ), - custom_files=ratapi.ClassList( - ratapi.models.CustomFile( - name="Model_IIb", - filename="Model_IIb.m", - function_name="Model_IIb", - language="matlab", - path=Path(__file__).parent / "test_data", - ) - ), - ) - - project.data.append( - name="d70acmw20", - data=np.array( - [ - [5.1793e-02, 2.3792e-04, 3.6498e-06], - [5.4383e-02, 2.2030e-04, 3.1361e-06], - [5.7102e-02, 1.9302e-04, 2.6450e-06], - [5.9957e-02, 1.7223e-04, 2.2673e-06], - [6.2955e-02, 1.5210e-04, 1.9699e-06], - [6.6103e-02, 1.3650e-04, 1.7055e-06], - [6.9408e-02, 1.1806e-04, 1.5072e-06], - [7.2878e-02, 1.0904e-04, 1.3658e-06], - [7.6522e-02, 9.5873e-05, 1.2024e-06], - [8.0348e-02, 8.2201e-05, 1.0754e-06], - [8.4365e-02, 7.0764e-05, 9.4576e-07], - [8.8584e-02, 6.2973e-05, 8.3975e-07], - [9.3013e-02, 5.3710e-05, 7.3854e-07], - [9.7664e-02, 4.6651e-05, 6.5893e-07], - [1.0255e-01, 4.0448e-05, 5.8945e-07], - [1.0767e-01, 3.4559e-05, 5.2655e-07], - [1.1306e-01, 2.9817e-05, 4.7806e-07], - [1.1871e-01, 2.5965e-05, 4.4165e-07], - [1.2465e-01, 2.1963e-05, 3.9117e-07], - [1.3088e-01, 1.8535e-05, 3.5668e-07], - [1.3742e-01, 1.6299e-05, 3.4665e-07], - [1.4429e-01, 1.3704e-05, 3.2491e-07], - [1.5151e-01, 1.0571e-05, 2.9830e-07], - [1.5908e-01, 8.9320e-06, 2.9188e-07], - [1.6704e-01, 6.8328e-06, 2.7922e-07], - [1.7539e-01, 5.7856e-06, 2.7261e-07], - [1.8416e-01, 4.5358e-06, 2.5335e-07], - [1.9337e-01, 3.9935e-06, 2.5336e-07], - [2.0304e-01, 3.1800e-06, 5.2440e-07], - [2.1319e-01, 2.7006e-06, 4.6690e-07], - [2.2385e-01, 2.2210e-06, 4.5090e-07], - [2.3504e-01, 1.6163e-06, 4.9340e-07], - [2.4679e-01, 1.7554e-06, 3.2120e-07], - [2.5913e-01, 1.3194e-06, 1.7170e-07], - [2.7209e-01, 1.5033e-06, 3.4760e-07], - [2.8569e-01, 1.3801e-06, 7.2017e-07], - [2.9998e-01, 1.2640e-06, 4.5486e-07], - [3.1497e-01, 1.0585e-06, 3.6820e-07], - [3.3072e-01, 1.3063e-06, 4.5401e-07], - [3.4726e-01, 1.1229e-06, 2.3240e-07], - [3.6462e-01, 1.5197e-06, 4.8780e-07], - [3.8285e-01, 1.1419e-06, 4.1880e-07], - [4.0200e-01, 1.3285e-06, 4.0215e-07], - [4.2210e-01, 1.2467e-06, 5.8010e-07], - [4.4320e-01, 1.1322e-06, 3.2730e-07], - [4.6536e-01, 1.1336e-06, 4.3291e-07], - [4.8863e-01, 1.4843e-06, 5.0110e-07], - [5.1306e-01, 1.2055e-06, 3.0660e-07], - [5.3871e-01, 1.2170e-06, 4.0500e-07], - [5.6565e-01, 8.9674e-07, 3.5866e-07], - [5.8877e-01, 9.4625e-07, 7.6511e-07], - ] - ), - data_range=[0.051793, 0.58877], - simulation_range=[0.051793, 0.58877], - ) - - project.data.append( - name="d70d2o20", - data=np.array( - [ - [5.1793e-02, 1.4943e-04, 3.2517e-06], - [5.4383e-02, 1.1882e-04, 2.5846e-06], - [5.7102e-02, 9.2164e-05, 2.0507e-06], - [5.9957e-02, 7.7813e-05, 1.7070e-06], - [6.2955e-02, 6.1143e-05, 1.3983e-06], - [6.6103e-02, 4.8033e-05, 1.1343e-06], - [6.9408e-02, 4.1379e-05, 1.0006e-06], - [7.2878e-02, 3.5090e-05, 8.6919e-07], - [7.6522e-02, 3.0350e-05, 7.5890e-07], - [8.0348e-02, 2.4115e-05, 6.5226e-07], - [8.4365e-02, 2.0755e-05, 5.7445e-07], - [8.8584e-02, 1.7500e-05, 4.9617e-07], - [9.3013e-02, 1.5011e-05, 4.3754e-07], - [9.7664e-02, 1.3632e-05, 3.9907e-07], - [1.0255e-01, 1.2997e-05, 3.7469e-07], - [1.0767e-01, 1.1656e-05, 3.4282e-07], - [1.1306e-01, 1.0820e-05, 3.2299e-07], - [1.1871e-01, 9.5831e-06, 3.0088e-07], - [1.2465e-01, 8.9996e-06, 2.8102e-07], - [1.3088e-01, 8.6498e-06, 2.7363e-07], - [1.3742e-01, 7.9412e-06, 2.7158e-07], - [1.4429e-01, 7.4042e-06, 2.6829e-07], - [1.5151e-01, 6.8321e-06, 2.6877e-07], - [1.5908e-01, 5.6809e-06, 2.6232e-07], - [1.6704e-01, 5.6646e-06, 2.8607e-07], - [1.7539e-01, 4.7762e-06, 2.7767e-07], - [1.8416e-01, 4.1971e-06, 2.7353e-07], - [1.9337e-01, 4.1815e-06, 2.9140e-07], - [2.0304e-01, 3.2725e-06, 2.3160e-07], - [2.1319e-01, 2.3244e-06, 4.2270e-07], - [2.2385e-01, 2.2892e-06, 1.4970e-07], - [2.3504e-01, 1.9198e-06, 8.1460e-07], - [2.4679e-01, 1.4828e-06, 1.0840e-07], - [2.5913e-01, 1.1450e-06, 4.7440e-07], - [2.7209e-01, 1.3047e-06, 1.8840e-07], - [2.8569e-01, 9.6081e-07, 3.9385e-07], - [2.9998e-01, 8.2280e-07, 2.3955e-07], - [3.1497e-01, 6.3219e-07, 3.5324e-07], - [3.3072e-01, 6.1254e-07, 5.0846e-07], - [3.4726e-01, 7.4092e-07, 2.2312e-07], - [3.6462e-01, 6.3584e-07, 4.2866e-07], - [3.8285e-01, 7.7287e-07, 2.9493e-07], - [4.0200e-01, 9.4637e-07, 2.3347e-07], - [4.2210e-01, 7.0576e-07, 3.3494e-07], - [4.4320e-01, 7.8969e-07, 2.3371e-07], - [4.6536e-01, 5.8374e-07, 3.2624e-07], - [4.8863e-01, 5.6711e-07, 6.0419e-07], - [5.1306e-01, 4.7782e-07, 3.4822e-07], - [5.3871e-01, 6.3813e-07, 4.3279e-07], - [5.6565e-01, 4.6186e-07, 1.8863e-07], - [5.8877e-01, 5.6129e-07, 4.3960e-07], - ] - ), - data_range=[0.051793, 0.58877], - simulation_range=[0.051793, 0.58877], - ) - project.data.append( - name="d13acmw20", - data=np.array( - [ - [5.1793e-02, 1.8087e-05, 7.9683e-07], - [5.4383e-02, 1.4582e-05, 6.3691e-07], - [5.7102e-02, 1.3621e-05, 5.5407e-07], - [5.9957e-02, 1.2409e-05, 4.8014e-07], - [6.2955e-02, 1.0992e-05, 4.1824e-07], - [6.6103e-02, 1.0619e-05, 3.7541e-07], - [6.9408e-02, 1.0162e-05, 3.4945e-07], - [7.2878e-02, 1.0716e-05, 3.3763e-07], - [7.6522e-02, 8.3468e-06, 2.8040e-07], - [8.0348e-02, 7.5250e-06, 2.5702e-07], - [8.4365e-02, 6.4395e-06, 2.2528e-07], - [8.8584e-02, 6.0544e-06, 2.0545e-07], - [9.3013e-02, 5.9517e-06, 1.9417e-07], - [9.7664e-02, 5.6433e-06, 1.8108e-07], - [1.0255e-01, 4.8172e-06, 1.6076e-07], - [1.0767e-01, 4.8066e-06, 1.5520e-07], - [1.1306e-01, 4.1559e-06, 1.4115e-07], - [1.1871e-01, 4.1418e-06, 1.3926e-07], - [1.2465e-01, 3.4580e-06, 1.2273e-07], - [1.3088e-01, 3.2376e-06, 1.1791e-07], - [1.3742e-01, 3.0976e-06, 1.1948e-07], - [1.4429e-01, 2.7478e-06, 1.1518e-07], - [1.5151e-01, 2.5492e-06, 1.1573e-07], - [1.5908e-01, 2.7500e-06, 1.2812e-07], - [1.6704e-01, 2.1813e-06, 2.0450e-07], - [1.7539e-01, 1.8609e-06, 5.4900e-07], - [1.8416e-01, 1.9405e-06, 1.5660e-07], - [1.9337e-01, 1.7421e-06, 2.3280e-07], - [2.0304e-01, 1.8050e-06, 3.9820e-07], - [2.1319e-01, 1.5801e-06, 1.4110e-07], - [2.2385e-01, 1.6724e-06, 7.7900e-08], - [2.3504e-01, 1.4150e-06, 4.0820e-07], - [2.4679e-01, 1.4340e-06, 5.3180e-07], - [2.5913e-01, 1.3102e-06, 2.6000e-07], - [2.7209e-01, 1.3702e-06, 2.8540e-07], - [2.8569e-01, 1.2468e-06, 2.3230e-07], - [2.9998e-01, 1.2956e-06, 5.3240e-07], - [3.1497e-01, 1.2947e-06, 3.9940e-07], - [3.3072e-01, 1.2488e-06, 2.1390e-07], - [3.4726e-01, 1.4620e-06, 3.3640e-07], - [3.6462e-01, 1.3056e-06, 2.1600e-07], - [3.8285e-01, 1.4553e-06, 2.3170e-07], - [4.0200e-01, 1.1579e-06, 2.6740e-07], - [4.2210e-01, 1.1753e-06, 3.0940e-07], - [4.4320e-01, 1.0066e-06, 5.2040e-07], - [4.6536e-01, 1.1043e-06, 3.1870e-07], - [4.8863e-01, 1.2969e-06, 4.1670e-07], - [5.1306e-01, 1.2495e-06, 2.0890e-07], - [5.3871e-01, 1.3898e-06, 4.7560e-07], - [5.6565e-01, 1.1225e-06, 3.0470e-07], - [5.8877e-01, 8.3346e-07, 3.8944e-07], - ] - ), - data_range=[0.051793, 0.58877], - simulation_range=[0.051793, 0.58877], - ) - project.data.append( - name="d13d2o20", - data=np.array( - [ - [5.1793e-02, 2.2464e-04, 3.4007e-06], - [5.4383e-02, 1.8531e-04, 2.7523e-06], - [5.7102e-02, 1.5463e-04, 2.2639e-06], - [5.9957e-02, 1.2459e-04, 1.8443e-06], - [6.2955e-02, 1.0332e-04, 1.5526e-06], - [6.6103e-02, 8.3207e-05, 1.2736e-06], - [6.9408e-02, 6.6859e-05, 1.0850e-06], - [7.2878e-02, 5.5540e-05, 9.3212e-07], - [7.6522e-02, 4.6869e-05, 8.0410e-07], - [8.0348e-02, 3.6672e-05, 6.8717e-07], - [8.4365e-02, 3.0955e-05, 5.9837e-07], - [8.8584e-02, 2.4781e-05, 5.0395e-07], - [9.3013e-02, 2.0163e-05, 4.3266e-07], - [9.7664e-02, 1.7194e-05, 3.8276e-07], - [1.0255e-01, 1.3801e-05, 3.2953e-07], - [1.0767e-01, 1.0868e-05, 2.8268e-07], - [1.1306e-01, 8.9118e-06, 2.5019e-07], - [1.1871e-01, 8.2266e-06, 2.3789e-07], - [1.2465e-01, 6.7891e-06, 2.0822e-07], - [1.3088e-01, 5.5048e-06, 1.8610e-07], - [1.3742e-01, 4.3011e-06, 1.7064e-07], - [1.4429e-01, 3.7549e-06, 1.6291e-07], - [1.5151e-01, 3.0281e-06, 1.5298e-07], - [1.5908e-01, 2.7102e-06, 1.5371e-07], - [1.6704e-01, 1.9817e-06, 5.2560e-07], - [1.7539e-01, 1.8156e-06, 6.2930e-07], - [1.8416e-01, 1.6126e-06, 1.0180e-07], - [1.9337e-01, 1.5010e-06, 2.6400e-07], - [2.0304e-01, 1.3504e-06, 3.6310e-07], - [2.1319e-01, 1.0658e-06, 6.1751e-07], - [2.2385e-01, 1.0028e-06, 2.4871e-07], - [2.3504e-01, 9.1701e-07, 2.3499e-07], - [2.4679e-01, 7.5092e-07, 2.4518e-07], - [2.5913e-01, 1.0126e-06, 1.6429e-07], - [2.7209e-01, 7.5725e-07, 4.1481e-07], - [2.8569e-01, 6.2167e-07, 3.5735e-07], - [2.9998e-01, 7.0777e-07, 2.0772e-07], - [3.1497e-01, 8.5576e-07, 1.6916e-07], - [3.3072e-01, 8.4284e-07, 2.2151e-07], - [3.4726e-01, 4.4441e-07, 3.2246e-07], - [3.6462e-01, 6.6378e-07, 2.3675e-07], - [3.8285e-01, 7.1382e-07, 3.7039e-07], - [4.0200e-01, 5.6163e-07, 4.4157e-07], - [4.2210e-01, 5.9761e-07, 3.4927e-07], - [4.4320e-01, 4.9182e-07, 3.5155e-07], - [4.6536e-01, 5.6609e-07, 2.3558e-07], - [4.8863e-01, 5.3547e-07, 1.7267e-07], - [5.1306e-01, 4.7647e-07, 5.4127e-07], - [5.3871e-01, 3.8841e-07, 2.9179e-07], - [5.6565e-01, 4.7749e-07, 8.6240e-08], - [5.8877e-01, 4.6278e-07, 2.3214e-07], - ] - ), - data_range=[0.051793, 0.58877], - simulation_range=[0.051793, 0.58877], - ) - project.data.append( - name="d83acmw20", - data=np.array( - [ - [5.1793e-02, 3.1675e-04, 4.7735e-06], - [5.4383e-02, 2.7591e-04, 3.9806e-06], - [5.7102e-02, 2.4370e-04, 3.3680e-06], - [5.9957e-02, 2.1836e-04, 2.8915e-06], - [6.2955e-02, 1.9492e-04, 2.5226e-06], - [6.6103e-02, 1.7128e-04, 2.1638e-06], - [6.9408e-02, 1.5381e-04, 1.9499e-06], - [7.2878e-02, 1.3398e-04, 1.7140e-06], - [7.6522e-02, 1.1643e-04, 1.5011e-06], - [8.0348e-02, 9.7386e-05, 1.3256e-06], - [8.4365e-02, 8.5091e-05, 1.1744e-06], - [8.8584e-02, 7.2996e-05, 1.0224e-06], - [9.3013e-02, 6.0693e-05, 8.8816e-07], - [9.7664e-02, 5.1967e-05, 7.8767e-07], - [1.0255e-01, 4.3371e-05, 6.9118e-07], - [1.0767e-01, 3.6363e-05, 6.1123e-07], - [1.1306e-01, 2.9948e-05, 5.4231e-07], - [1.1871e-01, 2.5863e-05, 4.9879e-07], - [1.2465e-01, 2.1196e-05, 4.3527e-07], - [1.3088e-01, 1.7278e-05, 3.8999e-07], - [1.3742e-01, 1.3647e-05, 3.5922e-07], - [1.4429e-01, 1.0898e-05, 3.2810e-07], - [1.5151e-01, 8.3399e-06, 2.9972e-07], - [1.5908e-01, 6.7776e-06, 2.8761e-07], - [1.6704e-01, 5.8668e-06, 2.9311e-07], - [1.7539e-01, 4.1380e-06, 2.6133e-07], - [1.8416e-01, 2.7663e-06, 2.2329e-07], - [1.9337e-01, 2.3200e-06, 2.1903e-07], - [2.0304e-01, 1.9127e-06, 5.6910e-07], - [2.1319e-01, 1.7434e-06, 1.2640e-07], - [2.2385e-01, 1.7550e-06, 1.9990e-07], - [2.3504e-01, 1.4527e-06, 3.8840e-07], - [2.4679e-01, 1.1333e-06, 5.9440e-07], - [2.5913e-01, 1.1667e-06, 5.7100e-07], - [2.7209e-01, 1.3539e-06, 2.1560e-07], - [2.8569e-01, 1.5357e-06, 3.5990e-07], - [2.9998e-01, 9.0768e-07, 8.9822e-07], - [3.1497e-01, 1.2821e-06, 3.1450e-07], - [3.3072e-01, 1.2360e-06, 4.1700e-07], - [3.4726e-01, 9.6932e-07, 4.5458e-07], - [3.6462e-01, 1.4644e-06, 4.7300e-07], - [3.8285e-01, 1.2330e-06, 3.4780e-07], - [4.0200e-01, 1.3783e-06, 4.5143e-07], - [4.2210e-01, 1.2637e-06, 2.4980e-07], - [4.4320e-01, 1.1299e-06, 1.9310e-07], - [4.6536e-01, 1.1748e-06, 4.3340e-07], - [4.8863e-01, 1.2029e-06, 1.4040e-07], - [5.1306e-01, 9.9648e-07, 6.1262e-07], - [5.3871e-01, 9.4235e-07, 6.9825e-07], - [5.6565e-01, 1.2561e-06, 4.5650e-07], - [5.8877e-01, 1.0005e-06, 1.1520e-07], - ] - ), - data_range=[0.051793, 0.58877], - simulation_range=[0.051793, 0.58877], - ) - project.data.append( - name="d83d2o20", - data=np.array( - [ - [5.1793e-02, 2.3497e-04, 4.1366e-06], - [5.4383e-02, 1.9138e-04, 3.3298e-06], - [5.7102e-02, 1.6092e-04, 2.7523e-06], - [5.9957e-02, 1.3177e-04, 2.2579e-06], - [6.2955e-02, 1.0694e-04, 1.8785e-06], - [6.6103e-02, 9.0449e-05, 1.5805e-06], - [6.9408e-02, 7.2115e-05, 1.3407e-06], - [7.2878e-02, 5.9602e-05, 1.1494e-06], - [7.6522e-02, 4.9097e-05, 9.7903e-07], - [8.0348e-02, 4.1264e-05, 8.6633e-07], - [8.4365e-02, 3.2611e-05, 7.3101e-07], - [8.8584e-02, 2.7676e-05, 6.3311e-07], - [9.3013e-02, 2.2224e-05, 5.4031e-07], - [9.7664e-02, 1.9035e-05, 4.7882e-07], - [1.0255e-01, 1.5324e-05, 4.1267e-07], - [1.0767e-01, 1.3008e-05, 3.6731e-07], - [1.1306e-01, 1.0121e-05, 3.1672e-07], - [1.1871e-01, 9.3837e-06, 3.0201e-07], - [1.2465e-01, 7.4003e-06, 2.5840e-07], - [1.3088e-01, 6.6417e-06, 2.4288e-07], - [1.3742e-01, 5.5185e-06, 2.2950e-07], - [1.4429e-01, 4.6301e-06, 2.1511e-07], - [1.5151e-01, 3.8179e-06, 2.0421e-07], - [1.5908e-01, 3.6504e-06, 2.1327e-07], - [1.6704e-01, 3.3693e-06, 5.8910e-07], - [1.7539e-01, 2.9089e-06, 6.0910e-07], - [1.8416e-01, 2.0826e-06, 8.8760e-07], - [1.9337e-01, 1.8413e-06, 2.0110e-07], - [2.0304e-01, 1.7280e-06, 4.2860e-07], - [2.1319e-01, 2.0794e-06, 4.5100e-07], - [2.2385e-01, 1.2345e-06, 4.2410e-07], - [2.3504e-01, 1.3707e-06, 2.7770e-07], - [2.4679e-01, 1.2666e-06, 9.8800e-08], - [2.5913e-01, 1.1391e-06, 6.9332e-07], - [2.7209e-01, 1.1299e-06, 2.1680e-07], - [2.8569e-01, 8.4537e-07, 5.3956e-07], - [2.9998e-01, 6.8579e-07, 4.6611e-07], - [3.1497e-01, 8.3948e-07, 3.2138e-07], - [3.3072e-01, 8.8276e-07, 4.6705e-07], - [3.4726e-01, 7.8563e-07, 6.4686e-07], - [3.6462e-01, 6.8788e-07, 3.9930e-07], - [3.8285e-01, 6.1412e-07, 1.8886e-07], - [4.0200e-01, 6.8538e-07, 4.0952e-07], - [4.2210e-01, 5.8111e-07, 5.0615e-07], - [4.4320e-01, 5.4626e-07, 2.3667e-07], - [4.6536e-01, 6.5234e-07, 4.2512e-07], - [4.8863e-01, 3.6587e-07, 4.3870e-07], - [5.1306e-01, 4.1699e-07, 1.9893e-07], - [5.3871e-01, 4.9769e-07, 2.1907e-07], - [5.6565e-01, 3.7836e-07, 3.9193e-07], - [5.8877e-01, 4.2082e-07, 3.5255e-07], - ] - ), - data_range=[0.051793, 0.58877], - simulation_range=[0.051793, 0.58877], - ) - project.data.append( - name="hd2o20", - data=np.array( - [ - [5.1793e-02, 2.1311e-04, 3.8170e-06], - [5.4383e-02, 1.7454e-04, 3.0814e-06], - [5.7102e-02, 1.4351e-04, 2.5155e-06], - [5.9957e-02, 1.1515e-04, 2.0424e-06], - [6.2955e-02, 9.0901e-05, 1.6762e-06], - [6.6103e-02, 7.4677e-05, 1.3909e-06], - [6.9408e-02, 6.1965e-05, 1.2044e-06], - [7.2878e-02, 4.9933e-05, 1.0186e-06], - [7.6522e-02, 4.1322e-05, 8.7025e-07], - [8.0348e-02, 3.2145e-05, 7.4114e-07], - [8.4365e-02, 2.6927e-05, 6.4343e-07], - [8.8584e-02, 2.0970e-05, 5.3415e-07], - [9.3013e-02, 1.6109e-05, 4.4582e-07], - [9.7664e-02, 1.2974e-05, 3.8305e-07], - [1.0255e-01, 1.0411e-05, 3.2993e-07], - [1.0767e-01, 7.7586e-06, 2.7512e-07], - [1.1306e-01, 6.8947e-06, 2.5357e-07], - [1.1871e-01, 5.5102e-06, 2.2445e-07], - [1.2465e-01, 4.3486e-06, 1.9200e-07], - [1.3088e-01, 3.3433e-06, 1.6724e-07], - [1.3742e-01, 2.7268e-06, 1.5634e-07], - [1.4429e-01, 2.2001e-06, 1.4377e-07], - [1.5151e-01, 1.8064e-06, 1.3591e-07], - [1.5908e-01, 1.4947e-06, 1.3214e-07], - [1.6704e-01, 1.5335e-06, 3.9200e-07], - [1.7539e-01, 1.0430e-06, 8.5200e-08], - [1.8416e-01, 1.0070e-06, 3.9617e-07], - [1.9337e-01, 7.5452e-07, 1.7785e-07], - [2.0304e-01, 6.9356e-07, 2.8065e-07], - [2.1319e-01, 5.9018e-07, 4.0612e-07], - [2.2385e-01, 7.0286e-07, 3.4384e-07], - [2.3504e-01, 6.0890e-07, 2.8376e-07], - [2.4679e-01, 8.0600e-07, 2.2092e-07], - [2.5913e-01, 7.9177e-07, 3.4918e-07], - [2.7209e-01, 8.5193e-07, 3.3083e-07], - [2.8569e-01, 8.1507e-07, 2.7682e-07], - [2.9998e-01, 7.1477e-07, 1.6790e-07], - [3.1497e-01, 6.1835e-07, 2.0612e-07], - [3.3072e-01, 5.7863e-07, 3.3869e-07], - [3.4726e-01, 4.0735e-07, 6.1275e-07], - [3.6462e-01, 8.2937e-07, 3.2510e-07], - [3.8285e-01, 7.5561e-07, 2.0851e-07], - [4.0200e-01, 6.6174e-07, 2.9566e-07], - [4.2210e-01, 5.6503e-07, 2.0503e-07], - [4.4320e-01, 6.5599e-07, 3.0025e-07], - [4.6536e-01, 4.8085e-07, 2.6812e-07], - [4.8863e-01, 4.1179e-07, 2.7538e-07], - [5.1306e-01, 6.0006e-07, 2.6417e-07], - [5.3871e-01, 6.3395e-07, 3.9303e-07], - [5.6565e-01, 6.3474e-07, 2.3217e-07], - [5.8877e-01, 3.3414e-07, 3.9170e-07], - ] - ), - data_range=[0.051793, 0.58877], - simulation_range=[0.051793, 0.58877], - ) - - project.contrasts.append( - name="d70, acmw", - data="d70acmw20", - background="Background ACMW", - background_action="add", - bulk_in="Air", - bulk_out="ACMW", - scalefactor="Scalefactor 1", - resolution="Resolution 1", - resample=False, - model=["Model_IIb"], - ) - project.contrasts.append( - name="d70 d2o", - data="d70d2o20", - background="Background D2O", - background_action="add", - bulk_in="Air", - bulk_out="D2O", - scalefactor="Scalefactor 1", - resolution="Resolution 1", - resample=False, - model=["Model_IIb"], - ) - project.contrasts.append( - name="d13 acmw", - data="d13acmw20", - background="Background ACMW", - background_action="add", - bulk_in="Air", - bulk_out="ACMW", - scalefactor="Scalefactor 1", - resolution="Resolution 1", - resample=False, - model=["Model_IIb"], - ) - project.contrasts.append( - name="d13 d2o", - data="d13d2o20", - background="Background D2O", - background_action="add", - bulk_in="Air", - bulk_out="D2O", - scalefactor="Scalefactor 1", - resolution="Resolution 1", - resample=False, - model=["Model_IIb"], - ) - project.contrasts.append( - name="d83 acmw", - data="d83acmw20", - background="Background ACMW", - background_action="add", - bulk_in="Air", - bulk_out="ACMW", - scalefactor="Scalefactor 1", - resolution="Resolution 1", - resample=False, - model=["Model_IIb"], - ) - project.contrasts.append( - name="d83 d2o", - data="d83d2o20", - background="Background D2O", - background_action="add", - bulk_in="Air", - bulk_out="D2O", - scalefactor="Scalefactor 1", - resolution="Resolution 1", - resample=False, - model=["Model_IIb"], - ) - project.contrasts.append( - name="fully h, D2O", - data="hd2o20", - background="Background D2O", - background_action="add", - bulk_in="Air", - bulk_out="D2O", - scalefactor="Scalefactor 1", - resolution="Resolution 1", - resample=False, - model=["Model_IIb"], - ) - - return project - - -@pytest.fixture -def r1_monolayer_8_contrasts(): - """The Project equivalent of the R1 Monolayer_8_contrasts RasCAL-1 project.""" - return ratapi.Project( - name="20nM_data", - calculation="normal", - model="standard layers", - geometry="air/substrate", - absorption=False, - parameters=[ - ratapi.models.ProtectedParameter( - name="Substrate Roughness", - min=3.0, - value=6.990825828311747, - max=7.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ratapi.models.Parameter( - name="Tails thick", - min=12.0, - value=18.769067940891517, - max=20.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ratapi.models.Parameter( - name="Deuterated tails SLD", - min=5e-06, - value=6.935587727961928e-06, - max=9e-06, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ratapi.models.Parameter( - name="Tails roughness", - min=3.0, - value=3.0000000000074776, - max=7.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ratapi.models.Parameter( - name="Hydrogenated tails SLD", - min=-6e-07, - value=-2.1907853109709215e-07, - max=-2e-07, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ratapi.models.Parameter( - name="Head thickness", - min=7.0, - value=7.000000000117902, - max=12.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ratapi.models.Parameter( - name="Deuterated head SLD", - min=3e-06, - value=5.855129143529369e-06, - max=6e-06, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ratapi.models.Parameter( - name="Head roughness", - min=3.0, - value=3.0000000000000258, - max=7.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ratapi.models.Parameter( - name="Hydrogenated head SLD", - min=1e-06, - value=1.8079398141440577e-06, - max=2e-06, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ratapi.models.Parameter( - name="Head hydration", - min=0.0, - value=9.33740417574095, - max=20.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ], - bulk_in=[ - ratapi.models.Parameter( - name="Air", - min=0.0, - value=0.0, - max=0.0, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - ], - bulk_out=[ - ratapi.models.Parameter( - name="D2O", - min=6.3e-06, - value=6.349999999999999e-06, - max=6.4e-06, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ratapi.models.Parameter( - name="ACMW", - min=-5e-07, - value=3.492898018624419e-08, - max=5e-07, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ], - scalefactors=[ - ratapi.models.Parameter( - name="Scalefactor 1", - min=0.1, - value=0.23251357931599084, - max=0.4, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - ], - domain_ratios=[], - background_parameters=[ - ratapi.models.Parameter( - name="Background parameter 1", - min=1e-07, - value=2.889465920816701e-06, - max=7e-06, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ratapi.models.Parameter( - name="Background parameter 2", - min=1e-07, - value=5.172884539063037e-06, - max=7e-06, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ], - backgrounds=[ - ratapi.models.Background( - name="Background D2O", - type="constant", - source="Background parameter 1", - ), - ratapi.models.Background( - name="Background ACMW", - type="constant", - source="Background parameter 2", - ), - ], - resolution_parameters=[ - ratapi.models.Parameter( - name="Resolution parameter 1", - min=0.01, - value=0.029999999999999964, - max=0.05, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - ], - resolutions=[ - ratapi.models.Resolution( - name="Resolution 1", - type="constant", - source="Resolution parameter 1", - ) - ], - custom_files=[], - data=[ - ratapi.models.Data( - name="d70acmw20", - data=np.array( - [ - [5.1793e-02, 2.3792e-04, 3.6498e-06], - [5.4383e-02, 2.2030e-04, 3.1361e-06], - [5.7102e-02, 1.9302e-04, 2.6450e-06], - [5.9957e-02, 1.7223e-04, 2.2673e-06], - [6.2955e-02, 1.5210e-04, 1.9699e-06], - [6.6103e-02, 1.3650e-04, 1.7055e-06], - [6.9408e-02, 1.1806e-04, 1.5072e-06], - [7.2878e-02, 1.0904e-04, 1.3658e-06], - [7.6522e-02, 9.5873e-05, 1.2024e-06], - [8.0348e-02, 8.2201e-05, 1.0754e-06], - [8.4365e-02, 7.0764e-05, 9.4576e-07], - [8.8584e-02, 6.2973e-05, 8.3975e-07], - [9.3013e-02, 5.3710e-05, 7.3854e-07], - [9.7664e-02, 4.6651e-05, 6.5893e-07], - [1.0255e-01, 4.0448e-05, 5.8945e-07], - [1.0767e-01, 3.4559e-05, 5.2655e-07], - [1.1306e-01, 2.9817e-05, 4.7806e-07], - [1.1871e-01, 2.5965e-05, 4.4165e-07], - [1.2465e-01, 2.1963e-05, 3.9117e-07], - [1.3088e-01, 1.8535e-05, 3.5668e-07], - [1.3742e-01, 1.6299e-05, 3.4665e-07], - [1.4429e-01, 1.3704e-05, 3.2491e-07], - [1.5151e-01, 1.0571e-05, 2.9830e-07], - [1.5908e-01, 8.9320e-06, 2.9188e-07], - [1.6704e-01, 6.8328e-06, 2.7922e-07], - [1.7539e-01, 5.7856e-06, 2.7261e-07], - [1.8416e-01, 4.5358e-06, 2.5335e-07], - [1.9337e-01, 3.9935e-06, 2.5336e-07], - [2.0304e-01, 3.1800e-06, 5.2440e-07], - [2.1319e-01, 2.7006e-06, 4.6690e-07], - [2.2385e-01, 2.2210e-06, 4.5090e-07], - [2.3504e-01, 1.6163e-06, 4.9340e-07], - [2.4679e-01, 1.7554e-06, 3.2120e-07], - [2.5913e-01, 1.3194e-06, 1.7170e-07], - [2.7209e-01, 1.5033e-06, 3.4760e-07], - [2.8569e-01, 1.3801e-06, 7.2017e-07], - [2.9998e-01, 1.2640e-06, 4.5486e-07], - [3.1497e-01, 1.0585e-06, 3.6820e-07], - [3.3072e-01, 1.3063e-06, 4.5401e-07], - [3.4726e-01, 1.1229e-06, 2.3240e-07], - [3.6462e-01, 1.5197e-06, 4.8780e-07], - [3.8285e-01, 1.1419e-06, 4.1880e-07], - [4.0200e-01, 1.3285e-06, 4.0215e-07], - [4.2210e-01, 1.2467e-06, 5.8010e-07], - [4.4320e-01, 1.1322e-06, 3.2730e-07], - [4.6536e-01, 1.1336e-06, 4.3291e-07], - [4.8863e-01, 1.4843e-06, 5.0110e-07], - [5.1306e-01, 1.2055e-06, 3.0660e-07], - [5.3871e-01, 1.2170e-06, 4.0500e-07], - [5.6565e-01, 8.9674e-07, 3.5866e-07], - [5.8877e-01, 9.4625e-07, 7.6511e-07], - ] - ), - data_range=[0.051793, 0.58877], - simulation_range=[0.051793, 0.58877], - ), - ratapi.models.Data( - name="d70d2o20", - data=np.array( - [ - [5.1793e-02, 1.4943e-04, 3.2517e-06], - [5.4383e-02, 1.1882e-04, 2.5846e-06], - [5.7102e-02, 9.2164e-05, 2.0507e-06], - [5.9957e-02, 7.7813e-05, 1.7070e-06], - [6.2955e-02, 6.1143e-05, 1.3983e-06], - [6.6103e-02, 4.8033e-05, 1.1343e-06], - [6.9408e-02, 4.1379e-05, 1.0006e-06], - [7.2878e-02, 3.5090e-05, 8.6919e-07], - [7.6522e-02, 3.0350e-05, 7.5890e-07], - [8.0348e-02, 2.4115e-05, 6.5226e-07], - [8.4365e-02, 2.0755e-05, 5.7445e-07], - [8.8584e-02, 1.7500e-05, 4.9617e-07], - [9.3013e-02, 1.5011e-05, 4.3754e-07], - [9.7664e-02, 1.3632e-05, 3.9907e-07], - [1.0255e-01, 1.2997e-05, 3.7469e-07], - [1.0767e-01, 1.1656e-05, 3.4282e-07], - [1.1306e-01, 1.0820e-05, 3.2299e-07], - [1.1871e-01, 9.5831e-06, 3.0088e-07], - [1.2465e-01, 8.9996e-06, 2.8102e-07], - [1.3088e-01, 8.6498e-06, 2.7363e-07], - [1.3742e-01, 7.9412e-06, 2.7158e-07], - [1.4429e-01, 7.4042e-06, 2.6829e-07], - [1.5151e-01, 6.8321e-06, 2.6877e-07], - [1.5908e-01, 5.6809e-06, 2.6232e-07], - [1.6704e-01, 5.6646e-06, 2.8607e-07], - [1.7539e-01, 4.7762e-06, 2.7767e-07], - [1.8416e-01, 4.1971e-06, 2.7353e-07], - [1.9337e-01, 4.1815e-06, 2.9140e-07], - [2.0304e-01, 3.2725e-06, 2.3160e-07], - [2.1319e-01, 2.3244e-06, 4.2270e-07], - [2.2385e-01, 2.2892e-06, 1.4970e-07], - [2.3504e-01, 1.9198e-06, 8.1460e-07], - [2.4679e-01, 1.4828e-06, 1.0840e-07], - [2.5913e-01, 1.1450e-06, 4.7440e-07], - [2.7209e-01, 1.3047e-06, 1.8840e-07], - [2.8569e-01, 9.6081e-07, 3.9385e-07], - [2.9998e-01, 8.2280e-07, 2.3955e-07], - [3.1497e-01, 6.3219e-07, 3.5324e-07], - [3.3072e-01, 6.1254e-07, 5.0846e-07], - [3.4726e-01, 7.4092e-07, 2.2312e-07], - [3.6462e-01, 6.3584e-07, 4.2866e-07], - [3.8285e-01, 7.7287e-07, 2.9493e-07], - [4.0200e-01, 9.4637e-07, 2.3347e-07], - [4.2210e-01, 7.0576e-07, 3.3494e-07], - [4.4320e-01, 7.8969e-07, 2.3371e-07], - [4.6536e-01, 5.8374e-07, 3.2624e-07], - [4.8863e-01, 5.6711e-07, 6.0419e-07], - [5.1306e-01, 4.7782e-07, 3.4822e-07], - [5.3871e-01, 6.3813e-07, 4.3279e-07], - [5.6565e-01, 4.6186e-07, 1.8863e-07], - [5.8877e-01, 5.6129e-07, 4.3960e-07], - ] - ), - data_range=[0.051793, 0.58877], - simulation_range=[0.051793, 0.58877], - ), - ratapi.models.Data( - name="d13acmw20", - data=np.array( - [ - [5.1793e-02, 1.8087e-05, 7.9683e-07], - [5.4383e-02, 1.4582e-05, 6.3691e-07], - [5.7102e-02, 1.3621e-05, 5.5407e-07], - [5.9957e-02, 1.2409e-05, 4.8014e-07], - [6.2955e-02, 1.0992e-05, 4.1824e-07], - [6.6103e-02, 1.0619e-05, 3.7541e-07], - [6.9408e-02, 1.0162e-05, 3.4945e-07], - [7.2878e-02, 1.0716e-05, 3.3763e-07], - [7.6522e-02, 8.3468e-06, 2.8040e-07], - [8.0348e-02, 7.5250e-06, 2.5702e-07], - [8.4365e-02, 6.4395e-06, 2.2528e-07], - [8.8584e-02, 6.0544e-06, 2.0545e-07], - [9.3013e-02, 5.9517e-06, 1.9417e-07], - [9.7664e-02, 5.6433e-06, 1.8108e-07], - [1.0255e-01, 4.8172e-06, 1.6076e-07], - [1.0767e-01, 4.8066e-06, 1.5520e-07], - [1.1306e-01, 4.1559e-06, 1.4115e-07], - [1.1871e-01, 4.1418e-06, 1.3926e-07], - [1.2465e-01, 3.4580e-06, 1.2273e-07], - [1.3088e-01, 3.2376e-06, 1.1791e-07], - [1.3742e-01, 3.0976e-06, 1.1948e-07], - [1.4429e-01, 2.7478e-06, 1.1518e-07], - [1.5151e-01, 2.5492e-06, 1.1573e-07], - [1.5908e-01, 2.7500e-06, 1.2812e-07], - [1.6704e-01, 2.1813e-06, 2.0450e-07], - [1.7539e-01, 1.8609e-06, 5.4900e-07], - [1.8416e-01, 1.9405e-06, 1.5660e-07], - [1.9337e-01, 1.7421e-06, 2.3280e-07], - [2.0304e-01, 1.8050e-06, 3.9820e-07], - [2.1319e-01, 1.5801e-06, 1.4110e-07], - [2.2385e-01, 1.6724e-06, 7.7900e-08], - [2.3504e-01, 1.4150e-06, 4.0820e-07], - [2.4679e-01, 1.4340e-06, 5.3180e-07], - [2.5913e-01, 1.3102e-06, 2.6000e-07], - [2.7209e-01, 1.3702e-06, 2.8540e-07], - [2.8569e-01, 1.2468e-06, 2.3230e-07], - [2.9998e-01, 1.2956e-06, 5.3240e-07], - [3.1497e-01, 1.2947e-06, 3.9940e-07], - [3.3072e-01, 1.2488e-06, 2.1390e-07], - [3.4726e-01, 1.4620e-06, 3.3640e-07], - [3.6462e-01, 1.3056e-06, 2.1600e-07], - [3.8285e-01, 1.4553e-06, 2.3170e-07], - [4.0200e-01, 1.1579e-06, 2.6740e-07], - [4.2210e-01, 1.1753e-06, 3.0940e-07], - [4.4320e-01, 1.0066e-06, 5.2040e-07], - [4.6536e-01, 1.1043e-06, 3.1870e-07], - [4.8863e-01, 1.2969e-06, 4.1670e-07], - [5.1306e-01, 1.2495e-06, 2.0890e-07], - [5.3871e-01, 1.3898e-06, 4.7560e-07], - [5.6565e-01, 1.1225e-06, 3.0470e-07], - [5.8877e-01, 8.3346e-07, 3.8944e-07], - ] - ), - data_range=[0.051793, 0.58877], - simulation_range=[0.051793, 0.58877], - ), - ratapi.models.Data( - name="d13d2o20", - data=np.array( - [ - [5.1793e-02, 2.2464e-04, 3.4007e-06], - [5.4383e-02, 1.8531e-04, 2.7523e-06], - [5.7102e-02, 1.5463e-04, 2.2639e-06], - [5.9957e-02, 1.2459e-04, 1.8443e-06], - [6.2955e-02, 1.0332e-04, 1.5526e-06], - [6.6103e-02, 8.3207e-05, 1.2736e-06], - [6.9408e-02, 6.6859e-05, 1.0850e-06], - [7.2878e-02, 5.5540e-05, 9.3212e-07], - [7.6522e-02, 4.6869e-05, 8.0410e-07], - [8.0348e-02, 3.6672e-05, 6.8717e-07], - [8.4365e-02, 3.0955e-05, 5.9837e-07], - [8.8584e-02, 2.4781e-05, 5.0395e-07], - [9.3013e-02, 2.0163e-05, 4.3266e-07], - [9.7664e-02, 1.7194e-05, 3.8276e-07], - [1.0255e-01, 1.3801e-05, 3.2953e-07], - [1.0767e-01, 1.0868e-05, 2.8268e-07], - [1.1306e-01, 8.9118e-06, 2.5019e-07], - [1.1871e-01, 8.2266e-06, 2.3789e-07], - [1.2465e-01, 6.7891e-06, 2.0822e-07], - [1.3088e-01, 5.5048e-06, 1.8610e-07], - [1.3742e-01, 4.3011e-06, 1.7064e-07], - [1.4429e-01, 3.7549e-06, 1.6291e-07], - [1.5151e-01, 3.0281e-06, 1.5298e-07], - [1.5908e-01, 2.7102e-06, 1.5371e-07], - [1.6704e-01, 1.9817e-06, 5.2560e-07], - [1.7539e-01, 1.8156e-06, 6.2930e-07], - [1.8416e-01, 1.6126e-06, 1.0180e-07], - [1.9337e-01, 1.5010e-06, 2.6400e-07], - [2.0304e-01, 1.3504e-06, 3.6310e-07], - [2.1319e-01, 1.0658e-06, 6.1751e-07], - [2.2385e-01, 1.0028e-06, 2.4871e-07], - [2.3504e-01, 9.1701e-07, 2.3499e-07], - [2.4679e-01, 7.5092e-07, 2.4518e-07], - [2.5913e-01, 1.0126e-06, 1.6429e-07], - [2.7209e-01, 7.5725e-07, 4.1481e-07], - [2.8569e-01, 6.2167e-07, 3.5735e-07], - [2.9998e-01, 7.0777e-07, 2.0772e-07], - [3.1497e-01, 8.5576e-07, 1.6916e-07], - [3.3072e-01, 8.4284e-07, 2.2151e-07], - [3.4726e-01, 4.4441e-07, 3.2246e-07], - [3.6462e-01, 6.6378e-07, 2.3675e-07], - [3.8285e-01, 7.1382e-07, 3.7039e-07], - [4.0200e-01, 5.6163e-07, 4.4157e-07], - [4.2210e-01, 5.9761e-07, 3.4927e-07], - [4.4320e-01, 4.9182e-07, 3.5155e-07], - [4.6536e-01, 5.6609e-07, 2.3558e-07], - [4.8863e-01, 5.3547e-07, 1.7267e-07], - [5.1306e-01, 4.7647e-07, 5.4127e-07], - [5.3871e-01, 3.8841e-07, 2.9179e-07], - [5.6565e-01, 4.7749e-07, 8.6240e-08], - [5.8877e-01, 4.6278e-07, 2.3214e-07], - ] - ), - data_range=[0.051793, 0.58877], - simulation_range=[0.051793, 0.58877], - ), - ratapi.models.Data( - name="d83acmw20", - data=np.array( - [ - [5.1793e-02, 3.1675e-04, 4.7735e-06], - [5.4383e-02, 2.7591e-04, 3.9806e-06], - [5.7102e-02, 2.4370e-04, 3.3680e-06], - [5.9957e-02, 2.1836e-04, 2.8915e-06], - [6.2955e-02, 1.9492e-04, 2.5226e-06], - [6.6103e-02, 1.7128e-04, 2.1638e-06], - [6.9408e-02, 1.5381e-04, 1.9499e-06], - [7.2878e-02, 1.3398e-04, 1.7140e-06], - [7.6522e-02, 1.1643e-04, 1.5011e-06], - [8.0348e-02, 9.7386e-05, 1.3256e-06], - [8.4365e-02, 8.5091e-05, 1.1744e-06], - [8.8584e-02, 7.2996e-05, 1.0224e-06], - [9.3013e-02, 6.0693e-05, 8.8816e-07], - [9.7664e-02, 5.1967e-05, 7.8767e-07], - [1.0255e-01, 4.3371e-05, 6.9118e-07], - [1.0767e-01, 3.6363e-05, 6.1123e-07], - [1.1306e-01, 2.9948e-05, 5.4231e-07], - [1.1871e-01, 2.5863e-05, 4.9879e-07], - [1.2465e-01, 2.1196e-05, 4.3527e-07], - [1.3088e-01, 1.7278e-05, 3.8999e-07], - [1.3742e-01, 1.3647e-05, 3.5922e-07], - [1.4429e-01, 1.0898e-05, 3.2810e-07], - [1.5151e-01, 8.3399e-06, 2.9972e-07], - [1.5908e-01, 6.7776e-06, 2.8761e-07], - [1.6704e-01, 5.8668e-06, 2.9311e-07], - [1.7539e-01, 4.1380e-06, 2.6133e-07], - [1.8416e-01, 2.7663e-06, 2.2329e-07], - [1.9337e-01, 2.3200e-06, 2.1903e-07], - [2.0304e-01, 1.9127e-06, 5.6910e-07], - [2.1319e-01, 1.7434e-06, 1.2640e-07], - [2.2385e-01, 1.7550e-06, 1.9990e-07], - [2.3504e-01, 1.4527e-06, 3.8840e-07], - [2.4679e-01, 1.1333e-06, 5.9440e-07], - [2.5913e-01, 1.1667e-06, 5.7100e-07], - [2.7209e-01, 1.3539e-06, 2.1560e-07], - [2.8569e-01, 1.5357e-06, 3.5990e-07], - [2.9998e-01, 9.0768e-07, 8.9822e-07], - [3.1497e-01, 1.2821e-06, 3.1450e-07], - [3.3072e-01, 1.2360e-06, 4.1700e-07], - [3.4726e-01, 9.6932e-07, 4.5458e-07], - [3.6462e-01, 1.4644e-06, 4.7300e-07], - [3.8285e-01, 1.2330e-06, 3.4780e-07], - [4.0200e-01, 1.3783e-06, 4.5143e-07], - [4.2210e-01, 1.2637e-06, 2.4980e-07], - [4.4320e-01, 1.1299e-06, 1.9310e-07], - [4.6536e-01, 1.1748e-06, 4.3340e-07], - [4.8863e-01, 1.2029e-06, 1.4040e-07], - [5.1306e-01, 9.9648e-07, 6.1262e-07], - [5.3871e-01, 9.4235e-07, 6.9825e-07], - [5.6565e-01, 1.2561e-06, 4.5650e-07], - [5.8877e-01, 1.0005e-06, 1.1520e-07], - ] - ), - data_range=[0.051793, 0.58877], - simulation_range=[0.051793, 0.58877], - ), - ratapi.models.Data( - name="d83d2o20", - data=np.array( - [ - [5.1793e-02, 2.3497e-04, 4.1366e-06], - [5.4383e-02, 1.9138e-04, 3.3298e-06], - [5.7102e-02, 1.6092e-04, 2.7523e-06], - [5.9957e-02, 1.3177e-04, 2.2579e-06], - [6.2955e-02, 1.0694e-04, 1.8785e-06], - [6.6103e-02, 9.0449e-05, 1.5805e-06], - [6.9408e-02, 7.2115e-05, 1.3407e-06], - [7.2878e-02, 5.9602e-05, 1.1494e-06], - [7.6522e-02, 4.9097e-05, 9.7903e-07], - [8.0348e-02, 4.1264e-05, 8.6633e-07], - [8.4365e-02, 3.2611e-05, 7.3101e-07], - [8.8584e-02, 2.7676e-05, 6.3311e-07], - [9.3013e-02, 2.2224e-05, 5.4031e-07], - [9.7664e-02, 1.9035e-05, 4.7882e-07], - [1.0255e-01, 1.5324e-05, 4.1267e-07], - [1.0767e-01, 1.3008e-05, 3.6731e-07], - [1.1306e-01, 1.0121e-05, 3.1672e-07], - [1.1871e-01, 9.3837e-06, 3.0201e-07], - [1.2465e-01, 7.4003e-06, 2.5840e-07], - [1.3088e-01, 6.6417e-06, 2.4288e-07], - [1.3742e-01, 5.5185e-06, 2.2950e-07], - [1.4429e-01, 4.6301e-06, 2.1511e-07], - [1.5151e-01, 3.8179e-06, 2.0421e-07], - [1.5908e-01, 3.6504e-06, 2.1327e-07], - [1.6704e-01, 3.3693e-06, 5.8910e-07], - [1.7539e-01, 2.9089e-06, 6.0910e-07], - [1.8416e-01, 2.0826e-06, 8.8760e-07], - [1.9337e-01, 1.8413e-06, 2.0110e-07], - [2.0304e-01, 1.7280e-06, 4.2860e-07], - [2.1319e-01, 2.0794e-06, 4.5100e-07], - [2.2385e-01, 1.2345e-06, 4.2410e-07], - [2.3504e-01, 1.3707e-06, 2.7770e-07], - [2.4679e-01, 1.2666e-06, 9.8800e-08], - [2.5913e-01, 1.1391e-06, 6.9332e-07], - [2.7209e-01, 1.1299e-06, 2.1680e-07], - [2.8569e-01, 8.4537e-07, 5.3956e-07], - [2.9998e-01, 6.8579e-07, 4.6611e-07], - [3.1497e-01, 8.3948e-07, 3.2138e-07], - [3.3072e-01, 8.8276e-07, 4.6705e-07], - [3.4726e-01, 7.8563e-07, 6.4686e-07], - [3.6462e-01, 6.8788e-07, 3.9930e-07], - [3.8285e-01, 6.1412e-07, 1.8886e-07], - [4.0200e-01, 6.8538e-07, 4.0952e-07], - [4.2210e-01, 5.8111e-07, 5.0615e-07], - [4.4320e-01, 5.4626e-07, 2.3667e-07], - [4.6536e-01, 6.5234e-07, 4.2512e-07], - [4.8863e-01, 3.6587e-07, 4.3870e-07], - [5.1306e-01, 4.1699e-07, 1.9893e-07], - [5.3871e-01, 4.9769e-07, 2.1907e-07], - [5.6565e-01, 3.7836e-07, 3.9193e-07], - [5.8877e-01, 4.2082e-07, 3.5255e-07], - ] - ), - data_range=[0.051793, 0.58877], - simulation_range=[0.051793, 0.58877], - ), - ratapi.models.Data( - name="hd2o20", - data=np.array( - [ - [5.1793e-02, 2.1311e-04, 3.8170e-06], - [5.4383e-02, 1.7454e-04, 3.0814e-06], - [5.7102e-02, 1.4351e-04, 2.5155e-06], - [5.9957e-02, 1.1515e-04, 2.0424e-06], - [6.2955e-02, 9.0901e-05, 1.6762e-06], - [6.6103e-02, 7.4677e-05, 1.3909e-06], - [6.9408e-02, 6.1965e-05, 1.2044e-06], - [7.2878e-02, 4.9933e-05, 1.0186e-06], - [7.6522e-02, 4.1322e-05, 8.7025e-07], - [8.0348e-02, 3.2145e-05, 7.4114e-07], - [8.4365e-02, 2.6927e-05, 6.4343e-07], - [8.8584e-02, 2.0970e-05, 5.3415e-07], - [9.3013e-02, 1.6109e-05, 4.4582e-07], - [9.7664e-02, 1.2974e-05, 3.8305e-07], - [1.0255e-01, 1.0411e-05, 3.2993e-07], - [1.0767e-01, 7.7586e-06, 2.7512e-07], - [1.1306e-01, 6.8947e-06, 2.5357e-07], - [1.1871e-01, 5.5102e-06, 2.2445e-07], - [1.2465e-01, 4.3486e-06, 1.9200e-07], - [1.3088e-01, 3.3433e-06, 1.6724e-07], - [1.3742e-01, 2.7268e-06, 1.5634e-07], - [1.4429e-01, 2.2001e-06, 1.4377e-07], - [1.5151e-01, 1.8064e-06, 1.3591e-07], - [1.5908e-01, 1.4947e-06, 1.3214e-07], - [1.6704e-01, 1.5335e-06, 3.9200e-07], - [1.7539e-01, 1.0430e-06, 8.5200e-08], - [1.8416e-01, 1.0070e-06, 3.9617e-07], - [1.9337e-01, 7.5452e-07, 1.7785e-07], - [2.0304e-01, 6.9356e-07, 2.8065e-07], - [2.1319e-01, 5.9018e-07, 4.0612e-07], - [2.2385e-01, 7.0286e-07, 3.4384e-07], - [2.3504e-01, 6.0890e-07, 2.8376e-07], - [2.4679e-01, 8.0600e-07, 2.2092e-07], - [2.5913e-01, 7.9177e-07, 3.4918e-07], - [2.7209e-01, 8.5193e-07, 3.3083e-07], - [2.8569e-01, 8.1507e-07, 2.7682e-07], - [2.9998e-01, 7.1477e-07, 1.6790e-07], - [3.1497e-01, 6.1835e-07, 2.0612e-07], - [3.3072e-01, 5.7863e-07, 3.3869e-07], - [3.4726e-01, 4.0735e-07, 6.1275e-07], - [3.6462e-01, 8.2937e-07, 3.2510e-07], - [3.8285e-01, 7.5561e-07, 2.0851e-07], - [4.0200e-01, 6.6174e-07, 2.9566e-07], - [4.2210e-01, 5.6503e-07, 2.0503e-07], - [4.4320e-01, 6.5599e-07, 3.0025e-07], - [4.6536e-01, 4.8085e-07, 2.6812e-07], - [4.8863e-01, 4.1179e-07, 2.7538e-07], - [5.1306e-01, 6.0006e-07, 2.6417e-07], - [5.3871e-01, 6.3395e-07, 3.9303e-07], - [5.6565e-01, 6.3474e-07, 2.3217e-07], - [5.8877e-01, 3.3414e-07, 3.9170e-07], - ] - ), - data_range=[0.051793, 0.58877], - simulation_range=[0.051793, 0.58877], - ), - ], - layers=[ - ratapi.models.Layer( - name="Deuterated tails", - thickness="Tails thick", - SLD="Deuterated tails SLD", - roughness="Tails roughness", - hydration="", - hydrate_with="bulk out", - ), - ratapi.models.Layer( - name="Hydrogenated tails", - thickness="Tails thick", - SLD="Hydrogenated tails SLD", - roughness="Tails roughness", - hydration="", - hydrate_with="bulk out", - ), - ratapi.models.Layer( - name="Deuterated heads", - thickness="Head thickness", - SLD="Deuterated head SLD", - roughness="Head roughness", - hydration="Head hydration", - hydrate_with="bulk out", - ), - ratapi.models.Layer( - name="Hydrogenated heads", - thickness="Head thickness", - SLD="Hydrogenated head SLD", - roughness="Head roughness", - hydration="Head hydration", - hydrate_with="bulk out", - ), - ], - domain_contrasts=[], - contrasts=[ - ratapi.models.Contrast( - name="d70, acmw", - data="d70acmw20", - background="Background ACMW", - background_action="add", - bulk_in="Air", - bulk_out="ACMW", - scalefactor="Scalefactor 1", - resolution="Resolution 1", - resample=False, - model=["Deuterated tails", "Hydrogenated heads"], - ), - ratapi.models.Contrast( - name="d70 d2o", - data="d70d2o20", - background="Background D2O", - background_action="add", - bulk_in="Air", - bulk_out="D2O", - scalefactor="Scalefactor 1", - resolution="Resolution 1", - resample=False, - model=["Deuterated tails", "Hydrogenated heads"], - ), - ratapi.models.Contrast( - name="d13 acmw", - data="d13acmw20", - background="Background ACMW", - background_action="add", - bulk_in="Air", - bulk_out="ACMW", - scalefactor="Scalefactor 1", - resolution="Resolution 1", - resample=False, - model=["Hydrogenated tails", "Deuterated heads"], - ), - ratapi.models.Contrast( - name="d13 d2o", - data="d13d2o20", - background="Background D2O", - background_action="add", - bulk_in="Air", - bulk_out="D2O", - scalefactor="Scalefactor 1", - resolution="Resolution 1", - resample=False, - model=["Hydrogenated tails", "Deuterated heads"], - ), - ratapi.models.Contrast( - name="d83 acmw", - data="d83acmw20", - background="Background ACMW", - background_action="add", - bulk_in="Air", - bulk_out="ACMW", - scalefactor="Scalefactor 1", - resolution="Resolution 1", - resample=False, - model=["Deuterated tails", "Deuterated heads"], - ), - ratapi.models.Contrast( - name="d83 d2o", - data="d83d2o20", - background="Background D2O", - background_action="add", - bulk_in="Air", - bulk_out="D2O", - scalefactor="Scalefactor 1", - resolution="Resolution 1", - resample=False, - model=["Deuterated tails", "Deuterated heads"], - ), - ratapi.models.Contrast( - name="fully h, D2O", - data="hd2o20", - background="Background D2O", - background_action="add", - bulk_in="Air", - bulk_out="D2O", - scalefactor="Scalefactor 1", - resolution="Resolution 1", - resample=False, - model=["Hydrogenated tails", "Hydrogenated heads"], - ), - ], - ) - - -@pytest.fixture -def r1_orso_polymer(): - """The project equivalent of the RasCAL-1 ORSO Polymer example.""" - # the test data is BIG (400 lines) so it's easier to just load it in - orso_poly_data = np.loadtxt(Path(__file__).parent / "test_data/orso_poly.dat") - - return ratapi.Project( - name="orsoPolymerExample", - calculation="normal", - model="standard layers", - geometry="air/substrate", - absorption=False, - parameters=[ - ratapi.models.ProtectedParameter( - name="Substrate Roughness", - min=3.0, - value=4.844363132849221, - max=8.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - ], - bulk_in=[ - ratapi.models.Parameter( - name="Air", - min=0.0, - value=0.0, - max=0.0, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - ], - bulk_out=[ - ratapi.models.Parameter( - name="D2O", - min=6.3e-06, - value=6.35e-06, - max=6.4e-06, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - ], - scalefactors=[ - ratapi.models.Parameter( - name="Scalefactor 1", - min=0.05, - value=0.10141560336360426, - max=0.3, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - ], - domain_ratios=[], - background_parameters=[ - ratapi.models.Parameter( - name="Background parameter 1", - min=5e-08, - value=3.069003361230152e-06, - max=7e-06, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - ], - backgrounds=[ - ratapi.models.Background( - name="Background 1", - type="constant", - source="Background parameter 1", - ) - ], - resolution_parameters=[ - ratapi.models.Parameter( - name="Resolution parameter 1", - min=0.01, - value=0.03, - max=0.05, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - ], - resolutions=[ - ratapi.models.Resolution( - name="Resolution 1", - type="constant", - source="Resolution parameter 1", - ) - ], - custom_files=[], - data=[ - ratapi.models.Data( - name="polymerData", - data=orso_poly_data, - data_range=[0.0080602, 0.46555], - simulation_range=[0.0080602, 0.46555], - ) - ], - layers=[], - domain_contrasts=[], - contrasts=[ - ratapi.models.Contrast( - name="Chain-d, acmw", - data="polymerData", - background="Background 1", - background_action="add", - bulk_in="Air", - bulk_out="D2O", - scalefactor="Scalefactor 1", - resolution="Resolution 1", - resample=False, - model=[], - ) - ], - ) - - -@pytest.fixture -def r1_motofit_bench_mark(): - """The project from the R1motofitBenchMark RasCAL-1 project file.""" - moto_data = np.loadtxt(Path(__file__).parent / "test_data/moto.dat") - - return ratapi.Project( - name="motofitBenchMark", - calculation="normal", - model="standard layers", - geometry="air/substrate", - absorption=False, - parameters=[ - ratapi.models.ProtectedParameter( - name="Substrate Roughness", - min=1.0, - value=3.0, - max=5.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ratapi.models.Parameter( - name="sub rough", - min=3.0, - value=3.9949146424129665, - max=8.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ratapi.models.Parameter( - name="Thick", - min=0.0, - value=33.2791896400743, - max=100.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ratapi.models.Parameter( - name="SLD 1", - min=0.0, - value=1.074484187182878e-06, - max=5e-06, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ratapi.models.Parameter( - name="SLD 2", - min=9e-06, - value=1.0658506835478824e-05, - max=1.2e-05, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ratapi.models.Parameter( - name="Thick2", - min=100.0, - value=498.6676783112137, - max=1000.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ratapi.models.Parameter( - name="Rough 1", - min=2.0, - value=4.563688983733924, - max=7.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ratapi.models.Parameter( - name="Rough 2", - min=2.0, - value=4.410704485333302, - max=7.0, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ), - ], - bulk_in=[ - ratapi.models.Parameter( - name="Air", - min=0.0, - value=0.0, - max=0.0, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - ], - bulk_out=[ - ratapi.models.Parameter( - name="D2O", - min=2e-05, - value=2.01e-05, - max=2.2e-05, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - ], - scalefactors=[ - ratapi.models.Parameter( - name="Scalefactor 1", - min=0.99, - value=0.9999894027309877, - max=1.01, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - ], - domain_ratios=[], - background_parameters=[ - ratapi.models.Parameter( - name="Background parameter 1", - min=5e-08, - value=1.306895319301746e-07, - max=1e-06, - fit=True, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - ], - backgrounds=[ - ratapi.models.Background( - name="Background 1", - type="constant", - source="Background parameter 1", - ) - ], - resolution_parameters=[ - ratapi.models.Parameter( - name="Resolution parameter 1", - min=0.0, - value=0.0, - max=0.05, - fit=False, - prior_type="uniform", - mu=0.0, - sigma=np.inf, - ) - ], - resolutions=[ - ratapi.models.Resolution( - name="Resolution 1", - type="constant", - source="Resolution parameter 1", - ) - ], - custom_files=[], - data=[ - ratapi.models.Data( - name="mFitBench", - data=moto_data, - data_range=[0.02, 0.59188], - simulation_range=[0.02, 0.59188], - ) - ], - layers=[ - ratapi.models.Layer( - name="New Layer 0", - thickness="Thick", - SLD="SLD 1", - roughness="Rough 1", - hydration="", - hydrate_with="bulk out", - ), - ratapi.models.Layer( - name="New Layer 1", - thickness="Thick2", - SLD="SLD 2", - roughness="Rough 2", - hydration="", - hydrate_with="bulk out", - ), - ], - domain_contrasts=[], - contrasts=[ - ratapi.models.Contrast( - name="Chain-d, acmw", - data="mFitBench", - background="Background 1", - background_action="add", - bulk_in="Air", - bulk_out="D2O", - scalefactor="Scalefactor 1", - resolution="Resolution 1", - resample=False, - model=["New Layer 0"], - ) - ], - ) - - -@pytest.fixture -def dspc_standard_layers(): - """The project from the DSPC Standard Layers example.""" - project, _ = ratapi.examples.DSPC_standard_layers() - return project - - -@pytest.fixture -def dspc_custom_layers(): - """The project from the DSPC Custom Layers example.""" - project, _ = ratapi.examples.DSPC_custom_layers() - return project - - -@pytest.fixture -def dspc_custom_xy(): - """The project from the DSPC Custom XY example.""" - project, _ = ratapi.examples.DSPC_custom_XY() - return project - - -@pytest.fixture -def domains_standard_layers(): - """The project from the domains Standard Layers example.""" - project, _ = ratapi.examples.domains_standard_layers() - return project - - -@pytest.fixture -def domains_custom_layers(): - """The project from the domains Custom Layers example.""" - project, _ = ratapi.examples.domains_custom_layers() - return project - - -@pytest.fixture -def domains_custom_xy(): - """The project from the domains Custom XY example.""" - project, _ = ratapi.examples.domains_custom_XY() - return project - - -@pytest.fixture -def absorption(): - """The project from the absorption example.""" - project, _ = ratapi.examples.absorption() - return project - - -@pytest.fixture -def absorption_different_function(): - """The project from the absorption example with a function name different from filename.""" - project, _ = ratapi.examples.absorption() - project.custom_files[0].function_name = "test_func" - return project diff --git a/tests/test_classlist.py b/tests/test_classlist.py deleted file mode 100644 index 98d9440c..00000000 --- a/tests/test_classlist.py +++ /dev/null @@ -1,1071 +0,0 @@ -"""Test the ClassList.""" - -import importlib -import re -import warnings -from collections import deque -from collections.abc import Iterable, Sequence -from typing import Any - -import prettytable -import pytest - -from ratapi.classlist import ClassList -from tests.utils import InputAttributes, SubInputAttributes - - -@pytest.fixture -def one_name_class_list(): - """A ClassList of InputAttributes, containing one element with a name defined.""" - return ClassList([InputAttributes(name="Alice")]) - - -@pytest.fixture -def two_name_class_list(): - """A ClassList of InputAttributes, containing two elements with names defined.""" - return ClassList([InputAttributes(name="Alice"), InputAttributes(name="Bob")]) - - -@pytest.fixture -def two_name_class_list_table(): - """The table representation of the ClassList defined in the "two_name_class_list" fixture.""" - return ( - "+-------+-------+\n" - "| index | name |\n" - "+-------+-------+\n" - "| 0 | Alice |\n" - "| 1 | Bob |\n" - "+-------+-------+" - ) - - -@pytest.fixture -def three_name_class_list(): - """A ClassList of InputAttributes, containing three elements with names defined.""" - return ClassList([InputAttributes(name="Alice"), InputAttributes(name="Bob"), InputAttributes(name="Eve")]) - - -class DisplayFieldsClass: - """A classlist with four attributes and a display_fields property.""" - - def __init__(self, display_range): - self.a = 1 - self.b = 2 - self.c = 3 - self.d = 4 - - self.display_range = display_range - - @property - def display_fields(self): - fields = ["a", "b", "c", "d"][self.display_range[0] : self.display_range[1]] - return {f: getattr(self, f) for f in fields} - - -class TestInitialisation: - @pytest.mark.parametrize( - "input_object", - [ - (InputAttributes()), - (InputAttributes(name="Alice")), - (InputAttributes(surname="Morgan")), - "Alice", - ], - ) - def test_input_object(self, input_object: Any) -> None: - """For an input of an object, the ClassList should contain a one-element list containing the object and - _class_handle should be set to the type of the object. - """ - class_list = ClassList(input_object) - assert class_list.data == [input_object] - assert isinstance(input_object, class_list._class_handle) - - @pytest.mark.parametrize( - "input_sequence", - [ - ([InputAttributes()]), - ([InputAttributes(name="Alice")]), - ([InputAttributes(surname="Morgan")]), - ([InputAttributes(name="Alice"), InputAttributes(name="Bob")]), - (InputAttributes(),), - (InputAttributes(name="Alice"),), - (InputAttributes(surname="Morgan"),), - (InputAttributes(name="Alice"), InputAttributes(name="Bob")), - ], - ) - def test_input_sequence(self, input_sequence: Sequence[object]) -> None: - """For an input of a sequence, the ClassList should be a list equal to the input sequence, and _class_handle - should be set to the type of the objects within. - """ - class_list = ClassList(input_sequence) - assert class_list.data == list(input_sequence) - for element in input_sequence: - assert isinstance(element, class_list._class_handle) - - @pytest.mark.parametrize( - "input_sequence", - [ - ([InputAttributes(name="Alice"), SubInputAttributes(name="Bob")]), - ([SubInputAttributes(name="Alice"), InputAttributes(name="Bob")]), - ], - ) - def test_input_sequence_subclass(self, input_sequence: Sequence[object]) -> None: - """For an input of a sequence containing objects of a class and its subclasses, the ClassList should be a list - equal to the input sequence, and _class_handle should be set to the type of the parent class. - """ - class_list = ClassList(input_sequence) - assert class_list.data == list(input_sequence) - for element in input_sequence: - assert isinstance(element, class_list._class_handle) - - @pytest.mark.parametrize("empty_input", [([]), (())]) - def test_empty_input(self, empty_input: Sequence[object]) -> None: - """If we initialise a ClassList with an empty input (list or tuple), the ClassList should be an empty list, and - _class_handle should be unset. - """ - class_list = ClassList(empty_input) - assert class_list.data == [] - assert not hasattr(class_list, "_class_handle") - - @pytest.mark.parametrize( - "input_list", - [ - ([InputAttributes(name="Alice"), dict(name="Bob")]), - ], - ) - def test_different_classes(self, input_list: Sequence[object]) -> None: - """If we initialise a ClassList with an input containing multiple classes, we should raise a ValueError.""" - with pytest.raises( - ValueError, - match=f"This ClassList only supports elements of type {type(input_list[0]).__name__}. In the input list:\n" - f" index 1 is of type {type(input_list[1]).__name__}\n", - ): - ClassList(input_list) - - @pytest.mark.parametrize( - "input_list, name_field", - [ - ([InputAttributes(name="Alice"), InputAttributes(name="Alice")], "name"), - ([InputAttributes(id="Alice"), InputAttributes(id="Alice")], "id"), - ], - ) - def test_identical_name_fields(self, input_list: Sequence[object], name_field: str) -> None: - """If we initialise a ClassList with input objects with identical values of the name_field, - we should raise a ValueError. - """ - with pytest.raises( - ValueError, - match=f"The value of the '{name_field}' attribute must be unique for each item in the " - f"ClassList:\n '{getattr(input_list[0], name_field).lower()}'" - f" is shared between items 0 and 1 of the input list", - ): - ClassList(input_list, name_field=name_field) - - -def test_str_table(two_name_class_list: ClassList, two_name_class_list_table: str) -> None: - """For classes with the __dict__ attribute, we should be able to print the ClassList like a table.""" - assert str(two_name_class_list) == two_name_class_list_table - - -def test_str_empty_table() -> None: - """For empty classes with the __dict__ attribute, we should be able to print the contents of the ClassList as a - list. - """ - empty_attributes = InputAttributes() - assert str(ClassList(empty_attributes)) == str([empty_attributes]) - - -@pytest.mark.parametrize( - "input_list", - [ - (["Alice", "Bob"]), - ], -) -def test_str_list(input_list: list[str]) -> None: - """For classes without the __dict__ attribute, we should be able to print the ClassList as a list.""" - class_list = ClassList(input_list) - assert str(class_list) == str(input_list) - - -def test_str_empty_classlist() -> None: - """For empty ClassLists, we should be able to print the ClassList as an empty list.""" - assert str(ClassList()) == str([]) - - -@pytest.mark.parametrize( - "display_ranges, expected_header", - ( - ([(1, 3), (1, 3), (1, 3)], ["b", "c"]), - ([(1, 2), (0, 4), (2, 3)], ["a", "b", "c", "d"]), - ([(0, 2), (0, 1), (2, 3)], ["a", "b", "c"]), - ), -) -def test_str_display_fields(display_ranges, expected_header): - """If a class has the `display_fields` property, the ClassList should print with the minimal required attributes.""" - class_list = ClassList([DisplayFieldsClass(dr) for dr in display_ranges]) - expected_table = prettytable.PrettyTable() - expected_table.field_names = ["index"] + expected_header - expected_vals = {"a": 1, "b": 2, "c": 3, "d": 4} - row = [expected_vals[v] for v in expected_header] - expected_table.add_rows([[0] + row, [1] + row, [2] + row]) - - assert str(class_list) == expected_table.get_string() - - -@pytest.mark.parametrize( - ["new_item", "expected_classlist"], - [ - (InputAttributes(name="Eve"), ClassList([InputAttributes(name="Eve"), InputAttributes(name="Bob")])), - ( - InputAttributes(name="John", surname="Luther"), - ClassList([InputAttributes(name="John", surname="Luther"), InputAttributes(name="Bob")]), - ), - ], -) -def test_setitem(two_name_class_list: ClassList, new_item: InputAttributes, expected_classlist: ClassList) -> None: - """We should be able to set values in an element of a ClassList using a new object.""" - class_list = two_name_class_list - class_list[0] = new_item - assert class_list == expected_classlist - - -@pytest.mark.parametrize( - "new_item", - [ - (InputAttributes(name="Bob")), - ], -) -def test_setitem_same_name_field(two_name_class_list: ClassList, new_item: InputAttributes) -> None: - """If we set the name_field of an object in the ClassList to one already defined, we should raise a ValueError.""" - with pytest.raises( - ValueError, - match=f"The value of the '{two_name_class_list.name_field}' attribute must be unique for each item in the " - f"ClassList:\n '{new_item.name.lower()}' is shared between item 1 of the existing ClassList," - f" and item 0 of the input list", - ): - two_name_class_list[0] = new_item - - -@pytest.mark.parametrize( - "new_values", - [ - "Bob", - ], -) -def test_setitem_different_classes(two_name_class_list: ClassList, new_values: dict[str, Any]) -> None: - """If we set the name_field of an object in the ClassList to one already defined, we should raise a ValueError.""" - with pytest.raises( - ValueError, - match=f"This ClassList only supports elements of type {two_name_class_list._class_handle.__name__}. " - f"In the input list:\n index 0 is of type {type(new_values).__name__}\n", - ): - two_name_class_list[0] = new_values - - -def test_delitem(two_name_class_list: ClassList, one_name_class_list: ClassList) -> None: - """We should be able to delete elements from a ClassList with the del operator.""" - class_list = two_name_class_list - del class_list[1] - assert class_list == one_name_class_list - - -def test_delitem_not_present(two_name_class_list: ClassList) -> None: - """If we use the del operator to delete an index out of range, we should raise an IndexError.""" - class_list = two_name_class_list - with pytest.raises(IndexError, match=re.escape("list assignment index out of range")): - del class_list[2] - - -@pytest.mark.parametrize( - "added_list", - [ - (ClassList(InputAttributes(name="Eve"))), - ([InputAttributes(name="Eve")]), - (InputAttributes(name="Eve"),), - (InputAttributes(name="Eve")), - ], -) -def test_iadd(two_name_class_list: ClassList, added_list: Iterable, three_name_class_list: ClassList) -> None: - """We should be able to use the "+=" operator to add iterables to a ClassList. Individual objects should be wrapped - in a list before being added. - """ - class_list = two_name_class_list - class_list += added_list - assert class_list == three_name_class_list - - -@pytest.mark.parametrize( - "added_list", - [ - (ClassList([InputAttributes(name="Alice"), InputAttributes(name="Bob")])), - ([InputAttributes(name="Alice"), InputAttributes(name="Bob")]), - (InputAttributes(name="Alice"), InputAttributes(name="Bob")), - ], -) -def test_iadd_empty_classlist(added_list: Sequence, two_name_class_list: ClassList) -> None: - """We should be able to use the "+=" operator to add iterables to an empty ClassList, whilst also setting - _class_handle. - """ - class_list = ClassList() - class_list += added_list - assert class_list == two_name_class_list - assert isinstance(added_list[-1], class_list._class_handle) - - -def test_mul(two_name_class_list: ClassList) -> None: - """If we use the "*" operator on a ClassList, we should raise a TypeError.""" - n = 2 - with pytest.raises( - TypeError, - match=re.escape( - f"unsupported operand type(s) for *: " - f"'{two_name_class_list.__class__.__name__}' and " - f"'{n.__class__.__name__}'", - ), - ): - two_name_class_list * n - - -def test_rmul(two_name_class_list: ClassList) -> None: - """If we use the "*" operator on a ClassList, we should raise a TypeError.""" - n = 2 - with pytest.raises( - TypeError, - match=re.escape( - f"unsupported operand type(s) for *: " - f"'{n.__class__.__name__}' and " - f"'{two_name_class_list.__class__.__name__}'", - ), - ): - n * two_name_class_list - - -def test_imul(two_name_class_list: ClassList) -> None: - """If we use the "*=" operator on a ClassList, we should raise a TypeError.""" - n = 2 - with pytest.raises( - TypeError, - match=re.escape( - f"unsupported operand type(s) for *=: " - f"'{two_name_class_list.__class__.__name__}' and " - f"'{n.__class__.__name__}'", - ), - ): - two_name_class_list *= n - - -@pytest.mark.parametrize( - "new_object", - [ - (InputAttributes(name="Eve")), - ], -) -def test_append_object(two_name_class_list: ClassList, new_object: object, three_name_class_list: ClassList) -> None: - """We should be able to append to a ClassList using a new object.""" - class_list = two_name_class_list - class_list.append(new_object) - assert class_list == three_name_class_list - - -@pytest.mark.parametrize( - "new_values", - [ - ({"name": "Eve"}), - ], -) -def test_append_kwargs( - two_name_class_list: ClassList, - new_values: dict[str, Any], - three_name_class_list: ClassList, -) -> None: - """We should be able to append to a ClassList using keyword arguments.""" - class_list = two_name_class_list - class_list.append(**new_values) - assert class_list == three_name_class_list - - -@pytest.mark.parametrize( - ["new_object", "new_values"], - [ - (InputAttributes(name="Eve"), {"name": "John"}), - ], -) -def test_append_object_and_kwargs( - two_name_class_list: ClassList, - new_object: object, - new_values: dict[str, Any], - three_name_class_list: ClassList, -) -> None: - """If we append to a ClassList using a new object and keyword arguments, we raise a warning, and append the object, - discarding the keyword arguments. - """ - class_list = two_name_class_list - with pytest.warns(SyntaxWarning): - warnings.warn( - "ClassList.append() called with both an object and keyword arguments. " - "The keyword arguments will be ignored.", - SyntaxWarning, - stacklevel=2, - ) - class_list.append(new_object, **new_values) - assert class_list == three_name_class_list - - -@pytest.mark.parametrize( - "new_object", - [ - (InputAttributes(name="Alice")), - ], -) -def test_append_object_empty_classlist(new_object: object, one_name_class_list: ClassList) -> None: - """We should be able to append to an empty ClassList using a new object, whilst also setting _class_handle.""" - class_list = ClassList() - class_list.append(new_object) - assert class_list == one_name_class_list - assert isinstance(new_object, class_list._class_handle) - - -@pytest.mark.parametrize( - "new_values", - [ - ({"name": "Alice"}), - ], -) -def test_append_kwargs_empty_classlist(new_values: dict[str, Any]) -> None: - """If we append to an empty ClassList using keyword arguments we should raise a TypeError.""" - class_list = ClassList() - with pytest.raises( - TypeError, - match=re.escape( - "ClassList.append() called with keyword arguments for a ClassList " - "without a class defined. Call ClassList.append() with an object to " - "define the class.", - ), - ): - class_list.append(**new_values) - - -@pytest.mark.parametrize( - "new_object", - [ - (InputAttributes(name="Alice")), - ], -) -def test_append_object_same_name_field(two_name_class_list: ClassList, new_object: object) -> None: - """If we append an object with an already-specified name_field value to a ClassList we should raise a ValueError.""" - with pytest.raises( - ValueError, - match=f"The value of the '{two_name_class_list.name_field}' attribute must be unique for each item in the " - f"ClassList:\n '{new_object.name.lower()}' is shared between item 0 of the existing ClassList, and " - f"item 0 of the input list", - ): - two_name_class_list.append(new_object) - - -@pytest.mark.parametrize( - "new_values", - [ - ({"name": "Alice"}), - ], -) -def test_append_kwargs_same_name_field(two_name_class_list: ClassList, new_values: dict[str, Any]) -> None: - """If we append an object with an already-specified name_field value to a ClassList we should raise a ValueError.""" - with pytest.raises( - ValueError, - match=f"Input arguments contain the {two_name_class_list.name_field} " - f"'{new_values[two_name_class_list.name_field]}', " - f"which is already specified at index 0 of the ClassList", - ): - two_name_class_list.append(**new_values) - - -@pytest.mark.parametrize( - "new_object", - [ - (InputAttributes(name="Eve")), - ], -) -def test_insert_object(two_name_class_list: ClassList, new_object: object) -> None: - """We should be able to insert an object within a ClassList using a new object.""" - two_name_class_list.insert(1, new_object) - assert two_name_class_list == ClassList( - [InputAttributes(name="Alice"), InputAttributes(name="Eve"), InputAttributes(name="Bob")], - ) - - -@pytest.mark.parametrize( - "new_values", - [ - ({"name": "Eve"}), - ], -) -def test_insert_kwargs(two_name_class_list: ClassList, new_values: dict[str, Any]) -> None: - """We should be able to insert an object within a ClassList using keyword arguments.""" - two_name_class_list.insert(1, **new_values) - assert two_name_class_list == ClassList( - [InputAttributes(name="Alice"), InputAttributes(name="Eve"), InputAttributes(name="Bob")], - ) - - -@pytest.mark.parametrize( - ["new_object", "new_values"], - [ - (InputAttributes(name="Eve"), {"name": "John"}), - ], -) -def test_insert_object_and_kwargs( - two_name_class_list: ClassList, - new_object: object, - new_values: dict[str, Any], - three_name_class_list: ClassList, -) -> None: - """If call insert() on a ClassList using a new object and keyword arguments, we raise a warning, and append the - object, discarding the keyword arguments. - """ - class_list = two_name_class_list - with pytest.warns(SyntaxWarning): - warnings.warn( - "ClassList.insert() called with both an object and keyword arguments. " - "The keyword arguments will be ignored.", - SyntaxWarning, - stacklevel=2, - ) - class_list.insert(1, new_object, **new_values) - assert class_list == ClassList( - [InputAttributes(name="Alice"), InputAttributes(name="Eve"), InputAttributes(name="Bob")], - ) - - -@pytest.mark.parametrize( - "new_object", - [ - (InputAttributes(name="Alice")), - ], -) -def test_insert_object_empty_classlist(new_object: object, one_name_class_list: ClassList) -> None: - """We should be able to insert a new object into an empty ClassList, whilst also setting _class_handle.""" - class_list = ClassList() - class_list.insert(0, new_object) - assert class_list == one_name_class_list - assert isinstance(new_object, class_list._class_handle) - - -@pytest.mark.parametrize( - "new_values", - [ - ({"name": "Alice"}), - ], -) -def test_insert_kwargs_empty_classlist(new_values: dict[str, Any]) -> None: - """If we append to an empty ClassList using keyword arguments we should raise a TypeError.""" - class_list = ClassList() - with pytest.raises( - TypeError, - match=re.escape( - "ClassList.insert() called with keyword arguments for a ClassList " - "without a class defined. Call ClassList.insert() with an object to " - "define the class.", - ), - ): - class_list.insert(0, **new_values) - - -@pytest.mark.parametrize( - "new_object", - [ - (InputAttributes(name="Alice")), - ], -) -def test_insert_object_same_name(two_name_class_list: ClassList, new_object: object) -> None: - """If we insert an object with an already-specified name_field value to a ClassList we should raise a ValueError.""" - with pytest.raises( - ValueError, - match=f"The value of the '{two_name_class_list.name_field}' attribute must be unique for each item in the " - f"ClassList:\n '{new_object.name.lower()}' is shared between item 0 of the existing " - f"ClassList, and item 0 of the input list", - ): - two_name_class_list.insert(1, new_object) - - -@pytest.mark.parametrize( - "new_values", - [ - ({"name": "Alice"}), - ], -) -def test_insert_kwargs_same_name(two_name_class_list: ClassList, new_values: dict[str, Any]) -> None: - """If we insert an object with an already-specified name_field value to a ClassList we should raise a ValueError.""" - with pytest.raises( - ValueError, - match=f"Input arguments contain the {two_name_class_list.name_field} " - f"'{new_values[two_name_class_list.name_field]}', " - f"which is already specified at index 0 of the ClassList", - ): - two_name_class_list.insert(1, **new_values) - - -@pytest.mark.parametrize( - "remove_value", - [ - "Bob", - (InputAttributes(name="Bob")), - ], -) -def test_remove(two_name_class_list: ClassList, remove_value: object | str) -> None: - """We should be able to remove an object either by the value of the name_field or by specifying the object - itself. - """ - two_name_class_list.remove(remove_value) - assert two_name_class_list == ClassList([InputAttributes(name="Alice")]) - - -@pytest.mark.parametrize( - "remove_value", - [ - "Eve", - (InputAttributes(name="Eve")), - ], -) -def test_remove_not_present(two_name_class_list: ClassList, remove_value: object | str) -> None: - """If we remove an object not included in the ClassList we should raise a ValueError.""" - with pytest.raises(ValueError, match=re.escape("list.remove(x): x not in list")): - two_name_class_list.remove(remove_value) - - -@pytest.mark.parametrize( - ["count_value", "expected_count"], - [ - ("Bob", 1), - (InputAttributes(name="Bob"), 1), - ("Eve", 0), - (InputAttributes(name="Eve"), 0), - ], -) -def test_count(two_name_class_list: ClassList, count_value: object | str, expected_count: int) -> None: - """We should be able to determine the number of times an object is in the ClassList using either the object itself - or its name_field value. - """ - assert two_name_class_list.count(count_value) == expected_count - - -@pytest.mark.parametrize( - ["index_value", "expected_index"], - [ - ("Bob", 1), - (InputAttributes(name="Bob"), 1), - ], -) -def test_index(two_name_class_list: ClassList, index_value: object | str, expected_index: int) -> None: - """We should be able to find the index of an object in the ClassList either by its name_field value or by - specifying the object itself. - """ - assert two_name_class_list.index(index_value) == expected_index - - -@pytest.mark.parametrize( - ["index_value", "offset", "expected_index"], - [ - ("Bob", 1, 2), - (InputAttributes(name="Bob"), -3, -2), - ], -) -def test_index_offset( - two_name_class_list: ClassList, - index_value: object | str, - offset: int, - expected_index: int, -) -> None: - """We should be able to find the index of an object in the ClassList either by its name_field value or by - specifying the object itself. When using an offset, the value of the index should be shifted accordingly. - """ - assert two_name_class_list.index(index_value, offset) == expected_index - - -@pytest.mark.parametrize( - "index_value", - [ - "Eve", - (InputAttributes(name="Eve")), - ], -) -def test_index_not_present(two_name_class_list: ClassList, index_value: object | str) -> None: - """If we try to find the index of an object not included in the ClassList we should raise a ValueError.""" - # with pytest.raises(ValueError, match=f"'{index_value}' is not in list") as e: - with pytest.raises(ValueError): - two_name_class_list.index(index_value) - - -@pytest.mark.parametrize( - "extended_list", - [ - (ClassList(InputAttributes(name="Eve"))), - ([InputAttributes(name="Eve")]), - (InputAttributes(name="Eve"),), - (InputAttributes(name="Eve")), - ], -) -def test_extend(two_name_class_list: ClassList, extended_list: Sequence, three_name_class_list: ClassList) -> None: - """We should be able to extend a ClassList using another ClassList or a sequence. Individual objects should be - wrapped in a list before being added. - """ - class_list = two_name_class_list - class_list.extend(extended_list) - assert class_list == three_name_class_list - - -@pytest.mark.parametrize( - "extended_list", - [ - (ClassList(InputAttributes(name="Alice"))), - ([InputAttributes(name="Alice")]), - (InputAttributes(name="Alice"),), - ], -) -def test_extend_empty_classlist(extended_list: Sequence, one_name_class_list: ClassList) -> None: - """We should be able to extend a ClassList using another ClassList or a sequence""" - class_list = ClassList() - class_list.extend(extended_list) - assert class_list == one_name_class_list - assert isinstance(extended_list[-1], class_list._class_handle) - - -@pytest.mark.parametrize("index", [0, "Alice", InputAttributes(name="Alice")]) -@pytest.mark.parametrize( - ["new_values", "expected_classlist"], - [ - ({"name": "Eve"}, ClassList([InputAttributes(name="Eve"), InputAttributes(name="Bob")])), - ( - {"name": "John", "surname": "Luther"}, - ClassList([InputAttributes(name="John", surname="Luther"), InputAttributes(name="Bob")]), - ), - ], -) -def test_set_fields( - two_name_class_list: ClassList, index: int | str, new_values: dict[str, Any], expected_classlist: ClassList -) -> None: - """We should be able to set field values in an element of a ClassList using keyword arguments.""" - class_list = two_name_class_list - class_list.set_fields(index, **new_values) - assert class_list == expected_classlist - - -@pytest.mark.parametrize( - "new_values", - [ - ({"name": "Bob"}), - ], -) -def test_set_fields_same_name_field(two_name_class_list: ClassList, new_values: dict[str, Any]) -> None: - """If we set the name_field of an object in the ClassList to one already defined, we should raise a ValueError.""" - with pytest.raises( - ValueError, - match=f"Input arguments contain the {two_name_class_list.name_field} " - f"'{new_values[two_name_class_list.name_field]}', " - f"which is already specified at index 1 of the ClassList", - ): - two_name_class_list.set_fields(0, **new_values) - - -@pytest.mark.parametrize( - ["class_list", "expected_names"], - [ - (ClassList([InputAttributes(name="Alice"), InputAttributes(name="Bob")]), ["Alice", "Bob"]), - (ClassList([InputAttributes(id="Alice"), InputAttributes(id="Bob")], name_field="id"), ["Alice", "Bob"]), - (ClassList([InputAttributes(name="Alice"), InputAttributes(name="Bob")], name_field="id"), []), - (ClassList([InputAttributes(surname="Morgan"), InputAttributes(surname="Terwilliger")]), []), - ( - ClassList([InputAttributes(name="Alice", surname="Morgan"), InputAttributes(surname="Terwilliger")]), - ["Alice"], - ), - ( - ClassList( - [InputAttributes(name="Alice", surname="Morgan"), InputAttributes(surname="Terwilliger")], - name_field="surname", - ), - ["Morgan", "Terwilliger"], - ), - (ClassList(InputAttributes()), []), - ], -) -def test_get_names(class_list: ClassList, expected_names: list[str]) -> None: - """We should get a list of the values of the name_field attribute from each object with it defined in the - ClassList. - """ - assert class_list.get_names() == expected_names - - -@pytest.mark.parametrize( - ["class_list", "expected_matches"], - [ - (ClassList([InputAttributes(name="Alice"), InputAttributes(name="Bob")]), [(0, "name")]), - (ClassList([InputAttributes(name="Alice"), InputAttributes(name="Bob", id="Alice")]), [(0, "name"), (1, "id")]), - (ClassList([InputAttributes(surname="Morgan"), InputAttributes(surname="Terwilliger")]), []), - (ClassList(InputAttributes()), []), - ], -) -def test_get_all_matches(class_list: ClassList, expected_matches: list[tuple]) -> None: - """We should get a list of (index, field) tuples matching the given value in the ClassList.""" - assert class_list.get_all_matches("Alice") == expected_matches - - -@pytest.mark.parametrize( - "input_dict", - [ - ({"name": "Eve"}), - ({"surname": "Polastri"}), - ], -) -def test__validate_name_field(two_name_class_list: ClassList, input_dict: dict[str, Any]) -> None: - """We should not raise an error if the input values do not contain a name_field value defined in an object in the - ClassList. - """ - assert two_name_class_list._validate_name_field(input_dict) is None - - -@pytest.mark.parametrize( - "input_dict", - [ - ({"name": "Alice"}), - ({"name": "BOB"}), - ({"name": "alice"}), - ], -) -def test__validate_name_field_not_unique(two_name_class_list: ClassList, input_dict: dict[str, Any]) -> None: - """We should raise a ValueError if we input values containing a name_field defined in an object in the ClassList, - accounting for case sensitivity. - """ - with pytest.raises( - ValueError, - match=f"Input arguments contain the {two_name_class_list.name_field} " - f"'{input_dict[two_name_class_list.name_field]}', which is already specified at index " - f"{two_name_class_list.index(input_dict['name'].lower())} of the ClassList", - ): - two_name_class_list._validate_name_field(input_dict) - - -@pytest.mark.parametrize( - "input_list", - [ - ([InputAttributes(name="Eve"), InputAttributes(name="Gareth")]), - ([InputAttributes(surname="Polastri"), InputAttributes(surname="Mallory")]), - ([InputAttributes(name="Eve", surname="Polastri"), InputAttributes(surname="Mallory")]), - ([InputAttributes()]), - ([]), - ], -) -def test__check_unique_name_fields(two_name_class_list: ClassList, input_list: Iterable) -> None: - """We should not raise an error if an input list contains objects with different name_field values, or if the - name_field is not defined. - """ - assert two_name_class_list._check_unique_name_fields(input_list) is None - - -@pytest.mark.parametrize( - ["input_list", "error_message"], - [ - ( - [InputAttributes(name="Alice"), InputAttributes(name="Bob")], - ( - " 'alice' is shared between item 0 of the existing ClassList, and item 0 of the input list\n" - " 'bob' is shared between item 1 of the existing ClassList, and item 1 of the input list" - ), - ), - ( - [InputAttributes(name="Alice"), InputAttributes(name="Alice")], - " 'alice' is shared between item 0 of the existing ClassList, and items 0 and 1 of the input list", - ), - ( - [InputAttributes(name="Alice"), InputAttributes(name="ALICE")], - " 'alice' is shared between item 0 of the existing ClassList, and items 0 and 1 of the input list", - ), - ( - [InputAttributes(name="Alice"), InputAttributes(name="alice")], - " 'alice' is shared between item 0 of the existing ClassList, and items 0 and 1 of the input list", - ), - ( - [InputAttributes(name="Eve"), InputAttributes(name="Eve")], - " 'eve' is shared between items 0 and 1 of the input list", - ), - ( - [ - InputAttributes(name="Bob"), - InputAttributes(name="Alice"), - InputAttributes(name="Eve"), - InputAttributes(name="Alice"), - InputAttributes(name="Eve"), - InputAttributes(name="Alice"), - ], - ( - " 'bob' is shared between item 1 of the existing ClassList, and item 0 of the input list\n" - " 'alice' is shared between item 0 of the existing ClassList," - " and items 1, 3 and 5 of the input list\n" - " 'eve' is shared between items 2 and 4 of the input list" - ), - ), - ], -) -def test__check_unique_name_fields_not_unique( - two_name_class_list: ClassList, input_list: Sequence, error_message: str -) -> None: - """We should raise a ValueError if an input list contains multiple objects with (case-insensitive) matching - name_field values defined. - """ - with pytest.raises( - ValueError, - match=f"The value of the '{two_name_class_list.name_field}' attribute must be unique for each item in the " - f"ClassList:\n{error_message}", - ): - two_name_class_list._check_unique_name_fields(input_list) - - -@pytest.mark.parametrize( - "input_list", - [ - ([InputAttributes(name="Alice"), InputAttributes(name="Bob")]), - ], -) -def test__check_classes(input_list: Iterable) -> None: - """We should not raise an error all objects in the ClassList are of the same type.""" - class_list = ClassList([InputAttributes()]) - assert class_list._check_classes(input_list) is None - - -@pytest.mark.parametrize( - "input_list", - [ - ([InputAttributes(name="Alice"), dict(name="Bob")]), - ], -) -def test__check_classes_different_classes(input_list: Sequence) -> None: - """We should raise a ValueError if an input list contains objects of different types.""" - class_list = ClassList([InputAttributes()]) - with pytest.raises( - ValueError, - match=( - f"This ClassList only supports elements of type {class_list._class_handle.__name__}. " - f"In the input list:\n index 1 is of type {type(input_list[1]).__name__}" - ), - ): - class_list._check_classes(input_list) - - -@pytest.mark.parametrize( - ["value", "expected_output"], - [ - ("Alice", InputAttributes(name="Alice")), - ("ALICE", InputAttributes(name="Alice")), - ("alice", InputAttributes(name="Alice")), - ("Eve", "Eve"), - ("EVE", "EVE"), - ("eve", "eve"), - ], -) -def test__get_item_from_name_field( - two_name_class_list: ClassList, - value: str, - expected_output: object | str, -) -> None: - """When we input the name_field value of an object defined in the ClassList, we should return the object. - If the value is not the name_field of an object defined in the ClassList, we should return the value. - """ - assert two_name_class_list._get_item_from_name_field(value) == expected_output - - -@pytest.mark.parametrize( - ["input_list", "expected_type"], - [ - ([InputAttributes(name="Alice")], InputAttributes), - ([InputAttributes(name="Alice"), SubInputAttributes(name="Bob")], InputAttributes), - ([SubInputAttributes(name="Alice"), InputAttributes(name="Bob")], InputAttributes), - ([SubInputAttributes(name="Alice"), SubInputAttributes(name="Bob")], SubInputAttributes), - ( - [SubInputAttributes(name="Alice"), SubInputAttributes(name="Bob"), InputAttributes(name="Eve")], - InputAttributes, - ), - ([InputAttributes(name="Alice"), dict(name="Bob")], InputAttributes), - ([dict(name="Alice"), InputAttributes(name="Bob")], dict), - ], -) -def test_determine_class_handle(input_list: ClassList, expected_type: type) -> None: - """The _class_handle for the ClassList should be the type that satisfies the condition "isinstance(element, type)" - for all elements in the ClassList. - """ - assert ClassList._determine_class_handle(input_list) == expected_type - - -def test_get_item(two_name_class_list): - """Test item names can be gotten by name, index, object or slice.""" - assert two_name_class_list[0] == two_name_class_list["Alice"] - assert two_name_class_list[1] == two_name_class_list["Bob"] - assert two_name_class_list[:] == two_name_class_list - alice = InputAttributes(name="Alice") - assert two_name_class_list[alice] == two_name_class_list["Alice"] - assert two_name_class_list[alice] == two_name_class_list[0] - - -@pytest.mark.skipif(importlib.util.find_spec("pydantic") is None, reason="Pydantic not installed") -class TestPydantic: - """Tests for the Pydantic integration for ClassLists.""" - - import pydantic - - class Model(pydantic.BaseModel): - classlist: ClassList[str] - - model_class = Model - - @pytest.mark.parametrize( - "sequence", [["a", "b", "c"], ("a", "b", "c", "d"), deque(["a", "b", "c"]), ClassList(["a", "b"])] - ) - def test_sequence_coercion(self, sequence): - """Test that sequences are coerced to ClassLists.""" - model = self.model_class(classlist=sequence) - assert model.classlist.data == list(sequence) - assert model.classlist._class_handle is type(sequence[0]) - - @pytest.mark.parametrize("input", [[1, 2, "string"], deque(["a", "b", 5.3]), [3.0, 4]]) - def test_coerce_bad_inputs(self, input): - """Test that Pydantic successfully checks the type for input sequences.""" - with pytest.raises(self.pydantic.ValidationError, match="This ClassList only supports elements of type str."): - self.model_class(classlist=input) - - def test_coerce_models(self): - """Test that a ClassList of pydantic Models is coerced from a list of dicts.""" - import pydantic - - class SubModel(pydantic.BaseModel): - i: int - s: str - f: float - - class NestedModel(pydantic.BaseModel): - submodels: ClassList[SubModel] - - submodels_list = [{"i": 3, "s": "hello", "f": 3.0}, {"i": 4, "s": "hi", "f": 3.14}] - - model = NestedModel(submodels=submodels_list) - for submodel, exp_dict in zip(model.submodels, submodels_list, strict=False): - for key, value in exp_dict.items(): - assert getattr(submodel, key) == value - - def test_set_pydantic_fields(self): - """Test that intermediate validation errors for pydantic models are suppressed when using "set_fields".""" - from pydantic import BaseModel, model_validator - - class MinMaxModel(BaseModel): - min: float - value: float - max: float - - @model_validator(mode="after") - def check_value_in_range(self) -> "MinMaxModel": - if self.value < self.min or self.value > self.max: - raise ValueError( - f"value {self.value} is not within the defined range: {self.min} <= value <= {self.max}" - ) - return self - - model_list = ClassList([MinMaxModel(min=1, value=2, max=5)]) - model_list.set_fields(0, min=3, value=4) - - assert model_list == ClassList([MinMaxModel(min=3.0, value=4.0, max=5.0)]) diff --git a/tests/test_controls.py b/tests/test_controls.py deleted file mode 100644 index 5a83bccc..00000000 --- a/tests/test_controls.py +++ /dev/null @@ -1,916 +0,0 @@ -"""Test the controls module.""" - -import contextlib -import os -import tempfile -from pathlib import Path -from typing import Any - -import pydantic -import pytest - -from ratapi.controls import Controls, fields -from ratapi.utils.enums import BoundHandling, Display, Parallel, Procedures, Strategies - - -@pytest.fixture -def IPC_controls(): - """A controls object with a temporary file set as the IPC file.""" - IPC_controls = Controls() - IPC_obj, IPC_controls._IPCFilePath = tempfile.mkstemp() - os.close(IPC_obj) - yield IPC_controls - with contextlib.suppress(FileNotFoundError): - os.remove(IPC_controls._IPCFilePath) - - -def test_initialise_procedure_error() -> None: - """Tests for a ValidationError if the procedure property of the Controls class is initialised with an invalid - value. - """ - with pytest.raises(pydantic.ValidationError, match="Input should be 'calculate', 'simplex', 'de', 'ns' or 'dream'"): - Controls(procedure="test") - - -def test_set_procedure_error() -> None: - """Tests for a ValidationError if the procedure property of the Controls class is set to an invalid value.""" - controls = Controls() - with pytest.raises(pydantic.ValidationError, match="Input should be 'calculate', 'simplex', 'de', 'ns' or 'dream'"): - controls.procedure = "test" - - -def test_extra_property_error() -> None: - """Tests the extra property setter in the Controls class.""" - controls = Controls() - with pytest.raises(pydantic.ValidationError, match="Object has no attribute 'test'"): - controls.test = 1 - - -@pytest.mark.parametrize( - "inputs", - [ - {"parallel": Parallel.Contrasts, "resampleMinAngle": 0.66}, - {"procedure": "simplex"}, - {"procedure": "dream", "nSamples": 504, "nChains": 1200}, - {"procedure": "de", "crossoverProbability": 0.45, "strategy": Strategies.RandomEitherOrAlgorithm}, - {"procedure": "ns", "nMCMC": 4, "propScale": 0.6}, - ], -) -def test_save_load(inputs): - """Test that saving and loading controls returns the same controls.""" - - original_controls = Controls(**inputs) - with tempfile.TemporaryDirectory() as tmp: - # ignore relative path warnings - path = Path(tmp, "controls.json") - original_controls.save(path) - converted_controls = Controls.load(path) - - for field in Controls.model_fields: - assert getattr(converted_controls, field) == getattr(original_controls, field) - - -class TestCalculate: - """Tests the Calculate class.""" - - @pytest.fixture(autouse=True) - def setup_class(self): - self.calculate = Controls() - - @pytest.fixture - def table_str(self): - table_str = ( - "+---------------------+-----------+\n" - "| Property | Value |\n" - "+---------------------+-----------+\n" - "| procedure | calculate |\n" - "| parallel | single |\n" - "| numSimulationPoints | 500 |\n" - "| resampleMinAngle | 0.9 |\n" - "| resampleNPoints | 50 |\n" - "| display | iter |\n" - "+---------------------+-----------+" - ) - - return table_str - - @pytest.mark.parametrize( - "control_property, value", - [ - ("parallel", Parallel.Single), - ("numSimulationPoints", 500), - ("resampleMinAngle", 0.9), - ("resampleNPoints", 50), - ("display", Display.Iter), - ("procedure", Procedures.Calculate), - ], - ) - def test_calculate_property_values(self, control_property: str, value: Any) -> None: - """Tests the default values of Calculate class.""" - assert getattr(self.calculate, control_property) == value - - @pytest.mark.parametrize( - "control_property, value", - [ - ("parallel", Parallel.Points), - ("numSimulationPoints", 10), - ("resampleMinAngle", 0.2), - ("resampleNPoints", 1), - ("display", Display.Notify), - ], - ) - def test_calculate_property_setters(self, control_property: str, value: Any) -> None: - """Tests the setters of Calculate class.""" - setattr(self.calculate, control_property, value) - assert getattr(self.calculate, control_property) == value - - @pytest.mark.parametrize( - "wrong_property, value", - [ - ("xTolerance", 4e-6), - ("funcTolerance", 3e-4), - ("maxFuncEvals", 100), - ("maxIterations", 50), - ("updateFreq", 4), - ("updatePlotFreq", 3), - ("populationSize", 200), - ("fWeight", 0.3), - ("crossoverProbability", 0.4), - ("strategy", Strategies.BestWithJitter), - ("targetValue", 2.0), - ("numGenerations", 50), - ("nLive", 1500), - ("nMCMC", 1), - ("propScale", 0.5), - ("nsTolerance", 0.8), - ("nSamples", 500), - ("nChains", 1000), - ("jumpProbability", 0.7), - ("pUnitGamma", 0.3), - ("boundHandling", BoundHandling.Fold), - ("adaptPCR", False), - ], - ) - def test_initialise_non_calculate_properties(self, wrong_property: str, value: Any) -> None: - incorrect_procedures = [key for (key, value) in fields.items() if wrong_property in value] - with pytest.warns( - UserWarning, - match=f'\nThe current controls procedure is "calculate", but the property' - f' "{wrong_property}" applies instead to the' - f" {', '.join(incorrect_procedures)} procedure.\n\n" - f' The fields for the "calculate" controls procedure are:\n' - f" {', '.join(fields['calculate'])}\n", - ): - Controls(procedure=Procedures.Calculate, **{wrong_property: value}) - - @pytest.mark.parametrize( - "wrong_property, value", - [ - ("xTolerance", 4e-6), - ("funcTolerance", 3e-4), - ("maxFuncEvals", 100), - ("maxIterations", 50), - ("updateFreq", 4), - ("updatePlotFreq", 3), - ("populationSize", 200), - ("fWeight", 0.3), - ("crossoverProbability", 0.4), - ("strategy", Strategies.BestWithJitter), - ("targetValue", 2.0), - ("numGenerations", 50), - ("nLive", 1500), - ("nMCMC", 1), - ("propScale", 0.5), - ("nsTolerance", 0.8), - ("nSamples", 500), - ("nChains", 1000), - ("jumpProbability", 0.7), - ("pUnitGamma", 0.3), - ("boundHandling", BoundHandling.Fold), - ("adaptPCR", False), - ], - ) - def test_set_non_calculate_properties(self, wrong_property: str, value: Any) -> None: - incorrect_procedures = [key for (key, value) in fields.items() if wrong_property in value] - with pytest.warns( - UserWarning, - match=f'\nThe current controls procedure is "calculate", but the property' - f' "{wrong_property}" applies instead to the' - f" {', '.join(incorrect_procedures)} procedure.\n\n" - f' The fields for the "calculate" controls procedure are:\n' - f" {', '.join(fields['calculate'])}\n", - ): - setattr(self.calculate, wrong_property, value) - - @pytest.mark.parametrize("value", ["test", "ALL", "Contrast", True, 1, 3.0]) - def test_calculate_parallel_validation(self, value: Any) -> None: - """Tests the parallel setter validation in Calculate class.""" - with pytest.raises(pydantic.ValidationError, match="Input should be 'single', 'points' or 'contrasts'"): - self.calculate.parallel = value - - @pytest.mark.parametrize("value", ["test", "iterate", True, 1, 3.0]) - def test_calculate_display_validation(self, value: Any) -> None: - """Tests the display setter validation in Calculate class.""" - with pytest.raises(pydantic.ValidationError, match="Input should be 'off', 'iter', 'notify' or 'final'"): - self.calculate.display = value - - def test_str(self, table_str) -> None: - """Tests the Calculate model __str__.""" - assert self.calculate.__str__() == table_str - - -class TestSimplex: - """Tests the Simplex class.""" - - @pytest.fixture(autouse=True) - def setup_class(self): - self.simplex = Controls(procedure=Procedures.Simplex) - - @pytest.fixture - def table_str(self): - table_str = ( - "+---------------------+---------+\n" - "| Property | Value |\n" - "+---------------------+---------+\n" - "| procedure | simplex |\n" - "| parallel | single |\n" - "| numSimulationPoints | 500 |\n" - "| resampleMinAngle | 0.9 |\n" - "| resampleNPoints | 50 |\n" - "| display | iter |\n" - "| xTolerance | 1e-06 |\n" - "| funcTolerance | 1e-06 |\n" - "| maxFuncEvals | 10000 |\n" - "| maxIterations | 1000 |\n" - "| updateFreq | 1 |\n" - "| updatePlotFreq | 20 |\n" - "+---------------------+---------+" - ) - - return table_str - - @pytest.mark.parametrize( - "control_property, value", - [ - ("parallel", Parallel.Single), - ("numSimulationPoints", 500), - ("resampleMinAngle", 0.9), - ("resampleNPoints", 50), - ("display", Display.Iter), - ("procedure", Procedures.Simplex), - ("xTolerance", 1e-6), - ("funcTolerance", 1e-6), - ("maxFuncEvals", 10000), - ("maxIterations", 1000), - ("updateFreq", 1), - ("updatePlotFreq", 20), - ], - ) - def test_simplex_property_values(self, control_property: str, value: Any) -> None: - """Tests the default values of Simplex class.""" - assert getattr(self.simplex, control_property) == value - - @pytest.mark.parametrize( - "control_property, value", - [ - ("parallel", Parallel.Points), - ("numSimulationPoints", 10), - ("resampleMinAngle", 0.2), - ("resampleNPoints", 1), - ("display", Display.Notify), - ("xTolerance", 4e-6), - ("funcTolerance", 3e-4), - ("maxFuncEvals", 100), - ("maxIterations", 50), - ("updateFreq", 4), - ("updatePlotFreq", 3), - ], - ) - def test_simplex_property_setters(self, control_property: str, value: Any) -> None: - """Tests the setters of Simplex class.""" - setattr(self.simplex, control_property, value) - assert getattr(self.simplex, control_property) == value - - @pytest.mark.parametrize( - "wrong_property, value", - [ - ("populationSize", 200), - ("fWeight", 0.3), - ("crossoverProbability", 0.4), - ("strategy", Strategies.BestWithJitter), - ("targetValue", 2.0), - ("numGenerations", 50), - ("nLive", 1500), - ("nMCMC", 1), - ("propScale", 0.5), - ("nsTolerance", 0.8), - ("nSamples", 500), - ("nChains", 1000), - ("jumpProbability", 0.7), - ("pUnitGamma", 0.3), - ("boundHandling", BoundHandling.Fold), - ("adaptPCR", False), - ], - ) - def test_initialise_non_simplex_properties(self, wrong_property: str, value: Any) -> None: - incorrect_procedures = [key for (key, value) in fields.items() if wrong_property in value] - with pytest.warns( - UserWarning, - match=f'\nThe current controls procedure is "simplex", but the property' - f' "{wrong_property}" applies instead to the' - f" {', '.join(incorrect_procedures)} procedure.\n\n" - f' The fields for the "simplex" controls procedure are:\n' - f" {', '.join(fields['simplex'])}\n", - ): - Controls(procedure=Procedures.Simplex, **{wrong_property: value}) - - @pytest.mark.parametrize( - "wrong_property, value", - [ - ("populationSize", 200), - ("fWeight", 0.3), - ("crossoverProbability", 0.4), - ("strategy", Strategies.BestWithJitter), - ("targetValue", 2.0), - ("numGenerations", 50), - ("nLive", 1500), - ("nMCMC", 1), - ("propScale", 0.5), - ("nsTolerance", 0.8), - ("nSamples", 500), - ("nChains", 1000), - ("jumpProbability", 0.7), - ("pUnitGamma", 0.3), - ("boundHandling", BoundHandling.Fold), - ("adaptPCR", False), - ], - ) - def test_set_non_simplex_properties(self, wrong_property: str, value: Any) -> None: - incorrect_procedures = [key for (key, value) in fields.items() if wrong_property in value] - with pytest.warns( - UserWarning, - match=f'\nThe current controls procedure is "simplex", but the property' - f' "{wrong_property}" applies instead to the' - f" {', '.join(incorrect_procedures)} procedure.\n\n" - f' The fields for the "simplex" controls procedure are:\n' - f" {', '.join(fields['simplex'])}\n", - ): - setattr(self.simplex, wrong_property, value) - - @pytest.mark.parametrize( - "control_property, value", - [ - ("xTolerance", -4e-6), - ("funcTolerance", -3e-4), - ("maxFuncEvals", -100), - ("maxIterations", -50), - ], - ) - def test_simplex_property_errors(self, control_property: str, value: float | int) -> None: - """Tests the property errors of Simplex class.""" - with pytest.raises(pydantic.ValidationError, match="Input should be greater than 0"): - setattr(self.simplex, control_property, value) - - def test_str(self, table_str) -> None: - """Tests the Simplex model __str__.""" - assert self.simplex.__str__() == table_str - - -class TestDE: - """Tests the DE class.""" - - @pytest.fixture(autouse=True) - def setup_class(self): - self.de = Controls(procedure=Procedures.DE) - - @pytest.fixture - def table_str(self): - table_str = ( - "+----------------------+---------------+\n" - "| Property | Value |\n" - "+----------------------+---------------+\n" - "| procedure | de |\n" - "| parallel | single |\n" - "| numSimulationPoints | 500 |\n" - "| resampleMinAngle | 0.9 |\n" - "| resampleNPoints | 50 |\n" - "| display | iter |\n" - "| populationSize | 20 |\n" - "| fWeight | 0.5 |\n" - "| crossoverProbability | 0.8 |\n" - "| strategy | vector dither |\n" - "| targetValue | 1.0 |\n" - "| numGenerations | 500 |\n" - "| updateFreq | 1 |\n" - "| updatePlotFreq | 20 |\n" - "+----------------------+---------------+" - ) - - return table_str - - @pytest.mark.parametrize( - "control_property, value", - [ - ("parallel", Parallel.Single), - ("numSimulationPoints", 500), - ("resampleMinAngle", 0.9), - ("resampleNPoints", 50), - ("display", Display.Iter), - ("procedure", Procedures.DE), - ("populationSize", 20), - ("fWeight", 0.5), - ("crossoverProbability", 0.8), - ("strategy", Strategies.RandomWithPerVectorDither), - ("targetValue", 1), - ("numGenerations", 500), - ], - ) - def test_de_property_values(self, control_property: str, value: Any) -> None: - """Tests the default values of DE class.""" - assert getattr(self.de, control_property) == value - - @pytest.mark.parametrize( - "control_property, value", - [ - ("parallel", Parallel.Points), - ("numSimulationPoints", 10), - ("resampleMinAngle", 0.2), - ("resampleNPoints", 1), - ("display", Display.Notify), - ("populationSize", 20), - ("fWeight", 0.3), - ("crossoverProbability", 0.4), - ("strategy", Strategies.BestWithJitter), - ("targetValue", 2.0), - ("numGenerations", 50), - ], - ) - def test_de_property_setters(self, control_property: str, value: Any) -> None: - """Tests the setters of DE class.""" - setattr(self.de, control_property, value) - assert getattr(self.de, control_property) == value - - @pytest.mark.parametrize( - "wrong_property, value", - [ - ("xTolerance", 4e-6), - ("funcTolerance", 3e-4), - ("maxFuncEvals", 100), - ("maxIterations", 50), - ("nLive", 1500), - ("nMCMC", 1), - ("propScale", 0.5), - ("nsTolerance", 0.8), - ("nSamples", 500), - ("nChains", 1000), - ("jumpProbability", 0.7), - ("pUnitGamma", 0.3), - ("boundHandling", BoundHandling.Fold), - ("adaptPCR", False), - ], - ) - def test_initialise_non_de_properties(self, wrong_property: str, value: Any) -> None: - incorrect_procedures = [key for (key, value) in fields.items() if wrong_property in value] - with pytest.warns( - UserWarning, - match=f'\nThe current controls procedure is "de", but the property' - f' "{wrong_property}" applies instead to the' - f" {', '.join(incorrect_procedures)} procedure.\n\n" - f' The fields for the "de" controls procedure are:\n' - f" {', '.join(fields['de'])}\n", - ): - Controls(procedure=Procedures.DE, **{wrong_property: value}) - - @pytest.mark.parametrize( - "wrong_property, value", - [ - ("xTolerance", 4e-6), - ("funcTolerance", 3e-4), - ("maxFuncEvals", 100), - ("maxIterations", 50), - ("nLive", 1500), - ("nMCMC", 1), - ("propScale", 0.5), - ("nsTolerance", 0.8), - ("nSamples", 500), - ("nChains", 1000), - ("jumpProbability", 0.7), - ("pUnitGamma", 0.3), - ("boundHandling", BoundHandling.Fold), - ("adaptPCR", False), - ], - ) - def test_set_non_de_properties(self, wrong_property: str, value: Any) -> None: - incorrect_procedures = [key for (key, value) in fields.items() if wrong_property in value] - with pytest.warns( - UserWarning, - match=f'\nThe current controls procedure is "de", but the property' - f' "{wrong_property}" applies instead to the' - f" {', '.join(incorrect_procedures)} procedure.\n\n" - f' The fields for the "de" controls procedure are:\n' - f" {', '.join(fields['de'])}\n", - ): - setattr(self.de, wrong_property, value) - - @pytest.mark.parametrize( - "value, msg", - [ - (0, "Input should be greater than 0"), - (2, "Input should be less than 1"), - ], - ) - def test_de_crossoverProbability_error(self, value: int, msg: str) -> None: - """Tests the crossoverProbability setter error in DE class.""" - with pytest.raises(pydantic.ValidationError, match=msg): - self.de.crossoverProbability = value - - @pytest.mark.parametrize( - "control_property, value", - [ - ("targetValue", 0), - ("targetValue", 0.999), - ("numGenerations", -500), - ("numGenerations", 0), - ("populationSize", 0), - ("populationSize", -1), - ], - ) - def test_de_targetValue_numGenerations_populationSize_error( - self, - control_property: str, - value: int | float, - ) -> None: - """Tests the targetValue, numGenerations, populationSize setter error in DE class.""" - with pytest.raises(pydantic.ValidationError, match="Input should be greater than or equal to 1"): - setattr(self.de, control_property, value) - - def test_str(self, table_str) -> None: - """Tests the DE model __str__.""" - assert self.de.__str__() == table_str - - -class TestNS: - """Tests the NS class.""" - - @pytest.fixture(autouse=True) - def setup_class(self): - self.ns = Controls(procedure=Procedures.NS) - - @pytest.fixture - def table_str(self): - table_str = ( - "+---------------------+--------+\n" - "| Property | Value |\n" - "+---------------------+--------+\n" - "| procedure | ns |\n" - "| parallel | single |\n" - "| numSimulationPoints | 500 |\n" - "| resampleMinAngle | 0.9 |\n" - "| resampleNPoints | 50 |\n" - "| display | iter |\n" - "| nLive | 150 |\n" - "| nMCMC | 0 |\n" - "| propScale | 0.1 |\n" - "| nsTolerance | 0.1 |\n" - "+---------------------+--------+" - ) - - return table_str - - @pytest.mark.parametrize( - "control_property, value", - [ - ("parallel", Parallel.Single), - ("numSimulationPoints", 500), - ("resampleMinAngle", 0.9), - ("resampleNPoints", 50), - ("display", Display.Iter), - ("procedure", Procedures.NS), - ("nLive", 150), - ("nMCMC", 0), - ("propScale", 0.1), - ("nsTolerance", 0.1), - ], - ) - def test_ns_property_values(self, control_property: str, value: Any) -> None: - """Tests the default values of NS class.""" - assert getattr(self.ns, control_property) == value - - @pytest.mark.parametrize( - "control_property, value", - [ - ("parallel", Parallel.Points), - ("numSimulationPoints", 10), - ("resampleMinAngle", 0.2), - ("resampleNPoints", 1), - ("display", Display.Notify), - ("nLive", 1500), - ("nMCMC", 1), - ("propScale", 0.5), - ("nsTolerance", 0.8), - ], - ) - def test_ns_property_setters(self, control_property: str, value: Any) -> None: - """Tests the setters of NS class.""" - setattr(self.ns, control_property, value) - assert getattr(self.ns, control_property) == value - - @pytest.mark.parametrize( - "wrong_property, value", - [ - ("xTolerance", 4e-6), - ("funcTolerance", 3e-4), - ("maxFuncEvals", 100), - ("maxIterations", 50), - ("updateFreq", 4), - ("updatePlotFreq", 3), - ("populationSize", 200), - ("fWeight", 0.3), - ("crossoverProbability", 0.4), - ("strategy", Strategies.BestWithJitter), - ("targetValue", 2.0), - ("numGenerations", 50), - ("nSamples", 500), - ("nChains", 1000), - ("jumpProbability", 0.7), - ("pUnitGamma", 0.3), - ("boundHandling", BoundHandling.Fold), - ("adaptPCR", False), - ], - ) - def test_initialise_non_ns_properties(self, wrong_property: str, value: Any) -> None: - incorrect_procedures = [key for (key, value) in fields.items() if wrong_property in value] - with pytest.warns( - UserWarning, - match=f'\nThe current controls procedure is "ns", but the property' - f' "{wrong_property}" applies instead to the' - f" {', '.join(incorrect_procedures)} procedure.\n\n" - f' The fields for the "ns" controls procedure are:\n' - f" {', '.join(fields['ns'])}\n", - ): - Controls(procedure=Procedures.NS, **{wrong_property: value}) - - @pytest.mark.parametrize( - "wrong_property, value", - [ - ("xTolerance", 4e-6), - ("funcTolerance", 3e-4), - ("maxFuncEvals", 100), - ("maxIterations", 50), - ("updateFreq", 4), - ("updatePlotFreq", 3), - ("populationSize", 200), - ("fWeight", 0.3), - ("crossoverProbability", 0.4), - ("strategy", Strategies.BestWithJitter), - ("targetValue", 2.0), - ("numGenerations", 50), - ("nSamples", 500), - ("nChains", 1000), - ("jumpProbability", 0.7), - ("pUnitGamma", 0.3), - ("boundHandling", BoundHandling.Fold), - ("adaptPCR", False), - ], - ) - def test_set_non_ns_properties(self, wrong_property: str, value: Any) -> None: - incorrect_procedures = [key for (key, value) in fields.items() if wrong_property in value] - with pytest.warns( - UserWarning, - match=f'\nThe current controls procedure is "ns", but the property' - f' "{wrong_property}" applies instead to the' - f" {', '.join(incorrect_procedures)} procedure.\n\n" - f' The fields for the "ns" controls procedure are:\n' - f" {', '.join(fields['ns'])}\n", - ): - setattr(self.ns, wrong_property, value) - - @pytest.mark.parametrize( - "control_property, value, bound", - [ - ("nMCMC", -1, 0), - ("nsTolerance", -500, 0), - ("nLive", -500, 1), - ], - ) - def test_ns_setter_error(self, control_property: str, value: int | float, bound: int) -> None: - """Tests the nMCMC, nsTolerance, nLive setter error in NS class.""" - with pytest.raises(pydantic.ValidationError, match=f"Input should be greater than or equal to {bound}"): - setattr(self.ns, control_property, value) - - @pytest.mark.parametrize( - "value, msg", - [ - (0, "Input should be greater than 0"), - (2, "Input should be less than 1"), - ], - ) - def test_ns_propScale_error(self, value: int, msg: str) -> None: - """Tests the propScale error in NS class.""" - with pytest.raises(pydantic.ValidationError, match=msg): - self.ns.propScale = value - - def test_control_class_ns_str(self, table_str) -> None: - """Tests the NS model __str__.""" - assert self.ns.__str__() == table_str - - -class TestDream: - """Tests the Dream class.""" - - @pytest.fixture(autouse=True) - def setup_class(self): - self.dream = Controls(procedure=Procedures.DREAM) - - @pytest.fixture - def table_str(self): - table_str = ( - "+---------------------+---------+\n" - "| Property | Value |\n" - "+---------------------+---------+\n" - "| procedure | dream |\n" - "| parallel | single |\n" - "| numSimulationPoints | 500 |\n" - "| resampleMinAngle | 0.9 |\n" - "| resampleNPoints | 50 |\n" - "| display | iter |\n" - "| nSamples | 20000 |\n" - "| nChains | 10 |\n" - "| jumpProbability | 0.5 |\n" - "| pUnitGamma | 0.2 |\n" - "| boundHandling | reflect |\n" - "| adaptPCR | True |\n" - "+---------------------+---------+" - ) - - return table_str - - @pytest.mark.parametrize( - "control_property, value", - [ - ("parallel", Parallel.Single), - ("numSimulationPoints", 500), - ("resampleMinAngle", 0.9), - ("resampleNPoints", 50), - ("display", Display.Iter), - ("procedure", Procedures.DREAM), - ("nSamples", 20000), - ("nChains", 10), - ("jumpProbability", 0.5), - ("pUnitGamma", 0.2), - ("boundHandling", BoundHandling.Reflect), - ("adaptPCR", True), - ], - ) - def test_dream_property_values(self, control_property: str, value: Any) -> None: - """Tests the default values of Dream class.""" - assert getattr(self.dream, control_property) == value - - @pytest.mark.parametrize( - "control_property, value", - [ - ("parallel", Parallel.Points), - ("numSimulationPoints", 10), - ("resampleMinAngle", 0.2), - ("resampleNPoints", 1), - ("display", Display.Notify), - ("nSamples", 500), - ("nChains", 1000), - ("jumpProbability", 0.7), - ("pUnitGamma", 0.3), - ("boundHandling", BoundHandling.Fold), - ("adaptPCR", False), - ], - ) - def test_dream_property_setters(self, control_property: str, value: Any) -> None: - """Tests the setters in Dream class.""" - setattr(self.dream, control_property, value) - assert getattr(self.dream, control_property) == value - - @pytest.mark.parametrize( - "wrong_property, value", - [ - ("xTolerance", 4e-6), - ("funcTolerance", 3e-4), - ("maxFuncEvals", 100), - ("maxIterations", 50), - ("updateFreq", 4), - ("updatePlotFreq", 3), - ("populationSize", 200), - ("fWeight", 0.3), - ("crossoverProbability", 0.4), - ("strategy", Strategies.BestWithJitter), - ("targetValue", 2.0), - ("numGenerations", 50), - ("nLive", 1500), - ("nMCMC", 1), - ("propScale", 0.5), - ("nsTolerance", 0.8), - ], - ) - def test_initialise_non_dream_properties(self, wrong_property: str, value: Any) -> None: - incorrect_procedures = [key for (key, value) in fields.items() if wrong_property in value] - with pytest.warns( - UserWarning, - match=f'\nThe current controls procedure is "dream", but the property' - f' "{wrong_property}" applies instead to the' - f" {', '.join(incorrect_procedures)} procedure.\n\n" - f' The fields for the "dream" controls procedure are:\n' - f" {', '.join(fields['dream'])}\n", - ): - Controls(procedure=Procedures.DREAM, **{wrong_property: value}) - - @pytest.mark.parametrize( - "wrong_property, value", - [ - ("xTolerance", 4e-6), - ("funcTolerance", 3e-4), - ("maxFuncEvals", 100), - ("maxIterations", 50), - ("updateFreq", 4), - ("updatePlotFreq", 3), - ("populationSize", 200), - ("fWeight", 0.3), - ("crossoverProbability", 0.4), - ("strategy", Strategies.BestWithJitter), - ("targetValue", 2.0), - ("numGenerations", 50), - ("nLive", 1500), - ("nMCMC", 1), - ("propScale", 0.5), - ("nsTolerance", 0.8), - ], - ) - def test_set_non_dream_properties(self, wrong_property: str, value: Any) -> None: - incorrect_procedures = [key for (key, value) in fields.items() if wrong_property in value] - with pytest.warns( - UserWarning, - match=f'\nThe current controls procedure is "dream", but the property' - f' "{wrong_property}" applies instead to the' - f" {', '.join(incorrect_procedures)} procedure.\n\n" - f' The fields for the "dream" controls procedure are:\n' - f" {', '.join(fields['dream'])}\n", - ): - setattr(self.dream, wrong_property, value) - - @pytest.mark.parametrize( - "control_property, value, msg", - [ - ("jumpProbability", 0, "Input should be greater than 0"), - ("jumpProbability", 2, "Input should be less than 1"), - ("pUnitGamma", -5, "Input should be greater than 0"), - ("pUnitGamma", 20, "Input should be less than 1"), - ], - ) - def test_dream_jumpProbability_pUnitGamma_error(self, control_property: str, value: int, msg: str) -> None: - """Tests the jumpProbability and pUnitGamma setter errors in Dream class.""" - with pytest.raises(pydantic.ValidationError, match=msg): - setattr(self.dream, control_property, value) - - @pytest.mark.parametrize("value", [-80, -2]) - def test_dream_nSamples_error(self, value: int) -> None: - """Tests the nSamples setter error in Dream class.""" - with pytest.raises(pydantic.ValidationError, match="Input should be greater than or equal to 0"): - self.dream.nSamples = value - - @pytest.mark.parametrize("value", [-5, 0]) - def test_dream_nChains_error(self, value: int) -> None: - """Tests the nChains setter error in Dream class.""" - with pytest.raises(pydantic.ValidationError, match="Input should be greater than 1"): - self.dream.nChains = value - - def test_control_class_dream_str(self, table_str) -> None: - """Tests the Dream model __str__.""" - assert self.dream.__str__() == table_str - - -def test_initialise_IPC() -> None: - """Tests that an Inter-Process Communication File can be set up.""" - test_controls = Controls() - test_controls.initialise_IPC() - assert test_controls._IPCFilePath != "" - with open(test_controls._IPCFilePath, "rb") as f: - file_content = f.read() - assert file_content == b"\x00" - os.remove(test_controls._IPCFilePath) - - -def test_sendStopEvent(IPC_controls) -> None: - """Tests that an Inter-Process Communication File can be modified.""" - IPC_controls.sendStopEvent() - with open(IPC_controls._IPCFilePath, "rb") as f: - file_content = f.read() - assert file_content == b"\x01" - - -def test_sendStopEvent_empty_file() -> None: - """Tests that we do not write to a non-existent Inter-Process Communication File.""" - test_controls = Controls() - with pytest.warns(UserWarning, match="An IPC file was not initialised."): - test_controls.sendStopEvent() - - -def test_delete_IPC(IPC_controls) -> None: - """Tests that an Inter-Process Communication File can be safely removed.""" - IPC_controls.delete_IPC() - assert not os.path.isfile(IPC_controls._IPCFilePath) diff --git a/tests/test_convert.py b/tests/test_convert.py deleted file mode 100644 index 0cbd621b..00000000 --- a/tests/test_convert.py +++ /dev/null @@ -1,130 +0,0 @@ -"""Test conversion to Project files.""" - -import importlib -import os -import pathlib -import tempfile - -import pytest - -import ratapi -from ratapi.utils.convert import project_to_r1, r1_to_project - -TEST_DIR_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "test_data") - - -@pytest.fixture -def dspc_bilayer(): - """The Project from the DSPC standard layers example, - with some changes to make it compatible with R1. - - """ - project, _ = ratapi.examples.DSPC_standard_layers() - - # change parameters to standardise arguments not in R1 - for class_list in ratapi.project.parameter_class_lists: - params = getattr(project, class_list) - for param in params: - param.prior_type = "uniform" - param.mu = 0.0 - param.sigma = float("inf") - - for i in range(0, len(project.background_parameters)): - param = project.background_parameters[i] - for background in project.backgrounds: - if background.source == param.name: - background.source = f"Background parameter {i + 1}" - param.name = f"Background parameter {i + 1}" - - for i in range(0, len(project.resolution_parameters)): - param = project.resolution_parameters[i] - for resolution in project.resolutions: - if resolution.source == param.name: - resolution.source = f"Resolution parameter {i + 1}" - param.name = f"Resolution parameter {i + 1}" - - return project - - -@pytest.mark.parametrize( - ["file", "project"], - [ - ["R1defaultProject.mat", "r1_default_project"], - ["R1monolayerVolumeModel.mat", "r1_monolayer"], - ["R1DSPCBilayer.mat", "dspc_bilayer"], - ["R1Monolayer_8_contrasts.mat", "r1_monolayer_8_contrasts"], - ["R1orsoPolymerExample.mat", "r1_orso_polymer"], - ["R1motofitBenchMark.mat", "r1_motofit_bench_mark"], - ], -) -@pytest.mark.parametrize("path_type", [os.path.join, pathlib.Path]) -def test_r1_to_project(file, project, path_type, request): - """Test that R1 to Project class conversion returns the expected Project.""" - output_project = r1_to_project(path_type(TEST_DIR_PATH, file)) - expected_project = request.getfixturevalue(project) - - # assert statements have to be more careful due to R1 missing features - # e.g. R1 doesn't support background parameter names, mu, sigma... - for class_list in ratapi.project.class_lists: - assert getattr(output_project, class_list) == getattr(expected_project, class_list) - - -def test_r1_with_non_unique_contrast_names(): - """Test that R1 to Project class conversion returns the expected Project.""" - output_project = r1_to_project(pathlib.Path(TEST_DIR_PATH, "nonUniqueContrast.mat")) - assert output_project.contrasts[0].name == "Contrast 1" - assert output_project.contrasts[1].name == "Contrast 2" - - -@pytest.mark.parametrize( - "project", - [ - "r1_default_project", - "r1_monolayer", - "r1_monolayer_8_contrasts", - "r1_orso_polymer", - "r1_motofit_bench_mark", - "dspc_bilayer", - ], -) -def test_r1_involution(project, request, monkeypatch): - """Test that converting a Project to an R1 struct and back returns the same project.""" - original_project = request.getfixturevalue(project) - r1_struct = project_to_r1(original_project, return_struct=True) - - # rather than writing the struct to a file and reading the file, just directly - # hand the struct over - def mock_load(ignored_filename, **ignored_settings): - """Load the generated R1 struct instead of reading a file.""" - return {"problem": r1_struct} - - monkeypatch.setattr("ratapi.utils.convert.loadmat", mock_load, raising=True) - - converted_project = r1_to_project(pathlib.Path(__file__).parent / "test_data" / project) - - for class_list in ratapi.project.class_lists: - assert getattr(converted_project, class_list) == getattr(original_project, class_list) - - -def test_invalid_constraints(): - """Test that invalid constraints are fixed where necessary.""" - with pytest.warns( - match=r"The parameter (.+) has invalid constraints," - " these have been adjusted to satisfy the current value of the parameter." - ): - output_project = r1_to_project(pathlib.Path(TEST_DIR_PATH, "R1DoubleBilayerVolumeModel.mat")) - - assert output_project.background_parameters[0].min == output_project.background_parameters[0].value - - -@pytest.mark.skipif(importlib.util.find_spec("matlab") is None, reason="Matlab not installed") -@pytest.mark.parametrize("path_type", [os.path.join, pathlib.Path]) -def test_matlab_save(path_type, request): - """Test that MATLAB correctly saves the .mat file.""" - project = request.getfixturevalue("r1_default_project") - with tempfile.TemporaryDirectory() as temp: - matfile = path_type(temp, "testfile.mat") - project_to_r1(project, filename=matfile) - converted_project = r1_to_project(matfile) - - assert project == converted_project diff --git a/tests/test_custom_errors.py b/tests/test_custom_errors.py deleted file mode 100644 index 92dbcab8..00000000 --- a/tests/test_custom_errors.py +++ /dev/null @@ -1,49 +0,0 @@ -"""Test the utils.custom_errors module.""" - -import re - -import pytest -from pydantic import ValidationError, create_model - -import ratapi.utils.custom_errors - - -@pytest.fixture -def TestModel(): - """Create a custom pydantic model for the tests.""" - TestModel = create_model("TestModel", int_field=(int, 1), str_field=(str, "a"), __config__={"extra": "forbid"}) - return TestModel - - -@pytest.mark.parametrize( - ["custom_errors", "expected_error_message"], - [ - ( - {}, - "2 validation errors for TestModel\nint_field\n Input should be a valid integer, unable to parse string " - "as an integer [type=int_parsing, input_value='string', input_type=str]\nstr_field\n Input should be a " - "valid string [type=string_type, input_value=5, input_type=int]", - ), - ( - {"int_parsing": "This is a custom error message", "string_type": "This is another custom error message"}, - "2 validation errors for TestModel\nint_field\n This is a custom error message [type=int_parsing, " - "input_value='string', input_type=str]\nstr_field\n This is another custom error message " - "[type=string_type, input_value=5, input_type=int]", - ), - ], -) -def test_custom_pydantic_validation_error( - TestModel, - custom_errors: dict[str, str], - expected_error_message: str, -) -> None: - """When we call custom_pydantic_validation_error with custom errors, we should return an error list containing - PydanticCustomErrors, otherwise we return the original set of errors. - """ - try: - TestModel(int_field="string", str_field=5) - except ValidationError as exc: - custom_error_list = ratapi.utils.custom_errors.custom_pydantic_validation_error(exc.errors(), custom_errors) - - with pytest.raises(ValidationError, match=re.escape(expected_error_message)): - raise ValidationError.from_exception_data("TestModel", custom_error_list) diff --git a/tests/test_data/ORSO/test0.layers b/tests/test_data/ORSO/test0.layers deleted file mode 100644 index f52fa9ae..00000000 --- a/tests/test_data/ORSO/test0.layers +++ /dev/null @@ -1,4 +0,0 @@ -0.000000000000000000e+00 2.069999999999999840e+00 0.000000000000000000e+00 0.000000000000000000e+00 -1.000000000000000000e+02 3.450000000000000178e+00 1.000000000000000056e-01 3.000000000000000000e+00 -2.000000000000000000e+02 5.000000000000000000e+00 1.000000000000000021e-02 1.000000000000000000e+00 -0.000000000000000000e+00 6.000000000000000000e+00 0.000000000000000000e+00 5.000000000000000000e+00 diff --git a/tests/test_data/ORSO/test1.layers b/tests/test_data/ORSO/test1.layers deleted file mode 100644 index 087d4d5a..00000000 --- a/tests/test_data/ORSO/test1.layers +++ /dev/null @@ -1,22 +0,0 @@ -0.0000 0.0000 0.0000 0.0000 -30.0000 -1.9493 0.0000 0.0000 -70.0000 9.4245 0.0000 0.0000 -30.0000 -1.9493 0.0000 0.0000 -70.0000 9.4245 0.0000 0.0000 -30.0000 -1.9493 0.0000 0.0000 -70.0000 9.4245 0.0000 0.0000 -30.0000 -1.9493 0.0000 0.0000 -70.0000 9.4245 0.0000 0.0000 -30.0000 -1.9493 0.0000 0.0000 -70.0000 9.4245 0.0000 0.0000 -30.0000 -1.9493 0.0000 0.0000 -70.0000 9.4245 0.0000 0.0000 -30.0000 -1.9493 0.0000 0.0000 -70.0000 9.4245 0.0000 0.0000 -30.0000 -1.9493 0.0000 0.0000 -70.0000 9.4245 0.0000 0.0000 -30.0000 -1.9493 0.0000 0.0000 -70.0000 9.4245 0.0000 0.0000 -30.0000 -1.9493 0.0000 0.0000 -70.0000 9.4245 0.0000 0.0000 -0.0000 2.0704 0.0000 0.0000 diff --git a/tests/test_data/ORSO/test2.layers b/tests/test_data/ORSO/test2.layers deleted file mode 100644 index b8c75ded..00000000 --- a/tests/test_data/ORSO/test2.layers +++ /dev/null @@ -1,2 +0,0 @@ -0.0000 0.0000 0.0000 0.0000 -0.0000 6.3600 0.0000 3.0000 diff --git a/tests/test_data/ORSO/test3.layers b/tests/test_data/ORSO/test3.layers deleted file mode 100644 index ad808bb5..00000000 --- a/tests/test_data/ORSO/test3.layers +++ /dev/null @@ -1,2001 +0,0 @@ -2.499999999999857891e-02 3.530509218307997976e-16 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.530509218307997976e-16 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.530509218307997976e-16 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.530509218307997976e-16 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.530509218307997976e-16 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.530509218307997976e-16 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.530509218307997976e-16 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.530509218307997976e-16 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.530509218307997976e-16 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.530509218307997976e-16 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.530509218307997976e-16 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.061018436615995952e-16 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.061018436615995952e-16 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.061018436615995952e-16 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.061018436615995952e-16 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.061018436615995952e-16 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.061018436615995952e-16 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.061018436615995952e-16 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.061018436615995952e-16 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.059152765492399442e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.059152765492399442e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.059152765492399442e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.059152765492399442e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.412203687323199190e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.412203687323199190e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.412203687323199190e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.412203687323199190e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.765254609153998939e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.765254609153998939e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.765254609153998939e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.118305530984798884e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.118305530984798884e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.471356452815598633e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.471356452815598633e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.471356452815598633e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.824407374646398381e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.177458296477198129e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.177458296477198129e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.530509218307997877e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.530509218307997877e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.883560140138798020e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.236611061969597768e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.589661983800397517e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.942712905631197265e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.295763827461997013e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.648814749292796762e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.001865671123596510e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.354916592954396258e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.707967514785196007e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.414069358446795503e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.767120280277596040e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.120171202108395000e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.826273045769994496e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.532374889431593993e-15 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.023847673309319349e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.094457857675479299e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.165068042041639406e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.235678226407799356e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.306288410773959305e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.412203687323199151e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.518118963872439154e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.624034240421679000e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.729949516970919161e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.835864793520159007e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.977085162252478906e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.118305530984798805e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.259525899717118705e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.400746268449438604e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.577271729364838557e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.753797190280238510e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.930322651195638148e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.106848112111038416e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.318678665209518107e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.565814310491077852e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.812949955772637597e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.060085601054197973e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.342526338518837772e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.624967075983477570e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.942712905631197423e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.260458735278917275e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.613509657109716550e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.001865671123596510e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.390221685137476470e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.813882791334435852e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.272848989714475919e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.767120280277595409e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.261391570840714899e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.826273045769994496e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.426459612882354778e-14 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.002664617999471380e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.069744293147323419e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.140354477513483400e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.218025680316259392e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.299227392337343200e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.383959613576735329e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.475752853252743090e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.574607111365366988e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.676991878696298954e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.786437664463847058e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.902944468668010793e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.030042800527098734e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.164202150822802812e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.305422519555122522e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.453703906724058369e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.616107330766226490e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.785571773245010243e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.969158252597026270e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.163336259603966250e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.368105794265830183e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.586997365800925884e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.820010974209253860e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.067146619490813605e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.331934810863913440e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.610845039110245044e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.907407813448116738e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.225153643095837348e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.564082528053404854e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.920663959102512954e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.301958954679776272e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.707967514785195817e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.138689639418771589e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.597655837798811909e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.084866109925315766e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.600320455798283162e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.151079893854331748e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.733613914875150173e-13 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.035498353729735811e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.101518876112095354e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.171776009556424477e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.246269754062723384e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.325353160552822503e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.409379279948552867e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.498701163171745106e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.593671861144230255e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.694291373866008313e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.801265803180740541e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.914595149088427142e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.035338564354560812e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.163496048979141148e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.299420653883998982e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.443818480912796383e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.597042580987363374e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.759446005029531192e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.932087905804792333e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.115321334234977225e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.309852392163747936e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.516034130512935298e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.734925702048031000e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.967233208612697514e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.213662752050595696e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.475273485127218042e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.752418458764396192e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.046509876649452667e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.358606891547879156e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.689415605303338937e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.040701272524984556e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.412816944134647654e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.807174823819650749e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.225893217110979644e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.669325174930463553e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.139589002809089894e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.638096904434177955e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.166614134414885937e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.726552896438533935e-12 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.032038454695794020e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.094952128966042482e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.161608143007697442e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.232253632466040562e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.307100427894170018e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.386395664937367798e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.470421784333098081e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.559425921726642692e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.653690517855466298e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.753533318549216566e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.859272069637540842e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.971295127134453767e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.089884931777419361e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.215465144672634947e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.348424121834114195e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.489220829460237109e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.638243623565017683e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.796022080531201924e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.963015166557170155e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.139787763117851708e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.326904751688175591e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.524895708650888134e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.734396125665284671e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.956112104575027192e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.190714442131593387e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.438909240178645891e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.701473210744211403e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.979253676040685212e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.273062653188276375e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.583853379675929835e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.912543787900403655e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.260157725535009428e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.627754345345238521e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.016463410280949595e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.427449988384183671e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.861985062973531420e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.321374922459768455e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.806996465438033811e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.320367810872199822e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.862936467541772821e-11 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.043643238496372316e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.104247959737847411e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.168294927467172804e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.235974789182137225e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.307481722889747382e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.383034620161538535e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.462852372569045687e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.547171524229895536e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.636239210789369746e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.730316689929622922e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.829679341369683388e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.934616666865451893e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.045432290209703421e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.162447487741303617e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.286004718854428575e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.416453503961691116e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.554175138058667409e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.699561507668591172e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.853032743388439423e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.015019567342847247e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.185988006748630534e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.366421741368697130e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.556836225548920807e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.757761035672047249e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.969768114231442517e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.193450586775782085e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.429436883945925336e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.678383680456477536e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.940986486623444803e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.217976117855017161e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.510118694651566991e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.818222703624087568e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.143135466984973019e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.485753734075672252e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.847013089839038127e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.227905607365415273e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.629469256364985127e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.052794964186206017e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.499033676834244985e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.969389297952545969e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.465132810859700674e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.987595217531008488e-10 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.053818519114457877e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.111837142353522234e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.172970380824978214e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.237380637952867445e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.305239496485199954e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.376726306290265728e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.452029596560322530e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.531348134964361084e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.614889868495339475e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.702873335673871373e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.795528372650068183e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.893096819305384497e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.995831460099850640e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.103998495428527316e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.217877188570582985e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.337760924842058429e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.463957564646790620e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.596790502629176039e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.736599020725094550e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.883738641212829949e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.038583598069522139e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.201526130869325603e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.372977190885251341e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.553369265496542084e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.743154965984985513e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.942809498891364361e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.152832078219148570e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.373745219332647560e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.606097563364386261e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.850464583316949538e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.107449996266666900e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.377686116414537607e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.661836679493604226e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.960597195819872770e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.274697421648767766e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.604901712226052401e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.952011846195205379e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.316867731699262041e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.700350230788188744e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.103382571622575841e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.526931054575471353e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.972009994945296889e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.439681016853996603e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.931056936807181112e-09 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.044730352894873730e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.098964129031543319e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.155935003049890543e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.215776922469658027e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.278630225032273515e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.344641850531402944e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.413965693863872414e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.486762887470405455e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.563202189691637257e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.643460161293575150e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.727721800959258837e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.816180686509128120e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.909039363257036958e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.006509979501913862e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.108814427748129291e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.216185050807339909e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.328864818323950230e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.447108103487139078e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.571180965471598026e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.701361749624098530e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.837941687650058736e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.981225356579742234e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.131531384870100991e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.289192946676067685e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.454558573867672120e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.627992650301337531e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.809876223836994684e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.000607677134837506e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.200603539672443139e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.410299264456796421e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.630150004736322307e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.860631567238371663e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.102241224186343966e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.355498631232080830e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.620946921913728134e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.899153590283035305e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.190711585363217433e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.496240476216996634e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.816387405184088499e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.151828535389982212e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.503270109898708421e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.871449722696155398e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.257137836809036987e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.661138949372927336e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.084293215666506299e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.527477896620340212e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.991608876935843226e-08 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.047764243033988513e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.098657680831394251e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.151945404065379819e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.207736173602924591e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.266143509437434076e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.327285884866746759e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.391286924201651306e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.458275632248984213e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.528386606142184711e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.601760278946429319e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.678543152672240651e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.758888048941642672e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.842954373776351015e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.930908389446983736e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.022923496913797819e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.119180525328445866e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.219868028596750042e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.325182620777077708e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.435329290295662623e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.550521745936507130e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.670982766361796022e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.796944574345872006e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.928649211009215407e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.066348941827001943e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.210306659107154124e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.360796316242975479e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.518103376087822495e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.682525248738244696e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.854371799927314284e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.033965831173880380e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.221643588175894426e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.417755308039339659e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.622665777098689253e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.836754888737360232e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.060418254165810735e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.294067813199631986e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.538132483873248572e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.793058829706155389e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.059311734030181640e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.337375137865919455e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.627752763677108983e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.930968902674195515e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.247569195056869612e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.578121470275256992e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.923216604943661508e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.283469398406851661e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.659519508324997955e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.052032400380661170e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.461700333290857156e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.889243389715751167e-07 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.033541053188091803e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.080098071015722765e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.128676398576278259e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.179360273466656369e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.232237284796156095e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.287398500990910611e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.344938599716627538e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.404956005215396524e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.467553027054702133e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.532836005937454793e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.600915465513885868e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.671906266664802174e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.745927768845856439e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.823103997080633043e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.903563816014752884e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.987441105735232803e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.074874949240523796e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.166009821675807398e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.260995789806763632e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.359988714670802017e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.463150464466767954e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.570649132740410486e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.682659264690023736e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.799362091592261169e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.920945771229810599e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.047605639263650936e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.179544466254125080e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.316972726685741063e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.460108872581635624e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.609179620533975791e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.764420245795374920e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.926074885902686230e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.094396857363680435e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.269648979051688136e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.452103907603976837e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.642044485529961508e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.839764098851784607e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.045567046395582724e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.259768922145636034e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.482697008896142421e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.714690686378088391e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.956101850683737030e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.207295348166219538e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.468649422755046141e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.740556179158919327e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.023422058425322066e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.317668330446558671e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.623731601646977449e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.942064338204436240e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.273135406924315746e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.617430631647771529e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.975453369430842055e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.347725100845583125e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.734786044288679989e-06 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.013719578335292704e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.055553391820618433e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.099040073532897539e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.144241789702293843e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.191222915527978604e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.240050108294976747e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.290792383103589499e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.343521190787733282e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.398310498128108044e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.455236870501419636e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.514379557248091248e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.575820579299502824e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.639644819488417403e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.705940115860338292e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.774797357315005772e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.846310582531263366e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.920577081363283853e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.997697499661388443e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.077775946987880915e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.160920107333819199e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.247241353330986757e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.336854863782544811e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.429879744265228653e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.526439151756321288e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.626660422332172172e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.730675202891497352e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.838619586621016523e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.950634251956296992e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.066864606167563230e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.187460932334796259e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.312578540877187246e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.442377925283901952e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.577024922222671620e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.716690875990913737e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.861552807591817370e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.011793588859058590e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.167602120747516004e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.329173517166884502e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.496709293475565348e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.670417560270312651e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.850513222506958153e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.037218183952196727e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.230761557248886904e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.431379879559550559e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.639317333999916077e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.854825977250843831e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.078165972924987412e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.309605831217757633e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.549422655125036849e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.797902392874588745e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.055340097136043084e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.322040191044765169e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.598316741074918423e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.884493737079446211e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.180905379532311104e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.487896374114179126e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.805822234135840803e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.135049590375699403e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.475956508931516293e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.828932817157022084e-05 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.019438043789522362e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.057271373204371522e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.096435984969912450e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.136975908998660850e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.178936527017460220e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.222364610350989999e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.267308358665575297e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.313817439637987637e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.361943029637502421e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.411737855343542236e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.463256236415411246e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.516554129168223950e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.571689171311519036e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.628720727750554540e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.687709937464410101e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.748719761545625096e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.811815032295460725e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.877062503558368865e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.944530902157981598e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.014290980586430863e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.086415570879918363e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.160979639751148479e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.238060344996273352e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.317737093165761562e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.400091598573328682e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.485207943618217221e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.573172640484378080e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.664074694209484276e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.758005667162622245e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.855059744965960191e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.955333803853333165e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.058927479518702979e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.165943237472146495e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.276486444910431525e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.390665444169261005e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.508591627736001774e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.630379514861736779e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.756146829843243413e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.886014581907826530e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.020107146831630816e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.158552350234945576e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.301481552642760883e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.449029736271748175e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.601335593638978053e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.758541617967671205e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.920794195453526447e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.088243699370442741e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.261044586110963676e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.439355493115538738e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.623339338771815707e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.813163424283951169e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.008999537554316275e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.211024059084647216e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.419418069942550969e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.634367461814538606e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.856063049163241318e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.084700683534706682e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.320481370036958316e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.563611385982760759e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.814302401784845812e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.072771604082418272e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.339241821141319278e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.613941650566659530e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.897105589303234020e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.188974166047270695e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.489794075981251419e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.799818317944787756e-04 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.011930633402036194e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.044852415157278107e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.078774452777762124e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.113724709665282449e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.149731851859341503e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.186825263249406941e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.225035061042780826e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.264392111491603526e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.304928045884650150e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.346675276801088212e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.389667014631141813e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.433937284367548101e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.479520942666035085e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.526453695177652087e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.574772114160007943e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.624513656361419381e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.675716681186085891e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.728420469138176700e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.782665240550829373e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.838492174595822773e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.895943428582047650e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.955062157538887350e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.015892534089807134e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.078479768614740694e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.142870129704799263e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.209110964910017145e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.277250721777302183e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.347338969189538549e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.419426418993488904e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.493564947929549722e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.569807619855249067e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.648208708269188510e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.728823719131903344e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.811709413986105723e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.896923833375613343e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.984526320566134334e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.074577545560850615e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.167139529420328562e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.262275668878998006e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.360050761259952053e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.460531029690905314e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.563784148616360500e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.669879269605274327e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.778887047459176651e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.890879666612257013e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.005930867825547095e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.124115975176954191e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.245511923337979415e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.370197285144872268e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.498252299453294085e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.629758899282472584e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.764800740240043332e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.903463229228968538e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.045833553435493182e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.192000709589648759e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.342055533500789620e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.496090729863563167e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.654200902329729016e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.816482583842293511e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.983034267232665605e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.153956436068839381e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.329351595759176788e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.509324304900856659e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.693981206871935270e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.883431061660647693e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.077784777929494418e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.277155445304220142e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.481658366886976934e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.691411091985205471e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.906533449051287785e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.127147578827669319e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.353377967686875447e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.585351481167458054e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.823197397690014238e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.067047442453599754e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.317035821499846868e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.573299255940899075e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.835977016340221799e-03 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.010521095724061652e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.038114555182889295e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.066392792672938086e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.095370789691819773e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.125063800074625406e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.155487353506534989e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.186657259044252705e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.218589608645846006e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.251300780707362281e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.284807443605659634e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.319126559245862619e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.354275386612736540e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.390271485324815794e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.427132719189450581e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.464877259758593994e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.503523589883107303e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.543090507265122528e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.583597128006451749e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.625062890152159656e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.667507557227920420e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.710951221769434205e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.755414308842943860e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.800917579554914619e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.847482134549957231e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.895129417494697405e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.943881218547138801e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.993759677808687805e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.044787288758420640e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.096986901667016734e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.150381726989364362e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.204995338733868604e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.260851677806583609e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.317975055328797343e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.376390155926124889e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.436122040987061602e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.497196151889729057e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.559638313194300546e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.623474735799630544e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.688732020062424566e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.755437158875984061e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.823617540707961532e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.893300952593811162e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.964515583085113731e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.037290025149574912e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.111653279021451765e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.187634755000221670e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.265264276194813908e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.344572081212053571e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.425588826786436086e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.508345590349488952e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.592873872536573449e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.679205599628338624e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.767373125925305849e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.857409236052693896e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.949347147193637414e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.043220511248239724e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.139063416916287375e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.236910391700993150e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.336796403832025165e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.438756864104484445e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.542827627632645138e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.649044995514838019e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.757445716408129077e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.868066988009438212e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.980946458441441738e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.096122227540358235e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.213632848043155132e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.333517326672085335e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.455815125113627068e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.580566160889600946e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.707810808118029405e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.837589898160953916e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.969944720157322610e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.104917021437621799e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.242549007818455620e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.382883343774306550e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.525963152484175189e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.671832015750060740e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.820533973785831983e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.972113524872693147e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.126615624880225375e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.284085686649298397e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.444569579235123247e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.608113627007889734e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.774764608608446259e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.944569755756682172e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.117576751910210442e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.293833730771182911e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.473389274638486179e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.656292412603094899e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.842592618585139175e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.032339809208506098e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.225584341512994835e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.422377010499909111e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.622769046509986601e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.826812112431108914e-02 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.003455830073357175e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.024606013033130397e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.046137054326602978e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.068054290121346339e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.090363098180851670e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.113068897478845798e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.136177147795133513e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.159693349292828662e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.183623042076773213e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.207971805732974274e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.232745258848865072e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.257949058514259977e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.283588899802801109e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.309670515233752053e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.336199674214005872e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.363182182460129233e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.390623881400347428e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.418530647556249524e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.446908391904197788e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.475763059216247119e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.505100627380449863e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.534927106700492705e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.565248539174548814e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.596070997753154808e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.627400585576219694e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.659243435188866023e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.691605707736217323e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.724493592136918663e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.757913304235463048e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.791871085933146868e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.826373204297714326e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.861425950651645345e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.897035639638940119e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.933208608270624573e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.969951214948705842e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.007269838468742906e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.045170877001037668e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.083660747050359308e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.122745882394377337e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.162432733000712037e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.202727763922705251e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.243637454174034762e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.285168295582085951e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.327326791620307478e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.370119456219578757e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.413552812558631133e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.457633391833766723e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.502367732007836909e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.547762376538768581e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.593823873087605092e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.640558772206351712e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.687973626005781824e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.736074986803201381e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.784869405750624582e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.834363431443342463e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.884563608509119192e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.935476476178393024e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.987108566835436907e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.039466404551018353e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.092556503596527451e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.146385366940023243e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.200959484724428816e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.256285332728060533e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.312369370807964342e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.369218041326168533e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.426837767559301473e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.485234952091895710e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.544415975193622170e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.604387193180924043e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.665154936763348470e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.726725509374896328e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.789105185490952987e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.852300208930957703e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.916316791147438914e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.981161109501680229e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.046839305526477304e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.113357483176559581e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.180721707066849535e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.248938000699374329e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.318012344678975323e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.387950674918463800e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.458758880833801896e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.530442803529520224e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.603008233975262598e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.676460911173642154e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.750806520320144388e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.826050690955621114e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.902198995111775592e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.979256945450387661e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.057229993396753498e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.136123527267844047e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.215942870396090836e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.296693279248885222e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.378379941544954024e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.461007974367843021e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.544582422277207767e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.629108255418782125e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.714590367633263224e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.801033574565200857e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.888442611772164437e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.976822132835090118e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.066176707470466445e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.156510819644825938e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.247828865692593991e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.340135152437625932e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.433433895319268236e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.527729216523850964e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.623025143121854530e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.719325605211997621e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.816634434072557092e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.914955360320802491e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.014292012081355665e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.114647913163980597e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.216026481251838209e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.318431026100656878e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.421864747749643554e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.526330734745125817e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.631831962377202405e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.738371290930653457e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.845951463950433524e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 7.954575106522763228e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.064244723572530082e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.174962698177601350e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.286731289901049236e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.399552633141798008e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.513428735504575684e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.628361476189956303e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.744352604405060125e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.861403737795964242e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 8.979516360902215499e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.098691823634380560e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.218931339775542355e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.340235985506994965e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.462606697959433655e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.586044273789982029e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.710549367785823449e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.836122491495479236e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 9.962764011887899063e-01 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.009047415004067139e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.021925297985757597e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.034910042681639553e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.048001626674776254e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.061200012464540876e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.074505147350896417e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.087916963321945873e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.101435376944848166e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.115060289260181525e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.128791585679758569e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.142629135888034941e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.156572793747108419e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.170622397205391296e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.184777768210047766e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.199038712623191394e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.213405020141967938e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.227876464222529274e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.242452802007974144e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.257133774260325687e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.271919105296557051e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.286808502928769693e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.301801658408528573e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.316898246375415971e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.332097924809886980e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.347400334990404014e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.362805101454968915e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.378311831967036882e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.393920117485881072e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.409629532141461361e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.425439633213788193e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.441349961116882294e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.457360039387303408e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.473469374677317312e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.489677456752741547e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.505983758495447189e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.522387735910622153e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.538888828138746057e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.555486457472347039e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.572180029377566290e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.588968932520502975e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.605852538798430151e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.622830203375830393e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.639901264725300400e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.657065044673355469e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.674320848451082977e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.691667964749735464e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.709105665781198047e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.726633207343367449e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.744249828890470422e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.761954753608253599e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.779747188494128718e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.797626324442197498e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.815591336333184591e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.833641383129287705e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.851775607973884297e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.869993138296145663e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.888293085920495606e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.906674547180906565e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.925136603040062289e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.943678319213281824e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.962298746297276963e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.980996919903643017e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 1.999771860797090017e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.018622575038409916e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.037548054132081177e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.056547275178562728e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.075619201031173144e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.094762780457547713e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.113976948305655412e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.133260625674279432e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.152612720087986542e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.172032125676484071e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.191517723358339165e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.211068381029038576e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.230682953753273079e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.250360283961477137e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.270099201650493281e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.289898524588342532e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.309757058523065343e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.329673597395497175e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.349646923556016898e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.369675807985115679e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.389759010517761073e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.409895280071515877e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.430083354878262547e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.450321962719562485e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.470609821165494324e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.490945637816929459e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.511328110551202197e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.531755927771016434e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.552227768656605278e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.572742303420985532e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.593298193568254639e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.613894092154882109e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.634528644053824031e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.655200486221477085e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.675908247967306863e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.696650551226081216e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.717426010832665106e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.738233234799196669e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.759070824594652915e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.779937375426626556e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.800831476525258434e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.821751711429254073e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.842696658273816457e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.863664890080482195e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.884654975048696279e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.905665476849047746e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.926694954918098279e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.947741964754635013e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.968805058217322212e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 2.989882783823591073e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.010973687049678382e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.032076310631754978e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.053189194867952594e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.074310877921289098e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.095439896123296286e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.116574784278287158e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.137714075968181415e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.158856303857713765e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.180000000000000160e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.201143696142289219e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.222285924031821569e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.243425215721716270e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.264560103876707142e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.285689122078711222e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.306810805132050390e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.327923689368248450e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.349026312950325046e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.370117216176411912e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.391194941782678107e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.412258035245368859e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.433305045081905149e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.454334523150955683e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.475345024951306705e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.496335109919518569e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.517303341726186972e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.538248288570748912e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.559168523474744550e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.580062624573376873e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.600929175405347404e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.621766765200806759e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.642573989167337878e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.663349448773921768e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.684091752032696565e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.704799513778523234e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.725471355946179841e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.746105907845120875e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.766701806431748789e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.787257696579018340e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.807772231343395042e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.828244072228986994e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.848671889448800343e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.869054362183073525e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.889390178834509104e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.909678037280437835e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.929916645121740437e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.950104719928487107e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.970240989482241467e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 3.990324192014887306e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.010353076443982978e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.030326402604505809e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.050242941476938086e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.070101475411660452e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.089900798349510147e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.109639716038523183e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.129317046246729461e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.148931618970964408e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.168482276641664264e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.187967874323519801e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.207387279912014222e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.226739374325723553e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.246023051694347572e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.265237219542455271e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.284380798968830284e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.303452724821437592e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.322451945867921808e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.341377424961592624e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.360228139202913411e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.379003080096359746e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.397701253702723356e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.416321680786721160e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.434863396959941362e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.453325452819096419e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.471706914079507378e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.490006861703854213e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.508224392026118466e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.526358616870714613e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.544408663666818171e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.562373675557805264e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.580252811505871158e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.598045246391749608e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.615750171109532118e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.633366792656635980e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.650894334218805604e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.668332035250264411e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.685679151548920451e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.702934955326647959e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.720098735274702584e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.737169796624172591e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.754147461201570835e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.771031067479499121e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.787819970622436472e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.804513542527655723e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.821111171861256928e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.837612264089377945e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.854016241504554685e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.870322543247260327e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.886530625322683896e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.902639960612699355e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.918650038883118469e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.934560366786214125e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.950370467858541623e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.966079882514121024e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.981688168032965436e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 4.997194898545030739e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.012599665009598304e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.027902075190115561e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.043101753624585903e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.058198341591474190e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.073191497071230849e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.088080894703445267e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.102866225739676409e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.117547197992029062e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.132123535777472156e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.146594979858032382e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.160961287376811590e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.175222231789954108e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.189377602794611022e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.203427206252893455e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.217370864111965822e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.231208414320244415e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.244939710739821237e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.258564623055153930e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.272083036678056445e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.285494852649104125e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.298799987535461220e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.311998373325226730e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.325089957318362544e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.338074702014243833e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.350952584995932959e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.363723598811212412e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.376387750850454061e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.388945063221419751e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.401395572621003893e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.413739330204056621e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.425976401449302600e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.438106866022446972e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.450130817636563485e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.462048363909780768e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.473859626220403563e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.485564739559495528e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.497163852381006244e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.508657126449543640e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.520044736685822073e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.531326871009895285e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.542503730182242627e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.553575527642748533e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.564542489347725329e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.575404853604958078e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.586162870906934863e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.596816803762282078e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.607366926525489070e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.617813525225037630e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.628156897389936297e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.638397351874816721e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.648535208683603592e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.658570798791865641e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.668504463967922291e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.678336556592745943e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.688067439478800225e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.697697485687816865e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.707227078347616889e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.716656610468074717e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.725986484756239392e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.735217113430740810e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.744348918035519169e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.753382329252954897e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.762317786716492307e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.771155738822785430e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.779896642543480567e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.788540963236674664e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.797089174458123217e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.805541757772281208e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.813899202563217017e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.822162005845505028e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.830330672075112908e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.838405712960392790e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.846387647273217247e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.854277000660326635e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.862074305454961554e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.869780100488823038e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.877394930904439541e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.884919347967986880e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.892353908882637548e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.899699176602474004e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.906955719647048575e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.914124111916621906e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.921204932508155494e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.928198765532103565e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.935106199930062942e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.941927829293316421e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.948664251682345139e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.955316069447352589e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.961883889049833130e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.968368320885256040e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.974769979106905993e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.981089481450905687e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.987327449062512130e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.993484506323667027e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 5.999561280681907860e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.005558402480638769e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.011476504790811859e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.017316223244071338e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.023078195867384466e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.028763062919203719e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.034371466727194822e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.039904051527558160e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.045361463305998662e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.050744349640348574e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.056053359544899095e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.061289143316457739e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.066452352382161628e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.071543639149088456e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.076563656855666906e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.081513059424938028e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.086392501319680903e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.091202637399423025e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.095944122779365593e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.100617612691240588e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.105223762346123628e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.109763226799216795e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.114236660816624536e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.118644718744137734e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.122988054378042833e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.127267320837970210e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.131483170441792474e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.135636254582597537e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.139727223607730267e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.143756726699930226e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.147725411760562864e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.151633925294964556e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.155482912299897080e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.159273016153126612e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.163004878505129902e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.166679139172937418e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.170296436036106336e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.173857404934836701e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.177362679570228998e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.180812891406686660e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.184208669576453765e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.187550640786308342e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.190839429226379309e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.194075656481114578e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.197259941442378128e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.200392900224684922e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.203475146082546132e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.206507289329951327e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.209489937261956527e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.212423694078376357e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.215309160809580291e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.218146935244376117e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.220937611859965521e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.223681781753987785e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.226380032578600066e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.229032948476624476e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.231641110019721097e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.234205094148574489e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.236725474115114132e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.239202819426703961e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.241637695792322305e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.244030665070717134e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.246382285220486885e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.248693110252116156e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.250963690181915666e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.253194570987865575e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.255386294567339966e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.257539398696686739e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.259654416992664672e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.261731878875689716e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.263772309534900273e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.265776229895001492e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.267744156584870829e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.269676601907915092e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.271574073814149664e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.273437075873968816e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.275266107253615999e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.277061662692288380e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.278824232480897827e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.280554302442434178e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.282252353913916565e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.283918863729922144e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.285554304207649601e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.287159143133507655e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.288733843751198371e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.290278864751273069e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.291794660262143069e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.293281679842499088e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.294740368475158832e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.296171166562257504e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.297574509921815888e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.298950829785623817e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.300300552798427489e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.301624101018390434e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.302921891918820130e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.304194338391104324e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.305441848748864153e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.306664826733279661e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.307863671519569060e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.309038777724597757e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.310190535415586055e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.311319330119906645e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.312425542835919501e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.313509550044852148e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.314571723723674701e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.315612431358955448e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.316632035961680103e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.317630896082990333e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.318609365830837099e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.319567794887517742e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.320506528528063939e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.321425907639473429e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.322326268740747324e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.323207944003716996e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.324071261274634814e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.324916544096504722e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.325744111732135799e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.326554279187879715e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.327347357238052084e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.328123652449997749e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.328883467209785785e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.329627099748504904e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.330354844169149509e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.331066990474062628e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.331763824592920642e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.332445628411241145e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.333112679799375755e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.333765252642003851e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.334403616868057085e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.335028038481103074e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.335638779590129666e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.336236098440738651e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.336820249446712516e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.337391483221935573e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.337950046612662369e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.338496182730106732e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.339030130983330125e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.339552127112416002e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.340062403221913279e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.340561187814528488e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.341048705825053311e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.341525178654500827e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.341990824204450483e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.342445856911570701e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.342890487782305797e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.343324924427721001e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.343749371098478917e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.344164028719935899e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.344569094927349440e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.344964764101169052e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.345351227402414196e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.345728672808105486e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.346097285146751865e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.346457246133873298e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.346808734407542119e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.347151925563943919e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.347486992192926891e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.347814103913542283e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.348133427409558216e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.348445126464935306e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.348749361999253438e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.349046292103081690e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.349336072073270998e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.349618854448171312e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.349894789042759058e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.350164022983659784e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.350426700744059794e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.350682964178500534e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.350932952557546862e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.351176802602310545e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.351414648518832529e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.351646622032313338e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.351872852421172944e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.352093466550948975e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.352308588908015530e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.352518341633113685e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.352722844554696380e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.352922215222070790e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.353116568938339981e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.353306018793128729e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.353490675695098844e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.353670648404241561e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.353846043563931012e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.354016965732768085e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.354183517416157834e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.354345799097670167e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.354503909270136752e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.354657944466499231e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.354807999290410514e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.354954166446565189e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.355096536770771465e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.355235199259760215e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.355370241100717799e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.355501747700547099e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.355629802714855003e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.355754488076662767e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.355875884024823286e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.355994069132174573e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.356109120333387708e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.356221112952541219e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.356330120730395272e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.356436215851384297e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.356539468970309414e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.356639949238740428e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.356737724331121164e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.356832860470579938e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.356925422454439811e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.357015473679433981e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.357103076166624511e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.357188290586014645e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.357271176280868019e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.357351791291731224e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.357430192380145506e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.357506435052070692e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.357580573581006256e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.357652661030810393e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.357722749278222452e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.357790889035090487e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.357857129870295942e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.357921520231385237e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.357984107465910917e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.358044937842461053e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.358104056571417750e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.358161507825404790e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.358217334759449280e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.358271579530862638e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.358324283318814274e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.358375486343638805e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.358425227885840414e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.358473546304822754e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.358520479057334640e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.358566062715633294e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.358610332985369595e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.358653324723198885e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.358695071954115541e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.358735607888508667e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.358774964938957552e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.358813174736750895e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.358850268148141360e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.358886275290335455e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.358921225547222278e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.358955147584842926e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.358988069366597884e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359020018168206612e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359051020592402459e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359081102583395761e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359110289441069597e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359138605834943725e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359166075817885400e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359192722839592804e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359218569759821804e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359243638861402204e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359267951862997315e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359291529931646814e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359314393695084000e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359336563253818575e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359358058193006258e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359378897594091917e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359399100046244868e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359418683657572124e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359437666066122929e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359456064450689006e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359473895541388977e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359491175630063609e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359507920580455220e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359524145838203246e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359539866440636402e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359555097026373005e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359569851844735666e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359584144764976799e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359597989285316721e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359611398541809457e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359624385317015793e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359636962048513809e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359649140837227321e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359660933455583809e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359672351355509790e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359683405676253010e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359694107252048312e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359704466619614749e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359714494025503484e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359724199433284042e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359733592530579571e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359742682735952002e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359751479205638880e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359759990840143651e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359768226290682946e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359776193965500646e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359783902036024728e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359791358442912212e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359798570901941339e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359805546909784724e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359812293749644851e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359818818496770554e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359825128023846474e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359831229006253750e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359837127927224998e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359842831082868742e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359848344587083702e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359853674376358512e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359858826214465743e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359863805697036021e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359868618256036221e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359873269164133980e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359877763538965390e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359882106347297892e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359886302409100800e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359890356401503020e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359894272862680609e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359898056195621763e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359901710671828745e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359905240434911455e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359908649504096623e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359911941777658839e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359915121036259222e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359918190946205030e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359921155062629339e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359924016832589899e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359926779598089830e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359929446599029035e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359932020976072131e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359934505773448876e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359936903941688868e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359939218340270983e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359941451740227514e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359943606826660378e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359945686201204929e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359947692384428031e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359949627818161311e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359951494867774890e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359953295824397834e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359955032907065764e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359956708264829395e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359958323978792905e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359959882064111447e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359961384471924717e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359962833091240775e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359964229750778131e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359965576220747430e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359966874214591392e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359968125390676796e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359969331353938493e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359970493657480795e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359971613804133561e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359972693247970987e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359973733395777096e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359974735608482810e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359975701202557730e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359976631451362827e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359977527586466728e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359978390798927350e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359979222240530028e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359980023025003426e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359980794229186607e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359981536894174781e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359982252026426863e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359982940598841061e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359983603551805587e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359984241794207627e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359984856204428105e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359985447631295585e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359986016895018857e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359986564788092878e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359987092076169191e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359987599498917454e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359988087770845233e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359988557582102686e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359989009599265053e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359989444466081387e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359989862804216187e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359990265213956384e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359990652274898792e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359991024546630456e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359991382569369023e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359991726864593353e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359992057935661691e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359992376268398750e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359992682331669478e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359992976577942159e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359993259443820435e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359993531350577989e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359993792704652371e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359994043898149485e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359994285309314321e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359994517302991035e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359994740231078580e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359994954432953485e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359995160235901501e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359995357955515516e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359995547896092560e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359995730351021059e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359995905603142319e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359996073925114679e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359996235579754575e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359996390820380263e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359996539891128009e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359996683027273612e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359996820455534383e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359996952394361358e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359997079054228841e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359997200637907966e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359997317340735812e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359997429350867648e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359997536849535393e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359997640011285647e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359997739004210615e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359997833990179039e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359997925125051133e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359998012558894409e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359998096436184412e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359998176896003663e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359998254072231738e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359998328093734443e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359998399084535237e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359998467163994640e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359998532446973663e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359998595043995451e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359998655061400719e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359998712601499626e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359998767762715666e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359998820639726880e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359998871323601755e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359998919901929781e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359998966458946690e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999011075660569e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999053829966442e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999094796759955e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999134048049285e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999171653060834e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999207678339594e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999242187853064e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999275243080952e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999306903110217e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999337224723881e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999366262486298e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999394068827527e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999420694117056e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999446186752614e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999470593218795e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999493958174988e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999516324511326e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999537733422414e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999558224469496e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999577835641738e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999596603416627e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999614562820369e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999631747475846e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999648189663013e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999663920368640e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999678969334269e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999693365105955e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999707135079561e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999720305542503e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999732901723490e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999744947825384e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999756467071386e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999767481737898e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999778013197158e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999788081947436e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999797707650337e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999806909161002e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999815704562742e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999824111195466e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999832145684984e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999839823972323e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999847161340369e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999854172436962e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999860871307753e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999867271411311e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999873385649316e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999879226382546e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999884805459303e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999890134232281e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999895223575450e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999900083911584e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999904725221143e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999909157068032e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999913388610260e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999917428621252e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999921285503177e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999924967299378e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999928481715692e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999931836126663e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999935037595975e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999938092884442e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999941008465107e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999943790531240e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999946445014096e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999948977588247e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999951393684903e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999953698499908e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999955897007951e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999957993965225e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999959993923646e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999961901237953e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999963720073701e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999965454414372e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999967108070251e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999968684686422e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999970187746321e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999971620584169e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999972986382311e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999974288190749e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999975528920046e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999976711351977e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999977838149299e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999978911856644e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999979934900516e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999980909606165e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999981838194039e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999982722782441e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999983565399084e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999984367978421e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999985132371414e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999985860343763e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999986553581230e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999987213697636e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999987842231306e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999988440649510e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999989010359123e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999989552696853e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999990068943454e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999990560319283e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999991027990518e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999991473069159e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999991896617466e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999992299650629e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999992683133208e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999993047988909e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999993395097917e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999993725302225e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999994039403859e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999994338163987e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999994622314468e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999994892550745e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999995149535401e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999995393903482e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999995626255398e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999995847168464e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999996057191574e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999996256846089e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999996446631165e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999996627022867e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999996798474164e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999996961416713e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999997116261738e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999997263400928e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999997403209981e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999997536042393e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999997662240112e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999997782122882e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999997896001567e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999998004169264e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999998106903085e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999998204472149e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999998297126922e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999998385109876e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999998468651938e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999998547970712e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999998623274031e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999998694760848e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999998762619455e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999998827029266e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999998888163475e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999998946181066e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999001240134e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999053487230e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999103061796e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999150096173e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999194720921e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999237053281e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999277209604e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999315299135e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999351424904e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999385686387e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999418177730e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999448987751e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999478202604e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999505901336e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999532162107e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999557056860e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999580654872e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999603023646e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999624224465e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999644316837e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999663357606e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999681401839e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999698498385e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999714696983e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999730043818e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999744582411e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999758355393e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999771400070e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999783755520e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999795456382e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999806538185e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999817032013e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999826968953e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999836376539e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999845283192e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999853714669e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999861696729e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999869252463e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999876403187e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999883171107e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999889575761e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999895635803e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999901370771e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999906796653e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999911930324e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999916785995e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999921380542e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999925725511e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999929836001e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999933722670e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999937398840e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999940875171e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999944161431e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999947270055e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999950207261e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999952985483e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999955610939e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999958093397e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999960439077e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999962655970e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999964752071e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999966731821e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999968603213e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999970369799e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999972040463e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999973617868e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999975108231e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999976515994e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999977845597e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999979101482e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999980287200e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999981407193e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999982465013e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999983463326e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999984405683e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999985296526e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999986136743e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999986928998e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999987677732e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999988383834e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999989050856e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999989679687e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999990273878e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999990833430e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999991361896e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999991860165e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999992330899e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999992774100e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999993193320e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999993587672e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999993959818e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999994310649e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999994641939e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999994953690e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999995248565e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999995524789e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999995785913e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999996033715e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999996264641e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999996484021e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999996690079e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999996884590e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999997068443e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999997240749e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999997403286e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999997556941e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999997700826e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999997836717e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999997965503e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999998085407e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999998199094e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999998305675e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999998406928e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999998501963e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999998590781e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999998675158e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999998754205e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999998827924e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999998898979e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999998965592e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999026876e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999085496e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999140563e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999192077e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999240927e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999286224e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999329745e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999370601e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999408793e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999444320e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999478071e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999509157e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999539355e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999566889e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999593534e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999618403e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999641496e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999663700e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999684128e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999703668e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999722320e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999739195e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999754294e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999770282e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999784492e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999796927e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999809361e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999821796e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999832454e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999843112e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999852882e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999861764e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999870646e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999878639e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999885745e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999892850e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999899956e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999905285e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999912390e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999917719e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999923048e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999927489e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999932818e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999936371e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999939924e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999943476e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999947917e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999950582e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999954134e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999956799e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999959464e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999962128e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999964793e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999967457e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999969233e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999971010e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999972786e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999974563e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999976339e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999978115e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999979003e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999980780e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999981668e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999983444e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999984333e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999985221e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999986109e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999987885e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999987885e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999988773e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999988773e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999990550e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999990550e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999991438e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999991438e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999992326e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999993214e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999993214e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999994102e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999994991e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999994991e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999994991e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999994991e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999995879e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999995879e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999995879e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999996767e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999996767e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999997655e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999997655e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999997655e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999997655e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999997655e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999997655e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999998543e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999998543e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999998543e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999998543e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999998543e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999998543e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999998543e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999998543e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999998543e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999998543e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999998543e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999998543e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999998543e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999999432e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999999432e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999999432e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999999432e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999999432e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999999432e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999999432e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.359999999999999432e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.360000000000000320e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.360000000000000320e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.360000000000000320e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.360000000000000320e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.360000000000000320e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.360000000000000320e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.360000000000000320e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.360000000000000320e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.360000000000000320e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.360000000000000320e+00 0.000000000000000000e+00 0.000000000000000000e+00 -2.499999999999857891e-02 6.360000000000000320e+00 0.000000000000000000e+00 0.000000000000000000e+00 diff --git a/tests/test_data/ORSO/test6.layers b/tests/test_data/ORSO/test6.layers deleted file mode 100644 index c1726df0..00000000 --- a/tests/test_data/ORSO/test6.layers +++ /dev/null @@ -1,3 +0,0 @@ -0.00e+00 2.07e+00 0.00e+00 0 -1.20e+03 4.66e+00 1.60e-02 1.00e+01 -0.00e+00 6.36e+00 0.00e+00 3.00e+00 \ No newline at end of file diff --git a/tests/test_data/ORSO/test7.layers b/tests/test_data/ORSO/test7.layers deleted file mode 100644 index 24d0fe1e..00000000 --- a/tests/test_data/ORSO/test7.layers +++ /dev/null @@ -1,3 +0,0 @@ -0.00e+00 0.0e+00 0.00e+00 0 -1.20e+03 4.66e+00 1.60e-02 1.00e+01 -0.00e+00 6.36e+00 0.00e+00 3.00e+00 \ No newline at end of file diff --git a/tests/test_data/ORSO/test_0.dat b/tests/test_data/ORSO/test_0.dat deleted file mode 100644 index 48a86fa4..00000000 --- a/tests/test_data/ORSO/test_0.dat +++ /dev/null @@ -1,1001 +0,0 @@ -5.000000000000000104e-03 9.665000503913141472e-01 0.000000000000000000 -5.494999999999999885e-03 9.631253196322540067e-01 0.000000000000000000 -5.990000000000000532e-03 9.597294737770289963e-01 0.000000000000000000 -6.485000000000000313e-03 9.563106251913106037e-01 0.000000000000000000 -6.980000000000000093e-03 9.528673984908934136e-01 0.000000000000000000 -7.474999999999999874e-03 9.493991543655699861e-01 0.000000000000000000 -7.969999999999999654e-03 9.459063203571898004e-01 0.000000000000000000 -8.465000000000000302e-03 9.423908868167988340e-01 0.000000000000000000 -8.959999999999999215e-03 9.388571643538128342e-01 0.000000000000000000 -9.454999999999999863e-03 9.353129674107756308e-01 0.000000000000000000 -9.950000000000000511e-03 9.317715164887934165e-01 0.000000000000000000 -1.044499999999999942e-02 9.282546034828660364e-01 0.000000000000000000 -1.094000000000000007e-02 9.247980927595669254e-01 0.000000000000000000 -1.143500000000000072e-02 9.214620278002197962e-01 0.000000000000000000 -1.192999999999999963e-02 9.183506161388482747e-01 0.000000000000000000 -1.242500000000000028e-02 9.156560117476597593e-01 0.000000000000000000 -1.292000000000000093e-02 9.137702868564654413e-01 0.000000000000000000 -1.341499999999999984e-02 9.136604579104798951e-01 0.000000000000000000 -1.390999999999999875e-02 9.193730244525446516e-01 0.000000000000000000 -1.440500000000000114e-02 1.714921119790818738e-01 0.000000000000000000 -1.490000000000000005e-02 5.958306785378732207e-02 0.000000000000000000 -1.539499999999999896e-02 2.440450965112313589e-02 0.000000000000000000 -1.589000000000000135e-02 1.014502025760992410e-02 0.000000000000000000 -1.638500000000000026e-02 3.961444323231197613e-03 0.000000000000000000 -1.687999999999999917e-02 1.371705764215192186e-03 0.000000000000000000 -1.737500000000000155e-02 4.818508477945342042e-04 0.000000000000000000 -1.787000000000000047e-02 4.003359027260820725e-04 0.000000000000000000 -1.836499999999999938e-02 6.802583708794605975e-04 0.000000000000000000 -1.886000000000000176e-02 1.090520635705883538e-03 0.000000000000000000 -1.935500000000000068e-02 1.511449194473834384e-03 0.000000000000000000 -1.984999999999999959e-02 1.883360414698527843e-03 0.000000000000000000 -2.034499999999999850e-02 2.179699542647192591e-03 0.000000000000000000 -2.084000000000000088e-02 2.392376676912041054e-03 0.000000000000000000 -2.133499999999999980e-02 2.523487485224354225e-03 0.000000000000000000 -2.183000000000000218e-02 2.580522661338841353e-03 0.000000000000000000 -2.232500000000000109e-02 2.573551595853644080e-03 0.000000000000000000 -2.282000000000000001e-02 2.513555729898779654e-03 0.000000000000000000 -2.331500000000000239e-02 2.411447292832342298e-03 0.000000000000000000 -2.381000000000000130e-02 2.277504382024556594e-03 0.000000000000000000 -2.430500000000000022e-02 2.121062623333965121e-03 0.000000000000000000 -2.479999999999999913e-02 1.950366520437797060e-03 0.000000000000000000 -2.529500000000000151e-02 1.772520641534203883e-03 0.000000000000000000 -2.579000000000000042e-02 1.593503070502854876e-03 0.000000000000000000 -2.628499999999999934e-02 1.418217193744504643e-03 0.000000000000000000 -2.678000000000000172e-02 1.250566384455460353e-03 0.000000000000000000 -2.727500000000000063e-02 1.093541506008351280e-03 0.000000000000000000 -2.776999999999999955e-02 9.493145850412820601e-04 0.000000000000000000 -2.826500000000000193e-02 8.193342269235605758e-04 0.000000000000000000 -2.876000000000000084e-02 7.044198053791499462e-04 0.000000000000000000 -2.925499999999999975e-02 6.048524299928025559e-04 0.000000000000000000 -2.975000000000000214e-02 5.204613533678317978e-04 0.000000000000000000 -3.024500000000000105e-02 4.507049337130127368e-04 0.000000000000000000 -3.073999999999999996e-02 3.947455887741073248e-04 0.000000000000000000 -3.123500000000000235e-02 3.515184083403329464e-04 0.000000000000000000 -3.173000000000000126e-02 3.197932640750941681e-04 0.000000000000000000 -3.222499999999999670e-02 2.982303858893446983e-04 0.000000000000000000 -3.271999999999999909e-02 2.854294756210801393e-04 0.000000000000000000 -3.321500000000000147e-02 2.799725092666949179e-04 0.000000000000000000 -3.370999999999999691e-02 2.804604435445192095e-04 0.000000000000000000 -3.420499999999999929e-02 2.855440945196244295e-04 0.000000000000000000 -3.470000000000000168e-02 2.939494976267552329e-04 0.000000000000000000 -3.519499999999999712e-02 3.044980912426223417e-04 0.000000000000000000 -3.568999999999999950e-02 3.161220910911499292e-04 0.000000000000000000 -3.618500000000000189e-02 3.278754410636460425e-04 0.000000000000000000 -3.667999999999999733e-02 3.389407381872478506e-04 0.000000000000000000 -3.717499999999999971e-02 3.486325360684768590e-04 0.000000000000000000 -3.766999999999999515e-02 3.563974327048583229e-04 0.000000000000000000 -3.816499999999999754e-02 3.618113455851717760e-04 0.000000000000000000 -3.865999999999999992e-02 3.645743699498288511e-04 0.000000000000000000 -3.915499999999999536e-02 3.645036053936043501e-04 0.000000000000000000 -3.964999999999999775e-02 3.615243220799577053e-04 0.000000000000000000 -4.014500000000000013e-02 3.556598210955979038e-04 0.000000000000000000 -4.063999999999999557e-02 3.470203242833020015e-04 0.000000000000000000 -4.113499999999999795e-02 3.357912076109730612e-04 0.000000000000000000 -4.163000000000000034e-02 3.222208691102914540e-04 0.000000000000000000 -4.212499999999999578e-02 3.066084979808539161e-04 0.000000000000000000 -4.261999999999999816e-02 2.892919859252748036e-04 0.000000000000000000 -4.311500000000000055e-02 2.706361954674823579e-04 0.000000000000000000 -4.360999999999999599e-02 2.510217732128565697e-04 0.000000000000000000 -4.410499999999999837e-02 2.308346690288415966e-04 0.000000000000000000 -4.459999999999999382e-02 2.104564952457407172e-04 0.000000000000000000 -4.509499999999999620e-02 1.902558334786057812e-04 0.000000000000000000 -4.558999999999999858e-02 1.705805708219954757e-04 0.000000000000000000 -4.608499999999999402e-02 1.517513222282850882e-04 0.000000000000000000 -4.657999999999999641e-02 1.340559720911568679e-04 0.000000000000000000 -4.707499999999999879e-02 1.177453456456203256e-04 0.000000000000000000 -4.756999999999999423e-02 1.030299999709845217e-04 0.000000000000000000 -4.806499999999999662e-02 9.007810532588240212e-05 0.000000000000000000 -4.855999999999999900e-02 7.901437041068618591e-05 0.000000000000000000 -4.905499999999999444e-02 6.991995006796396326e-05 0.000000000000000000 -4.954999999999999682e-02 6.283326099029555058e-05 0.000000000000000000 -5.004499999999999921e-02 5.775162026674022879e-05 0.000000000000000000 -5.053999999999999465e-02 5.463361309070174530e-05 0.000000000000000000 -5.103499999999999703e-02 5.340208966396771921e-05 0.000000000000000000 -5.152999999999999942e-02 5.394768722199556134e-05 0.000000000000000000 -5.202499999999999486e-02 5.613277109949464449e-05 0.000000000000000000 -5.251999999999999724e-02 5.979568874819540477e-05 0.000000000000000000 -5.301499999999999962e-02 6.475523247915131251e-05 0.000000000000000000 -5.350999999999999507e-02 7.081521027445391464e-05 0.000000000000000000 -5.400499999999999745e-02 7.776902912331245198e-05 0.000000000000000000 -5.449999999999999983e-02 8.540420179439664689e-05 0.000000000000000000 -5.499499999999999528e-02 9.350669555859472530e-05 0.000000000000000000 -5.548999999999999766e-02 1.018650499152425407e-04 0.000000000000000000 -5.598500000000000004e-02 1.102741996387353746e-04 0.000000000000000000 -5.647999999999999549e-02 1.185389492412449700e-04 0.000000000000000000 -5.697499999999999787e-02 1.264770550353150119e-04 0.000000000000000000 -5.747000000000000025e-02 1.339218811803211009e-04 0.000000000000000000 -5.796499999999999569e-02 1.407246062229117710e-04 0.000000000000000000 -5.845999999999999808e-02 1.467559665211636000e-04 0.000000000000000000 -5.895500000000000046e-02 1.519075324182569508e-04 0.000000000000000000 -5.944999999999999590e-02 1.560925219644843662e-04 0.000000000000000000 -5.994499999999999829e-02 1.592461652548708088e-04 0.000000000000000000 -6.044000000000000067e-02 1.613256399517439183e-04 0.000000000000000000 -6.093499999999999611e-02 1.623096052144035433e-04 0.000000000000000000 -6.142999999999999849e-02 1.621973669988027592e-04 0.000000000000000000 -6.192499999999999394e-02 1.610077124750920654e-04 0.000000000000000000 -6.241999999999999632e-02 1.587774551151332710e-04 0.000000000000000000 -6.291499999999999870e-02 1.555597348187712529e-04 0.000000000000000000 -6.340999999999999415e-02 1.514221192869470343e-04 0.000000000000000000 -6.390500000000000347e-02 1.464445537375784641e-04 0.000000000000000000 -6.439999999999999891e-02 1.407172060372469439e-04 0.000000000000000000 -6.489499999999999436e-02 1.343382534416530676e-04 0.000000000000000000 -6.539000000000000368e-02 1.274116554659633432e-04 0.000000000000000000 -6.588499999999999912e-02 1.200449550176506186e-04 0.000000000000000000 -6.637999999999999456e-02 1.123471469027240621e-04 0.000000000000000000 -6.687500000000000389e-02 1.044266492511661411e-04 0.000000000000000000 -6.736999999999999933e-02 9.638940939376006427e-05 0.000000000000000000 -6.786500000000000865e-02 8.833717135741299159e-05 0.000000000000000000 -6.836000000000000409e-02 8.036592752861807301e-05 0.000000000000000000 -6.885499999999999954e-02 7.256457226265916713e-05 0.000000000000000000 -6.935000000000000886e-02 6.501377038540964931e-05 0.000000000000000000 -6.984500000000000430e-02 5.778504873719187746e-05 0.000000000000000000 -7.033999999999999975e-02 5.094011423086555388e-05 0.000000000000000000 -7.083500000000000907e-02 4.453039741930946583e-05 0.000000000000000000 -7.133000000000000451e-02 3.859681636316308570e-05 0.000000000000000000 -7.182499999999999996e-02 3.316975172203380300e-05 0.000000000000000000 -7.232000000000000928e-02 2.826922051555540405e-05 0.000000000000000000 -7.281500000000000472e-02 2.390523295898025743e-05 0.000000000000000000 -7.331000000000000016e-02 2.007831420536266930e-05 0.000000000000000000 -7.380500000000000949e-02 1.678017074613669021e-05 0.000000000000000000 -7.430000000000000493e-02 1.399447964675333721e-05 0.000000000000000000 -7.479500000000000037e-02 1.169777772672906321e-05 0.000000000000000000 -7.529000000000000969e-02 9.860427226689935383e-06 0.000000000000000000 -7.578500000000000514e-02 8.447634422427182380e-06 0.000000000000000000 -7.628000000000000058e-02 7.420498022782654379e-06 0.000000000000000000 -7.677500000000000990e-02 6.737064992173760663e-06 0.000000000000000000 -7.727000000000000535e-02 6.353372630793248100e-06 0.000000000000000000 -7.776500000000000079e-02 6.224457281953143957e-06 0.000000000000000000 -7.826000000000001011e-02 6.305311867958266546e-06 0.000000000000000000 -7.875500000000000556e-02 6.551776531896834452e-06 0.000000000000000000 -7.925000000000000100e-02 6.921348928898578023e-06 0.000000000000000000 -7.974500000000001032e-02 7.373903112575820720e-06 0.000000000000000000 -8.024000000000000576e-02 7.872308446066495828e-06 0.000000000000000000 -8.073500000000000121e-02 8.382942479538479453e-06 0.000000000000000000 -8.123000000000001053e-02 8.876094226448479849e-06 0.000000000000000000 -8.172500000000000597e-02 9.326256691630531844e-06 0.000000000000000000 -8.222000000000000142e-02 9.712309811688466126e-06 0.000000000000000000 -8.271500000000001074e-02 1.001759712282525315e-05 0.000000000000000000 -8.321000000000000618e-02 1.022990143889558785e-05 0.000000000000000000 -8.370500000000000163e-02 1.034132657422960483e-05 0.000000000000000000 -8.419999999999999707e-02 1.034809365837675406e-05 0.000000000000000000 -8.469500000000000639e-02 1.025026184608369174e-05 0.000000000000000000 -8.519000000000000183e-02 1.005138421396708656e-05 0.000000000000000000 -8.568499999999999728e-02 9.758110349881624041e-06 0.000000000000000000 -8.618000000000000660e-02 9.379747581882740334e-06 0.000000000000000000 -8.667500000000000204e-02 8.927792966247648286e-06 0.000000000000000000 -8.716999999999999749e-02 8.415448068688783707e-06 0.000000000000000000 -8.766500000000000681e-02 7.857128244550779875e-06 0.000000000000000000 -8.816000000000000225e-02 7.267977571487112315e-06 0.000000000000000000 -8.865499999999999770e-02 6.663399834385784171e-06 0.000000000000000000 -8.915000000000000702e-02 6.058615032598972787e-06 0.000000000000000000 -8.964500000000000246e-02 5.468249801604943446e-06 0.000000000000000000 -9.013999999999999790e-02 4.905968944441799803e-06 0.000000000000000000 -9.063500000000000723e-02 4.384153983009630694e-06 0.000000000000000000 -9.113000000000000267e-02 3.913633296325915168e-06 0.000000000000000000 -9.162499999999999811e-02 3.503467042538443262e-06 0.000000000000000000 -9.212000000000000743e-02 3.160788693495074921e-06 0.000000000000000000 -9.261500000000000288e-02 2.890703673092192125e-06 0.000000000000000000 -9.310999999999999832e-02 2.696244309777646360e-06 0.000000000000000000 -9.360500000000000764e-02 2.578379113289906022e-06 0.000000000000000000 -9.410000000000000309e-02 2.536073287138565627e-06 0.000000000000000000 -9.459499999999999853e-02 2.566396409606154249e-06 0.000000000000000000 -9.509000000000000785e-02 2.664672371932071160e-06 0.000000000000000000 -9.558500000000000330e-02 2.824665964299255494e-06 0.000000000000000000 -9.607999999999999874e-02 3.038799956057515098e-06 0.000000000000000000 -9.657500000000000806e-02 3.298396130733936035e-06 0.000000000000000000 -9.707000000000000350e-02 3.593933509565863661e-06 0.000000000000000000 -9.756499999999999895e-02 3.915316927231527681e-06 0.000000000000000000 -9.806000000000000827e-02 4.252149204441249631e-06 0.000000000000000000 -9.855500000000000371e-02 4.594000385719410066e-06 0.000000000000000000 -9.904999999999999916e-02 4.930667865946074680e-06 0.000000000000000000 -9.954500000000000848e-02 5.252421702749102437e-06 0.000000000000000000 -1.000400000000000039e-01 5.550229988457076520e-06 0.000000000000000000 -1.005349999999999994e-01 5.815959818366009312e-06 0.000000000000000000 -1.010300000000000087e-01 6.042550123744568202e-06 0.000000000000000000 -1.015250000000000041e-01 6.224153419938869278e-06 0.000000000000000000 -1.020199999999999996e-01 6.356244333330188696e-06 0.000000000000000000 -1.025150000000000089e-01 6.435693597268485328e-06 0.000000000000000000 -1.030100000000000043e-01 6.460807028298937111e-06 0.000000000000000000 -1.035049999999999998e-01 6.431329792845432285e-06 0.000000000000000000 -1.040000000000000091e-01 6.348417034915222302e-06 0.000000000000000000 -1.044950000000000045e-01 6.214572642797414859e-06 0.000000000000000000 -1.049900000000000000e-01 6.033558574171867219e-06 0.000000000000000000 -1.054850000000000093e-01 5.810277723578255693e-06 0.000000000000000000 -1.059800000000000048e-01 5.550633794791104459e-06 0.000000000000000000 -1.064750000000000002e-01 5.261372026501575741e-06 0.000000000000000000 -1.069700000000000095e-01 4.949904908204729818e-06 0.000000000000000000 -1.074650000000000050e-01 4.624127211890433264e-06 0.000000000000000000 -1.079600000000000004e-01 4.292224753836244784e-06 0.000000000000000000 -1.084550000000000097e-01 3.962481291326354775e-06 0.000000000000000000 -1.089500000000000052e-01 3.643087855352604564e-06 0.000000000000000000 -1.094450000000000006e-01 3.341958627924044645e-06 0.000000000000000000 -1.099400000000000099e-01 3.066557198858582194e-06 0.000000000000000000 -1.104350000000000054e-01 2.823736690580863076e-06 0.000000000000000000 -1.109300000000000008e-01 2.619596830440908198e-06 0.000000000000000000 -1.114250000000000101e-01 2.459360589287039759e-06 0.000000000000000000 -1.119200000000000056e-01 2.347272504039111063e-06 0.000000000000000000 -1.124150000000000010e-01 2.286520272812265947e-06 0.000000000000000000 -1.129100000000000104e-01 2.279180665880931823e-06 0.000000000000000000 -1.134050000000000058e-01 2.326190246513927334e-06 0.000000000000000000 -1.139000000000000012e-01 2.427340854132424923e-06 0.000000000000000000 -1.143950000000000106e-01 2.581299279528182420e-06 0.000000000000000000 -1.148900000000000060e-01 2.785650068288720069e-06 0.000000000000000000 -1.153850000000000015e-01 3.036959933576395465e-06 0.000000000000000000 -1.158800000000000108e-01 3.330861851142939722e-06 0.000000000000000000 -1.163750000000000062e-01 3.662156554965000084e-06 0.000000000000000000 -1.168700000000000017e-01 4.024928856718445573e-06 0.000000000000000000 -1.173649999999999971e-01 4.412675980672368633e-06 0.000000000000000000 -1.178600000000000064e-01 4.818444940134443894e-06 0.000000000000000000 -1.183550000000000019e-01 5.234975883600831529e-06 0.000000000000000000 -1.188499999999999973e-01 5.654848307947394972e-06 0.000000000000000000 -1.193450000000000066e-01 6.070627070821400986e-06 0.000000000000000000 -1.198400000000000021e-01 6.475005231849424831e-06 0.000000000000000000 -1.203349999999999975e-01 6.860940908263738515e-06 0.000000000000000000 -1.208300000000000068e-01 7.221785539885778135e-06 0.000000000000000000 -1.213250000000000023e-01 7.551401214889840919e-06 0.000000000000000000 -1.218199999999999977e-01 7.844265004563152514e-06 0.000000000000000000 -1.223150000000000071e-01 8.095558584822332352e-06 0.000000000000000000 -1.228100000000000025e-01 8.301241776636406514e-06 0.000000000000000000 -1.233049999999999979e-01 8.458109008549570250e-06 0.000000000000000000 -1.238000000000000073e-01 8.563828083965509540e-06 0.000000000000000000 -1.242950000000000027e-01 8.616961015592759134e-06 0.000000000000000000 -1.247899999999999981e-01 8.616967061619456886e-06 0.000000000000000000 -1.252850000000000075e-01 8.564188455302446071e-06 0.000000000000000000 -1.257800000000000029e-01 8.459819654887802570e-06 0.000000000000000000 -1.262749999999999984e-01 8.305861247906351610e-06 0.000000000000000000 -1.267699999999999938e-01 8.105059917511166478e-06 0.000000000000000000 -1.272649999999999892e-01 7.860836114135193775e-06 0.000000000000000000 -1.277599999999999847e-01 7.577201269758093117e-06 0.000000000000000000 -1.282550000000000079e-01 7.258666541857485466e-06 0.000000000000000000 -1.287500000000000033e-01 6.910145178129714948e-06 0.000000000000000000 -1.292449999999999988e-01 6.536850650648383778e-06 0.000000000000000000 -1.297399999999999942e-01 6.144192719724897499e-06 0.000000000000000000 -1.302350000000000174e-01 5.737673554619307002e-06 0.000000000000000000 -1.307300000000000129e-01 5.322785962672806524e-06 0.000000000000000000 -1.312250000000000083e-01 4.904915663368263668e-06 0.000000000000000000 -1.317200000000000037e-01 4.489249393036131954e-06 0.000000000000000000 -1.322149999999999992e-01 4.080690443733145887e-06 0.000000000000000000 -1.327099999999999946e-01 3.683783031084570475e-06 0.000000000000000000 -1.332049999999999901e-01 3.302646655837594763e-06 0.000000000000000000 -1.337000000000000133e-01 2.940921378021860989e-06 0.000000000000000000 -1.341950000000000087e-01 2.601724666608497793e-06 0.000000000000000000 -1.346900000000000042e-01 2.287620227028509563e-06 0.000000000000000000 -1.351849999999999996e-01 2.000598949486405553e-06 0.000000000000000000 -1.356799999999999951e-01 1.742071867957836217e-06 0.000000000000000000 -1.361749999999999905e-01 1.512874778200590678e-06 0.000000000000000000 -1.366700000000000137e-01 1.313283937608676029e-06 0.000000000000000000 -1.371650000000000091e-01 1.143042064463222645e-06 0.000000000000000000 -1.376600000000000046e-01 1.001393672635612863e-06 0.000000000000000000 -1.381550000000000000e-01 8.871286230386589126e-07 0.000000000000000000 -1.386499999999999955e-01 7.986326473527051729e-07 0.000000000000000000 -1.391449999999999909e-01 7.339435044461783354e-07 0.000000000000000000 -1.396400000000000141e-01 6.908113662780594845e-07 0.000000000000000000 -1.401350000000000096e-01 6.667619982166363173e-07 0.000000000000000000 -1.406300000000000050e-01 6.591612980818231490e-07 0.000000000000000000 -1.411250000000000004e-01 6.652797878098401082e-07 0.000000000000000000 -1.416199999999999959e-01 6.823557096464559446e-07 0.000000000000000000 -1.421149999999999913e-01 7.076554630513800969e-07 0.000000000000000000 -1.426100000000000145e-01 7.385302262503321790e-07 0.000000000000000000 -1.431050000000000100e-01 7.724677345326453069e-07 0.000000000000000000 -1.436000000000000054e-01 8.071383324873717440e-07 0.000000000000000000 -1.440950000000000009e-01 8.404345757385826486e-07 0.000000000000000000 -1.445899999999999963e-01 8.705038255271385383e-07 0.000000000000000000 -1.450849999999999917e-01 8.957734528025810904e-07 0.000000000000000000 -1.455800000000000149e-01 9.149684434290505733e-07 0.000000000000000000 -1.460750000000000104e-01 9.271213689127427910e-07 0.000000000000000000 -1.465700000000000058e-01 9.315748540776084957e-07 0.000000000000000000 -1.470650000000000013e-01 9.279768310089414595e-07 0.000000000000000000 -1.475599999999999967e-01 9.162690142921175844e-07 0.000000000000000000 -1.480549999999999922e-01 8.966691633816720694e-07 0.000000000000000000 -1.485500000000000154e-01 8.696478115842969942e-07 0.000000000000000000 -1.490450000000000108e-01 8.359002357776614976e-07 0.000000000000000000 -1.495400000000000063e-01 7.963145152342271968e-07 0.000000000000000000 -1.500350000000000017e-01 7.519365809085332339e-07 0.000000000000000000 -1.505299999999999971e-01 7.039331878515760591e-07 0.000000000000000000 -1.510249999999999926e-01 6.535537531292294156e-07 0.000000000000000000 -1.515200000000000158e-01 6.020919902712146351e-07 0.000000000000000000 -1.520150000000000112e-01 5.508482398413202961e-07 0.000000000000000000 -1.525100000000000067e-01 5.010933455663838863e-07 0.000000000000000000 -1.530050000000000021e-01 4.540348583219919946e-07 0.000000000000000000 -1.534999999999999976e-01 4.107862681963696624e-07 0.000000000000000000 -1.539949999999999930e-01 3.723398701227520304e-07 0.000000000000000000 -1.544900000000000162e-01 3.395437636948939451e-07 0.000000000000000000 -1.549850000000000116e-01 3.130833753837486561e-07 0.000000000000000000 -1.554800000000000071e-01 2.934677741768251342e-07 0.000000000000000000 -1.559750000000000025e-01 2.810209323877752339e-07 0.000000000000000000 -1.564699999999999980e-01 2.758779647252070362e-07 0.000000000000000000 -1.569649999999999934e-01 2.779862632545462779e-07 0.000000000000000000 -1.574600000000000166e-01 2.871113360706200588e-07 0.000000000000000000 -1.579550000000000121e-01 3.028470555598597139e-07 0.000000000000000000 -1.584500000000000075e-01 3.246299300769666282e-07 0.000000000000000000 -1.589450000000000029e-01 3.517569323857624245e-07 0.000000000000000000 -1.594399999999999984e-01 3.834063507723731451e-07 0.000000000000000000 -1.599349999999999938e-01 4.186610753733210365e-07 0.000000000000000000 -1.604300000000000170e-01 4.565336937544804381e-07 0.000000000000000000 -1.609250000000000125e-01 4.959927465076154549e-07 0.000000000000000000 -1.614200000000000079e-01 5.359894856657390000e-07 0.000000000000000000 -1.619150000000000034e-01 5.754844857888850676e-07 0.000000000000000000 -1.624099999999999988e-01 6.134734790458202149e-07 0.000000000000000000 -1.629049999999999943e-01 6.490118206104414487e-07 0.000000000000000000 -1.633999999999999897e-01 6.812370380435290559e-07 0.000000000000000000 -1.638950000000000129e-01 7.093889766341250412e-07 0.000000000000000000 -1.643900000000000083e-01 7.328271203360174540e-07 0.000000000000000000 -1.648850000000000038e-01 7.510447431864785190e-07 0.000000000000000000 -1.653799999999999992e-01 7.636796270680945570e-07 0.000000000000000000 -1.658749999999999947e-01 7.705211664231386851e-07 0.000000000000000000 -1.663699999999999901e-01 7.715137670784514613e-07 0.000000000000000000 -1.668650000000000133e-01 7.667565327270775024e-07 0.000000000000000000 -1.673600000000000088e-01 7.564993169488874264e-07 0.000000000000000000 -1.678550000000000042e-01 7.411352991257035257e-07 0.000000000000000000 -1.683499999999999996e-01 7.211903175517308977e-07 0.000000000000000000 -1.688449999999999951e-01 6.973092609559167074e-07 0.000000000000000000 -1.693399999999999905e-01 6.702398792293577644e-07 0.000000000000000000 -1.698350000000000137e-01 6.408144242929899533e-07 0.000000000000000000 -1.703300000000000092e-01 6.099295718998973208e-07 0.000000000000000000 -1.708250000000000046e-01 5.785251041208233809e-07 0.000000000000000000 -1.713200000000000001e-01 5.475618499638148071e-07 0.000000000000000000 -1.718149999999999955e-01 5.179993879173844923e-07 0.000000000000000000 -1.723099999999999909e-01 4.907740093341187940e-07 0.000000000000000000 -1.728050000000000141e-01 4.667774258689090864e-07 0.000000000000000000 -1.733000000000000096e-01 4.468366782629765882e-07 0.000000000000000000 -1.737950000000000050e-01 4.316956684436242317e-07 0.000000000000000000 -1.742900000000000005e-01 4.219986931792096364e-07 0.000000000000000000 -1.747849999999999959e-01 4.182763065525390247e-07 0.000000000000000000 -1.752799999999999914e-01 4.209337815667329124e-07 0.000000000000000000 -1.757750000000000146e-01 4.302423796660925423e-07 0.000000000000000000 -1.762700000000000100e-01 4.463335722664827997e-07 0.000000000000000000 -1.767650000000000055e-01 4.691962920328160567e-07 0.000000000000000000 -1.772600000000000009e-01 4.986772250770226727e-07 0.000000000000000000 -1.777549999999999963e-01 5.344840899283003740e-07 0.000000000000000000 -1.782499999999999918e-01 5.761917864122179475e-07 0.000000000000000000 -1.787450000000000150e-01 6.232512387570358719e-07 0.000000000000000000 -1.792400000000000104e-01 6.750007035021761932e-07 0.000000000000000000 -1.797350000000000059e-01 7.306792651294629603e-07 0.000000000000000000 -1.802300000000000013e-01 7.894422016581250095e-07 0.000000000000000000 -1.807249999999999968e-01 8.503778694400008144e-07 0.000000000000000000 -1.812199999999999922e-01 9.125257315781544134e-07 0.000000000000000000 -1.817150000000000154e-01 9.748951381101131382e-07 0.000000000000000000 -1.822100000000000108e-01 1.036484458477129741e-06 0.000000000000000000 -1.827050000000000063e-01 1.096300167801006937e-06 0.000000000000000000 -1.832000000000000017e-01 1.153375497887055247e-06 0.000000000000000000 -1.836949999999999972e-01 1.206788281239166297e-06 0.000000000000000000 -1.841899999999999926e-01 1.255677641175201563e-06 0.000000000000000000 -1.846850000000000158e-01 1.299259212638049646e-06 0.000000000000000000 -1.851800000000000113e-01 1.336838615683788791e-06 0.000000000000000000 -1.856750000000000067e-01 1.367822945962577100e-06 0.000000000000000000 -1.861700000000000021e-01 1.391730092759206693e-06 0.000000000000000000 -1.866649999999999976e-01 1.408195744262683065e-06 0.000000000000000000 -1.871599999999999930e-01 1.416977990579310967e-06 0.000000000000000000 -1.876550000000000162e-01 1.417959486455905757e-06 0.000000000000000000 -1.881500000000000117e-01 1.411147186675485260e-06 0.000000000000000000 -1.886450000000000071e-01 1.396669716512313003e-06 0.000000000000000000 -1.891400000000000026e-01 1.374772486532716477e-06 0.000000000000000000 -1.896349999999999980e-01 1.345810704446789728e-06 0.000000000000000000 -1.901299999999999935e-01 1.310240475840981255e-06 0.000000000000000000 -1.906250000000000167e-01 1.268608219743216434e-06 0.000000000000000000 -1.911200000000000121e-01 1.221538653494193117e-06 0.000000000000000000 -1.916150000000000075e-01 1.169721623875224513e-06 0.000000000000000000 -1.921100000000000030e-01 1.113898077553873310e-06 0.000000000000000000 -1.926049999999999984e-01 1.054845473494751245e-06 0.000000000000000000 -1.930999999999999939e-01 9.933629429997963193e-07 0.000000000000000000 -1.935950000000000171e-01 9.302564996243403346e-07 0.000000000000000000 -1.940900000000000125e-01 8.663245915905477929e-07 0.000000000000000000 -1.945850000000000080e-01 8.023442738701147131e-07 0.000000000000000000 -1.950800000000000034e-01 7.390582563153525120e-07 0.000000000000000000 -1.955749999999999988e-01 6.771630586704946436e-07 0.000000000000000000 -1.960699999999999943e-01 6.172984736576098790e-07 0.000000000000000000 -1.965649999999999897e-01 5.600385063495729965e-07 0.000000000000000000 -1.970600000000000129e-01 5.058839225057216701e-07 0.000000000000000000 -1.975550000000000084e-01 4.552565012700060733e-07 0.000000000000000000 -1.980500000000000038e-01 4.084950494642577245e-07 0.000000000000000000 -1.985449999999999993e-01 3.658531964759427938e-07 0.000000000000000000 -1.990399999999999947e-01 3.274989512522766344e-07 0.000000000000000000 -1.995349999999999902e-01 2.935159669515498531e-07 0.000000000000000000 -2.000300000000000133e-01 2.639064250766419108e-07 0.000000000000000000 -2.005250000000000088e-01 2.385954200782702267e-07 0.000000000000000000 -2.010200000000000042e-01 2.174366980513574669e-07 0.000000000000000000 -2.015149999999999997e-01 2.002195797129620680e-07 0.000000000000000000 -2.020099999999999951e-01 1.866768787503766731e-07 0.000000000000000000 -2.025049999999999906e-01 1.764936121339090143e-07 0.000000000000000000 -2.030000000000000138e-01 1.693162892740693107e-07 0.000000000000000000 -2.034950000000000092e-01 1.647625620289037854e-07 0.000000000000000000 -2.039900000000000047e-01 1.624310175105519041e-07 0.000000000000000000 -2.044850000000000001e-01 1.619109002352719055e-07 0.000000000000000000 -2.049799999999999955e-01 1.627915591914925843e-07 0.000000000000000000 -2.054749999999999910e-01 1.646714285272923795e-07 0.000000000000000000 -2.059700000000000142e-01 1.671663673773533474e-07 0.000000000000000000 -2.064650000000000096e-01 1.699172043940377659e-07 0.000000000000000000 -2.069600000000000051e-01 1.725963552794117210e-07 0.000000000000000000 -2.074550000000000005e-01 1.749134064663755894e-07 0.000000000000000000 -2.079499999999999960e-01 1.766195844686593351e-07 0.000000000000000000 -2.084449999999999914e-01 1.775110576851685795e-07 0.000000000000000000 -2.089400000000000146e-01 1.774310449962093689e-07 0.000000000000000000 -2.094350000000000100e-01 1.762707327088914932e-07 0.000000000000000000 -2.099300000000000055e-01 1.739690277202610263e-07 0.000000000000000000 -2.104250000000000009e-01 1.705111996201750424e-07 0.000000000000000000 -2.109199999999999964e-01 1.659264873508179579e-07 0.000000000000000000 -2.114149999999999918e-01 1.602847665364869854e-07 0.000000000000000000 -2.119100000000000150e-01 1.536923913135634573e-07 0.000000000000000000 -2.124050000000000105e-01 1.462873391241233119e-07 0.000000000000000000 -2.129000000000000059e-01 1.382337982538248583e-07 0.000000000000000000 -2.133950000000000014e-01 1.297163457450835877e-07 0.000000000000000000 -2.138899999999999968e-01 1.209338676284841367e-07 0.000000000000000000 -2.143849999999999922e-01 1.120933741971231917e-07 0.000000000000000000 -2.148800000000000154e-01 1.034038603850666826e-07 0.000000000000000000 -2.153750000000000109e-01 9.507035536026284004e-08 0.000000000000000000 -2.158700000000000063e-01 8.728829643305758068e-08 0.000000000000000000 -2.163650000000000018e-01 8.023835059615854957e-08 0.000000000000000000 -2.168599999999999972e-01 7.408179279769844078e-08 0.000000000000000000 -2.173549999999999927e-01 6.895653378549319787e-08 0.000000000000000000 -2.178500000000000159e-01 6.497387246792377290e-08 0.000000000000000000 -2.183450000000000113e-01 6.221602866347468889e-08 0.000000000000000000 -2.188400000000000067e-01 6.073449231052076084e-08 0.000000000000000000 -2.193350000000000022e-01 6.054920514231316621e-08 0.000000000000000000 -2.198299999999999976e-01 6.164857096378309851e-08 0.000000000000000000 -2.203249999999999931e-01 6.399027142437959652e-08 0.000000000000000000 -2.208200000000000163e-01 6.750284598719578962e-08 0.000000000000000000 -2.213150000000000117e-01 7.208797802538331722e-08 0.000000000000000000 -2.218100000000000072e-01 7.762341397162055742e-08 0.000000000000000000 -2.223050000000000026e-01 8.396642949571979216e-08 0.000000000000000000 -2.227999999999999980e-01 9.095774602690579448e-08 0.000000000000000000 -2.232949999999999935e-01 9.842579275264869848e-08 0.000000000000000000 -2.237900000000000167e-01 1.061912036356615096e-07 0.000000000000000000 -2.242850000000000121e-01 1.140714360555606989e-07 0.000000000000000000 -2.247800000000000076e-01 1.218853974046074359e-07 0.000000000000000000 -2.252750000000000030e-01 1.294579682847766425e-07 0.000000000000000000 -2.257699999999999985e-01 1.366243157577544810e-07 0.000000000000000000 -2.262649999999999939e-01 1.432338972168728807e-07 0.000000000000000000 -2.267600000000000171e-01 1.491540646725311707e-07 0.000000000000000000 -2.272550000000000125e-01 1.542731903097046225e-07 0.000000000000000000 -2.277500000000000080e-01 1.585032468002478424e-07 0.000000000000000000 -2.282450000000000034e-01 1.617817897149352884e-07 0.000000000000000000 -2.287399999999999989e-01 1.640733041420296182e-07 0.000000000000000000 -2.292349999999999943e-01 1.653698929315150702e-07 0.000000000000000000 -2.297299999999999898e-01 1.656912994927389679e-07 0.000000000000000000 -2.302250000000000130e-01 1.650842734267576539e-07 0.000000000000000000 -2.307200000000000084e-01 1.636213021365346074e-07 0.000000000000000000 -2.312150000000000039e-01 1.613987456054476658e-07 0.000000000000000000 -2.317099999999999993e-01 1.585344244749948595e-07 0.000000000000000000 -2.322049999999999947e-01 1.551647231198324521e-07 0.000000000000000000 -2.326999999999999902e-01 1.514412793862683773e-07 0.000000000000000000 -2.331950000000000134e-01 1.475273408413232940e-07 0.000000000000000000 -2.336900000000000088e-01 1.435938736279390323e-07 0.000000000000000000 -2.341850000000000043e-01 1.398155142425697717e-07 0.000000000000000000 -2.346799999999999997e-01 1.363664566898842263e-07 0.000000000000000000 -2.351749999999999952e-01 1.334163675218042077e-07 0.000000000000000000 -2.356699999999999906e-01 1.311264192771908341e-07 0.000000000000000000 -2.361650000000000138e-01 1.296455288869103354e-07 0.000000000000000000 -2.366600000000000092e-01 1.291068818253618056e-07 0.000000000000000000 -2.371550000000000047e-01 1.296248153333861478e-07 0.000000000000000000 -2.376500000000000001e-01 1.312921251136448344e-07 0.000000000000000000 -2.381449999999999956e-01 1.341778497200433660e-07 0.000000000000000000 -2.386399999999999910e-01 1.383255756880041633e-07 0.000000000000000000 -2.391350000000000142e-01 1.437522945349044397e-07 0.000000000000000000 -2.396300000000000097e-01 1.504478303819828652e-07 0.000000000000000000 -2.401250000000000051e-01 1.583748443820877517e-07 0.000000000000000000 -2.406200000000000006e-01 1.674694096641629315e-07 0.000000000000000000 -2.411149999999999960e-01 1.776421383871583465e-07 0.000000000000000000 -2.416099999999999914e-01 1.887798309984000303e-07 0.000000000000000000 -2.421050000000000146e-01 2.007476071339980670e-07 0.000000000000000000 -2.426000000000000101e-01 2.133914680164706732e-07 0.000000000000000000 -2.430950000000000055e-01 2.265412318610952635e-07 0.000000000000000000 -2.435900000000000010e-01 2.400137768652760541e-07 0.000000000000000000 -2.440849999999999964e-01 2.536165209440037603e-07 0.000000000000000000 -2.445799999999999919e-01 2.671510635638228207e-07 0.000000000000000000 -2.450750000000000151e-01 2.804169128867386099e-07 0.000000000000000000 -2.455700000000000105e-01 2.932152209493872963e-07 0.000000000000000000 -2.460650000000000059e-01 3.053524507741491616e-07 0.000000000000000000 -2.465600000000000014e-01 3.166439020583791269e-07 0.000000000000000000 -2.470549999999999968e-01 3.269170263355468380e-07 0.000000000000000000 -2.475499999999999923e-01 3.360144681192449913e-07 0.000000000000000000 -2.480450000000000155e-01 3.437967753831660433e-07 0.000000000000000000 -2.485400000000000109e-01 3.501447306242482370e-07 0.000000000000000000 -2.490350000000000064e-01 3.549612625088479711e-07 0.000000000000000000 -2.495300000000000018e-01 3.581729075151094754e-07 0.000000000000000000 -2.500249999999999972e-01 3.597308008369024822e-07 0.000000000000000000 -2.505199999999999649e-01 3.596111858920031830e-07 0.000000000000000000 -2.510149999999999881e-01 3.578154418612221155e-07 0.000000000000000000 -2.515100000000000113e-01 3.543696385556993795e-07 0.000000000000000000 -2.520049999999999790e-01 3.493236373731821415e-07 0.000000000000000000 -2.525000000000000022e-01 3.427497659588049961e-07 0.000000000000000000 -2.529949999999999699e-01 3.347411022651280546e-07 0.000000000000000000 -2.534899999999999931e-01 3.254094108536514815e-07 0.000000000000000000 -2.539850000000000163e-01 3.148827803686610821e-07 0.000000000000000000 -2.544799999999999840e-01 3.033030160378932411e-07 0.000000000000000000 -2.549750000000000072e-01 2.908228447380034481e-07 0.000000000000000000 -2.554700000000000304e-01 2.776029925562102184e-07 0.000000000000000000 -2.559649999999999981e-01 2.638091958678441987e-07 0.000000000000000000 -2.564600000000000213e-01 2.496092067331897089e-07 0.000000000000000000 -2.569549999999999890e-01 2.351698519427563222e-07 0.000000000000000000 -2.574500000000000122e-01 2.206542023609525852e-07 0.000000000000000000 -2.579449999999999799e-01 2.062189054282013083e-07 0.000000000000000000 -2.584400000000000031e-01 1.920117288817375068e-07 0.000000000000000000 -2.589350000000000263e-01 1.781693580820991321e-07 0.000000000000000000 -2.594299999999999939e-01 1.648154829163869845e-07 0.000000000000000000 -2.599250000000000171e-01 1.520592032604092885e-07 0.000000000000000000 -2.604199999999999848e-01 1.399937745669751651e-07 0.000000000000000000 -2.609150000000000080e-01 1.286957074891519705e-07 0.000000000000000000 -2.614099999999999757e-01 1.182242277084878080e-07 0.000000000000000000 -2.619049999999999989e-01 1.086210944834820922e-07 0.000000000000000000 -2.624000000000000221e-01 9.991076902879992382e-08 0.000000000000000000 -2.628949999999999898e-01 9.210091683026240794e-08 0.000000000000000000 -2.633900000000000130e-01 8.518322153214401226e-08 0.000000000000000000 -2.638849999999999807e-01 7.913448222603720113e-08 0.000000000000000000 -2.643800000000000039e-01 7.391796093111346204e-08 0.000000000000000000 -2.648750000000000271e-01 6.948494287257691111e-08 0.000000000000000000 -2.653699999999999948e-01 6.577646890053292112e-08 0.000000000000000000 -2.658650000000000180e-01 6.272519709451340610e-08 0.000000000000000000 -2.663599999999999857e-01 6.025734928742395826e-08 0.000000000000000000 -2.668550000000000089e-01 5.829469792569614226e-08 0.000000000000000000 -2.673499999999999766e-01 5.675654932617621010e-08 0.000000000000000000 -2.678449999999999998e-01 5.556168096847991786e-08 0.000000000000000000 -2.683400000000000230e-01 5.463019290113967996e-08 0.000000000000000000 -2.688349999999999906e-01 5.388523657253900830e-08 0.000000000000000000 -2.693300000000000138e-01 5.325458832655081902e-08 0.000000000000000000 -2.698249999999999815e-01 5.267203932322533012e-08 0.000000000000000000 -2.703200000000000047e-01 5.207857864294553063e-08 0.000000000000000000 -2.708150000000000279e-01 5.142335168470370786e-08 0.000000000000000000 -2.713099999999999956e-01 5.066438154887696793e-08 0.000000000000000000 -2.718050000000000188e-01 4.976904677260103406e-08 0.000000000000000000 -2.722999999999999865e-01 4.871431443614565165e-08 0.000000000000000000 -2.727950000000000097e-01 4.748673315633127725e-08 0.000000000000000000 -2.732899999999999774e-01 4.608219571222300289e-08 0.000000000000000000 -2.737850000000000006e-01 4.450548590171156393e-08 0.000000000000000000 -2.742800000000000238e-01 4.276962860735554401e-08 0.000000000000000000 -2.747749999999999915e-01 4.089506587418590604e-08 0.000000000000000000 -2.752700000000000147e-01 3.890868499970547411e-08 0.000000000000000000 -2.757649999999999824e-01 3.684272715583101052e-08 0.000000000000000000 -2.762600000000000056e-01 3.473360686475024807e-08 0.000000000000000000 -2.767550000000000288e-01 3.262067371725050256e-08 0.000000000000000000 -2.772499999999999964e-01 3.054494804663442116e-08 0.000000000000000000 -2.777450000000000196e-01 2.854786187097238529e-08 0.000000000000000000 -2.782399999999999873e-01 2.667003531582894765e-08 0.000000000000000000 -2.787350000000000105e-01 2.495011697313786149e-08 0.000000000000000000 -2.792299999999999782e-01 2.342371430044138201e-08 0.000000000000000000 -2.797250000000000014e-01 2.212243727898790507e-08 0.000000000000000000 -2.802200000000000246e-01 2.107307521675029191e-08 0.000000000000000000 -2.807149999999999923e-01 2.029692288371895798e-08 0.000000000000000000 -2.812100000000000155e-01 1.980926819695495132e-08 0.000000000000000000 -2.817049999999999832e-01 1.961904952857326623e-08 0.000000000000000000 -2.822000000000000064e-01 1.972868648938899510e-08 0.000000000000000000 -2.826950000000000296e-01 2.013408383661252640e-08 0.000000000000000000 -2.831899999999999973e-01 2.082480407130054674e-08 0.000000000000000000 -2.836850000000000205e-01 2.178440040555468355e-08 0.000000000000000000 -2.841799999999999882e-01 2.299089818535655183e-08 0.000000000000000000 -2.846750000000000114e-01 2.441740962009672132e-08 0.000000000000000000 -2.851699999999999791e-01 2.603286386244853487e-08 0.000000000000000000 -2.856650000000000023e-01 2.780283215228305768e-08 0.000000000000000000 -2.861600000000000255e-01 2.969042593159395003e-08 0.000000000000000000 -2.866549999999999931e-01 3.165724457899208611e-08 0.000000000000000000 -2.871500000000000163e-01 3.366434872044360989e-08 0.000000000000000000 -2.876449999999999840e-01 3.567323494970259796e-08 0.000000000000000000 -2.881400000000000072e-01 3.764678822821058603e-08 0.000000000000000000 -2.886350000000000304e-01 3.955018920582269726e-08 0.000000000000000000 -2.891299999999999981e-01 4.135175518042980009e-08 0.000000000000000000 -2.896250000000000213e-01 4.302369534911431124e-08 0.000000000000000000 -2.901199999999999890e-01 4.454276334339993952e-08 0.000000000000000000 -2.906150000000000122e-01 4.589079272701187627e-08 0.000000000000000000 -2.911099999999999799e-01 4.705510409480653850e-08 0.000000000000000000 -2.916050000000000031e-01 4.802877557796328056e-08 0.000000000000000000 -2.921000000000000263e-01 4.881077185464113210e-08 0.000000000000000000 -2.925949999999999940e-01 4.940593011226651778e-08 0.000000000000000000 -2.930900000000000172e-01 4.982480473004944680e-08 0.000000000000000000 -2.935849999999999849e-01 5.008337567496295167e-08 0.000000000000000000 -2.940800000000000081e-01 5.020262866030345885e-08 0.000000000000000000 -2.945749999999999758e-01 5.020801793871705487e-08 0.000000000000000000 -2.950699999999999990e-01 5.012882513116714697e-08 0.000000000000000000 -2.955650000000000222e-01 4.999742968030015832e-08 0.000000000000000000 -2.960599999999999898e-01 4.984850831805449965e-08 0.000000000000000000 -2.965550000000000130e-01 4.971818231968933293e-08 0.000000000000000000 -2.970499999999999807e-01 4.964313225808193827e-08 0.000000000000000000 -2.975450000000000039e-01 4.965970045832412095e-08 0.000000000000000000 -2.980400000000000271e-01 4.980300138338575625e-08 0.000000000000000000 -2.985349999999999948e-01 5.010605976225426768e-08 0.000000000000000000 -2.990300000000000180e-01 5.059899542092764685e-08 0.000000000000000000 -2.995249999999999857e-01 5.130827252084771200e-08 0.000000000000000000 -3.000200000000000089e-01 5.225602928235692504e-08 0.000000000000000000 -3.005149999999999766e-01 5.345950231690924802e-08 0.000000000000000000 -3.010099999999999998e-01 5.493055745788405302e-08 0.000000000000000000 -3.015050000000000230e-01 5.667533652106124858e-08 0.000000000000000000 -3.019999999999999907e-01 5.869402679821528632e-08 0.000000000000000000 -3.024950000000000139e-01 6.098075735608050194e-08 0.000000000000000000 -3.029899999999999816e-01 6.352362343093326867e-08 0.000000000000000000 -3.034850000000000048e-01 6.630483744636865637e-08 0.000000000000000000 -3.039800000000000280e-01 6.930100249350715044e-08 0.000000000000000000 -3.044749999999999956e-01 7.248350155561192896e-08 0.000000000000000000 -3.049700000000000188e-01 7.581899338879230494e-08 0.000000000000000000 -3.054649999999999865e-01 7.927000383111037433e-08 0.000000000000000000 -3.059600000000000097e-01 8.279559944983727826e-08 0.000000000000000000 -3.064549999999999774e-01 8.635212888352076323e-08 0.000000000000000000 -3.069500000000000006e-01 8.989401601773107563e-08 0.000000000000000000 -3.074450000000000238e-01 9.337458827772847315e-08 0.000000000000000000 -3.079399999999999915e-01 9.674692283012004946e-08 0.000000000000000000 -3.084350000000000147e-01 9.996469336922015975e-08 0.000000000000000000 -3.089299999999999824e-01 1.029830004167963952e-07 0.000000000000000000 -3.094250000000000056e-01 1.057591686681371154e-07 0.000000000000000000 -3.099200000000000288e-01 1.082534958638745486e-07 0.000000000000000000 -3.104149999999999965e-01 1.104299389148882970e-07 0.000000000000000000 -3.109100000000000197e-01 1.122567245390141693e-07 0.000000000000000000 -3.114049999999999874e-01 1.137068734326969240e-07 0.000000000000000000 -3.119000000000000106e-01 1.147586289641110085e-07 0.000000000000000000 -3.123949999999999783e-01 1.153957834868586861e-07 0.000000000000000000 -3.128900000000000015e-01 1.156078975877370465e-07 0.000000000000000000 -3.133850000000000247e-01 1.153904098518046454e-07 0.000000000000000000 -3.138799999999999923e-01 1.147446369987451798e-07 0.000000000000000000 -3.143750000000000155e-01 1.136776664746141729e-07 0.000000000000000000 -3.148699999999999832e-01 1.122021457208702330e-07 0.000000000000000000 -3.153650000000000064e-01 1.103359743456424890e-07 0.000000000000000000 -3.158600000000000296e-01 1.081019072565954537e-07 0.000000000000000000 -3.163549999999999973e-01 1.055270784362617595e-07 0.000000000000000000 -3.168500000000000205e-01 1.026424564278367652e-07 0.000000000000000000 -3.173449999999999882e-01 9.948224372407782834e-08 0.000000000000000000 -3.178400000000000114e-01 9.608323309787939415e-08 0.000000000000000000 -3.183349999999999791e-01 9.248413446691503307e-08 0.000000000000000000 -3.188300000000000023e-01 8.872488614524009637e-08 0.000000000000000000 -3.193250000000000255e-01 8.484596429947868206e-08 0.000000000000000000 -3.198199999999999932e-01 8.088770410537438045e-08 0.000000000000000000 -3.203150000000000164e-01 7.688964550851964941e-08 0.000000000000000000 -3.208099999999999841e-01 7.288991564335235635e-08 0.000000000000000000 -3.213050000000000073e-01 6.892465889020185596e-08 0.000000000000000000 -3.217999999999999750e-01 6.502752427176795239e-08 0.000000000000000000 -3.222949999999999982e-01 6.122921844363642630e-08 0.000000000000000000 -3.227900000000000214e-01 5.755713095539548577e-08 0.000000000000000000 -3.232849999999999890e-01 5.403503677983761710e-08 0.000000000000000000 -3.237800000000000122e-01 5.068287937419286739e-08 0.000000000000000000 -3.242749999999999799e-01 4.751663578026204217e-08 0.000000000000000000 -3.247700000000000031e-01 4.454826353184982771e-08 0.000000000000000000 -3.252650000000000263e-01 4.178572745536348647e-08 0.000000000000000000 -3.257599999999999940e-01 3.923310285127587169e-08 0.000000000000000000 -3.262550000000000172e-01 3.689075007132369693e-08 0.000000000000000000 -3.267499999999999849e-01 3.475555417812694628e-08 0.000000000000000000 -3.272450000000000081e-01 3.282122222138029072e-08 0.000000000000000000 -3.277399999999999758e-01 3.107862970302026735e-08 0.000000000000000000 -3.282349999999999990e-01 2.951620705340836634e-08 0.000000000000000000 -3.287300000000000222e-01 2.812035640469401585e-08 0.000000000000000000 -3.292249999999999899e-01 2.687588864140881645e-08 0.000000000000000000 -3.297200000000000131e-01 2.576647062086454076e-08 0.000000000000000000 -3.302149999999999808e-01 2.477507259379541267e-08 0.000000000000000000 -3.307100000000000040e-01 2.388440620186704369e-08 0.000000000000000000 -3.312050000000000272e-01 2.307734397242664822e-08 0.000000000000000000 -3.316999999999999948e-01 2.233731195651392766e-08 0.000000000000000000 -3.321950000000000180e-01 2.164864803928930012e-08 0.000000000000000000 -3.326899999999999857e-01 2.099691947188361994e-08 0.000000000000000000 -3.331850000000000089e-01 2.036919430201140482e-08 0.000000000000000000 -3.336799999999999766e-01 1.975426259152155132e-08 0.000000000000000000 -3.341749999999999998e-01 1.914280457142530912e-08 0.000000000000000000 -3.346700000000000230e-01 1.852750417149897549e-08 0.000000000000000000 -3.351649999999999907e-01 1.790310764230426592e-08 0.000000000000000000 -3.356600000000000139e-01 1.726642823396807068e-08 0.000000000000000000 -3.361549999999999816e-01 1.661629908279854995e-08 0.000000000000000000 -3.366500000000000048e-01 1.595347755869347287e-08 0.000000000000000000 -3.371450000000000280e-01 1.528050531973779909e-08 0.000000000000000000 -3.376399999999999957e-01 1.460152919013509477e-08 0.000000000000000000 -3.381350000000000189e-01 1.392208870259843802e-08 0.000000000000000000 -3.386299999999999866e-01 1.324887671956536469e-08 0.000000000000000000 -3.391250000000000098e-01 1.258947995626008243e-08 0.000000000000000000 -3.396199999999999775e-01 1.195210647101936588e-08 0.000000000000000000 -3.401150000000000007e-01 1.134530726171616917e-08 0.000000000000000000 -3.406100000000000239e-01 1.077769901589524886e-08 0.000000000000000000 -3.411049999999999915e-01 1.025769481133655026e-08 0.000000000000000000 -3.416000000000000147e-01 9.793249165186949612e-09 0.000000000000000000 -3.420949999999999824e-01 9.391623293917409771e-09 0.000000000000000000 -3.425900000000000056e-01 9.059175792067207276e-09 0.000000000000000000 -3.430850000000000288e-01 8.801183179381491931e-09 0.000000000000000000 -3.435799999999999965e-01 8.621693927028023361e-09 0.000000000000000000 -3.440750000000000197e-01 8.523418672149286122e-09 0.000000000000000000 -3.445699999999999874e-01 8.507658389987899617e-09 0.000000000000000000 -3.450650000000000106e-01 8.574271336865750805e-09 0.000000000000000000 -3.455599999999999783e-01 8.721678624791400757e-09 0.000000000000000000 -3.460550000000000015e-01 8.946907365361574522e-09 0.000000000000000000 -3.465500000000000247e-01 9.245669442817675334e-09 0.000000000000000000 -3.470449999999999924e-01 9.612473166232856799e-09 0.000000000000000000 -3.475400000000000156e-01 1.004076432306006305e-08 0.000000000000000000 -3.480349999999999833e-01 1.052309252713271758e-08 0.000000000000000000 -3.485300000000000065e-01 1.105129823396793024e-08 0.000000000000000000 -3.490250000000000297e-01 1.161671539729180009e-08 0.000000000000000000 -3.495199999999999974e-01 1.221038446536266215e-08 0.000000000000000000 -3.500150000000000206e-01 1.282327027100933641e-08 0.000000000000000000 -3.505099999999999882e-01 1.344647935416390465e-08 0.000000000000000000 -3.510050000000000114e-01 1.407147136811586052e-08 0.000000000000000000 -3.514999999999999791e-01 1.469025945369796586e-08 0.000000000000000000 -3.519950000000000023e-01 1.529559481573492077e-08 0.000000000000000000 -3.524900000000000255e-01 1.588113118730360861e-08 0.000000000000000000 -3.529849999999999932e-01 1.644156541118762740e-08 0.000000000000000000 -3.534800000000000164e-01 1.697275098992543236e-08 0.000000000000000000 -3.539749999999999841e-01 1.747178213761023576e-08 0.000000000000000000 -3.544700000000000073e-01 1.793704659545164024e-08 0.000000000000000000 -3.549649999999999750e-01 1.836824622744469649e-08 0.000000000000000000 -3.554599999999999982e-01 1.876638517907206361e-08 0.000000000000000000 -3.559550000000000214e-01 1.913372613876507314e-08 0.000000000000000000 -3.564499999999999891e-01 1.947371597602423778e-08 0.000000000000000000 -3.569450000000000123e-01 1.979088272266642200e-08 0.000000000000000000 -3.574399999999999800e-01 2.009070650087254166e-08 0.000000000000000000 -3.579350000000000032e-01 2.037946757103567218e-08 0.000000000000000000 -3.584300000000000264e-01 2.066407515964299919e-08 0.000000000000000000 -3.589249999999999940e-01 2.095188112733686151e-08 0.000000000000000000 -3.594200000000000172e-01 2.125048283744856414e-08 0.000000000000000000 -3.599149999999999849e-01 2.156751978501948854e-08 0.000000000000000000 -3.604100000000000081e-01 2.191046864075705769e-08 0.000000000000000000 -3.609049999999999758e-01 2.228644135279893046e-08 0.000000000000000000 -3.613999999999999990e-01 2.270199083563226480e-08 0.000000000000000000 -3.618950000000000222e-01 2.316292856262320288e-08 0.000000000000000000 -3.623899999999999899e-01 2.367415807203139547e-08 0.000000000000000000 -3.628850000000000131e-01 2.423952800857445738e-08 0.000000000000000000 -3.633799999999999808e-01 2.486170785652935833e-08 0.000000000000000000 -3.638750000000000040e-01 2.554208899546158417e-08 0.000000000000000000 -3.643700000000000272e-01 2.628071313179934573e-08 0.000000000000000000 -3.648649999999999949e-01 2.707622954598928570e-08 0.000000000000000000 -3.653600000000000181e-01 2.792588195901891497e-08 0.000000000000000000 -3.658549999999999858e-01 2.882552517708983040e-08 0.000000000000000000 -3.663500000000000090e-01 2.976967103447278733e-08 0.000000000000000000 -3.668449999999999767e-01 3.075156253477281760e-08 0.000000000000000000 -3.673399999999999999e-01 3.176327450413345569e-08 0.000000000000000000 -3.678350000000000231e-01 3.279583852824928444e-08 0.000000000000000000 -3.683299999999999907e-01 3.383938945731988208e-08 0.000000000000000000 -3.688250000000000139e-01 3.488333034306978554e-08 0.000000000000000000 -3.693199999999999816e-01 3.591651232336546174e-08 0.000000000000000000 -3.698150000000000048e-01 3.692742570031571376e-08 0.000000000000000000 -3.703100000000000280e-01 3.790439827374823150e-08 0.000000000000000000 -3.708049999999999957e-01 3.883579689160558677e-08 0.000000000000000000 -3.713000000000000189e-01 3.971022816674681611e-08 0.000000000000000000 -3.717949999999999866e-01 4.051673438306160370e-08 0.000000000000000000 -3.722900000000000098e-01 4.124498076717833711e-08 0.000000000000000000 -3.727849999999999775e-01 4.188543053599052995e-08 0.000000000000000000 -3.732800000000000007e-01 4.242950443301410598e-08 0.000000000000000000 -3.737750000000000239e-01 4.286972183235922621e-08 0.000000000000000000 -3.742699999999999916e-01 4.319982091058997701e-08 0.000000000000000000 -3.747650000000000148e-01 4.341485585106263247e-08 0.000000000000000000 -3.752599999999999825e-01 4.351126954364792197e-08 0.000000000000000000 -3.757550000000000057e-01 4.348694076337917760e-08 0.000000000000000000 -3.762500000000000289e-01 4.334120534276358832e-08 0.000000000000000000 -3.767449999999999966e-01 4.307485138322552084e-08 0.000000000000000000 -3.772400000000000198e-01 4.269008907044460582e-08 0.000000000000000000 -3.777349999999999874e-01 4.219049615455987723e-08 0.000000000000000000 -3.782300000000000106e-01 4.158094062024585214e-08 0.000000000000000000 -3.787249999999999783e-01 4.086748249469892492e-08 0.000000000000000000 -3.792200000000000015e-01 4.005725711405962215e-08 0.000000000000000000 -3.797150000000000247e-01 3.915834248677704539e-08 0.000000000000000000 -3.802099999999999924e-01 3.817961364641245335e-08 0.000000000000000000 -3.807050000000000156e-01 3.713058707749278197e-08 0.000000000000000000 -3.811999999999999833e-01 3.602125841936853833e-08 0.000000000000000000 -3.816950000000000065e-01 3.486193670539177112e-08 0.000000000000000000 -3.821900000000000297e-01 3.366307838024691399e-08 0.000000000000000000 -3.826849999999999974e-01 3.243512425532141799e-08 0.000000000000000000 -3.831800000000000206e-01 3.118834241748837597e-08 0.000000000000000000 -3.836749999999999883e-01 2.993267990292510549e-08 0.000000000000000000 -3.841700000000000115e-01 2.867762569123941143e-08 0.000000000000000000 -3.846649999999999792e-01 2.743208727305183217e-08 0.000000000000000000 -3.851600000000000024e-01 2.620428270345172217e-08 0.000000000000000000 -3.856550000000000256e-01 2.500164968300175967e-08 0.000000000000000000 -3.861499999999999932e-01 2.383077281516078181e-08 0.000000000000000000 -3.866450000000000164e-01 2.269732978374304613e-08 0.000000000000000000 -3.871399999999999841e-01 2.160605678563854971e-08 0.000000000000000000 -3.876350000000000073e-01 2.056073314903509522e-08 0.000000000000000000 -3.881299999999999750e-01 1.956418467742543376e-08 0.000000000000000000 -3.886249999999999982e-01 1.861830489030515331e-08 0.000000000000000000 -3.891200000000000214e-01 1.772409299071463983e-08 0.000000000000000000 -3.896149999999999891e-01 1.688170708422905335e-08 0.000000000000000000 -3.901100000000000123e-01 1.609053090956924816e-08 0.000000000000000000 -3.906049999999999800e-01 1.534925212084473633e-08 0.000000000000000000 -3.911000000000000032e-01 1.465594999061976486e-08 0.000000000000000000 -3.915950000000000264e-01 1.400819028276227887e-08 0.000000000000000000 -3.920899999999999941e-01 1.340312497558415398e-08 0.000000000000000000 -3.925850000000000173e-01 1.283759450004609082e-08 0.000000000000000000 -3.930799999999999850e-01 1.230823019163286365e-08 0.000000000000000000 -3.935750000000000082e-01 1.181155473798613268e-08 0.000000000000000000 -3.940699999999999759e-01 1.134407853276911474e-08 0.000000000000000000 -3.945649999999999991e-01 1.090239001545729004e-08 0.000000000000000000 -3.950600000000000223e-01 1.048323828301218696e-08 0.000000000000000000 -3.955549999999999899e-01 1.008360649539456917e-08 0.000000000000000000 -3.960500000000000131e-01 9.700774858472852878e-09 0.000000000000000000 -3.965449999999999808e-01 9.332372246622308054e-09 0.000000000000000000 -3.970400000000000040e-01 8.976415818174406079e-09 0.000000000000000000 -3.975350000000000272e-01 8.631338272437599152e-09 0.000000000000000000 -3.980299999999999949e-01 8.296002689667833716e-09 0.000000000000000000 -3.985250000000000181e-01 7.969705181024683436e-09 0.000000000000000000 -3.990199999999999858e-01 7.652165845375051603e-09 0.000000000000000000 -3.995150000000000090e-01 7.343508780417073927e-09 0.000000000000000000 -4.000099999999999767e-01 7.044232120494151201e-09 0.000000000000000000 -4.005049999999999999e-01 6.755169269409685663e-09 0.000000000000000000 -4.010000000000000231e-01 6.477442659479981512e-09 0.000000000000000000 -4.014949999999999908e-01 6.212411494797449313e-09 0.000000000000000000 -4.019900000000000140e-01 5.961615027059779816e-09 0.000000000000000000 -4.024849999999999817e-01 5.726712963250029767e-09 0.000000000000000000 -4.029800000000000049e-01 5.509424617239932481e-09 0.000000000000000000 -4.034750000000000281e-01 5.311468393076287309e-09 0.000000000000000000 -4.039699999999999958e-01 5.134503126165067520e-09 0.000000000000000000 -4.044650000000000190e-01 4.980072714861337590e-09 0.000000000000000000 -4.049599999999999866e-01 4.849555349235844055e-09 0.000000000000000000 -4.054550000000000098e-01 4.744118492205433960e-09 0.000000000000000000 -4.059499999999999775e-01 4.664680593739816733e-09 0.000000000000000000 -4.064450000000000007e-01 4.611880325831865455e-09 0.000000000000000000 -4.069400000000000239e-01 4.586053920308072653e-09 0.000000000000000000 -4.074349999999999916e-01 4.587220977924695275e-09 0.000000000000000000 -4.079300000000000148e-01 4.615078899378049320e-09 0.000000000000000000 -4.084249999999999825e-01 4.669005875256890160e-09 0.000000000000000000 -4.089200000000000057e-01 4.748072163309128833e-09 0.000000000000000000 -4.094150000000000289e-01 4.851059185191857083e-09 0.000000000000000000 -4.099099999999999966e-01 4.976485794904445368e-09 0.000000000000000000 -4.104050000000000198e-01 5.122640910039118327e-09 0.000000000000000000 -4.108999999999999875e-01 5.287621558921616948e-09 0.000000000000000000 -4.113950000000000107e-01 5.469375284613462609e-09 0.000000000000000000 -4.118899999999999784e-01 5.665745761639552971e-09 0.000000000000000000 -4.123850000000000016e-01 5.874520425188240073e-09 0.000000000000000000 -4.128800000000000248e-01 6.093478886063645317e-09 0.000000000000000000 -4.133749999999999925e-01 6.320440907901102260e-09 0.000000000000000000 -4.138700000000000156e-01 6.553312753988550385e-09 0.000000000000000000 -4.143649999999999833e-01 6.790130771367156588e-09 0.000000000000000000 -4.148600000000000065e-01 7.029101163410273193e-09 0.000000000000000000 -4.153550000000000297e-01 7.268635010600130017e-09 0.000000000000000000 -4.158499999999999974e-01 7.507377726671668201e-09 0.000000000000000000 -4.163450000000000206e-01 7.744232281709863047e-09 0.000000000000000000 -4.168399999999999883e-01 7.978375682144205689e-09 0.000000000000000000 -4.173350000000000115e-01 8.209268363850622799e-09 0.000000000000000000 -4.178299999999999792e-01 8.436656327499291240e-09 0.000000000000000000 -4.183250000000000024e-01 8.660566018637588098e-09 0.000000000000000000 -4.188200000000000256e-01 8.881292125676694436e-09 0.000000000000000000 -4.193149999999999933e-01 9.099378633848062782e-09 0.000000000000000000 -4.198100000000000165e-01 9.315593626627259896e-09 0.000000000000000000 -4.203049999999999842e-01 9.530898467515246062e-09 0.000000000000000000 -4.208000000000000074e-01 9.746412118950913698e-09 0.000000000000000000 -4.212949999999999751e-01 9.963371460286649087e-09 0.000000000000000000 -4.217899999999999983e-01 1.018308855181658974e-08 0.000000000000000000 -4.222850000000000215e-01 1.040690585266617756e-08 0.000000000000000000 -4.227799999999999891e-01 1.063615043926497002e-08 0.000000000000000000 -4.232750000000000123e-01 1.087208828519019441e-08 0.000000000000000000 -4.237699999999999800e-01 1.111587965289071394e-08 0.000000000000000000 -4.242650000000000032e-01 1.136853661583180541e-08 0.000000000000000000 -4.247600000000000264e-01 1.163088367279463618e-08 0.000000000000000000 -4.252549999999999941e-01 1.190352234130271635e-08 0.000000000000000000 -4.257500000000000173e-01 1.218680052197535278e-08 0.000000000000000000 -4.262449999999999850e-01 1.248078731469023245e-08 0.000000000000000000 -4.267400000000000082e-01 1.278525384311730212e-08 0.000000000000000000 -4.272349999999999759e-01 1.309966050910587465e-08 0.000000000000000000 -4.277299999999999991e-01 1.342315095589872567e-08 0.000000000000000000 -4.282250000000000223e-01 1.375455287205582836e-08 0.000000000000000000 -4.287199999999999900e-01 1.409238562079113363e-08 0.000000000000000000 -4.292150000000000132e-01 1.443487453314645187e-08 0.000000000000000000 -4.297099999999999809e-01 1.477997156373545718e-08 0.000000000000000000 -4.302050000000000041e-01 1.512538187580669995e-08 0.000000000000000000 -4.307000000000000273e-01 1.546859580133828023e-08 0.000000000000000000 -4.311949999999999950e-01 1.580692551463737943e-08 0.000000000000000000 -4.316900000000000182e-01 1.613754566577390438e-08 0.000000000000000000 -4.321849999999999858e-01 1.645753714599011433e-08 0.000000000000000000 -4.326800000000000090e-01 1.676393310002758873e-08 0.000000000000000000 -4.331749999999999767e-01 1.705376626490258598e-08 0.000000000000000000 -4.336699999999999999e-01 1.732411669653720288e-08 0.000000000000000000 -4.341650000000000231e-01 1.757215894925126622e-08 0.000000000000000000 -4.346599999999999908e-01 1.779520779548350610e-08 0.000000000000000000 -4.351550000000000140e-01 1.799076161362543704e-08 0.000000000000000000 -4.356499999999999817e-01 1.815654263086063115e-08 0.000000000000000000 -4.361450000000000049e-01 1.829053328157484957e-08 0.000000000000000000 -4.366400000000000281e-01 1.839100803044917176e-08 0.000000000000000000 -4.371349999999999958e-01 1.845656010927652435e-08 0.000000000000000000 -4.376300000000000190e-01 1.848612272608700538e-08 0.000000000000000000 -4.381249999999999867e-01 1.847898442161774779e-08 0.000000000000000000 -4.386200000000000099e-01 1.843479836949822567e-08 0.000000000000000000 -4.391149999999999776e-01 1.835358553896912584e-08 0.000000000000000000 -4.396100000000000008e-01 1.823573176129404449e-08 0.000000000000000000 -4.401050000000000240e-01 1.808197885939603732e-08 0.000000000000000000 -4.405999999999999917e-01 1.789341011348342798e-08 0.000000000000000000 -4.410950000000000149e-01 1.767143044023607812e-08 0.000000000000000000 -4.415899999999999825e-01 1.741774175811971450e-08 0.000000000000000000 -4.420850000000000057e-01 1.713431409473244335e-08 0.000000000000000000 -4.425800000000000289e-01 1.682335306189678160e-08 0.000000000000000000 -4.430749999999999966e-01 1.648726438020696314e-08 0.000000000000000000 -4.435700000000000198e-01 1.612861617500588260e-08 0.000000000000000000 -4.440649999999999875e-01 1.575009979047387784e-08 0.000000000000000000 -4.445600000000000107e-01 1.535448987805421877e-08 0.000000000000000000 -4.450549999999999784e-01 1.494460450820156242e-08 0.000000000000000000 -4.455500000000000016e-01 1.452326603333806454e-08 0.000000000000000000 -4.460450000000000248e-01 1.409326339387842717e-08 0.000000000000000000 -4.465399999999999925e-01 1.365731651025635248e-08 0.000000000000000000 -4.470350000000000157e-01 1.321804334286182776e-08 0.000000000000000000 -4.475299999999999834e-01 1.277793013177696666e-08 0.000000000000000000 -4.480250000000000066e-01 1.233930524775555563e-08 0.000000000000000000 -4.485200000000000298e-01 1.190431700117814050e-08 0.000000000000000000 -4.490149999999999975e-01 1.147491566480354247e-08 0.000000000000000000 -4.495100000000000207e-01 1.105283987343516414e-08 0.000000000000000000 -4.500049999999999883e-01 1.063960747044149186e-08 0.000000000000000000 -4.505000000000000115e-01 1.023651077918770782e-08 0.000000000000000000 -4.509949999999999792e-01 9.844616188803198748e-09 0.000000000000000000 -4.514900000000000024e-01 9.464767861106116008e-09 0.000000000000000000 -4.519850000000000256e-01 9.097595288108603557e-09 0.000000000000000000 -4.524799999999999933e-01 8.743524362105601483e-09 0.000000000000000000 -4.529750000000000165e-01 8.402791560871834732e-09 0.000000000000000000 -4.534699999999999842e-01 8.075460802443148244e-09 0.000000000000000000 -4.539650000000000074e-01 7.761442486046111164e-09 0.000000000000000000 -4.544599999999999751e-01 7.460514210424042824e-09 0.000000000000000000 -4.549549999999999983e-01 7.172342646170907000e-09 0.000000000000000000 -4.554500000000000215e-01 6.896506036714323153e-09 0.000000000000000000 -4.559449999999999892e-01 6.632516811281122672e-09 0.000000000000000000 -4.564400000000000124e-01 6.379843812657275924e-09 0.000000000000000000 -4.569349999999999801e-01 6.137933673162139564e-09 0.000000000000000000 -4.574300000000000033e-01 5.906230910290281566e-09 0.000000000000000000 -4.579250000000000265e-01 5.684196360615556579e-09 0.000000000000000000 -4.584199999999999942e-01 5.471323624331185598e-09 0.000000000000000000 -4.589150000000000174e-01 5.267153250837432023e-09 0.000000000000000000 -4.594099999999999850e-01 5.071284459126574927e-09 0.000000000000000000 -4.599050000000000082e-01 4.883384250931931307e-09 0.000000000000000000 -4.603999999999999759e-01 4.703193840668581048e-09 0.000000000000000000 -4.608949999999999991e-01 4.530532390899307624e-09 0.000000000000000000 -4.613900000000000223e-01 4.365298105153216542e-09 0.000000000000000000 -4.618849999999999900e-01 4.207466789022336332e-09 0.000000000000000000 -4.623800000000000132e-01 4.057088045494296224e-09 0.000000000000000000 -4.628749999999999809e-01 3.914279319195624469e-09 0.000000000000000000 -4.633700000000000041e-01 3.779218046709925823e-09 0.000000000000000000 -4.638650000000000273e-01 3.652132205013703572e-09 0.000000000000000000 -4.643599999999999950e-01 3.533289576706884067e-09 0.000000000000000000 -4.648550000000000182e-01 3.422986069808274892e-09 0.000000000000000000 -4.653499999999999859e-01 3.321533439416051253e-09 0.000000000000000000 -4.658450000000000091e-01 3.229246760435336710e-09 0.000000000000000000 -4.663399999999999768e-01 3.146431993994970754e-09 0.000000000000000000 -4.668350000000000000e-01 3.073373975345013034e-09 0.000000000000000000 -4.673300000000000232e-01 3.010325129642277786e-09 0.000000000000000000 -4.678249999999999909e-01 2.957495193257146136e-09 0.000000000000000000 -4.683200000000000141e-01 2.915042184678358687e-09 0.000000000000000000 -4.688149999999999817e-01 2.883064829842742190e-09 0.000000000000000000 -4.693100000000000049e-01 2.861596604193283212e-09 0.000000000000000000 -4.698050000000000281e-01 2.850601508972300431e-09 0.000000000000000000 -4.702999999999999958e-01 2.849971651914613278e-09 0.000000000000000000 -4.707950000000000190e-01 2.859526656006997309e-09 0.000000000000000000 -4.712899999999999867e-01 2.879014873141595932e-09 0.000000000000000000 -4.717850000000000099e-01 2.908116335166235172e-09 0.000000000000000000 -4.722799999999999776e-01 2.946447332886401864e-09 0.000000000000000000 -4.727750000000000008e-01 2.993566475442111645e-09 0.000000000000000000 -4.732700000000000240e-01 3.048982048894810377e-09 0.000000000000000000 -4.737649999999999917e-01 3.112160464332474383e-09 0.000000000000000000 -4.742600000000000149e-01 3.182535562880660334e-09 0.000000000000000000 -4.747549999999999826e-01 3.259518528611297958e-09 0.000000000000000000 -4.752500000000000058e-01 3.342508149576631695e-09 0.000000000000000000 -4.757450000000000290e-01 3.430901163840657496e-09 0.000000000000000000 -4.762399999999999967e-01 3.524102429278429806e-09 0.000000000000000000 -4.767350000000000199e-01 3.621534665102449216e-09 0.000000000000000000 -4.772299999999999875e-01 3.722647527460664005e-09 0.000000000000000000 -4.777250000000000107e-01 3.826925801322355374e-09 0.000000000000000000 -4.782199999999999784e-01 3.933896515816877786e-09 0.000000000000000000 -4.787150000000000016e-01 4.043134819189915393e-09 0.000000000000000000 -4.792100000000000248e-01 4.154268481635412397e-09 0.000000000000000000 -4.797049999999999925e-01 4.266980929593508030e-09 0.000000000000000000 -4.802000000000000157e-01 4.381012751424321055e-09 0.000000000000000000 -4.806949999999999834e-01 4.496161652199732591e-09 0.000000000000000000 -4.811900000000000066e-01 4.612280872640621975e-09 0.000000000000000000 -4.816849999999999743e-01 4.729276124038926593e-09 0.000000000000000000 -4.821799999999999975e-01 4.847101125726263636e-09 0.000000000000000000 -4.826750000000000207e-01 4.965751864300368648e-09 0.000000000000000000 -4.831699999999999884e-01 5.085259722846209651e-09 0.000000000000000000 -4.836650000000000116e-01 5.205683653909438055e-09 0.000000000000000000 -4.841599999999999793e-01 5.327101591364630244e-09 0.000000000000000000 -4.846550000000000025e-01 5.449601312131226840e-09 0.000000000000000000 -4.851500000000000257e-01 5.573270970900816755e-09 0.000000000000000000 -4.856449999999999934e-01 5.698189536512434654e-09 0.000000000000000000 -4.861400000000000166e-01 5.824417359925500247e-09 0.000000000000000000 -4.866349999999999842e-01 5.951987099613675371e-09 0.000000000000000000 -4.871300000000000074e-01 6.080895220433315428e-09 0.000000000000000000 -4.876249999999999751e-01 6.211094268638991865e-09 0.000000000000000000 -4.881199999999999983e-01 6.342486106845018088e-09 0.000000000000000000 -4.886150000000000215e-01 6.474916270754308835e-09 0.000000000000000000 -4.891099999999999892e-01 6.608169583862010463e-09 0.000000000000000000 -4.896050000000000124e-01 6.741967137986912580e-09 0.000000000000000000 -4.900999999999999801e-01 6.875964717127975807e-09 0.000000000000000000 -4.905950000000000033e-01 7.009752710491016055e-09 0.000000000000000000 -4.910900000000000265e-01 7.142857528022041833e-09 0.000000000000000000 -4.915849999999999942e-01 7.274744499695702001e-09 0.000000000000000000 -4.920800000000000174e-01 7.404822208039219847e-09 0.000000000000000000 -4.925749999999999851e-01 7.532448173396777785e-09 0.000000000000000000 -4.930700000000000083e-01 7.656935783228315582e-09 0.000000000000000000 -4.935649999999999760e-01 7.777562331712137321e-09 0.000000000000000000 -4.940599999999999992e-01 7.893578012955520028e-09 0.000000000000000000 -4.945550000000000224e-01 8.004215693228740211e-09 0.000000000000000000 -4.950499999999999901e-01 8.108701272028350674e-09 0.000000000000000000 -4.955450000000000133e-01 8.206264431718087464e-09 0.000000000000000000 -4.960399999999999809e-01 8.296149568706190762e-09 0.000000000000000000 -4.965350000000000041e-01 8.377626697440333365e-09 0.000000000000000000 -4.970300000000000273e-01 8.450002120679014276e-09 0.000000000000000000 -4.975249999999999950e-01 8.512628666134923592e-09 0.000000000000000000 -4.980200000000000182e-01 8.564915300040312215e-09 0.000000000000000000 -4.985149999999999859e-01 8.606335942736847812e-09 0.000000000000000000 -4.990100000000000091e-01 8.636437328660788286e-09 0.000000000000000000 -4.995049999999999768e-01 8.654845773786825943e-09 0.000000000000000000 -5.000000000000000000e-01 8.661272736629355656e-09 0.000000000000000000 \ No newline at end of file diff --git a/tests/test_data/ORSO/test_1.dat b/tests/test_data/ORSO/test_1.dat deleted file mode 100644 index 14642ec9..00000000 --- a/tests/test_data/ORSO/test_1.dat +++ /dev/null @@ -1,1998 +0,0 @@ -7.120926687274507999e-04 9.999999999999996669e-01 0.000000000000000000 -1.068139001396520987e-03 1.000000000000000888e+00 0.000000000000000000 -1.424185332032005527e-03 1.000000000000000444e+00 0.000000000000000000 -1.780231659956042463e-03 9.999999999999997780e-01 0.000000000000000000 -2.136277984490769083e-03 1.000000000000000000e+00 0.000000000000000000 -2.492324304958323973e-03 1.000000000000000444e+00 0.000000000000000000 -2.848370620680845938e-03 9.999999999999993339e-01 0.000000000000000000 -3.204416930980470962e-03 9.999999999999993339e-01 0.000000000000000000 -3.560463235179339367e-03 1.000000000000000000e+00 0.000000000000000000 -3.916509532599587139e-03 9.999999999999998890e-01 0.000000000000000000 -4.272555822563354165e-03 1.000000000000000444e+00 0.000000000000000000 -4.628602104392778166e-03 9.999999999999994449e-01 0.000000000000000000 -4.984648377409996861e-03 9.999999999999996669e-01 0.000000000000000000 -5.340694640937147103e-03 9.999999999999996669e-01 0.000000000000000000 -5.696740894296370081e-03 1.000000000000000222e+00 0.000000000000000000 -6.052787136809801780e-03 9.999999999999991118e-01 0.000000000000000000 -6.408833367799581654e-03 1.000000000000000222e+00 0.000000000000000000 -6.764879586587847424e-03 9.999999999999997780e-01 0.000000000000000000 -7.120925792496735074e-03 1.000000000000000888e+00 0.000000000000000000 -7.476971984848386661e-03 9.999999999999997780e-01 0.000000000000000000 -7.833018162964939038e-03 1.000000000000000222e+00 0.000000000000000000 -8.189064326168529057e-03 9.999999999999995559e-01 0.000000000000000000 -8.545110473781298774e-03 1.000000000000000888e+00 0.000000000000000000 -8.901156605125380705e-03 9.999999999999990008e-01 0.000000000000000000 -9.257202719522919510e-03 9.999999999999997780e-01 0.000000000000000000 -9.613248816296047702e-03 9.999999999999992228e-01 0.000000000000000000 -9.969294894766909942e-03 1.000000000000000222e+00 0.000000000000000000 -1.032534095425764221e-02 9.999992503238016583e-01 0.000000000000000000 -1.068138699409038050e-02 9.999980643079933174e-01 0.000000000000000000 -1.103743301358726427e-02 9.999966126029437019e-01 0.000000000000000000 -1.139347901207043469e-02 9.999945750665667488e-01 0.000000000000000000 -1.174952498886202776e-02 9.999916063279130629e-01 0.000000000000000000 -1.210557094328418640e-02 9.999871933535626756e-01 0.000000000000000000 -1.246161687465904312e-02 9.999805294321724158e-01 0.000000000000000000 -1.281766278230874086e-02 9.999703119118247274e-01 0.000000000000000000 -1.317370866555541732e-02 9.999543902597648470e-01 0.000000000000000000 -1.352975452372121370e-02 9.999291324755025245e-01 0.000000000000000000 -1.388580035612826426e-02 9.998882494422177691e-01 0.000000000000000000 -1.424184616209871364e-02 9.998205409439229197e-01 0.000000000000000000 -1.459789194095469610e-02 9.997054114424506199e-01 0.000000000000000000 -1.495393769201834935e-02 9.995035606107141035e-01 0.000000000000000000 -1.530998341461181980e-02 9.991366701847683718e-01 0.000000000000000000 -1.566602910805724169e-02 9.984403861412076697e-01 0.000000000000000000 -1.602207477167675448e-02 9.970474634133739134e-01 0.000000000000000000 -1.637812040479250109e-02 9.940708597801094504e-01 0.000000000000000000 -1.673416600672661750e-02 9.871457348401537768e-01 0.000000000000000000 -1.709021157680123623e-02 9.691155171813401470e-01 0.000000000000000000 -1.744625711433850715e-02 9.146714791553381962e-01 0.000000000000000000 -1.780230261866056971e-02 7.235824663202072848e-01 0.000000000000000000 -1.815834808908955642e-02 1.982172144901543087e-01 0.000000000000000000 -1.851439352494761714e-02 5.368656202412908779e-02 0.000000000000000000 -1.887043892555688440e-02 2.826235383946479884e-01 0.000000000000000000 -1.922648429023949418e-02 3.875217379569827481e-01 0.000000000000000000 -1.958252961831759634e-02 3.916784480059969931e-01 0.000000000000000000 -1.993857490911332339e-02 3.310002219487748754e-01 0.000000000000000000 -2.029462016194881133e-02 2.272914448127881237e-01 0.000000000000000000 -2.065066537614621694e-02 1.112565297862627839e-01 0.000000000000000000 -2.100671055102766582e-02 2.688746936767203236e-02 0.000000000000000000 -2.136275568591530089e-02 3.822708968259131909e-03 0.000000000000000000 -2.171880078013126505e-02 3.222404371616335167e-02 0.000000000000000000 -2.207484583299769779e-02 8.026862564036112146e-02 0.000000000000000000 -2.243089084383674200e-02 1.225273725226444926e-01 0.000000000000000000 -2.278693581197053369e-02 1.473760379764722239e-01 0.000000000000000000 -2.314298073672121578e-02 1.523081321702720592e-01 0.000000000000000000 -2.349902561741092424e-02 1.392821746311279085e-01 0.000000000000000000 -2.385507045336181242e-02 1.126622529182146754e-01 0.000000000000000000 -2.421111524389600242e-02 7.861467279052444801e-02 0.000000000000000000 -2.456715998833565104e-02 4.455798023951239306e-02 0.000000000000000000 -2.492320468600290120e-02 1.778995627595785986e-02 0.000000000000000000 -2.527924933621987849e-02 3.395073093927740340e-03 0.000000000000000000 -2.563529393830873276e-02 2.595774676754369469e-03 0.000000000000000000 -2.599133849159160695e-02 1.275152602517853721e-02 0.000000000000000000 -2.634738299539064049e-02 2.895359745352929851e-02 0.000000000000000000 -2.670342744902797633e-02 4.602963456971208983e-02 0.000000000000000000 -2.705947185182575390e-02 5.990089564089792068e-02 0.000000000000000000 -2.741551620310611614e-02 6.806634079247522728e-02 0.000000000000000000 -2.777156050219120598e-02 6.953268660952754976e-02 0.000000000000000000 -2.812760474840316285e-02 6.455321611687926675e-02 0.000000000000000000 -2.848364894106412623e-02 5.436137845621738518e-02 0.000000000000000000 -2.883969307949624944e-02 4.092087484200730013e-02 0.000000000000000000 -2.919573716302166153e-02 2.663426033083630268e-02 0.000000000000000000 -2.955178119096250888e-02 1.395760727452293425e-02 0.000000000000000000 -2.990782516264093790e-02 4.940537297759796907e-03 0.000000000000000000 -3.026386907737909499e-02 8.038319201654679867e-04 0.000000000000000000 -3.061991293449910570e-02 1.708620388673709424e-03 0.000000000000000000 -3.097595673332313032e-02 6.811949263714371823e-03 0.000000000000000000 -3.133200047317330483e-02 1.457483812733798012e-02 0.000000000000000000 -3.168804415337176522e-02 2.318514893188180007e-02 0.000000000000000000 -3.204408777324066482e-02 3.094512785677362016e-02 0.000000000000000000 -3.240013133210215002e-02 3.653622957946371652e-02 0.000000000000000000 -3.275617482927836027e-02 3.914963327880489896e-02 0.000000000000000000 -3.311221826409141422e-02 3.851481114579176357e-02 0.000000000000000000 -3.346826163586349295e-02 3.486474359367892212e-02 0.000000000000000000 -3.382430494391673592e-02 2.886145256362034062e-02 0.000000000000000000 -3.418034818757326176e-02 2.148792850395982168e-02 0.000000000000000000 -3.453639136615522381e-02 1.390413248740521995e-02 0.000000000000000000 -3.489243447898477540e-02 7.270110580682173120e-03 0.000000000000000000 -3.524847752538406292e-02 2.555702842096856196e-03 0.000000000000000000 -3.560452050467521889e-02 3.740565631443482628e-04 0.000000000000000000 -3.596056341618038277e-02 8.818651216682591408e-04 0.000000000000000000 -3.631660625922172175e-02 3.774815561286619554e-03 0.000000000000000000 -3.667264903312136837e-02 8.376908074210839480e-03 0.000000000000000000 -3.702869173720146900e-02 1.379291825993611900e-02 0.000000000000000000 -3.738473437078415618e-02 1.907949142362600978e-02 0.000000000000000000 -3.774077693319158322e-02 2.339598362662987860e-02 0.000000000000000000 -3.809681942374590347e-02 2.611330228093514810e-02 0.000000000000000000 -3.845286184176926331e-02 2.687623558768857668e-02 0.000000000000000000 -3.880890418658378832e-02 2.562490347851576616e-02 0.000000000000000000 -3.916494645751164572e-02 2.258313239139892598e-02 0.000000000000000000 -3.952098865387497495e-02 1.821896548411633399e-02 0.000000000000000000 -3.987703077499590854e-02 1.317946753385513398e-02 0.000000000000000000 -4.023307282019660674e-02 8.201854622170537054e-03 0.000000000000000000 -4.058911478879920903e-02 4.007143453574814329e-03 0.000000000000000000 -4.094515668012587567e-02 1.189698981073644083e-03 0.000000000000000000 -4.130119849349873917e-02 1.224908690321959781e-04 0.000000000000000000 -4.165724022823994593e-02 8.989246294339966244e-04 0.000000000000000000 -4.201328188367164235e-02 3.325234142660786658e-03 0.000000000000000000 -4.236932345911597481e-02 6.964416333509426855e-03 0.000000000000000000 -4.272536495389510358e-02 1.121916028646527050e-02 0.000000000000000000 -4.308140636733116119e-02 1.543308351017479846e-02 0.000000000000000000 -4.343744769874631484e-02 1.898937468850776106e-02 0.000000000000000000 -4.379348894746269011e-02 2.139184438746310687e-02 0.000000000000000000 -4.414953011280244033e-02 2.232123954774985555e-02 0.000000000000000000 -4.450557119408771189e-02 2.166580616421132782e-02 0.000000000000000000 -4.486161219064066508e-02 1.952791764179004005e-02 0.000000000000000000 -4.521765310178343933e-02 1.620864628817681591e-02 0.000000000000000000 -4.557369392683818798e-02 1.217116170030136703e-02 0.000000000000000000 -4.592973466512705744e-02 7.983720670709770414e-03 0.000000000000000000 -4.628577531597218020e-02 4.245096364625116844e-03 0.000000000000000000 -4.664181587869571655e-02 1.499662726512367974e-03 0.000000000000000000 -4.699785635261983369e-02 1.545027354873637127e-04 0.000000000000000000 -4.735389673706665026e-02 4.141355837711353186e-04 0.000000000000000000 -4.770993703135834041e-02 2.247168622565268344e-03 0.000000000000000000 -4.806597723481704360e-02 5.392666820119029931e-03 0.000000000000000000 -4.842201734676489927e-02 9.404372644912777079e-03 0.000000000000000000 -4.877805736652407465e-02 1.372202677205701035e-02 0.000000000000000000 -4.913409729341672305e-02 1.775440026889581191e-02 0.000000000000000000 -4.949013712676497007e-02 2.095931024224749126e-02 0.000000000000000000 -4.984617686589098984e-02 2.291029585609997282e-02 0.000000000000000000 -5.020221651011690794e-02 2.334497783304607249e-02 0.000000000000000000 -5.055825605876489853e-02 2.219404885039374942e-02 0.000000000000000000 -5.091429551115710106e-02 1.959135400128038731e-02 0.000000000000000000 -5.127033486661566886e-02 1.586501758945364771e-02 0.000000000000000000 -5.162637412446277607e-02 1.150836376986204453e-02 0.000000000000000000 -5.198241328402053441e-02 7.129105837473640080e-03 0.000000000000000000 -5.233845234461111107e-02 3.377320603196695345e-03 0.000000000000000000 -5.269449130555668021e-02 8.575130055426591737e-04 0.000000000000000000 -5.305053016617936046e-02 3.647209063101535984e-05 0.000000000000000000 -5.340656892580131904e-02 1.163857944713281691e-03 0.000000000000000000 -5.376260758374470927e-02 4.223231029490143000e-03 0.000000000000000000 -5.411864613933167756e-02 8.925724651729985415e-03 0.000000000000000000 -5.447468459188439110e-02 1.474812225204646075e-02 0.000000000000000000 -5.483072294072498243e-02 2.100598463112585829e-02 0.000000000000000000 -5.518676118517561874e-02 2.694540653430236438e-02 0.000000000000000000 -5.554279932455844643e-02 3.183636109342779380e-02 0.000000000000000000 -5.589883735819563965e-02 3.505540309109209801e-02 0.000000000000000000 -5.625487528540931703e-02 3.615250239324107467e-02 0.000000000000000000 -5.661091310552165967e-02 3.490258163056411678e-02 0.000000000000000000 -5.696695081785480008e-02 3.134484432943147880e-02 0.000000000000000000 -5.732298842173092629e-02 2.581165665858425537e-02 0.000000000000000000 -5.767902591647214999e-02 1.894420382277415063e-02 0.000000000000000000 -5.803506330140065922e-02 1.168589120710910277e-02 0.000000000000000000 -5.839110057583860036e-02 5.239071212323875154e-03 0.000000000000000000 -5.874713773910812675e-02 9.699661692567669710e-04 0.000000000000000000 -5.910317479053139172e-02 2.548571947934354402e-04 0.000000000000000000 -5.945921172943054861e-02 4.279563213805427473e-03 0.000000000000000000 -5.981524855512776462e-02 1.382936523764148433e-02 0.000000000000000000 -6.017128526694519308e-02 2.912530634580091926e-02 0.000000000000000000 -6.052732186420497346e-02 4.976035489709161597e-02 0.000000000000000000 -6.088335834622928683e-02 7.475990790658799956e-02 0.000000000000000000 -6.123939471234027265e-02 1.027476759571164938e-01 0.000000000000000000 -6.159543096186008426e-02 1.321634319850614470e-01 0.000000000000000000 -6.195146709411090274e-02 1.614707216140106316e-01 0.000000000000000000 -6.230750310841486755e-02 1.893099215347545106e-01 0.000000000000000000 -6.266353900409413202e-02 2.145805097230245873e-01 0.000000000000000000 -6.301957478047087724e-02 2.364605236578511682e-01 0.000000000000000000 -6.337561043686723572e-02 2.543834511500450701e-01 0.000000000000000000 -6.373164597260537467e-02 2.679941669489654954e-01 0.000000000000000000 -6.408768138700744743e-02 2.771008025286855192e-01 0.000000000000000000 -6.444371667939563508e-02 2.816331303301823907e-01 0.000000000000000000 -6.479975184909207708e-02 2.816127054877834435e-01 0.000000000000000000 -6.515578689541892676e-02 2.771363892317091904e-01 0.000000000000000000 -6.551182181769835133e-02 2.683727121290661599e-01 0.000000000000000000 -6.586785661525253188e-02 2.555692006368687763e-01 0.000000000000000000 -6.622389128740358011e-02 2.390676879866036886e-01 0.000000000000000000 -6.657992583347371873e-02 2.193233636074038151e-01 0.000000000000000000 -6.693596025278504558e-02 1.969217972999726951e-01 0.000000000000000000 -6.729199454465978336e-02 1.725867214819165052e-01 0.000000000000000000 -6.764802870842004379e-02 1.471707263969875557e-01 0.000000000000000000 -6.800406274338798018e-02 1.216222784467115708e-01 0.000000000000000000 -6.836009664888580140e-02 9.692650349357995188e-02 0.000000000000000000 -6.871613042423563300e-02 7.402395197622313461e-02 0.000000000000000000 -6.907216406875968384e-02 5.371945996552492802e-02 0.000000000000000000 -6.942819758178006562e-02 3.659914943369632634e-02 0.000000000000000000 -6.978423096261893166e-02 2.297434648199053742e-02 0.000000000000000000 -7.014026421059849081e-02 1.286540951239448748e-02 0.000000000000000000 -7.049629732504089641e-02 6.027982687480571908e-03 0.000000000000000000 -7.085233030526828790e-02 2.013275425197893088e-03 0.000000000000000000 -7.120836315060283250e-02 2.468755563170781488e-04 0.000000000000000000 -7.156439586036672518e-02 1.093047733947922145e-04 0.000000000000000000 -7.192042843388209150e-02 1.005124351334935138e-03 0.000000000000000000 -7.227646087047111256e-02 2.413304299788868439e-03 0.000000000000000000 -7.263249316945594170e-02 3.917201295728916545e-03 0.000000000000000000 -7.298852533015878774e-02 5.216361638169828702e-03 0.000000000000000000 -7.334455735190174852e-02 6.124202100679557170e-03 0.000000000000000000 -7.370058923400707451e-02 6.555911045997408343e-03 0.000000000000000000 -7.405662097579682190e-02 6.510363841711615251e-03 0.000000000000000000 -7.441265257659324117e-02 6.049045190383253723e-03 0.000000000000000000 -7.476868403571845789e-02 5.274253535248039047e-03 0.000000000000000000 -7.512471535249466703e-02 4.308339791017238261e-03 0.000000000000000000 -7.548074652624400804e-02 3.275368027027975634e-03 0.000000000000000000 -7.583677755628866202e-02 2.286281923377684027e-03 0.000000000000000000 -7.619280844195079616e-02 1.428327001933368898e-03 0.000000000000000000 -7.654883918255257769e-02 7.590718926671823031e-04 0.000000000000000000 -7.690486977741615993e-02 3.049095232574781629e-04 0.000000000000000000 -7.726090022586373784e-02 6.346498439523581814e-05 0.000000000000000000 -7.761693052721746477e-02 8.971312499623633620e-06 0.000000000000000000 -7.797296068079949405e-02 9.946193680944292851e-05 0.000000000000000000 -7.832899068593204839e-02 2.845955828948539749e-04 0.000000000000000000 -7.868502054193722561e-02 5.130601042093955316e-04 0.000000000000000000 -7.904105024813724845e-02 7.387486163540610056e-04 0.000000000000000000 -7.939707980385422859e-02 9.252041386305923576e-04 0.000000000000000000 -7.975310920841041651e-02 1.048132033417172471e-03 0.000000000000000000 -8.010913846112791004e-02 1.096042544049322933e-03 0.000000000000000000 -8.046516756132893189e-02 1.069286418981557803e-03 0.000000000000000000 -8.082119650833562152e-02 9.778778225035848152e-04 0.000000000000000000 -8.117722530147016002e-02 8.385631428781712771e-04 0.000000000000000000 -8.153325394005471460e-02 6.715996891405033890e-04 0.000000000000000000 -8.188928242341148023e-02 4.976646626575670406e-04 0.000000000000000000 -8.224531075086258247e-02 3.352335337838832446e-04 0.000000000000000000 -8.260133892173024406e-02 1.986606514487722309e-04 0.000000000000000000 -8.295736693533657669e-02 9.707735928655198581e-05 0.000000000000000000 -8.331339479100383083e-02 3.410829710717231935e-05 0.000000000000000000 -8.366942248805409044e-02 8.308033604611576680e-06 0.000000000000000000 -8.402545002580961986e-02 1.414786716311659249e-05 0.000000000000000000 -8.438147740359254467e-02 4.334227498273019591e-05 0.000000000000000000 -8.473750462072503209e-02 8.629674991516118009e-05 0.000000000000000000 -8.509353167652927707e-02 1.334796499856705525e-04 0.000000000000000000 -8.544955857032743296e-02 1.765628259126242967e-04 0.000000000000000000 -8.580558530144170859e-02 2.092301378552286167e-04 0.000000000000000000 -8.616161186919424342e-02 2.276104714561805978e-04 0.000000000000000000 -8.651763827290724629e-02 2.303447594084227854e-04 0.000000000000000000 -8.687366451190285666e-02 2.183391277391872134e-04 0.000000000000000000 -8.722969058550328336e-02 1.942852890145829780e-04 0.000000000000000000 -8.758571649303067974e-02 1.620436259952447969e-04 0.000000000000000000 -8.794174223380724076e-02 1.259848982617479073e-04 0.000000000000000000 -8.829776780715511975e-02 9.037547505689172065e-05 0.000000000000000000 -8.865379321239652555e-02 5.887172066550819168e-05 0.000000000000000000 -8.900981844885362537e-02 3.416534252355031038e-05 0.000000000000000000 -8.936584351584860031e-02 1.779680742061332706e-05 0.000000000000000000 -8.972186841270360369e-02 1.013149623178605324e-05 0.000000000000000000 -9.007789313874083048e-02 1.047544159156060060e-05 0.000000000000000000 -9.043391769328244789e-02 1.729561252381977442e-05 0.000000000000000000 -9.078994207565069252e-02 2.850409080344256811e-05 0.000000000000000000 -9.114596628516766219e-02 4.176555482191795913e-05 0.000000000000000000 -9.150199032115559350e-02 5.479204031225699107e-05 0.000000000000000000 -9.185801418293662590e-02 6.559644639526214483e-05 0.000000000000000000 -9.221403786983298212e-02 7.268513659439882304e-05 0.000000000000000000 -9.257006138116681548e-02 7.517890428405253655e-05 0.000000000000000000 -9.292608471626032096e-02 7.285956334126011643e-05 0.000000000000000000 -9.328210787443567964e-02 6.614595182554889089e-05 0.000000000000000000 -9.363813085501505873e-02 5.600805815264254205e-05 0.000000000000000000 -9.399415365732066707e-02 4.383144435331396506e-05 0.000000000000000000 -9.435017628067465800e-02 3.124644879350179061e-05 0.000000000000000000 -9.470619872439926812e-02 1.993810949992266325e-05 0.000000000000000000 -9.506222098781658136e-02 1.145356365488822627e-05 0.000000000000000000 -9.541824307024888985e-02 7.023886535066620586e-06 0.000000000000000000 -9.577426497101829139e-02 7.416800595041411032e-06 0.000000000000000000 -9.613028668944702260e-02 1.283516013789619059e-05 0.000000000000000000 -9.648630822485723679e-02 2.287332276312405784e-05 0.000000000000000000 -9.684232957657118446e-02 3.653927002790868079e-05 0.000000000000000000 -9.719835074391096341e-02 5.234464934130625532e-05 0.000000000000000000 -9.755437172619881026e-02 6.845806277362821528e-05 0.000000000000000000 -9.791039252275690608e-02 8.290950695128456913e-05 0.000000000000000000 -9.826641313290743196e-02 9.382670782815655361e-05 0.000000000000000000 -9.862243355597255512e-02 9.967818875406802962e-05 0.000000000000000000 -9.897845379127453991e-02 9.949426899230886189e-05 0.000000000000000000 -9.933447383813544251e-02 9.303667249708322978e-05 0.000000000000000000 -9.969049369587758280e-02 8.089058319673479410e-05 0.000000000000000000 -1.000465133638230725e-01 6.445992151903826971e-05 0.000000000000000000 -1.004025328412940926e-01 4.585692330584841258e-05 0.000000000000000000 -1.007585521276129076e-01 2.768982607827679971e-05 0.000000000000000000 -1.011145712221016152e-01 1.276618442061887835e-05 0.000000000000000000 -1.014705901240824798e-01 3.742288566040074791e-06 0.000000000000000000 -1.018266088328776409e-01 2.759468808386639137e-06 0.000000000000000000 -1.021826273478093211e-01 1.111399388889338987e-05 0.000000000000000000 -1.025386456681996877e-01 2.900749403134073737e-05 0.000000000000000000 -1.028946637933709773e-01 5.541871035227143385e-05 0.000000000000000000 -1.032506817226453294e-01 8.812509142791419042e-05 0.000000000000000000 -1.036066994553449527e-01 1.238854304385895945e-04 0.000000000000000000 -1.039627169907920423e-01 1.587742902448870791e-04 0.000000000000000000 -1.043187343283087792e-01 1.886379263912715994e-04 0.000000000000000000 -1.046747514672173585e-01 2.096225884859581991e-04 0.000000000000000000 -1.050307684068400166e-01 2.187121503802830170e-04 0.000000000000000000 -1.053867851464988792e-01 2.142052049765487008e-04 0.000000000000000000 -1.057428016855162245e-01 1.960634957971946234e-04 0.000000000000000000 -1.060988180232141503e-01 1.660742922637250716e-04 0.000000000000000000 -1.064548341589149211e-01 1.277884105978826699e-04 0.000000000000000000 -1.068108500919407039e-01 8.622132208667974192e-05 0.000000000000000000 -1.071668658216137077e-01 4.733449434705914880e-05 0.000000000000000000 -1.075228813472561273e-01 1.734434760081200050e-05 0.000000000000000000 -1.078788966681901579e-01 1.933118656369010416e-06 0.000000000000000000 -1.082349117837379943e-01 5.455659258887862833e-06 0.000000000000000000 -1.085909266932218176e-01 3.024542857905961391e-05 0.000000000000000000 -1.089469413959638505e-01 7.611941956014601899e-05 0.000000000000000000 -1.093029558912862742e-01 1.401647771652088912e-04 0.000000000000000000 -1.096589701785113113e-01 2.168605424404625908e-04 0.000000000000000000 -1.100149842569611430e-01 2.985492361386503043e-04 0.000000000000000000 -1.103709981259579642e-01 3.762293309851267903e-04 0.000000000000000000 -1.107270117848239699e-01 4.405964106256916196e-04 0.000000000000000000 -1.110830252328813966e-01 4.832234871945571223e-04 0.000000000000000000 -1.114390384694523978e-01 4.977444658418705547e-04 0.000000000000000000 -1.117950514938592238e-01 4.808928316538502406e-04 0.000000000000000000 -1.121510643054240280e-01 4.332524663460849768e-04 0.000000000000000000 -1.125070769034690332e-01 3.595995585983343063e-04 0.000000000000000000 -1.128630892873164482e-01 2.687526470951428549e-04 0.000000000000000000 -1.132191014562884679e-01 1.728991032888055270e-04 0.000000000000000000 -1.135751134097072873e-01 8.642644558309738555e-05 0.000000000000000000 -1.139311251468951292e-01 2.434995658576660226e-05 0.000000000000000000 -1.142871366671741884e-01 4.871332911674904110e-07 0.000000000000000000 -1.146431479698666461e-01 2.557686056594543939e-05 0.000000000000000000 -1.149991590542947528e-01 1.055694366321243013e-04 0.000000000000000000 -1.153551699197806757e-01 2.403167539066789686e-04 0.000000000000000000 -1.157111805656466652e-01 4.228669098875471291e-04 0.000000000000000000 -1.160671909912148747e-01 6.395149834138812422e-04 0.000000000000000000 -1.164232011958075269e-01 8.706865365835499094e-04 0.000000000000000000 -1.167792111787468445e-01 1.092641079005167524e-03 0.000000000000000000 -1.171352209393550226e-01 1.279889917418906668e-03 0.000000000000000000 -1.174912304769542698e-01 1.408137396975669194e-03 0.000000000000000000 -1.178472397908667951e-01 1.457485765100531442e-03 0.000000000000000000 -1.182032488804148213e-01 1.415598123074409071e-03 0.000000000000000000 -1.185592577449205293e-01 1.280494398398293598e-03 0.000000000000000000 -1.189152663837061141e-01 1.062662707987248713e-03 0.000000000000000000 -1.192712747960938680e-01 7.862023083468068062e-04 0.000000000000000000 -1.196272829814059163e-01 4.887737236485311439e-04 0.000000000000000000 -1.199832909389645097e-01 2.202159189247301777e-04 0.000000000000000000 -1.203392986680918431e-01 3.979830839398972161e-05 0.000000000000000000 -1.206953061681101530e-01 1.220350711631287037e-05 0.000000000000000000 -1.210513134383415929e-01 2.024772858306064501e-04 0.000000000000000000 -1.214073204781084547e-01 6.703215492764690161e-04 0.000000000000000000 -1.217633272867328920e-01 1.464224940939182554e-03 0.000000000000000000 -1.221193338635371411e-01 2.616001291675263546e-03 0.000000000000000000 -1.224753402078434111e-01 4.136317795377386815e-03 0.000000000000000000 -1.228313463189739246e-01 6.011729879899218969e-03 0.000000000000000000 -1.231873521962508905e-01 8.203599311089578364e-03 0.000000000000000000 -1.235433578389965176e-01 1.064907325468252182e-02 0.000000000000000000 -1.238993632465330147e-01 1.326407565021464098e-02 0.000000000000000000 -1.242553684181826323e-01 1.594804589567879946e-02 0.000000000000000000 -1.246113733532675794e-01 1.858998840281154974e-02 0.000000000000000000 -1.249673780511100230e-01 2.107529362738292181e-02 0.000000000000000000 -1.253233825110322275e-01 2.329276398118123453e-02 0.000000000000000000 -1.256793867323563740e-01 2.514131773352146215e-02 0.000000000000000000 -1.260353907144047547e-01 2.653593029410738352e-02 0.000000000000000000 -1.263913944564994951e-01 2.741248045644777837e-02 0.000000000000000000 -1.267473979579628873e-01 2.773127720409010108e-02 0.000000000000000000 -1.271034012181170847e-01 2.747913598426924078e-02 0.000000000000000000 -1.274594042362844071e-01 2.666994684051260736e-02 0.000000000000000000 -1.278154070117869523e-01 2.534373397932043748e-02 0.000000000000000000 -1.281714095439470125e-01 2.356425644370230624e-02 0.000000000000000000 -1.285274118320868242e-01 2.141525350765790051e-02 0.000000000000000000 -1.288834138755285685e-01 1.899550465513106731e-02 0.000000000000000000 -1.292394156735944544e-01 1.641295502586023747e-02 0.000000000000000000 -1.295954172256067738e-01 1.377824733243297045e-02 0.000000000000000000 -1.299514185308876801e-01 1.119808666537737939e-02 0.000000000000000000 -1.303074195887594100e-01 8.768925840754077800e-03 0.000000000000000000 -1.306634203985442555e-01 6.571475698095328305e-03 0.000000000000000000 -1.310194209595643700e-01 4.666501959614566611e-03 0.000000000000000000 -1.313754212711419622e-01 3.092263662854505268e-03 0.000000000000000000 -1.317314213325993244e-01 1.863787371175296007e-03 0.000000000000000000 -1.320874211432586653e-01 9.739788607820338857e-04 0.000000000000000000 -1.324434207024421384e-01 3.963802668736982667e-04 0.000000000000000000 -1.327994200094720634e-01 8.921674493044612559e-05 0.000000000000000000 -1.331554190636706492e-01 2.665952073295560575e-07 0.000000000000000000 -1.335114178643601046e-01 7.204451553262165473e-05 0.000000000000000000 -1.338674164108626385e-01 2.468079355140588354e-04 0.000000000000000000 -1.342234147025005153e-01 4.709691611840681100e-04 0.000000000000000000 -1.345794127385959993e-01 6.986031137617786492e-04 0.000000000000000000 -1.349354105184712160e-01 8.938625339974852696e-04 0.000000000000000000 -1.352914080414484854e-01 1.032233272837267991e-03 0.000000000000000000 -1.356474053068499885e-01 1.100670165759236405e-03 0.000000000000000000 -1.360034023139979620e-01 1.096742387334400607e-03 0.000000000000000000 -1.363593990622146979e-01 1.026983290192023382e-03 0.000000000000000000 -1.367153955508223495e-01 9.046829782939392077e-04 0.000000000000000000 -1.370713917791431813e-01 7.473826517818878959e-04 0.000000000000000000 -1.374273877464994298e-01 5.743288455797241135e-04 0.000000000000000000 -1.377833834522133039e-01 4.041242294020531349e-04 0.000000000000000000 -1.381393788956070956e-01 2.527717022236912470e-04 0.000000000000000000 -1.384953740760029861e-01 1.322536032598316106e-04 0.000000000000000000 -1.388513689927232952e-01 4.972316958766892492e-05 0.000000000000000000 -1.392073636450900931e-01 7.317517967114064301e-06 0.000000000000000000 -1.395633580324257550e-01 2.537677108587326546e-06 0.000000000000000000 -1.399193521540525176e-01 2.908835027570081237e-05 0.000000000000000000 -1.402753460092925342e-01 7.803339032303392069e-05 0.000000000000000000 -1.406313395974680969e-01 1.391053081044480594e-04 0.000000000000000000 -1.409873329179014423e-01 2.020087466444986369e-04 0.000000000000000000 -1.413433259699148070e-01 2.575765483758868835e-04 0.000000000000000000 -1.416993187528304277e-01 2.986688295301005150e-04 0.000000000000000000 -1.420553112659705131e-01 3.207453690561380731e-04 0.000000000000000000 -1.424113035086573553e-01 3.220844265491808384e-04 0.000000000000000000 -1.427672954802131633e-01 3.036620472458394096e-04 0.000000000000000000 -1.431232871799602568e-01 2.687410374968812179e-04 0.000000000000000000 -1.434792786072207338e-01 2.222451849224639628e-04 0.000000000000000000 -1.438352697613169140e-01 1.700101604961256198e-04 0.000000000000000000 -1.441912606415710896e-01 1.180072167506263824e-04 0.000000000000000000 -1.445472512473053861e-01 7.162973129632132499e-05 0.000000000000000000 -1.449032415778421790e-01 3.511730379804545903e-05 0.000000000000000000 -1.452592316325035937e-01 1.116983220888827088e-05 0.000000000000000000 -1.456152214106120057e-01 7.777283395139781894e-07 0.000000000000000000 -1.459712109114895129e-01 3.267429409928755642e-06 0.000000000000000000 -1.463272001344584627e-01 1.653676404955362850e-05 0.000000000000000000 -1.466831890788410642e-01 3.743519360125543239e-05 0.000000000000000000 -1.470391777439595815e-01 6.223132893986060073e-05 0.000000000000000000 -1.473951661291362514e-01 8.710529387389396986e-05 0.000000000000000000 -1.477511542336933659e-01 1.086063318426373905e-04 0.000000000000000000 -1.481071420569531061e-01 1.240255000048975584e-04 0.000000000000000000 -1.484631295982377364e-01 1.316476568555218331e-04 0.000000000000000000 -1.488191168568695488e-01 1.308641240165144915e-04 0.000000000000000000 -1.491751038321706968e-01 1.221451788117454299e-04 0.000000000000000000 -1.495310905234635834e-01 1.068878480401105961e-04 0.000000000000000000 -1.498870769300703343e-01 8.716761338618064802e-05 0.000000000000000000 -1.502430630513132692e-01 6.543138988379636754e-05 0.000000000000000000 -1.505990488865145693e-01 4.417286511353148116e-05 0.000000000000000000 -1.509550344349965822e-01 2.562995585053618792e-05 0.000000000000000000 -1.513110196960814890e-01 1.153828666902127318e-05 0.000000000000000000 -1.516670046690915818e-01 2.965235759156494224e-06 0.000000000000000000 -1.520229893533490695e-01 2.375799839852772526e-07 0.000000000000000000 -1.523789737481762996e-01 2.963620748559541254e-06 0.000000000000000000 -1.527349578528954532e-01 1.013937457113441147e-05 0.000000000000000000 -1.530909416668287393e-01 2.031925017450853009e-05 0.000000000000000000 -1.534469251892985331e-01 3.182553792128342513e-05 0.000000000000000000 -1.538029084196269880e-01 4.296849512713465805e-05 0.000000000000000000 -1.541588913571364794e-01 5.224984095593289532e-05 0.000000000000000000 -1.545148740011491328e-01 5.852666389340268379e-05 0.000000000000000000 -1.548708563509873237e-01 6.111933592639955343e-05 0.000000000000000000 -1.552268384059732331e-01 5.985504110310268079e-05 0.000000000000000000 -1.555828201654291809e-01 5.504689643007802332e-05 0.000000000000000000 -1.559388016286773482e-01 4.741635006511724901e-05 0.000000000000000000 -1.562947827950400825e-01 3.797272496357615167e-05 0.000000000000000000 -1.566507636638395928e-01 2.786782030213914843e-05 0.000000000000000000 -1.570067442343981712e-01 1.824507016429453263e-05 0.000000000000000000 -1.573627245060380819e-01 1.010188399731723001e-05 0.000000000000000000 -1.577187044780815062e-01 4.180743690407739994e-06 0.000000000000000000 -1.580746841498507915e-01 8.999352539747241527e-07 0.000000000000000000 -1.584306635206682023e-01 3.291384610701385866e-07 0.000000000000000000 -1.587866425898560307e-01 2.209243188621883886e-06 0.000000000000000000 -1.591426213567364301e-01 6.010435270108753439e-06 0.000000000000000000 -1.594985998206318034e-01 1.101840877966192323e-05 0.000000000000000000 -1.598545779808643041e-01 1.643594171742741798e-05 0.000000000000000000 -1.602105558367562799e-01 2.148621869868597563e-05 0.000000000000000000 -1.605665333876299672e-01 2.550516468535396394e-05 0.000000000000000000 -1.609225106328075749e-01 2.801242400403508741e-05 0.000000000000000000 -1.612784875716115063e-01 2.875407056220063696e-05 0.000000000000000000 -1.616344642033639145e-01 2.771415921962680788e-05 0.000000000000000000 -1.619904405273871473e-01 2.509628534763581434e-05 0.000000000000000000 -1.623464165430034134e-01 2.127990839067300612e-05 0.000000000000000000 -1.627023922495350050e-01 1.675891059642977993e-05 0.000000000000000000 -1.630583676463042420e-01 1.207143716837361807e-05 0.000000000000000000 -1.634143427326333609e-01 7.730392826651313014e-06 0.000000000000000000 -1.637703175078445705e-01 4.163108299111086397e-06 0.000000000000000000 -1.641262919712602741e-01 1.666838683256887413e-06 0.000000000000000000 -1.644822661222026805e-01 3.842230227906430383e-07 0.000000000000000000 -1.648382399599940262e-01 2.999926007570094749e-07 0.000000000000000000 -1.651942134839566589e-01 1.257447392305794977e-06 0.000000000000000000 -1.655501866934127597e-01 2.990870497965352064e-06 0.000000000000000000 -1.659061595876847317e-01 5.168384013160258488e-06 0.000000000000000000 -1.662621321660947560e-01 7.438923370792001123e-06 0.000000000000000000 -1.666181044279652079e-01 9.477057076390020565e-06 0.000000000000000000 -1.669740763726181854e-01 1.102022537901142458e-05 0.000000000000000000 -1.673300479993762024e-01 1.189443856190296805e-05 0.000000000000000000 -1.676860193075613570e-01 1.202632073413337422e-05 0.000000000000000000 -1.680419902964960521e-01 1.144133631291558719e-05 0.000000000000000000 -1.683979609655024134e-01 1.024983018201071423e-05 0.000000000000000000 -1.687539313139028996e-01 8.623927379987487136e-06 0.000000000000000000 -1.691099013410197471e-01 6.769220795462518602e-06 0.000000000000000000 -1.694658710461751094e-01 4.895455609086372992e-06 0.000000000000000000 -1.698218404286914729e-01 3.190113289274418335e-06 0.000000000000000000 -1.701778094878909353e-01 1.797999666524523074e-06 0.000000000000000000 -1.705337782230959276e-01 8.088040545546147058e-07 0.000000000000000000 -1.708897466336286308e-01 2.533065822331901015e-07 0.000000000000000000 -1.712457147188113649e-01 1.076615254951338627e-07 0.000000000000000000 -1.716016824779664218e-01 3.041465350388869230e-07 0.000000000000000000 -1.719576499104161771e-01 7.460681489742753102e-07 0.000000000000000000 -1.723136170154827285e-01 1.324220752222025398e-06 0.000000000000000000 -1.726695837924885624e-01 1.932412544855609679e-06 0.000000000000000000 -1.730255502407558044e-01 2.480040996392723469e-06 0.000000000000000000 -1.733815163596068576e-01 2.900416708919564217e-06 0.000000000000000000 -1.737374821483639864e-01 3.154364580513317717e-06 0.000000000000000000 -1.740934476063493996e-01 3.229433683842765013e-06 0.000000000000000000 -1.744494127328855004e-01 3.135696362522462666e-06 0.000000000000000000 -1.748053775272945531e-01 2.899520308567937198e-06 0.000000000000000000 -1.751613419888988221e-01 2.556808738275931952e-06 0.000000000000000000 -1.755173061170206272e-01 2.147028597314123673e-06 0.000000000000000000 -1.758732699109822051e-01 1.708938832546787614e-06 0.000000000000000000 -1.762292333701059310e-01 1.278382022611821128e-06 0.000000000000000000 -1.765851964937140972e-01 8.879267397751094873e-07 0.000000000000000000 -1.769411592811289125e-01 5.676610123502146731e-07 0.000000000000000000 -1.772971217316727521e-01 3.461380276079722355e-07 0.000000000000000000 -1.776530838446679084e-01 2.504285056077941324e-07 0.000000000000000000 -1.780090456194367010e-01 3.044590868243752206e-07 0.000000000000000000 -1.783650070553013389e-01 5.252816802839334994e-07 0.000000000000000000 -1.787209681515841975e-01 9.175475618961617589e-07 0.000000000000000000 -1.790769289076075133e-01 1.467139141091585756e-06 0.000000000000000000 -1.794328893226936616e-01 2.135510314238924347e-06 0.000000000000000000 -1.797888493961649348e-01 2.856673998169197392e-06 0.000000000000000000 -1.801448091273435692e-01 3.538847147317965509e-06 0.000000000000000000 -1.805007685155519126e-01 4.072456084991282567e-06 0.000000000000000000 -1.808567275601123125e-01 4.345511017452451744e-06 0.000000000000000000 -1.812126862603470057e-01 4.266332661519509790e-06 0.000000000000000000 -1.815686446155782841e-01 3.792369439228995033e-06 0.000000000000000000 -1.819246026251284953e-01 2.962541342940312717e-06 0.000000000000000000 -1.822805602883199871e-01 1.929374983339477777e-06 0.000000000000000000 -1.826365176044749405e-01 9.863455918093047055e-07 0.000000000000000000 -1.829924745729158142e-01 5.854847547471093298e-07 0.000000000000000000 -1.833484311929647892e-01 1.340567785800901897e-06 0.000000000000000000 -1.837043874639442409e-01 4.012113124293805079e-06 0.000000000000000000 -1.840603433851764892e-01 9.471977045142035314e-06 0.000000000000000000 -1.844162989559837984e-01 1.864739378685414768e-05 0.000000000000000000 -1.847722541756884607e-01 3.244669916381921401e-05 0.000000000000000000 -1.851282090436128791e-01 5.167142943140016906e-05 0.000000000000000000 -1.854841635590793736e-01 7.692171728882853034e-05 0.000000000000000000 -1.858401177214100697e-01 1.085036232282542834e-04 0.000000000000000000 -1.861960715299275093e-01 1.463479876901880596e-04 0.000000000000000000 -1.865520249839538180e-01 1.899503815588748370e-04 0.000000000000000000 -1.869079780828115100e-01 2.383406806231707503e-04 0.000000000000000000 -1.872639308258226554e-01 2.900887201006568700e-04 0.000000000000000000 -1.876198832123097959e-01 3.433495442083197473e-04 0.000000000000000000 -1.879758352415951128e-01 3.959482084958235496e-04 0.000000000000000000 -1.883317869130010092e-01 4.455002596893518235e-04 0.000000000000000000 -1.886877382258497493e-01 4.895602988239268613e-04 0.000000000000000000 -1.890436891794636254e-01 5.257878247229267775e-04 0.000000000000000000 -1.893996397731650405e-01 5.521172150073502208e-04 0.000000000000000000 -1.897555900062762591e-01 5.669175114659875166e-04 0.000000000000000000 -1.901115398781196564e-01 5.691278069494392364e-04 0.000000000000000000 -1.904674893880174136e-01 5.583555238115983340e-04 0.000000000000000000 -1.908234385352920170e-01 5.349276354955198511e-04 0.000000000000000000 -1.911793873192657034e-01 4.998886906644803415e-04 0.000000000000000000 -1.915353357392608480e-01 4.549440213965135621e-04 0.000000000000000000 -1.918912837945997152e-01 4.023513415116584816e-04 0.000000000000000000 -1.922472314846046526e-01 3.447686135888582875e-04 0.000000000000000000 -1.926031788085980079e-01 2.850701290599796153e-04 0.000000000000000000 -1.929591257659021009e-01 2.261457947346995421e-04 0.000000000000000000 -1.933150723558391959e-01 1.707003281964997101e-04 0.000000000000000000 -1.936710185777317517e-01 1.210692346449203718e-04 0.000000000000000000 -1.940269644309019492e-01 7.906702003329146627e-05 0.000000000000000000 -1.943829099146722750e-01 4.588020246837628760e-05 0.000000000000000000 -1.947388550283649100e-01 2.201358390830739767e-05 0.000000000000000000 -1.950947997713022575e-01 7.293336045823737323e-06 0.000000000000000000 -1.954507441428066372e-01 9.252262154856471493e-07 0.000000000000000000 -1.958066881422003969e-01 1.601285880002985206e-06 0.000000000000000000 -1.961626317688058563e-01 7.643908463132016528e-06 0.000000000000000000 -1.965185750219453076e-01 1.717318009637506531e-05 0.000000000000000000 -1.968745179009412094e-01 2.828149786008608612e-05 0.000000000000000000 -1.972304604051157706e-01 3.919936309822959257e-05 0.000000000000000000 -1.975864025337913388e-01 4.843763436167945491e-05 0.000000000000000000 -1.979423442862902893e-01 5.489430848521220793e-05 0.000000000000000000 -1.982982856619349699e-01 5.791775658249328481e-05 0.000000000000000000 -1.986542266600476725e-01 5.732286218237246401e-05 0.000000000000000000 -1.990101672799508281e-01 5.336122393788524332e-05 0.000000000000000000 -1.993661075209666733e-01 4.665102050553604859e-05 0.000000000000000000 -1.997220473824175557e-01 3.807585502049723106e-05 0.000000000000000000 -2.000779868636259062e-01 2.866454745669817108e-05 0.000000000000000000 -2.004339259639139614e-01 1.946518700320736041e-05 0.000000000000000000 -2.007898646826041245e-01 1.142669354877474980e-05 0.000000000000000000 -2.011458030190187152e-01 5.299714736438235724e-06 0.000000000000000000 -2.015017409724800812e-01 1.566091146902458539e-06 0.000000000000000000 -2.018576785423105702e-01 4.026651359075934996e-07 0.000000000000000000 -2.022136157278325297e-01 1.681282151611436078e-06 0.000000000000000000 -2.025695525283682796e-01 5.002871589409538899e-06 0.000000000000000000 -2.029254889432401954e-01 9.759924382879398998e-06 0.000000000000000000 -2.032814249717706800e-01 1.521887858564278347e-05 0.000000000000000000 -2.036373606132819980e-01 2.061215906995900928e-05 0.000000000000000000 -2.039932958670964691e-01 2.522904682399217829e-05 0.000000000000000000 -2.043492307325364965e-01 2.849519450012334441e-05 0.000000000000000000 -2.047051652089245111e-01 3.003234163810449768e-05 0.000000000000000000 -2.050610992955826661e-01 2.969238316629291735e-05 0.000000000000000000 -2.054170329918335314e-01 2.756308974279663603e-05 0.000000000000000000 -2.057729662969992601e-01 2.394610083840538576e-05 0.000000000000000000 -2.061288992104023665e-01 1.931093645612241421e-05 0.000000000000000000 -2.064848317313651704e-01 1.423135979906144990e-05 0.000000000000000000 -2.068407638592099085e-01 9.312199466116636372e-06 0.000000000000000000 -2.071966955932590670e-01 5.115531919461725959e-06 0.000000000000000000 -2.075526269328349105e-01 2.094873713437147655e-06 0.000000000000000000 -2.079085578772599530e-01 5.447979266944590749e-07 0.000000000000000000 -2.082644884258563478e-01 5.713400269409196353e-07 0.000000000000000000 -2.086204185779465814e-01 2.085953357441809966e-06 0.000000000000000000 -2.089763483328529181e-01 4.822929335948564482e-06 0.000000000000000000 -2.093322776898979276e-01 8.377447909787557340e-06 0.000000000000000000 -2.096882066484037077e-01 1.225908591020606872e-05 0.000000000000000000 -2.100441352076927726e-01 1.595394496079915217e-05 0.000000000000000000 -2.104000633670873865e-01 1.898774205519814144e-05 0.000000000000000000 -2.107559911259100360e-01 2.098230745250231360e-05 0.000000000000000000 -2.111119184834830409e-01 2.169892021507130244e-05 0.000000000000000000 -2.114678454391286933e-01 2.106364413376642772e-05 0.000000000000000000 -2.118237719921693962e-01 1.917208556424397550e-05 0.000000000000000000 -2.121796981419276085e-01 1.627350379474826734e-05 0.000000000000000000 -2.125356238877255666e-01 1.273666512882906154e-05 0.000000000000000000 -2.128915492288856737e-01 9.001956836942117556e-06 0.000000000000000000 -2.132474741647303329e-01 5.525823850136786935e-06 0.000000000000000000 -2.136033986945818919e-01 2.724388402501055755e-06 0.000000000000000000 -2.139593228177627815e-01 9.230799063256901580e-07 0.000000000000000000 -2.143152465335952384e-01 3.182568425487276085e-07 0.000000000000000000 -2.146711698414017766e-01 9.552574446170507813e-07 0.000000000000000000 -2.150270927405046328e-01 2.725265626615183525e-06 0.000000000000000000 -2.153830152302263212e-01 5.381074428354149575e-06 0.000000000000000000 -2.157389373098891061e-01 8.569549490893455884e-06 0.000000000000000000 -2.160948589788154184e-01 1.187661135574279510e-05 0.000000000000000000 -2.164507802363275779e-01 1.487910039621436682e-05 0.000000000000000000 -2.168067010817480433e-01 1.719712856117240743e-05 0.000000000000000000 -2.171626215143991900e-01 1.854053957493135123e-05 0.000000000000000000 -2.175185415336032269e-01 1.874388224981669699e-05 0.000000000000000000 -2.178744611386827512e-01 1.778574805647824546e-05 0.000000000000000000 -2.182303803289600275e-01 1.579025471339463242e-05 0.000000000000000000 -2.185862991037574588e-01 1.301063764277111631e-05 0.000000000000000000 -2.189422174623973927e-01 9.797078719471988956e-06 0.000000000000000000 -2.192981354042022601e-01 6.552798316362948958e-06 0.000000000000000000 -2.196540529284944920e-01 3.683837366356750384e-06 0.000000000000000000 -2.200099700345962972e-01 1.548695982552249733e-06 0.000000000000000000 -2.203658867218302175e-01 4.139881502624459350e-07 0.000000000000000000 -2.207218029895186284e-01 4.215213494170291030e-07 0.000000000000000000 -2.210777188369837942e-01 1.570807714703152636e-06 0.000000000000000000 -2.214336342635482846e-01 3.719129414464846040e-06 0.000000000000000000 -2.217895492685343084e-01 6.599142829491929937e-06 0.000000000000000000 -2.221454638512643243e-01 9.851871607361456580e-06 0.000000000000000000 -2.225013780110607908e-01 1.307106478734194164e-05 0.000000000000000000 -2.228572917472460002e-01 1.585350836065541267e-05 0.000000000000000000 -2.232132050591423833e-01 1.784914374214487015e-05 0.000000000000000000 -2.235691179460722877e-01 1.880485329805080074e-05 0.000000000000000000 -2.239250304073581443e-01 1.859652137021163115e-05 0.000000000000000000 -2.242809424423224396e-01 1.724538094034458823e-05 0.000000000000000000 -2.246368540502874100e-01 1.491654525518869076e-05 0.000000000000000000 -2.249927652305755144e-01 1.189977625366486847e-05 0.000000000000000000 -2.253486759825091001e-01 8.574701332865957782e-06 0.000000000000000000 -2.257045863054106816e-01 5.364598503175520927e-06 0.000000000000000000 -2.260604961986025507e-01 2.684296998205506907e-06 0.000000000000000000 -2.264164056614071663e-01 8.885109021706287485e-07 0.000000000000000000 -2.267723146931468481e-01 2.269387755172305801e-07 0.000000000000000000 -2.271282232931441103e-01 8.117130274576717298e-07 0.000000000000000000 -2.274841314607211895e-01 2.601350541286858548e-06 0.000000000000000000 -2.278400391952006554e-01 5.403405051271055218e-06 0.000000000000000000 -2.281959464959048556e-01 8.895780203323300507e-06 0.000000000000000000 -2.285518533621561377e-01 1.266439565916192375e-05 0.000000000000000000 -2.289077597932770158e-01 1.625287851587211947e-05 0.000000000000000000 -2.292636657885897267e-01 1.921842375589885143e-05 0.000000000000000000 -2.296195713474168398e-01 2.118711963628318900e-05 0.000000000000000000 -2.299754764690806474e-01 2.190197743659813359e-05 0.000000000000000000 -2.303313811529036359e-01 2.125765812816730969e-05 0.000000000000000000 -2.306872853982081806e-01 1.931737449380772429e-05 0.000000000000000000 -2.310431892043166846e-01 1.630950214887374417e-05 0.000000000000000000 -2.313990925705515234e-01 1.260382386764334503e-05 0.000000000000000000 -2.317549954962352110e-01 8.669782561512120501e-06 0.000000000000000000 -2.321108979806900952e-01 5.021341101723627460e-06 0.000000000000000000 -2.324668000232385512e-01 2.154774729344937035e-06 0.000000000000000000 -2.328227016232030655e-01 4.867389736402934433e-07 0.000000000000000000 -2.331786027799059857e-01 3.001259223516114284e-07 0.000000000000000000 -2.335345034926697427e-01 1.704503440762166951e-06 0.000000000000000000 -2.338904037608167397e-01 4.616387714822101882e-06 0.000000000000000000 -2.342463035836694629e-01 8.762389837498357379e-06 0.000000000000000000 -2.346022029605502601e-01 1.370564444212667862e-05 0.000000000000000000 -2.349581018907815899e-01 1.889317020500523808e-05 0.000000000000000000 -2.353140003736858554e-01 2.371924749966310597e-05 0.000000000000000000 -2.356698984085854320e-01 2.759783143302083051e-05 0.000000000000000000 -2.360257959948028339e-01 3.003570209926986591e-05 0.000000000000000000 -2.363816931316604086e-01 3.069766081847430963e-05 0.000000000000000000 -2.367375898184805871e-01 2.945568273778616204e-05 0.000000000000000000 -2.370934860545858003e-01 2.641549295136802239e-05 0.000000000000000000 -2.374493818392984790e-01 2.191639744937105749e-05 0.000000000000000000 -2.378052771719410818e-01 1.650312997341350603e-05 0.000000000000000000 -2.381611720518359565e-01 1.087165997853145378e-05 0.000000000000000000 -2.385170664783056171e-01 5.793996854177354880e-06 0.000000000000000000 -2.388729604506723836e-01 2.029672430229204538e-06 0.000000000000000000 -2.392288539682587978e-01 2.334762818299180701e-07 0.000000000000000000 -2.395847470303871796e-01 8.699179991498312256e-07 0.000000000000000000 -2.399406396363800431e-01 4.144660474612152276e-06 0.000000000000000000 -2.402965317855597915e-01 9.961791541408701635e-06 0.000000000000000000 -2.406524234772489113e-01 1.791338702387342853e-05 0.000000000000000000 -2.410083147107696944e-01 2.730459304993447634e-05 0.000000000000000000 -2.413642054854447105e-01 3.721374143640554153e-05 0.000000000000000000 -2.417200958005962796e-01 4.658319308735471689e-05 0.000000000000000000 -2.420759856555469991e-01 5.433308529352394223e-05 0.000000000000000000 -2.424318750496191055e-01 5.948732099064817986e-05 0.000000000000000000 -2.427877639821351963e-01 6.129929832590169875e-05 0.000000000000000000 -2.431436524524176190e-01 5.936425581594036036e-05 0.000000000000000000 -2.434995404597888602e-01 5.370579915080085409e-05 0.000000000000000000 -2.438554280035713229e-01 4.482614607596483542e-05 0.000000000000000000 -2.442113150830874935e-01 3.371271321212440799e-05 0.000000000000000000 -2.445672016976597751e-01 2.179759754490732802e-05 0.000000000000000000 -2.449230878466105987e-01 1.087091256722121274e-05 0.000000000000000000 -2.452789735292624784e-01 2.953407623529836242e-06 0.000000000000000000 -2.456348587449377341e-01 1.378965095403991584e-07 0.000000000000000000 -2.459907434929589354e-01 4.412341088162594809e-06 0.000000000000000000 -2.463466277726484299e-01 1.747963651819163614e-05 0.000000000000000000 -2.467025115833287874e-01 4.058998672819138994e-05 0.000000000000000000 -2.470583949243223276e-01 7.440113038936007023e-05 0.000000000000000000 -2.474142777949515648e-01 1.188796107863463163e-04 0.000000000000000000 -2.477701601945389021e-01 1.732529536870416789e-04 0.000000000000000000 -2.481260421224068813e-01 2.360183303176609216e-04 0.000000000000000000 -2.484819235778777946e-01 3.050084408937693602e-04 0.000000000000000000 -2.488378045602742950e-01 3.775104169066744483e-04 0.000000000000000000 -2.491936850689187022e-01 4.504289736652605097e-04 0.000000000000000000 -2.495495651031335027e-01 5.204812724094251422e-04 0.000000000000000000 -2.499054446622411274e-01 5.844083121543468783e-04 0.000000000000000000 -2.502613237455640349e-01 6.391863863911446952e-04 0.000000000000000000 -2.506172023524247394e-01 6.822222950896620307e-04 0.000000000000000000 -2.509730804821456718e-01 7.115175474495154598e-04 0.000000000000000000 -2.513289581340492629e-01 7.257895500113648079e-04 0.000000000000000000 -2.516848353074579991e-01 7.245414708931537757e-04 0.000000000000000000 -2.520407120016943114e-01 7.080767557977541088e-04 0.000000000000000000 -2.523965882160806307e-01 6.774587599310439049e-04 0.000000000000000000 -2.527524639499395542e-01 6.344202646996567390e-04 0.000000000000000000 -2.531083392025934575e-01 5.812314118152217676e-04 0.000000000000000000 -2.534642139733647159e-01 5.205375116692655037e-04 0.000000000000000000 -2.538200882615759268e-01 4.551800505310196515e-04 0.000000000000000000 -2.541759620665495212e-01 3.880149129923076800e-04 0.000000000000000000 -2.545318353876079298e-01 3.217413387649486643e-04 0.000000000000000000 -2.548877082240736391e-01 2.587535382368726274e-04 0.000000000000000000 -2.552435805752691356e-01 2.010243859077969072e-04 0.000000000000000000 -2.555994524405169055e-01 1.500274575711582690e-04 0.000000000000000000 -2.559553238191393243e-01 1.067001875450348863e-04 0.000000000000000000 -2.563111947104590449e-01 7.144742543980928595e-05 0.000000000000000000 -2.566670651137983872e-01 4.418148121403505301e-05 0.000000000000000000 -2.570229350284797820e-01 2.439212957370051342e-05 0.000000000000000000 -2.573788044538258268e-01 1.123819615210764163e-05 0.000000000000000000 -2.577346733891588970e-01 3.651377769462780292e-06 0.000000000000000000 -2.580905418338016455e-01 4.428748279827912932e-07 0.000000000000000000 -2.584464097870762811e-01 4.041659086940563928e-07 0.000000000000000000 -2.588022772483055678e-01 2.394690110333204590e-06 0.000000000000000000 -2.591581442168117699e-01 5.411126126420877825e-06 0.000000000000000000 -2.595140106919174294e-01 8.635144417758657128e-06 0.000000000000000000 -2.598698766729450327e-01 1.145873217275213932e-05 0.000000000000000000 -2.602257421592170661e-01 1.348824097373507993e-05 0.000000000000000000 -2.605816071500560716e-01 1.453001254346222851e-05 0.000000000000000000 -2.609374716447844245e-01 1.456167744160321416e-05 0.000000000000000000 -2.612933356427246112e-01 1.369393122354649354e-05 0.000000000000000000 -2.616491991431992847e-01 1.212776634161773513e-05 0.000000000000000000 -2.620050621455306539e-01 1.011182265544068162e-05 0.000000000000000000 -2.623609246490414826e-01 7.903804347304775398e-06 0.000000000000000000 -2.627167866530541462e-01 5.738915397532913392e-06 0.000000000000000000 -2.630726481568910202e-01 3.807123161115975743e-06 0.000000000000000000 -2.634285091598748130e-01 2.239902932464384948e-06 0.000000000000000000 -2.637843696613278444e-01 1.106064262284895556e-06 0.000000000000000000 -2.641402296605725453e-01 4.154055390482466289e-07 0.000000000000000000 -2.644960891569317352e-01 1.283479844538967136e-07 0.000000000000000000 -2.648519481497275674e-01 1.693895833381682224e-07 0.000000000000000000 -2.652078066382826393e-01 4.421855803582058112e-07 0.000000000000000000 -2.655636646219196040e-01 8.442681586998003212e-07 0.000000000000000000 -2.659195220999608367e-01 1.279805684329238197e-06 0.000000000000000000 -2.662753790717287128e-01 1.669301341198835630e-06 0.000000000000000000 -2.666312355365458853e-01 1.955669443602227276e-06 0.000000000000000000 -2.669870914937347295e-01 2.106638625176283343e-06 0.000000000000000000 -2.673429469426180094e-01 2.113860849524210864e-06 0.000000000000000000 -2.676988018825179338e-01 1.989417564585745452e-06 0.000000000000000000 -2.680546563127571558e-01 1.760592384013312853e-06 0.000000000000000000 -2.684105102326581060e-01 1.463825009865333994e-06 0.000000000000000000 -2.687663636415433821e-01 1.138690952369575721e-06 0.000000000000000000 -2.691222165387354148e-01 8.225944216121352054e-07 0.000000000000000000 -2.694780689235566906e-01 5.466520236472639533e-07 0.000000000000000000 -2.698339207953296959e-01 3.330177657028442152e-07 0.000000000000000000 -2.701897721533771946e-01 1.936866186863442292e-07 0.000000000000000000 -2.705456229970213400e-01 1.306383756205589873e-07 0.000000000000000000 -2.709014733255848406e-01 1.370603049970941533e-07 0.000000000000000000 -2.712573231383901273e-01 1.993209001818383826e-07 0.000000000000000000 -2.716131724347597975e-01 2.993539208881253968e-07 0.000000000000000000 -2.719690212140163377e-01 4.171413717783399900e-07 0.000000000000000000 -2.723248694754821786e-01 5.330417195243628955e-07 0.000000000000000000 -2.726807172184800288e-01 6.297802913672740836e-07 0.000000000000000000 -2.730365644423320970e-01 6.939889455432200900e-07 0.000000000000000000 -2.733924111463612583e-01 7.172419463966876585e-07 0.000000000000000000 -2.737482573298897215e-01 6.965793810952710754e-07 0.000000000000000000 -2.741041029922401950e-01 6.345379895852175783e-07 0.000000000000000000 -2.744599481327350543e-01 5.387253599863911556e-07 0.000000000000000000 -2.748157927506970077e-01 4.209828298957167418e-07 0.000000000000000000 -2.751716368454484862e-01 2.961914239939332171e-07 0.000000000000000000 -2.755274804163119207e-01 1.807888081972191381e-07 0.000000000000000000 -2.758833234626099640e-01 9.108598633582704498e-08 0.000000000000000000 -2.762391659836649915e-01 4.149936874993870342e-08 0.000000000000000000 -2.765950079787997673e-01 4.284260706090866919e-08 0.000000000000000000 -2.769508494473366667e-01 1.008463400533703195e-07 0.000000000000000000 -2.773066903885982315e-01 2.150846751737722855e-07 0.000000000000000000 -2.776625308019069482e-01 3.784773645911775979e-07 0.000000000000000000 -2.780183706865854143e-01 5.775011393897619779e-07 0.000000000000000000 -2.783742100419561161e-01 7.931813542898681220e-07 0.000000000000000000 -2.787300488673416510e-01 1.002849593991517249e-06 0.000000000000000000 -2.790858871620645054e-01 1.182552745946481302e-06 0.000000000000000000 -2.794417249254471658e-01 1.309896939472225696e-06 0.000000000000000000 -2.797975621568122850e-01 1.367020915003293640e-06 0.000000000000000000 -2.801533988554822940e-01 1.343333370951616153e-06 0.000000000000000000 -2.805092350207796792e-01 1.237630997235039906e-06 0.000000000000000000 -2.808650706520272600e-01 1.059246980603195153e-06 0.000000000000000000 -2.812209057485471897e-01 8.279659293138247783e-07 0.000000000000000000 -2.815767403096623434e-01 5.725749114887673110e-07 0.000000000000000000 -2.819325743346951518e-01 3.280884244629944250e-07 0.000000000000000000 -2.822884078229679905e-01 1.318678369264864515e-07 0.000000000000000000 -2.826442407738036233e-01 1.902906699676500189e-08 0.000000000000000000 -2.830000731865244812e-01 1.767063186496526808e-08 0.000000000000000000 -2.833559050604531060e-01 1.445346953632103439e-07 0.000000000000000000 -2.837117363949121507e-01 4.017191631161880995e-07 0.000000000000000000 -2.840675671892240461e-01 7.749808928305430438e-07 0.000000000000000000 -2.844233974427113898e-01 1.234011200423702327e-06 0.000000000000000000 -2.847792271546967235e-01 1.734839009403498591e-06 0.000000000000000000 -2.851350563245025338e-01 2.224248681802033589e-06 0.000000000000000000 -2.854908849514516400e-01 2.645821274249989942e-06 0.000000000000000000 -2.858467130348661400e-01 2.946956387901472803e-06 0.000000000000000000 -2.862025405740689643e-01 3.086043165975969531e-06 0.000000000000000000 -2.865583675683825438e-01 3.038854138485934867e-06 0.000000000000000000 -2.869141940171294758e-01 2.803255276438101838e-06 0.000000000000000000 -2.872700199196321913e-01 2.401466921066061765e-06 0.000000000000000000 -2.876258452752133432e-01 1.879364672651541047e-06 0.000000000000000000 -2.879816700831954734e-01 1.302652615367303123e-06 0.000000000000000000 -2.883374943429012349e-01 7.501354771282871334e-07 0.000000000000000000 -2.886933180536529475e-01 3.047138153896334636e-07 0.000000000000000000 -2.890491412147734862e-01 4.307525183489898607e-08 0.000000000000000000 -2.894049638255851153e-01 2.530565284298806053e-08 0.000000000000000000 -2.897607858854106544e-01 2.857564616730391576e-07 0.000000000000000000 -2.901166073935724232e-01 8.264525758712525465e-07 0.000000000000000000 -2.904724283493931858e-01 1.614103052506884620e-06 0.000000000000000000 -2.908282487521953730e-01 2.581399933099753418e-06 0.000000000000000000 -2.911840686013016932e-01 3.632795187953028304e-06 0.000000000000000000 -2.915398878960346329e-01 4.654386718200645332e-06 0.000000000000000000 -2.918957066357167340e-01 5.526988270841967471e-06 0.000000000000000000 -2.922515248196707605e-01 6.140976291762791942e-06 0.000000000000000000 -2.926073424472189211e-01 6.411166195033439170e-06 0.000000000000000000 -2.929631595176840908e-01 6.289825251788085086e-06 0.000000000000000000 -2.933189760303886451e-01 5.776012526604314983e-06 0.000000000000000000 -2.936747919846554589e-01 4.919754875370242965e-06 0.000000000000000000 -2.940306073798067410e-01 3.820099785938308823e-06 0.000000000000000000 -2.943864222151653109e-01 2.616780325112386209e-06 0.000000000000000000 -2.947422364900537106e-01 1.476010201605695031e-06 0.000000000000000000 -2.950980502037944819e-01 5.717070691808662942e-07 0.000000000000000000 -2.954538633557101668e-01 6.412240753057372628e-08 0.000000000000000000 -2.958096759451234181e-01 7.834452550070047346e-08 0.000000000000000000 -2.961654879713568334e-01 6.853621931580115660e-07 0.000000000000000000 -2.965212994337328989e-01 1.888282195828092748e-06 0.000000000000000000 -2.968771103315741566e-01 3.615871908319725428e-06 0.000000000000000000 -2.972329206642034261e-01 5.724874174167235370e-06 0.000000000000000000 -2.975887304309431380e-01 8.011581401171847166e-06 0.000000000000000000 -2.979445396311158900e-01 1.023205738041955132e-05 0.000000000000000000 -2.983003482640443904e-01 1.212928128217131382e-05 0.000000000000000000 -2.986561563290510146e-01 1.346449172054411452e-05 0.000000000000000000 -2.990119638254584711e-01 1.404925845060793942e-05 0.000000000000000000 -2.993677707525893572e-01 1.377441398177880147e-05 0.000000000000000000 -2.997235771097662149e-01 1.263201197269311112e-05 0.000000000000000000 -3.000793828963118082e-01 1.072697358919602690e-05 0.000000000000000000 -3.004351881115484568e-01 8.276015589527190502e-06 0.000000000000000000 -3.007909927547989803e-01 5.592750990357599034e-06 0.000000000000000000 -3.011467968253859206e-01 3.059393608156355916e-06 0.000000000000000000 -3.015026003226318752e-01 1.087123523656169138e-06 0.000000000000000000 -3.018584032458593858e-01 6.870198431207566763e-08 0.000000000000000000 -3.022142055943911054e-01 3.281790484155284290e-07 0.000000000000000000 -3.025700073675495760e-01 2.073350572859191871e-06 0.000000000000000000 -3.029258085646575061e-01 5.356865534108479539e-06 0.000000000000000000 -3.032816091850374374e-01 1.005148707042055369e-05 0.000000000000000000 -3.036374092280120229e-01 1.584396421990267640e-05 0.000000000000000000 -3.039932086929038602e-01 2.225034066105107379e-05 0.000000000000000000 -3.043490075790354354e-01 2.865344506829487289e-05 0.000000000000000000 -3.047048058857294572e-01 3.436096620741153359e-05 0.000000000000000000 -3.050606036123086340e-01 3.868014611235645562e-05 0.000000000000000000 -3.054164007580953966e-01 4.100297537632336065e-05 0.000000000000000000 -3.057721973224123979e-01 4.089408605212581843e-05 0.000000000000000000 -3.061279933045822910e-01 3.817251605849881054e-05 0.000000000000000000 -3.064837887039277287e-01 3.297831357451005545e-05 0.000000000000000000 -3.068395835197713084e-01 2.581563543152805653e-05 0.000000000000000000 -3.071953777514356276e-01 1.756555963009633845e-05 0.000000000000000000 -3.075511713982432838e-01 9.464180675485895627e-06 0.000000000000000000 -3.079069644595169297e-01 3.044507034260995551e-06 0.000000000000000000 -3.082627569345790519e-01 4.398340847757714896e-08 0.000000000000000000 -3.086185488227524698e-01 2.282819034545636383e-06 0.000000000000000000 -3.089743401233597253e-01 1.152139686764456422e-05 0.000000000000000000 -3.093301308357235269e-01 2.930755494398151056e-05 0.000000000000000000 -3.096859209591663609e-01 5.682619693770850583e-05 0.000000000000000000 -3.100417104930108247e-01 9.476429902232491598e-05 0.000000000000000000 -3.103974994365796825e-01 1.432038230053431064e-04 0.000000000000000000 -3.107532877891955869e-01 2.015533195975139941e-04 0.000000000000000000 -3.111090755501809135e-01 2.685262243218171406e-04 0.000000000000000000 -3.114648627188585928e-01 3.421702341225852360e-04 0.000000000000000000 -3.118206492945510555e-01 4.199480162276016310e-04 0.000000000000000000 -3.121764352765810657e-01 4.988652118315280420e-04 0.000000000000000000 -3.125322206642711653e-01 5.756376463806531490e-04 0.000000000000000000 -3.128880054569440627e-01 6.468862174276704315e-04 0.000000000000000000 -3.132437896539224109e-01 7.093454156871356522e-04 0.000000000000000000 -3.135995732545286963e-01 7.600700738443550613e-04 0.000000000000000000 -3.139553562580856272e-01 7.966248527656674423e-04 0.000000000000000000 -3.143111386639159122e-01 8.172421725655580138e-04 0.000000000000000000 -3.146669204713421486e-01 8.209366706577928387e-04 0.000000000000000000 -3.150227016796869894e-01 8.075676150994425461e-04 0.000000000000000000 -3.153784822882730321e-01 7.778447348757390120e-04 0.000000000000000000 -3.157342622964229295e-01 7.332773113879679887e-04 0.000000000000000000 -3.160900417034595011e-01 6.760707442142153967e-04 0.000000000000000000 -3.164458205087051224e-01 6.089788000728341925e-04 0.000000000000000000 -3.168015987114825016e-01 5.351230501558338921e-04 0.000000000000000000 -3.171573763111144584e-01 4.577933297993463740e-04 0.000000000000000000 -3.175131533069234790e-01 3.802442295203863802e-04 0.000000000000000000 -3.178689296982322166e-01 3.055025600714749053e-04 0.000000000000000000 -3.182247054843633793e-01 2.361994466883514886e-04 0.000000000000000000 -3.185804806646397314e-01 1.744383275514083456e-04 0.000000000000000000 -3.189362552383837590e-01 1.217068847718338990e-04 0.000000000000000000 -3.192920292049181707e-01 7.883712602652217594e-05 0.000000000000000000 -3.196478025635655640e-01 4.601381190489314436e-05 0.000000000000000000 -3.200035753136487027e-01 2.282755119373516877e-05 0.000000000000000000 -3.203593474544901287e-01 8.365502742461869900e-06 0.000000000000000000 -3.207151189854126061e-01 1.330009667573684608e-06 0.000000000000000000 -3.210708899057387877e-01 1.738469328049556589e-07 0.000000000000000000 -3.214266602147912155e-01 3.240183989730661379e-06 0.000000000000000000 -3.217824299118927089e-01 8.895842451567237172e-06 0.000000000000000000 -3.221381989963659209e-01 1.564785868691668445e-05 0.000000000000000000 -3.224939674675335044e-01 2.223555480820218057e-05 0.000000000000000000 -3.228497353247179458e-01 2.769303224896247327e-05 0.000000000000000000 -3.232055025672420645e-01 3.137995208037116482e-05 0.000000000000000000 -3.235612691944285690e-01 3.298137419949766995e-05 0.000000000000000000 -3.239170352056000568e-01 3.248003513699595433e-05 0.000000000000000000 -3.242728006000791807e-01 3.010653800462737939e-05 0.000000000000000000 -3.246285653771887048e-01 2.627435601011819143e-05 0.000000000000000000 -3.249843295362513929e-01 2.150723245195658117e-05 0.000000000000000000 -3.253400930765895649e-01 1.636648913494628371e-05 0.000000000000000000 -3.256958559975262069e-01 1.138499635688629140e-05 0.000000000000000000 -3.260516182983839162e-01 7.013236135102983471e-06 0.000000000000000000 -3.264073799784854013e-01 3.581176347718683289e-06 0.000000000000000000 -3.267631410371532041e-01 1.277763075330528838e-06 0.000000000000000000 -3.271189014737100886e-01 1.479328792824541110e-07 0.000000000000000000 -3.274746612874787632e-01 1.053320521965737384e-07 0.000000000000000000 -3.278304204777819919e-01 9.575590643975668771e-07 0.000000000000000000 -3.281861790439423165e-01 2.439826246235408288e-06 0.000000000000000000 -3.285419369852824456e-01 4.252519956621929194e-06 0.000000000000000000 -3.288976943011250875e-01 6.098222393826246475e-06 0.000000000000000000 -3.292534509907929507e-01 7.714289113043314497e-06 0.000000000000000000 -3.296092070536086882e-01 8.897959065905971439e-06 0.000000000000000000 -3.299649624888950639e-01 9.522085115205666551e-06 0.000000000000000000 -3.303207172959746751e-01 9.540775877614321489e-06 0.000000000000000000 -3.306764714741703415e-01 8.985399923042071508e-06 0.000000000000000000 -3.310322250228045493e-01 7.952402348351219591e-06 0.000000000000000000 -3.313879779412001736e-01 6.585130224865954192e-06 0.000000000000000000 -3.317437302286799228e-01 5.052300637397182621e-06 0.000000000000000000 -3.320994818845662833e-01 3.525854030780806291e-06 0.000000000000000000 -3.324552329081821855e-01 2.160734207667600466e-06 0.000000000000000000 -3.328109832988502270e-01 1.078674408943095866e-06 0.000000000000000000 -3.331667330558931162e-01 3.574203688512575689e-07 0.000000000000000000 -3.335224821786336169e-01 2.607413953109771505e-08 0.000000000000000000 -3.338782306663943267e-01 6.648829611264919592e-08 0.000000000000000000 -3.342339785184980649e-01 4.199633949175347683e-07 0.000000000000000000 -3.345897257342674291e-01 9.979710384795665384e-07 0.000000000000000000 -3.349454723130251832e-01 1.695287220028348825e-06 0.000000000000000000 -3.353012182540939801e-01 2.403796805788598601e-06 0.000000000000000000 -3.356569635567965837e-01 3.025315219469268861e-06 0.000000000000000000 -3.360127082204557580e-01 3.482039556639474930e-06 0.000000000000000000 -3.363684522443941005e-01 3.723642275852057921e-06 0.000000000000000000 -3.367241956279344306e-01 3.730498681319971658e-06 0.000000000000000000 -3.370799383703995122e-01 3.513033107142893611e-06 0.000000000000000000 -3.374356804711117763e-01 3.107619939100319320e-06 0.000000000000000000 -3.377914219293941533e-01 2.569836059633062670e-06 0.000000000000000000 -3.381471627445694628e-01 1.966097199253590031e-06 0.000000000000000000 -3.385029029159602465e-01 1.364805482573432649e-06 0.000000000000000000 -3.388586424428891020e-01 8.280903745782109270e-07 0.000000000000000000 -3.392143813246790707e-01 4.050576360073813127e-07 0.000000000000000000 -3.395701195606526945e-01 1.272009971664955400e-07 0.000000000000000000 -3.399258571501328485e-01 6.317538587169728130e-09 0.000000000000000000 -3.402815940924420191e-01 3.494179267865054903e-08 0.000000000000000000 -3.406373303869030811e-01 1.890148627414501095e-07 0.000000000000000000 -3.409930660328387431e-01 4.322663449509891600e-07 0.000000000000000000 -3.413488010295717134e-01 7.216315554566167344e-07 0.000000000000000000 -3.417045353764247562e-01 1.012965676041129043e-06 0.000000000000000000 -3.420602690727206907e-01 1.266348898552882102e-06 0.000000000000000000 -3.424160021177820035e-01 1.450390361708279202e-06 0.000000000000000000 -3.427717345109315694e-01 1.545112831212648782e-06 0.000000000000000000 -3.431274662514922635e-01 1.543208409701329951e-06 0.000000000000000000 -3.434831973387865722e-01 1.449669975753089475e-06 0.000000000000000000 -3.438389277721373705e-01 1.279997158619713115e-06 0.000000000000000000 -3.441946575508673112e-01 1.057327847579578195e-06 0.000000000000000000 -3.445503866742993249e-01 8.089418971523142475e-07 0.000000000000000000 -3.449061151417559534e-01 5.626163868030299670e-07 0.000000000000000000 -3.452618429525600163e-01 3.432833550452891393e-07 0.000000000000000000 -3.456175701060342220e-01 1.703605056084287724e-07 0.000000000000000000 -3.459732966015015010e-01 5.600768684618338659e-08 0.000000000000000000 -3.463290224382843951e-01 4.424931741379965395e-09 0.000000000000000000 -3.466847476157056129e-01 1.217019990778858870e-08 0.000000000000000000 -3.470404721330880293e-01 6.935370169823737015e-08 0.000000000000000000 -3.473961959897544083e-01 1.614741752560913656e-07 0.000000000000000000 -3.477519191850273472e-01 2.716091001561150535e-07 0.000000000000000000 -3.481076417182297766e-01 3.826583444097986574e-07 0.000000000000000000 -3.484633635886843495e-01 4.793665139293721604e-07 0.000000000000000000 -3.488190847957139962e-01 5.499060975039306139e-07 0.000000000000000000 -3.491748053386413142e-01 5.868809668708009384e-07 0.000000000000000000 -3.495305252167889565e-01 5.876959450836271488e-07 0.000000000000000000 -3.498862444294797980e-01 5.543211978082490599e-07 0.000000000000000000 -3.502419629760367137e-01 4.925500096613590698e-07 0.000000000000000000 -3.505976808557822455e-01 4.108977901007903930e-07 0.000000000000000000 -3.509533980680393794e-01 3.193151133294547723e-07 0.000000000000000000 -3.513091146121306574e-01 2.278880577661219552e-07 0.000000000000000000 -3.516648304873790654e-01 1.456781394357662547e-07 0.000000000000000000 -3.520205456931073118e-01 7.981725480975271201e-08 0.000000000000000000 -3.523762602286379941e-01 3.492719962042973633e-08 0.000000000000000000 -3.527319740932940983e-01 1.288572747968084380e-08 0.000000000000000000 -3.530876872863982774e-01 1.291819944494828076e-08 0.000000000000000000 -3.534433998072732397e-01 3.196049965851401878e-08 0.000000000000000000 -3.537991116552418602e-01 6.521780633286415526e-08 0.000000000000000000 -3.541548228296270140e-01 1.068355484364506463e-07 0.000000000000000000 -3.545105333297512984e-01 1.506020003284180606e-07 0.000000000000000000 -3.548662431549375884e-01 1.906135627075649902e-07 0.000000000000000000 -3.552219523045087035e-01 2.218501836439769351e-07 0.000000000000000000 -3.555776607777871856e-01 2.406259164864611462e-07 0.000000000000000000 -3.559333685740961317e-01 2.448952845644259314e-07 0.000000000000000000 -3.562890756927580282e-01 2.344080629599235168e-07 0.000000000000000000 -3.566447821330959167e-01 2.107127943063855377e-07 0.000000000000000000 -3.570004878944324500e-01 1.770136189345231823e-07 0.000000000000000000 -3.573561929760903921e-01 1.378875675534673035e-07 0.000000000000000000 -3.577118973773926180e-01 9.887251627813323997e-08 0.000000000000000000 -3.580676010976618917e-01 6.594153480189665209e-08 0.000000000000000000 -3.584233041362209771e-01 4.488859638175557491e-08 0.000000000000000000 -3.587790064923925826e-01 4.066358372350814281e-08 0.000000000000000000 -3.591347081654997497e-01 5.670983067791766599e-08 0.000000000000000000 -3.594904091548650205e-01 9.437238041185259996e-08 0.000000000000000000 -3.598461094598112697e-01 1.524560761811534110e-07 0.000000000000000000 -3.602018090796613170e-01 2.270155856088429442e-07 0.000000000000000000 -3.605575080137380373e-01 3.114510245556564805e-07 0.000000000000000000 -3.609132062613640279e-01 3.969608064539795251e-07 0.000000000000000000 -3.612689038218623305e-01 4.733674852298133184e-07 0.000000000000000000 -3.616246006945555425e-01 5.302848867845921634e-07 0.000000000000000000 -3.619802968787665942e-01 5.585404383634335394e-07 0.000000000000000000 -3.623359923738181942e-01 5.517121859915188679e-07 0.000000000000000000 -3.626916871790332175e-01 5.075938604008694404e-07 0.000000000000000000 -3.630473812937344835e-01 4.293722050597392659e-07 0.000000000000000000 -3.634030747172447562e-01 3.262963926035103313e-07 0.000000000000000000 -3.637587674488868550e-01 2.136452555297714929e-07 0.000000000000000000 -3.641144594879835994e-01 1.118563391667006283e-07 0.000000000000000000 -3.644701508338578089e-01 4.476927194426336868e-08 0.000000000000000000 -3.648258414858323029e-01 3.704784833312698697e-08 0.000000000000000000 -3.651815314432297344e-01 1.109693951515426210e-07 0.000000000000000000 -3.655372207053732003e-01 2.828918625967232155e-07 0.000000000000000000 -3.658929092715854092e-01 5.598121167912022869e-07 0.000000000000000000 -3.662485971411891250e-01 9.364965665689122057e-07 0.000000000000000000 -3.666042843135071672e-01 1.393683148003502224e-06 0.000000000000000000 -3.669599707878624661e-01 1.897811733783449531e-06 0.000000000000000000 -3.673156565635776749e-01 2.402634287333163100e-06 0.000000000000000000 -3.676713416399758350e-01 2.852889994529023483e-06 0.000000000000000000 -3.680270260163794882e-01 3.190015486214992219e-06 0.000000000000000000 -3.683827096921117872e-01 3.359614808837336454e-06 0.000000000000000000 -3.687383926664952738e-01 3.320162672191834438e-06 0.000000000000000000 -3.690940749388529341e-01 3.052186046609207450e-06 0.000000000000000000 -3.694497565085075319e-01 2.566992473201096908e-06 0.000000000000000000 -3.698054373747819978e-01 1.913914988121897946e-06 0.000000000000000000 -3.701611175369990403e-01 1.185043953483522797e-06 0.000000000000000000 -3.705167969944815343e-01 5.165271291903117811e-07 0.000000000000000000 -3.708724757465524657e-01 8.574182318949783467e-08 0.000000000000000000 -3.712281537925343766e-01 1.039656391150682944e-07 0.000000000000000000 -3.715838311317504195e-01 8.045719712357218184e-07 0.000000000000000000 -3.719395077635231917e-01 2.427219291460662701e-06 0.000000000000000000 -3.722951836871756792e-01 5.198948048028036066e-06 0.000000000000000000 -3.726508589020308126e-01 9.313500383653400445e-06 0.000000000000000000 -3.730065334074110783e-01 1.491049125934540941e-05 0.000000000000000000 -3.733622072026396288e-01 2.205624574872812327e-05 0.000000000000000000 -3.737178802870392280e-01 3.072814702908325911e-05 0.000000000000000000 -3.740735526599326954e-01 4.080419746910782876e-05 0.000000000000000000 -3.744292243206429616e-01 5.205918201281495999e-05 0.000000000000000000 -3.747848952684927348e-01 6.416835683033329297e-05 0.000000000000000000 -3.751405655028050568e-01 7.671900138768749961e-05 0.000000000000000000 -3.754962350229026358e-01 8.922951688373978462e-05 0.000000000000000000 -3.758519038281084579e-01 1.011750861797404064e-04 0.000000000000000000 -3.762075719177452315e-01 1.120182918414781457e-04 0.000000000000000000 -3.765632392911358317e-01 1.212425797986380987e-04 0.000000000000000000 -3.769189059476031889e-01 1.283861085671017066e-04 0.000000000000000000 -3.772745718864701781e-01 1.330733768013294413e-04 0.000000000000000000 -3.776302371070596742e-01 1.350420964145651191e-04 0.000000000000000000 -3.779859016086944412e-01 1.341630757350874411e-04 0.000000000000000000 -3.783415653906972986e-01 1.304513774748465344e-04 0.000000000000000000 -3.786972284523913990e-01 1.240676805287288585e-04 0.000000000000000000 -3.790528907930993952e-01 1.153095474682144968e-04 0.000000000000000000 -3.794085524121439956e-01 1.045931143860401292e-04 0.000000000000000000 -3.797642133088482974e-01 9.242650455555936006e-05 0.000000000000000000 -3.801198734825353420e-01 7.937695166102082755e-05 0.000000000000000000 -3.804755329325276159e-01 6.603413968138079938e-05 0.000000000000000000 -3.808311916581481604e-01 5.297257655123509246e-05 0.000000000000000000 -3.811868496587199617e-01 4.071588810764252049e-05 0.000000000000000000 -3.815425069335656727e-01 2.970574020930361525e-05 0.000000000000000000 -3.818981634820084459e-01 2.027768593801681135e-05 0.000000000000000000 -3.822538193033709342e-01 1.264562882748508832e-05 0.000000000000000000 -3.826094743969760681e-01 6.895847739550726173e-06 0.000000000000000000 -3.829651287621468891e-01 2.990712881674291635e-06 0.000000000000000000 -3.833207823982059947e-01 7.814103533743625335e-07 0.000000000000000000 -3.836764353044764819e-01 2.825830193953688667e-08 0.000000000000000000 -3.840320874802811701e-01 4.266067991471513432e-07 0.000000000000000000 -3.843877389249429899e-01 1.635916922019445182e-06 0.000000000000000000 -3.847433896377847606e-01 3.309443924535430398e-06 0.000000000000000000 -3.850990396181294684e-01 5.122014455172035639e-06 0.000000000000000000 -3.854546888652999326e-01 6.793675582512761987e-06 0.000000000000000000 -3.858103373786190282e-01 8.107470216963528188e-06 0.000000000000000000 -3.861659851574096858e-01 8.920208620013377282e-06 0.000000000000000000 -3.865216322009948358e-01 9.165796671134573921e-06 0.000000000000000000 -3.868772785086974642e-01 8.851380715886959644e-06 0.000000000000000000 -3.872329240798401684e-01 8.047209865310652198e-06 0.000000000000000000 -3.875885689137461565e-01 6.871641097465341151e-06 0.000000000000000000 -3.879442130097381924e-01 5.473075265997156527e-06 0.000000000000000000 -3.882998563671392067e-01 4.010785317230856067e-06 0.000000000000000000 -3.886554989852719633e-01 2.636573375576141611e-06 0.000000000000000000 -3.890111408634595591e-01 1.478982367802183436e-06 0.000000000000000000 -3.893667820010249248e-01 6.314200147001840859e-07 0.000000000000000000 -3.897224223972907686e-01 1.450722793696093082e-07 0.000000000000000000 -3.900780620515802433e-01 2.694321508231597951e-08 0.000000000000000000 -3.904337009632160016e-01 2.428158555352135424e-07 0.000000000000000000 -3.907893391315212517e-01 7.244393574375254894e-07 0.000000000000000000 -3.911449765558186464e-01 1.379858248570811129e-06 0.000000000000000000 -3.915006132354312274e-01 2.105545166836161007e-06 0.000000000000000000 -3.918562491696819250e-01 2.798898187648370571e-06 0.000000000000000000 -3.922118843578935588e-01 3.369720112390561608e-06 0.000000000000000000 -3.925675187993891702e-01 3.749495855656401992e-06 0.000000000000000000 -3.929231524934915787e-01 3.897596958315291011e-06 0.000000000000000000 -3.932787854395238814e-01 3.803930200648835265e-06 0.000000000000000000 -3.936344176368087866e-01 3.487965107200239915e-06 0.000000000000000000 -3.939900490846692804e-01 2.994476561238153772e-06 0.000000000000000000 -3.943456797824283488e-01 2.386681411705897317e-06 0.000000000000000000 -3.947013097294089778e-01 1.737697740508298500e-06 0.000000000000000000 -3.950569389249338759e-01 1.121389811844372166e-06 0.000000000000000000 -3.954125673683261399e-01 6.036716188500071956e-07 0.000000000000000000 -3.957681950589087005e-01 2.352322978855664252e-07 0.000000000000000000 -3.961238219960045437e-01 4.643527595075079844e-08 0.000000000000000000 -3.964794481789364888e-01 4.485803482753671181e-08 0.000000000000000000 -3.968350736070275220e-01 2.156159022387486820e-07 0.000000000000000000 -3.971906982796005736e-01 5.242891685490664411e-07 0.000000000000000000 -3.975463221959786297e-01 9.219844043230975303e-07 0.000000000000000000 -3.979019453554845098e-01 1.351838949382799242e-06 0.000000000000000000 -3.982575677574412554e-01 1.756144272911112141e-06 0.000000000000000000 -3.986131894011718524e-01 2.083230535169551150e-06 0.000000000000000000 -3.989688102859991758e-01 2.293320791889986261e-06 0.000000000000000000 -3.993244304112460452e-01 2.362717249930910011e-06 0.000000000000000000 -3.996800497762358351e-01 2.285902710879557621e-06 0.000000000000000000 -4.000356683802910318e-01 2.075399981414209593e-06 0.000000000000000000 -4.003912862227348435e-01 1.759499372815496532e-06 0.000000000000000000 -4.007469033028899785e-01 1.378208522689532031e-06 0.000000000000000000 -4.011025196200798115e-01 9.779724834814673137e-07 0.000000000000000000 -4.014581351736268844e-01 6.058348872801351951e-07 0.000000000000000000 -4.018137499628543496e-01 3.037513848372950806e-07 0.000000000000000000 -4.021693639870851933e-01 1.037226923184815984e-07 0.000000000000000000 -4.025249772456424013e-01 2.429442716946531876e-08 0.000000000000000000 -4.028805897378487377e-01 6.879096476438050340e-08 0.000000000000000000 -4.032362014630272440e-01 2.254336626393015285e-07 0.000000000000000000 -4.035918124205009616e-01 4.692663947786272162e-07 0.000000000000000000 -4.039474226095929321e-01 7.656002373561609821e-07 0.000000000000000000 -4.043030320296259195e-01 1.074518475153850660e-06 0.000000000000000000 -4.046586406799229652e-01 1.355871575682607467e-06 0.000000000000000000 -4.050142485598071662e-01 1.574150712082092990e-06 0.000000000000000000 -4.053698556686013976e-01 1.702660596667376855e-06 0.000000000000000000 -4.057254620056285344e-01 1.726511999275805487e-06 0.000000000000000000 -4.060810675702117289e-01 1.644107851805160571e-06 0.000000000000000000 -4.064366723616739119e-01 1.466984833016855353e-06 0.000000000000000000 -4.067922763793379026e-01 1.218071810561058374e-06 0.000000000000000000 -4.071478796225269092e-01 9.286137433350256450e-07 0.000000000000000000 -4.075034820905637512e-01 6.341628752616245574e-07 0.000000000000000000 -4.078590837827715254e-01 3.701410266053757913e-07 0.000000000000000000 -4.082146846984731070e-01 1.675166504761680198e-07 0.000000000000000000 -4.085702848369915929e-01 4.911473036417218732e-08 0.000000000000000000 -4.089258841976499692e-01 2.699096187502378372e-08 0.000000000000000000 -4.092814827797710553e-01 1.011654801289741868e-07 0.000000000000000000 -4.096370805826779482e-01 2.598427518917470782e-07 0.000000000000000000 -4.099926776056936895e-01 4.810637268023040598e-07 0.000000000000000000 -4.103482738481413206e-01 7.355655291835660116e-07 0.000000000000000000 -4.107038693093437165e-01 9.904829326026218095e-07 0.000000000000000000 -4.110594639886238078e-01 1.213430798805664933e-06 0.000000000000000000 -4.114150578853046358e-01 1.376468095981564293e-06 0.000000000000000000 -4.117706509987095198e-01 1.459465725093900414e-06 0.000000000000000000 -4.121262433281610571e-01 1.452478712505188800e-06 0.000000000000000000 -4.124818348729823447e-01 1.356848272330167787e-06 0.000000000000000000 -4.128374256324964242e-01 1.184915349208938003e-06 0.000000000000000000 -4.131930156060264481e-01 9.583956000239150549e-07 0.000000000000000000 -4.135486047928950692e-01 7.056262356370750265e-07 0.000000000000000000 -4.139041931924256068e-01 4.580287640402134143e-07 0.000000000000000000 -4.142597808039410467e-01 2.462228744358057969e-07 0.000000000000000000 -4.146153676267643196e-01 9.626506355102191712e-08 0.000000000000000000 -4.149709536602183002e-01 2.646705077338114691e-08 0.000000000000000000 -4.153265389036263078e-01 4.517622899398817427e-08 0.000000000000000000 -4.156821233563112172e-01 1.497824031262526863e-07 0.000000000000000000 -4.160377070175959036e-01 3.270661915385643299e-07 0.000000000000000000 -4.163932898868034638e-01 5.548425642647716937e-07 0.000000000000000000 -4.167488719632571059e-01 8.046973466467927772e-07 0.000000000000000000 -4.171044532462796495e-01 1.045483561974146509e-06 0.000000000000000000 -4.174600337351942470e-01 1.247153653392108502e-06 0.000000000000000000 -4.178156134293237178e-01 1.384463552529197987e-06 0.000000000000000000 -4.181711923279914367e-01 1.440099874809658628e-06 0.000000000000000000 -4.185267704305199454e-01 1.406850316541905431e-06 0.000000000000000000 -4.188823477362327297e-01 1.288551423655530982e-06 0.000000000000000000 -4.192379242444525533e-01 1.099693808311253075e-06 0.000000000000000000 -4.195934999545026245e-01 8.637253996008082035e-07 0.000000000000000000 -4.199490748657058181e-01 6.102495108734476940e-07 0.000000000000000000 -4.203046489773852312e-01 3.714479644689056146e-07 0.000000000000000000 -4.206602222888640719e-01 1.781544444826542668e-07 0.000000000000000000 -4.210157947994650485e-01 5.604832791898397735e-08 0.000000000000000000 -4.213713665085113691e-01 2.242893952061704409e-08 0.000000000000000000 -4.217269374153261308e-01 8.396538951196736575e-08 0.000000000000000000 -4.220825075192322640e-01 2.357051390056722686e-07 0.000000000000000000 -4.224380768195528657e-01 4.614779753594248125e-07 0.000000000000000000 -4.227936453156110885e-01 7.356680195934601181e-07 0.000000000000000000 -4.231492130067298074e-01 1.026163721871216185e-06 0.000000000000000000 -4.235047798922321749e-01 1.298153484415789150e-06 0.000000000000000000 -4.238603459714412325e-01 1.518329324929950909e-06 0.000000000000000000 -4.242159112436799107e-01 1.659005453906985410e-06 0.000000000000000000 -4.245714757082713620e-01 1.701659776068872395e-06 0.000000000000000000 -4.249270393645387944e-01 1.639464694765798013e-06 0.000000000000000000 -4.252826022118049165e-01 1.478483218063546968e-06 0.000000000000000000 -4.256381642493931028e-01 1.237355357306488869e-06 0.000000000000000000 -4.259937254766262282e-01 9.454716992468190786e-07 0.000000000000000000 -4.263492858928275009e-01 6.398065772428534852e-07 0.000000000000000000 -4.267048454973199068e-01 3.607425938485194593e-07 0.000000000000000000 -4.270604042894264318e-01 1.473430795562211982e-07 0.000000000000000000 -4.274159622684702842e-01 3.260478420126560006e-08 0.000000000000000000 -4.277715194337743387e-01 3.924037324604156029e-08 0.000000000000000000 -4.281270757846618591e-01 1.764962160182985160e-07 0.000000000000000000 -4.284826313204558867e-01 4.384093503582473349e-07 0.000000000000000000 -4.288381860404794632e-01 8.037586306771793350e-07 0.000000000000000000 -4.291937399440555745e-01 1.237784479515538720e-06 0.000000000000000000 -4.295492930305074841e-01 1.695558587246551313e-06 0.000000000000000000 -4.299048452991581226e-01 2.126700142585162750e-06 0.000000000000000000 -4.302603967493306425e-01 2.480978857419584025e-06 0.000000000000000000 -4.306159473803479742e-01 2.714234444667615487e-06 0.000000000000000000 -4.309714971915332704e-01 2.793989853349957369e-06 0.000000000000000000 -4.313270461822099056e-01 2.704147894465562304e-06 0.000000000000000000 -4.316825943517004771e-01 2.448237526420163159e-06 0.000000000000000000 -4.320381416993284152e-01 2.050809840510539825e-06 0.000000000000000000 -4.323936882244167057e-01 1.556761479859658387e-06 0.000000000000000000 -4.327492339262884458e-01 1.028566961762167756e-06 0.000000000000000000 -4.331047788042666769e-01 5.416104873553339844e-07 0.000000000000000000 -4.334603228576746070e-01 1.780010178811160334e-07 0.000000000000000000 -4.338158660858351667e-01 1.941196507400915054e-08 0.000000000000000000 -4.341714084880715641e-01 1.395927025062533572e-07 0.000000000000000000 -4.345269500637068405e-01 5.972424495164063513e-07 0.000000000000000000 -4.348824908120642041e-01 1.429913468563890590e-06 0.000000000000000000 -4.352380307324666409e-01 2.649522291109147683e-06 0.000000000000000000 -4.355935698242373588e-01 4.239903676261069155e-06 0.000000000000000000 -4.359491080866992330e-01 6.156656565291469703e-06 0.000000000000000000 -4.363046455191755824e-01 8.329322776808783117e-06 0.000000000000000000 -4.366601821209895595e-01 1.066572802236432625e-05 0.000000000000000000 -4.370157178914641505e-01 1.305812141316229239e-05 0.000000000000000000 -4.373712528299223967e-01 1.539059228446236399e-05 0.000000000000000000 -4.377267869356875618e-01 1.754713629499684411e-05 0.000000000000000000 -4.380823202080826317e-01 1.941969550919575300e-05 0.000000000000000000 -4.384378526464309811e-01 2.091551263213001869e-05 0.000000000000000000 -4.387933842500553738e-01 2.196321463139480320e-05 0.000000000000000000 -4.391489150182791290e-01 2.251716682832167655e-05 0.000000000000000000 -4.395044449504252881e-01 2.255980170365015064e-05 0.000000000000000000 -4.398599740458170038e-01 2.210181051791195952e-05 0.000000000000000000 -4.402155023037774284e-01 2.118027238618788873e-05 0.000000000000000000 -4.405710297236297701e-01 1.985496711762554960e-05 0.000000000000000000 -4.409265563046969039e-01 1.820325956409611973e-05 0.000000000000000000 -4.412820820463021487e-01 1.631404266897297931e-05 0.000000000000000000 -4.416376069477686572e-01 1.428127674639221193e-05 0.000000000000000000 -4.419931310084194709e-01 1.219766175371391640e-05 0.000000000000000000 -4.423486542275775757e-01 1.014893051957592798e-05 0.000000000000000000 -4.427041766045663462e-01 8.209161630290013963e-06 0.000000000000000000 -4.430596981387089905e-01 6.437392032412252927e-06 0.000000000000000000 -4.434152188293282726e-01 4.875674633252669459e-06 0.000000000000000000 -4.437707386757476780e-01 3.548589239852201363e-06 0.000000000000000000 -4.441262576772901927e-01 2.464089281386492051e-06 0.000000000000000000 -4.444817758332790802e-01 1.615463064405061411e-06 0.000000000000000000 -4.448372931430373267e-01 9.841149068830808675e-07 0.000000000000000000 -4.451928096058881401e-01 5.428327945135981842e-07 0.000000000000000000 -4.455483252211546175e-01 2.592057401671960534e-07 0.000000000000000000 -4.459038399881600778e-01 9.888271315383753221e-08 0.000000000000000000 -4.462593539062274517e-01 2.841972928710609103e-08 0.000000000000000000 -4.466148669746800581e-01 1.753422394399019979e-08 0.000000000000000000 -4.469703791928409942e-01 4.066687379768543509e-08 0.000000000000000000 -4.473258905600334123e-01 7.783132623673237654e-08 0.000000000000000000 -4.476814010755804651e-01 1.148036128189290779e-07 0.000000000000000000 -4.480369107388051941e-01 1.427589825661378983e-07 0.000000000000000000 -4.483924195490310849e-01 1.575004873471197338e-07 0.000000000000000000 -4.487479275055809014e-01 1.584394739050627530e-07 0.000000000000000000 -4.491034346077780182e-01 1.474842686391492427e-07 0.000000000000000000 -4.494589408549456433e-01 1.279729791491896671e-07 0.000000000000000000 -4.498144462464068738e-01 1.037541964240810477e-07 0.000000000000000000 -4.501699507814848067e-01 7.848097535800238119e-08 0.000000000000000000 -4.505254544595028166e-01 5.514435553885443344e-08 0.000000000000000000 -4.508809572797838894e-01 3.583777262481576580e-08 0.000000000000000000 -4.512364592416512332e-01 2.171673093073071309e-08 0.000000000000000000 -4.515919603444279451e-01 1.310126000169013627e-08 0.000000000000000000 -4.519474605874373996e-01 9.662520362135993957e-09 0.000000000000000000 -4.523029599700026382e-01 1.063848463514328415e-08 0.000000000000000000 -4.526584584914469245e-01 1.503470246366209938e-08 0.000000000000000000 -4.530139561510933000e-01 2.178178027859237438e-08 0.000000000000000000 -4.533694529482650837e-01 2.983811587189905443e-08 0.000000000000000000 -4.537249488822854282e-01 3.824159958933605769e-08 0.000000000000000000 -4.540804439524774860e-01 4.612506459353170090e-08 0.000000000000000000 -4.544359381581645208e-01 5.271583124996346210e-08 0.000000000000000000 -4.547914314986695183e-01 5.733942976645156886e-08 0.000000000000000000 -4.551469239733159644e-01 5.944223700002027910e-08 0.000000000000000000 -4.555024155814267339e-01 5.863891812972829075e-08 0.000000000000000000 -4.558579063223253125e-01 5.478034742874018498e-08 0.000000000000000000 -4.562133961953347971e-01 4.802836921788963717e-08 0.000000000000000000 -4.565688851997783959e-01 3.891737966638151439e-08 0.000000000000000000 -4.569243733349790948e-01 2.838070523941004073e-08 0.000000000000000000 -4.572798606002603794e-01 1.772274202155022524e-08 0.000000000000000000 -4.576353469949453467e-01 8.525493237508245431e-09 0.000000000000000000 -4.579908325183571494e-01 2.489314309723645914e-09 0.000000000000000000 -4.583463171698189953e-01 1.220473658615476664e-09 0.000000000000000000 -4.587018009486542591e-01 5.990307144295503266e-09 0.000000000000000000 -4.590572838541859824e-01 1.750001232798627313e-08 0.000000000000000000 -4.594127658857374286e-01 3.568958424707874015e-08 0.000000000000000000 -4.597682470426318058e-01 5.962781561784359318e-08 0.000000000000000000 -4.601237273241923775e-01 8.751236942928215896e-08 0.000000000000000000 -4.604792067297421854e-01 1.167953923988647846e-07 0.000000000000000000 -4.608346852586046039e-01 1.444326392725710941e-07 0.000000000000000000 -4.611901629101028410e-01 1.672350315930169861e-07 0.000000000000000000 -4.615456396835601605e-01 1.822838065259814444e-07 0.000000000000000000 -4.619011155782996036e-01 1.873567551138942862e-07 0.000000000000000000 -4.622565905936446007e-01 1.813059180270696272e-07 0.000000000000000000 -4.626120647289183041e-01 1.643281075109256732e-07 0.000000000000000000 -4.629675379834438664e-01 1.380792715856193417e-07 0.000000000000000000 -4.633230103565444957e-01 1.056012922565860734e-07 0.000000000000000000 -4.636784818475435666e-01 7.105339228527581322e-08 0.000000000000000000 -4.640339524557642870e-01 3.926699563207291785e-08 0.000000000000000000 -4.643894221805298095e-01 1.516908547831722462e-08 0.000000000000000000 -4.647448910211634532e-01 3.141098362343917982e-09 0.000000000000000000 -4.651003589769883706e-01 6.394794456871191003e-09 0.000000000000000000 -4.654558260473278808e-01 2.645080236646428772e-08 0.000000000000000000 -4.658112922315051918e-01 6.279834594836479413e-08 0.000000000000000000 -4.661667575288434562e-01 1.127962126486206553e-07 0.000000000000000000 -4.665222219386659930e-01 1.718470693312717028e-07 0.000000000000000000 -4.668776854602961768e-01 2.338429346237037478e-07 0.000000000000000000 -4.672331480930571046e-01 2.918431995063168645e-07 0.000000000000000000 -4.675886098362719845e-01 3.389128224014940686e-07 0.000000000000000000 -4.679440706892640800e-01 3.690219194053525713e-07 0.000000000000000000 -4.682995306513569878e-01 3.778929315508253624e-07 0.000000000000000000 -4.686549897218734162e-01 3.636806086297762160e-07 0.000000000000000000 -4.690104479001370175e-01 3.273842190446843386e-07 0.000000000000000000 -4.693659051854708886e-01 2.729197485577245796e-07 0.000000000000000000 -4.697213615771982376e-01 2.068195284378954437e-07 0.000000000000000000 -4.700768170746424945e-01 1.375732157735331682e-07 0.000000000000000000 -4.704322716771267565e-01 7.467165809605995387e-08 0.000000000000000000 -4.707877253839744536e-01 2.745775605424428615e-08 0.000000000000000000 -4.711431781945087383e-01 3.920137721467226756e-09 0.000000000000000000 -4.714986301080528741e-01 9.581502794204269406e-09 0.000000000000000000 -4.718540811239301802e-01 4.663087116929062306e-08 0.000000000000000000 -4.722095312414638646e-01 1.134269116433501193e-07 0.000000000000000000 -4.725649804599772463e-01 2.044597342637353353e-07 0.000000000000000000 -4.729204287787935890e-01 3.108050879864997087e-07 0.000000000000000000 -4.732758761972362671e-01 4.210438832359786350e-07 0.000000000000000000 -4.736313227146283777e-01 5.225587398857735017e-07 0.000000000000000000 -4.739867683302932955e-01 6.030656673567305378e-07 0.000000000000000000 -4.743422130435543949e-01 6.522003008034031337e-07 0.000000000000000000 -4.746976568537348284e-01 6.629601381382001747e-07 0.000000000000000000 -4.750530997601578598e-01 6.328104296400525398e-07 0.000000000000000000 -4.754085417621468634e-01 5.642923729288309265e-07 0.000000000000000000 -4.757639828590249920e-01 4.650255633309030831e-07 0.000000000000000000 -4.761194230501157865e-01 3.470667886024187181e-07 0.000000000000000000 -4.764748623347422884e-01 2.256663549909615972e-07 0.000000000000000000 -4.768303007122279835e-01 1.175417383366281090e-07 0.000000000000000000 -4.771857381818961352e-01 3.885655237987243722e-08 0.000000000000000000 -4.775411747430698961e-01 3.141449466589613392e-09 0.000000000000000000 -4.778966103950725852e-01 1.941538495266626609e-08 0.000000000000000000 -4.782520451372276327e-01 9.075639674577749321e-08 0.000000000000000000 -4.786074789688583575e-01 2.135300223087796743e-07 0.000000000000000000 -4.789629118892878012e-01 3.774139582891510553e-07 0.000000000000000000 -4.793183438978396160e-01 5.662665469681741883e-07 0.000000000000000000 -4.796737749938369544e-01 7.597841949101129317e-07 0.000000000000000000 -4.800292051766030244e-01 9.357909270195469974e-07 0.000000000000000000 -4.803846344454613115e-01 1.072914603029309734e-06 0.000000000000000000 -4.807400627997350240e-01 1.153340616848146571e-06 0.000000000000000000 -4.810954902387474807e-01 1.165304510942202751e-06 0.000000000000000000 -4.814509167618220009e-01 1.104995547280542237e-06 0.000000000000000000 -4.818063423682819590e-01 9.775949979815834186e-07 0.000000000000000000 -4.821617670574505632e-01 7.972619141424027438e-07 0.000000000000000000 -4.825171908286513545e-01 5.859967983775801941e-07 0.000000000000000000 -4.828726136812074299e-01 3.714473538108323349e-07 0.000000000000000000 -4.832280356144422195e-01 1.838550235386639373e-07 0.000000000000000000 -4.835834566276789870e-01 5.246007664103314381e-08 0.000000000000000000 -4.839388767202411068e-01 1.771138369161038603e-09 0.000000000000000000 -4.842942958914519536e-01 4.814968960615295786e-08 0.000000000000000000 -4.846497141406346798e-01 1.971530153567530390e-07 0.000000000000000000 -4.850051314671129377e-01 4.420178892310001806e-07 0.000000000000000000 -4.853605478702097131e-01 7.635557729870845032e-07 0.000000000000000000 -4.857159633492485473e-01 1.131578538338854011e-06 0.000000000000000000 -4.860713779035527593e-01 1.507797126818346210e-06 0.000000000000000000 -4.864267915324456681e-01 1.849953486757044708e-06 0.000000000000000000 -4.867822042352505929e-01 2.116779749106213189e-06 0.000000000000000000 -4.871376160112908527e-01 2.273248596734296455e-06 0.000000000000000000 -4.874930268598898775e-01 2.295502871312581224e-06 0.000000000000000000 -4.878484367803710420e-01 2.174843209385597620e-06 0.000000000000000000 -4.882038457720576097e-01 1.920215556181015545e-06 0.000000000000000000 -4.885592538342727886e-01 1.558773465161453583e-06 0.000000000000000000 -4.889146609663402865e-01 1.134282687422472369e-06 0.000000000000000000 -4.892700671675832558e-01 7.033697742002953981e-07 0.000000000000000000 -4.896254724373250711e-01 3.298684826120591000e-07 0.000000000000000000 -4.899808767748889404e-01 7.776037911000820668e-08 0.000000000000000000 -4.903362801795985715e-01 3.411176641095765047e-09 0.000000000000000000 -4.906916826507769502e-01 1.479464028882873123e-07 0.000000000000000000 -4.910470841877476733e-01 5.306687164134530613e-07 0.000000000000000000 -4.914024847898340598e-01 1.144382197095129539e-06 0.000000000000000000 -4.917578844563594842e-01 1.953353565509562970e-06 0.000000000000000000 -4.921132831866473767e-01 2.894414390779074731e-06 0.000000000000000000 -4.924686809800208898e-01 3.881410040957273238e-06 0.000000000000000000 -4.928240778358036200e-01 4.812857381723305568e-06 0.000000000000000000 -4.931794737533187756e-01 5.582317436969448734e-06 0.000000000000000000 -4.935348687318898420e-01 6.090657997305091923e-06 0.000000000000000000 -4.938902627708400828e-01 6.259110613024774220e-06 0.000000000000000000 -4.942456558694931501e-01 6.041848350222915101e-06 0.000000000000000000 -4.946010480271720300e-01 5.436749128693112121e-06 0.000000000000000000 -4.949564392432004856e-01 4.493077768711678829e-06 0.000000000000000000 -4.953118295169017249e-01 3.315018947528392533e-06 0.000000000000000000 -4.956672188475991225e-01 2.060310899757753805e-06 0.000000000000000000 -4.960226072346160531e-01 9.336412603333653863e-07 0.000000000000000000 -4.963779946772758911e-01 1.749368468727900783e-07 0.000000000000000000 -4.967333811749020667e-01 4.316591838060171268e-08 0.000000000000000000 -4.970887667268181764e-01 7.967285609878296016e-07 0.000000000000000000 -4.974441513323472619e-01 2.671893295680360283e-06 0.000000000000000000 -4.977995349908129752e-01 5.861006120123578346e-06 0.000000000000000000 -4.981549177015386354e-01 1.049232179075205171e-05 0.000000000000000000 -4.985102994638475615e-01 1.661326875678320435e-05 0.000000000000000000 -4.988656802770632392e-01 2.417875614389178456e-05 0.000000000000000000 -4.992210601405089876e-01 3.304577644319349857e-05 0.000000000000000000 -4.995764390535085142e-01 4.297507866439970902e-05 0.000000000000000000 -4.999318170153848606e-01 5.364012359314078904e-05 0.000000000000000000 -5.002871940254615124e-01 6.464293414593171884e-05 0.000000000000000000 -5.006425700830620107e-01 7.553587257457403874e-05 0.000000000000000000 -5.009979451875098411e-01 8.584786461065854724e-05 0.000000000000000000 -5.013533193381281006e-01 9.511319501886554030e-05 0.000000000000000000 -5.017086925342405523e-01 1.029007557696417282e-04 0.000000000000000000 -5.020640647751702934e-01 1.088415598947611797e-04 0.000000000000000000 -5.024194360602410869e-01 1.126524481082640552e-04 0.000000000000000000 -5.027748063887760299e-01 1.141542021862283768e-04 0.000000000000000000 -5.031301757600986635e-01 1.132827142336810051e-04 0.000000000000000000 -5.034855441735326398e-01 1.100924065861112982e-04 0.000000000000000000 -5.038409116284010558e-01 1.047517059284283164e-04 0.000000000000000000 -5.041962781240275637e-01 9.753099479446994033e-05 0.000000000000000000 -5.045516436597354826e-01 8.878404106356167205e-05 0.000000000000000000 -5.049070082348482424e-01 7.892439285388931733e-05 0.000000000000000000 -5.052623718486892734e-01 6.839858243628690827e-05 0.000000000000000000 -5.056177345005821167e-01 5.765818067891420866e-05 0.000000000000000000 -5.059730961898502022e-01 4.713276973999451074e-05 0.000000000000000000 -5.063284569158168491e-01 3.720575831985868274e-05 0.000000000000000000 -5.066838166778055985e-01 2.819466775326767664e-05 0.000000000000000000 -5.070391754751398805e-01 2.033709863337896940e-05 0.000000000000000000 -5.073945333071430142e-01 1.378308658415959779e-05 0.000000000000000000 -5.077498901731386516e-01 8.594018378079283735e-06 0.000000000000000000 -5.081052460724502229e-01 4.747753602831922439e-06 0.000000000000000000 -5.084606010044010471e-01 2.149127436915237620e-06 0.000000000000000000 -5.088159549683146654e-01 6.446348103444160907e-07 0.000000000000000000 -5.091713079635145078e-01 3.984312954695506769e-08 0.000000000000000000 -5.095266599893238935e-01 1.179653188520227918e-07 0.000000000000000000 -5.098820110450665855e-01 6.580494302105423640e-07 0.000000000000000000 -5.102373611300659029e-01 1.451394955570976866e-06 0.000000000000000000 -5.105927102436452758e-01 2.315067541057765070e-06 0.000000000000000000 -5.109480583851281343e-01 3.101722815644790442e-06 0.000000000000000000 -5.113034055538379086e-01 3.705331050630431903e-06 0.000000000000000000 -5.116587517490982506e-01 4.062780300110130791e-06 0.000000000000000000 -5.120140969702328126e-01 4.151691451361341718e-06 0.000000000000000000 -5.123694412165643586e-01 3.985074306038405260e-06 0.000000000000000000 -5.127247844874170957e-01 3.603667143713819481e-06 0.000000000000000000 -5.130801267821141209e-01 3.066920189016125059e-06 0.000000000000000000 -5.134354680999788645e-01 2.443602917294917904e-06 0.000000000000000000 -5.137908084403349784e-01 1.802942632447226608e-06 0.000000000000000000 -5.141461478025060039e-01 1.207051938160951283e-06 0.000000000000000000 -5.145014861858152599e-01 7.051965640478476917e-07 0.000000000000000000 -5.148568235895862877e-01 3.302172315404854924e-07 0.000000000000000000 -5.152121600131426282e-01 9.717564429177106188e-08 0.000000000000000000 -5.155674954558076006e-01 4.069488942222941613e-09 0.000000000000000000 -5.159228299169049681e-01 3.427489806011555759e-08 0.000000000000000000 -5.162781633957580496e-01 1.602419176778044232e-07 0.000000000000000000 -5.166334958916902753e-01 3.478972478484937128e-07 0.000000000000000000 -5.169888274040252973e-01 5.612000596623017566e-07 0.000000000000000000 -5.173441579320866568e-01 7.663457215606076105e-07 0.000000000000000000 -5.176994874751976727e-01 9.352080749538885055e-07 0.000000000000000000 -5.180548160326818863e-01 1.047738929311404056e-06 0.000000000000000000 -5.184101436038628385e-01 1.093187148364550845e-06 0.000000000000000000 -5.187654701880640706e-01 1.070142426929611339e-06 0.000000000000000000 -5.191207957846091237e-01 9.855356328076274987e-07 0.000000000000000000 -5.194761203928213167e-01 8.528265353239900210e-07 0.000000000000000000 -5.198314440120244129e-01 6.896730800119970670e-07 0.000000000000000000 -5.201867666415417313e-01 5.154008785137433543e-07 0.000000000000000000 -5.205420882806968130e-01 3.485785454283366516e-07 0.000000000000000000 -5.208974089288131992e-01 2.049591677157010706e-07 0.000000000000000000 -5.212527285852146530e-01 9.597880360430736003e-08 0.000000000000000000 -5.216080472492242714e-01 2.791958963700704424e-08 0.000000000000000000 -5.219633649201658177e-01 1.758462582826448919e-09 0.000000000000000000 -5.223186815973629438e-01 1.364268095268559424e-08 0.000000000000000000 -5.226739972801388578e-01 5.586853642329606625e-08 0.000000000000000000 -5.230293119678172120e-01 1.181956620969015219e-07 0.000000000000000000 -5.233846256597216584e-01 1.893090417174680161e-07 0.000000000000000000 -5.237399383551755161e-01 2.582441043684730694e-07 0.000000000000000000 -5.240952500535024372e-01 3.156143777762950561e-07 0.000000000000000000 -5.244505607540259629e-01 3.545211868510523188e-07 0.000000000000000000 -5.248058704560697452e-01 3.710745908755473329e-07 0.000000000000000000 -5.251611791589573253e-01 3.645074195817125629e-07 0.000000000000000000 -5.255164868620119112e-01 3.369134877981779005e-07 0.000000000000000000 -5.258717935645573771e-01 2.926814726582823392e-07 0.000000000000000000 -5.262270992659172641e-01 2.377237248647651285e-07 0.000000000000000000 -5.265824039654148914e-01 1.786125145567391886e-07 0.000000000000000000 -5.269377076623737999e-01 1.217348485594300857e-07 0.000000000000000000 -5.272930103561179749e-01 7.256272897846305802e-08 0.000000000000000000 -5.276483120459702914e-01 3.511159651028639038e-08 0.000000000000000000 -5.280036127312551786e-01 1.162961488257664832e-08 0.000000000000000000 -5.283589124112954005e-01 2.528608934239516956e-09 0.000000000000000000 -5.287142110854147203e-01 6.537839974442226560e-09 0.000000000000000000 -5.290695087529370122e-01 2.103767382954850094e-08 0.000000000000000000 -5.294248054131855952e-01 4.251384216807760996e-08 0.000000000000000000 -5.297801010654838993e-01 6.706550635385340809e-08 0.000000000000000000 -5.301353957091556879e-01 9.090160520040974112e-08 0.000000000000000000 -5.304906893435248350e-01 1.107688538567185972e-07 0.000000000000000000 -5.308459819679142155e-01 1.242693172221489730e-07 0.000000000000000000 -5.312012735816479259e-01 1.300432985526712808e-07 0.000000000000000000 -5.315565641840493960e-01 1.278118383292428196e-07 0.000000000000000000 -5.319118537744420561e-01 1.182900982787083105e-07 0.000000000000000000 -5.322671423521496692e-01 1.029964746519141071e-07 0.000000000000000000 -5.326224299164956655e-01 8.399125566372632153e-08 0.000000000000000000 -5.329777164668038081e-01 6.358253975450874878e-08 0.000000000000000000 -5.333330020023976381e-01 4.403617820426607344e-08 0.000000000000000000 -5.336882865226005856e-01 2.732147861699862508e-08 0.000000000000000000 -5.340435700267366359e-01 1.491647493550943453e-08 0.000000000000000000 -5.343988525141287749e-01 7.687087598421340105e-09 0.000000000000000000 -5.347541339841010988e-01 5.844796496759625044e-09 0.000000000000000000 -5.351094144359769267e-01 8.978669970143985722e-09 0.000000000000000000 -5.354646938690800217e-01 1.615056435974732372e-08 0.000000000000000000 -5.358199722827339251e-01 2.603749182283217817e-08 0.000000000000000000 -5.361752496762620668e-01 3.710264865995068443e-08 0.000000000000000000 -5.365305260489883210e-01 4.777619952785105826e-08 0.000000000000000000 -5.368858014002362289e-01 5.662821559725726611e-08 0.000000000000000000 -5.372410757293293315e-01 6.251866328412636341e-08 0.000000000000000000 -5.375963490355910590e-01 6.471254198246048687e-08 0.000000000000000000 -5.379516213183452855e-01 6.295177432054326809e-08 0.000000000000000000 -5.383068925769156632e-01 5.747899897974179530e-08 0.000000000000000000 -5.386621628106255111e-01 4.901188461741618392e-08 0.000000000000000000 -5.390174320187987034e-01 3.866996392649106288e-08 0.000000000000000000 -5.393727002007586702e-01 2.785931877057018161e-08 0.000000000000000000 -5.397279673558293966e-01 1.812374830397954429e-08 0.000000000000000000 -5.400832334833340909e-01 1.097425283175474643e-08 0.000000000000000000 -5.404384985825965160e-01 7.711568555180349724e-09 0.000000000000000000 -5.407937626529405462e-01 9.258757182882143171e-09 0.000000000000000000 -5.411490256936892784e-01 1.602205045329230772e-08 0.000000000000000000 -5.415042877041665870e-01 2.779780003141316738e-08 0.000000000000000000 -5.418595486836963460e-01 4.374107953450975505e-08 0.000000000000000000 -5.422148086316018745e-01 6.240699252121553845e-08 0.000000000000000000 -5.425700675472069356e-01 8.186909588997306142e-08 0.000000000000000000 -5.429253254298352926e-01 9.991093164606391332e-08 0.000000000000000000 -5.432805822788103756e-01 1.142772126711774720e-07 0.000000000000000000 -5.436358380934558365e-01 1.229617933160216958e-07 0.000000000000000000 -5.439910928730954387e-01 1.245014563756426982e-07 0.000000000000000000 -5.443463466170528342e-01 1.182391098120244031e-07 0.000000000000000000 -5.447015993246515642e-01 1.045184229820992780e-07 0.000000000000000000 -5.450568509952152807e-01 8.477511882775591434e-08 0.000000000000000000 -5.454121016280676360e-01 6.149842692846236301e-08 0.000000000000000000 -5.457673512225323931e-01 3.804928372343702930e-08 0.000000000000000000 -5.461225997779333152e-01 1.833871369299138075e-08 0.000000000000000000 -5.464778472935934994e-01 6.388732365258210851e-09 0.000000000000000000 -5.468330937688372639e-01 5.816834533679286728e-09 0.000000000000000000 -5.471883392029879278e-01 1.930112444437385104e-08 0.000000000000000000 -5.475435835953690322e-01 4.809387452564117136e-08 0.000000000000000000 -5.478988269453045623e-01 9.165459004710275194e-08 0.000000000000000000 -5.482540692521181702e-01 1.474680354034504768e-07 0.000000000000000000 -5.486093105151332860e-01 2.110976612192607152e-07 0.000000000000000000 -5.489645507336736729e-01 2.765011592002896653e-07 0.000000000000000000 -5.493197899070632051e-01 3.366043985402819793e-07 0.000000000000000000 -5.496750280346252016e-01 3.840958314887903904e-07 0.000000000000000000 -5.500302651156836475e-01 4.123695334208518463e-07 0.000000000000000000 -5.503855011495618621e-01 4.165157642580528355e-07 0.000000000000000000 -5.507407361355840525e-01 3.942376551345655092e-07 0.000000000000000000 -5.510959700730733157e-01 3.465650799567433566e-07 0.000000000000000000 -5.514512029613537480e-01 2.782445577422907543e-07 0.000000000000000000 -5.518064347997490016e-01 1.977081331264959453e-07 0.000000000000000000 -5.521616655875826174e-01 1.165636752213546533e-07 0.000000000000000000 -5.525168953241783587e-01 4.860098969352259141e-08 0.000000000000000000 -5.528721240088597666e-01 8.367760998585424341e-09 0.000000000000000000 -5.532273516409508263e-01 9.430353101122091145e-09 0.000000000000000000 -5.535825782197750788e-01 6.248973475763105519e-08 0.000000000000000000 -5.539378037446562875e-01 1.735649745308116899e-07 0.000000000000000000 -5.542930282149178822e-01 3.424793142509701248e-07 0.000000000000000000 -5.546482516298839593e-01 5.618817927608130284e-07 0.000000000000000000 -5.550034739888780599e-01 8.170080788678706437e-07 0.000000000000000000 -5.553586952912237251e-01 1.086327752288006408e-06 0.000000000000000000 -5.557139155362449401e-01 1.343145011339269744e-06 0.000000000000000000 -5.560691347232651349e-01 1.558121973119186577e-06 0.000000000000000000 -5.564243528516082948e-01 1.702587243794158192e-06 0.000000000000000000 -5.567795699205979609e-01 1.752387985796346793e-06 0.000000000000000000 -5.571347859295578964e-01 1.691952820165713121e-06 0.000000000000000000 -5.574900008778118643e-01 1.518166720582494084e-06 0.000000000000000000 -5.578452147646836279e-01 1.243627103419817056e-06 0.000000000000000000 -5.582004275894966172e-01 8.988593382997276616e-07 0.000000000000000000 -5.585556393515749285e-01 5.331229183700368738e-07 0.000000000000000000 -5.589108500502421029e-01 2.135352329213494017e-07 0.000000000000000000 -5.592660596848220145e-01 2.237245332480038751e-08 0.000000000000000000 -5.596212682546380934e-01 5.256641249082886638e-08 0.000000000000000000 -5.599764757590142139e-01 4.015889629583112437e-07 0.000000000000000000 -5.603316821972743611e-01 1.164085226527194772e-06 0.000000000000000000 -5.606868875687419651e-01 2.423767606860195418e-06 0.000000000000000000 -5.610420918727407891e-01 4.245197401551981539e-06 0.000000000000000000 -5.613972951085947072e-01 6.666146730012677022e-06 0.000000000000000000 -5.617524972756273716e-01 9.691240636485898844e-06 0.000000000000000000 -5.621076983731625454e-01 1.328752310894187334e-05 0.000000000000000000 -5.624628984005241028e-01 1.738247270140474960e-05 0.000000000000000000 -5.628180973570354739e-01 2.186482080552924000e-05 0.000000000000000000 -5.631732952420209770e-01 2.658831131842155624e-05 0.000000000000000000 -5.635284920548035981e-01 3.137830199983121976e-05 0.000000000000000000 -5.638836877947076553e-01 3.604086576498851611e-05 0.000000000000000000 -5.642388824610570230e-01 4.037382626781467471e-05 0.000000000000000000 -5.645940760531749092e-01 4.417897727819636593e-05 0.000000000000000000 -5.649492685703852990e-01 4.727460753994559964e-05 0.000000000000000000 -5.653044600120120666e-01 4.950739531450985820e-05 0.000000000000000000 -5.656596503773789753e-01 5.076275689797175454e-05 0.000000000000000000 -5.660148396658096770e-01 5.097283136458282044e-05 0.000000000000000000 -5.663700278766280460e-01 5.012145288217879707e-05 0.000000000000000000 -5.667252150091578455e-01 4.824568880927998244e-05 0.000000000000000000 -5.670804010627228386e-01 4.543378761611116231e-05 0.000000000000000000 -5.674355860366465665e-01 4.181966286648011033e-05 0.000000000000000000 -5.677907699302532363e-01 3.757431369748243566e-05 0.000000000000000000 -5.681459527428662781e-01 3.289482456900954204e-05 0.000000000000000000 -5.685011344738097883e-01 2.799177633316403453e-05 0.000000000000000000 -5.688563151224071968e-01 2.307602038306005098e-05 0.000000000000000000 -5.692114946879824888e-01 1.834580747694843569e-05 0.000000000000000000 -5.695666731698596497e-01 1.397521968928968294e-05 0.000000000000000000 -5.699218505673619983e-01 1.010473218642439027e-05 0.000000000000000000 -5.702770268798136311e-01 6.834542598810351446e-06 0.000000000000000000 -5.706322021065380889e-01 4.221067071540306012e-06 0.000000000000000000 -5.709873762468596903e-01 2.276735332538790033e-06 0.000000000000000000 -5.713425493001019762e-01 9.729462724315820966e-07 0.000000000000000000 -5.716977212655882656e-01 2.457944946245843366e-07 0.000000000000000000 -5.720528921426430990e-01 3.968706046638148174e-09 0.000000000000000000 -5.724080619305896844e-01 1.380720442778640443e-07 0.000000000000000000 -5.727632306287523400e-01 5.305340249631355537e-07 0.000000000000000000 -5.731183982364544960e-01 1.065278520825731126e-06 0.000000000000000000 -5.734735647530203595e-01 1.636379772908109541e-06 0.000000000000000000 -5.738287301777731386e-01 2.155069962917634422e-06 0.000000000000000000 -5.741838945100372626e-01 2.554642812821457152e-06 0.000000000000000000 -5.745390577491360506e-01 2.793009438712501159e-06 0.000000000000000000 -5.748942198943938209e-01 2.852884527770904297e-06 0.000000000000000000 -5.752493809451340034e-01 2.739791978271238505e-06 0.000000000000000000 -5.756045409006803615e-01 2.478260476923418210e-06 0.000000000000000000 -5.759596997603573243e-01 2.106715752156362338e-06 0.000000000000000000 -5.763148575234880999e-01 1.671657070079121494e-06 0.000000000000000000 -5.766700141893965625e-01 1.221726338257173734e-06 0.000000000000000000 -5.770251697574069194e-01 8.022403399100469323e-07 0.000000000000000000 -5.773803242268427116e-01 4.506671227127235789e-07 0.000000000000000000 -5.777354775970277023e-01 1.933980666431630193e-07 0.000000000000000000 -5.780906298672860988e-01 4.401262235227615587e-08 0.000000000000000000 -5.784457810369414421e-01 3.069791506412061400e-09 0.000000000000000000 -5.788009311053174955e-01 5.930569947955459364e-08 0.000000000000000000 -5.791560800717384661e-01 1.919849538166339636e-07 0.000000000000000000 -5.795112279355278950e-01 3.740566181750995670e-07 0.000000000000000000 -5.798663746960098786e-01 5.757111207604499255e-07 0.000000000000000000 -5.802215203525079579e-01 7.679250892288131867e-07 0.000000000000000000 -5.805766649043461181e-01 9.256150144514058985e-07 0.000000000000000000 -5.809318083508484554e-01 1.030091518218040927e-06 0.000000000000000000 -5.812869506913382889e-01 1.070604105679546085e-06 0.000000000000000000 -5.816420919251400479e-01 1.044879630936900765e-06 0.000000000000000000 -5.819972320515772735e-01 9.586734108407089225e-07 0.000000000000000000 -5.823523710699739508e-01 8.244576098605085741e-07 0.000000000000000000 -5.827075089796537322e-01 6.594565901354358784e-07 0.000000000000000000 -5.830626457799410467e-01 4.832955827134131369e-07 0.000000000000000000 -5.834177814701591025e-01 3.155529781886816642e-07 0.000000000000000000 -5.837729160496319958e-01 1.734972033053205203e-07 0.000000000000000000 -5.841280495176837118e-01 7.024960603823802908e-08 0.000000000000000000 -5.844831818736380136e-01 1.355117066974925709e-08 0.000000000000000000 -5.848383131168189975e-01 5.231646658483380718e-09 0.000000000000000000 -5.851934432465499825e-01 4.139445213949721264e-08 0.000000000000000000 -5.855485722621556199e-01 1.132492706768242678e-07 0.000000000000000000 -5.859037001629591179e-01 2.084554044988801242e-07 0.000000000000000000 -5.862588269482849057e-01 3.127896081962887065e-07 0.000000000000000000 -5.866139526174566354e-01 4.119266904076093740e-07 0.000000000000000000 -5.869690771697980702e-01 4.931211280501292892e-07 0.000000000000000000 -5.873242006046331953e-01 5.466018666620154117e-07 0.000000000000000000 -5.876793229212859959e-01 5.665363548072090036e-07 0.000000000000000000 -5.880344441190803462e-01 5.514776299888961305e-07 0.000000000000000000 -5.883895641973397872e-01 5.042726427583313958e-07 0.000000000000000000 -5.887446831553889703e-01 4.314733143395663393e-07 0.000000000000000000 -5.890998009925512147e-01 3.423469248657454971e-07 0.000000000000000000 -5.894549177081503943e-01 2.476234717293410357e-07 0.000000000000000000 -5.898100333015108276e-01 1.581406599529662958e-07 0.000000000000000000 -5.901651477719559447e-01 8.355047699320131675e-08 0.000000000000000000 -5.905202611188101747e-01 3.123548673909274376e-08 0.000000000000000000 -5.908753733413971698e-01 5.550829446517932527e-09 0.000000000000000000 -5.912304844390405822e-01 7.463950214674967116e-09 0.000000000000000000 -5.915855944110647302e-01 3.461395275187763592e-08 0.000000000000000000 -5.919407032567934879e-01 8.176228253046440707e-08 0.000000000000000000 -5.922958109755506184e-01 1.415620004793798655e-07 0.000000000000000000 -5.926509175666601070e-01 2.055390976517006177e-07 0.000000000000000000 -5.930060230294459389e-01 2.651595515562552045e-07 0.000000000000000000 -5.933611273632317662e-01 3.128517805912988746e-07 0.000000000000000000 -5.937162305673420182e-01 3.428655634929768786e-07 0.000000000000000000 -5.940713326411000139e-01 3.518733218726289231e-07 0.000000000000000000 -5.944264335838304047e-01 3.392544111246220884e-07 0.000000000000000000 -5.947815333948567318e-01 3.070432225060939968e-07 0.000000000000000000 -5.951366320735027582e-01 2.595625256559252980e-07 0.000000000000000000 -5.954917296190926912e-01 2.027997918868187191e-07 0.000000000000000000 -5.958468260309504050e-01 1.436121571067611870e-07 0.000000000000000000 -5.962019213083999958e-01 8.886228507389958148e-08 0.000000000000000000 -5.965570154507651157e-01 4.459119989464450971e-08 0.000000000000000000 -5.969121084573697500e-01 1.532525539227711285e-08 0.000000000000000000 -5.972672003275382169e-01 3.594371291710108674e-09 0.000000000000000000 -5.976222910605941685e-01 9.710310954815937794e-09 0.000000000000000000 -5.979773806558615901e-01 3.182078810096570803e-08 0.000000000000000000 -5.983324691126644668e-01 6.622165643929785402e-08 0.000000000000000000 -5.986875564303267838e-01 1.078793474086084133e-07 0.000000000000000000 -5.990426426081723044e-01 1.510925076619811829e-07 0.000000000000000000 -5.993977276455254577e-01 1.902079367556136187e-07 0.000000000000000000 -5.997528115417097849e-01 2.203027229412409921e-07 0.000000000000000000 -6.001078942960493823e-01 2.377518991009780282e-07 0.000000000000000000 -6.004629759078682349e-01 2.406177120932415508e-07 0.000000000000000000 -6.008180563764903281e-01 2.288203765903281190e-07 0.000000000000000000 -6.011731357012397581e-01 2.040778821159689532e-07 0.000000000000000000 -6.015282138814402879e-01 1.696305980459083549e-07 0.000000000000000000 -6.018832909164160139e-01 1.297916995675552685e-07 0.000000000000000000 -6.022383668054908101e-01 8.938390458878155905e-08 0.000000000000000000 -6.025934415479888839e-01 5.313454619682417894e-08 0.000000000000000000 -6.029485151432339984e-01 2.510350336706501463e-08 0.000000000000000000 -6.033035875905502499e-01 8.211983994774108679e-09 0.000000000000000000 -6.036586588892616234e-01 3.925684546299965943e-09 0.000000000000000000 -6.040137290386919933e-01 1.212543663294888145e-08 0.000000000000000000 -6.043687980381656777e-01 3.117473372649500105e-08 0.000000000000000000 -6.047238658870061068e-01 5.816946122348397297e-08 0.000000000000000000 -6.050789325845380429e-01 8.933362804047829995e-08 0.000000000000000000 -6.054339981300849161e-01 1.205084197393921003e-07 0.000000000000000000 -6.057890625229709336e-01 1.476722815269256049e-07 0.000000000000000000 -6.061441257625198586e-01 1.674279356704786550e-07 0.000000000000000000 -6.064991878480563425e-01 1.773982191775640313e-07 0.000000000000000000 -6.068542487789035933e-01 1.764854388634637543e-07 0.000000000000000000 -6.072093085543860402e-01 1.649668365156935220e-07 0.000000000000000000 -6.075643671738278906e-01 1.444194324690211976e-07 0.000000000000000000 -6.079194246365526855e-01 1.174884005266132424e-07 0.000000000000000000 -6.082744809418847431e-01 8.753169842753077014e-08 0.000000000000000000 -6.086295360891479378e-01 5.818776293652670453e-08 0.000000000000000000 -6.089845900776666987e-01 3.292110407111610624e-08 0.000000000000000000 -6.093396429067645670e-01 1.460179799887659025e-08 0.000000000000000000 -6.096946945757656389e-01 5.169228961318951754e-09 0.000000000000000000 -6.100497450839942326e-01 5.418832463221475358e-09 0.000000000000000000 -6.104047944307741114e-01 1.493460369477177727e-08 0.000000000000000000 -6.107598426154294824e-01 3.217180383015590700e-08 0.000000000000000000 -6.111148896372842199e-01 5.467589936047240389e-08 0.000000000000000000 -6.114699354956625310e-01 7.940753315753586485e-08 0.000000000000000000 -6.118249801898882900e-01 1.031311614235340368e-07 0.000000000000000000 -6.121800237192857042e-01 1.228182705728388879e-07 0.000000000000000000 -6.125350660831785365e-01 1.360154944467403528e-07 0.000000000000000000 -6.128901072808914385e-01 1.411334110249803310e-07 0.000000000000000000 -6.132451473117479512e-01 1.376225055695315520e-07 0.000000000000000000 -6.136001861750719488e-01 1.260173248398855709e-07 0.000000000000000000 -6.139552238701880826e-01 1.078463649424724593e-07 0.000000000000000000 -6.143102603964201158e-01 8.542168580387930961e-08 0.000000000000000000 -6.146652957530919226e-01 6.153663365791806754e-08 0.000000000000000000 -6.150203299395279322e-01 3.911067741617503879e-08 0.000000000000000000 -6.153753629550520188e-01 2.082601508102251189e-08 0.000000000000000000 -6.157303947989879456e-01 8.800699592306875260e-09 0.000000000000000000 -6.160854254706605859e-01 4.337671601725734574e-09 0.000000000000000000 -6.164404549693931479e-01 7.779030207735163843e-09 0.000000000000000000 -6.167954832945102828e-01 1.848143588459323187e-08 0.000000000000000000 -6.171505104453358648e-01 3.491342101186632433e-08 0.000000000000000000 -6.175055364211936570e-01 5.486045234043456016e-08 0.000000000000000000 -6.178605612214085330e-01 7.571065844854521093e-08 0.000000000000000000 -6.182155848453037006e-01 9.478474002640195863e-08 0.000000000000000000 -6.185706072922038112e-01 1.096688014451697396e-07 0.000000000000000000 -6.189256285614329611e-01 1.185091793312379582e-07 0.000000000000000000 -6.192806486523148024e-01 1.202336691788801304e-07 0.000000000000000000 -6.196356675641737644e-01 1.146731327774274321e-07 0.000000000000000000 -6.199906852963338322e-01 1.025700714165373497e-07 0.000000000000000000 -6.203457018481191021e-01 8.547479006590840982e-08 0.000000000000000000 -6.207007172188536703e-01 6.554352431670386034e-08 0.000000000000000000 -6.210557314078619662e-01 4.526468590535363813e-08 0.000000000000000000 -6.214107444144674197e-01 2.714779910370142789e-08 0.000000000000000000 -6.217657562379947933e-01 1.341377424901839325e-08 0.000000000000000000 -6.221207668777678501e-01 5.724463152620582700e-09 0.000000000000000000 -6.224757763331105753e-01 4.984117501160354466e-09 0.000000000000000000 -6.228307846033475093e-01 1.123613866110955925e-08 0.000000000000000000 -6.231857916878023040e-01 2.366654387982076812e-08 0.000000000000000000 -6.235407975857995000e-01 4.071237424968245054e-08 0.000000000000000000 -6.238958022966629713e-01 6.026045908988496155e-08 0.000000000000000000 -6.242508058197168141e-01 7.991108644256738377e-08 0.000000000000000000 -6.246058081542852358e-01 9.727351059472338928e-08 0.000000000000000000 -6.249608092996924436e-01 1.102567441778984028e-07 0.000000000000000000 -6.253158092552624225e-01 1.173201094727000962e-07 0.000000000000000000 -6.256708080203193800e-01 1.176533822713431772e-07 0.000000000000000000 -6.260258055941873012e-01 1.112653475027756747e-07 0.000000000000000000 -6.263808019761903934e-01 9.897105998834258918e-08 0.000000000000000000 -6.267357971656530857e-01 8.228063628771186367e-08 0.000000000000000000 -6.270907911618989194e-01 6.320445064534374103e-08 0.000000000000000000 -6.274457839642527679e-01 4.399970062873813791e-08 0.000000000000000000 -6.278007755720382832e-01 2.689023043781056004e-08 0.000000000000000000 -6.281557659845794506e-01 1.379443530623955978e-08 0.000000000000000000 -6.285107552012010323e-01 6.094697104895225460e-09 0.000000000000000000 -6.288657432212267917e-01 4.476327327905971895e-09 0.000000000000000000 -6.292207300439807138e-01 8.855127379127930071e-09 0.000000000000000000 -6.295757156687872280e-01 1.840153550282695006e-08 0.000000000000000000 -6.299307000949706525e-01 3.165730291529897918e-08 0.000000000000000000 -6.302856833218546395e-01 4.672921527884810356e-08 0.000000000000000000 -6.306406653487638403e-01 6.153495222151182057e-08 0.000000000000000000 -6.309956461750222401e-01 7.406990467197694917e-08 0.000000000000000000 -6.313506257999537130e-01 8.266140081759297709e-08 0.000000000000000000 -6.317056042228827994e-01 8.617859577559573058e-08 0.000000000000000000 -6.320605814431335956e-01 8.417201209513729616e-08 0.000000000000000000 -6.324155574600303087e-01 7.692565018355481670e-08 0.000000000000000000 -6.327705322728970350e-01 6.541560083438141149e-08 0.000000000000000000 -6.331255058810578706e-01 5.118081507944576529e-08 0.000000000000000000 -6.334804782838371340e-01 3.612266531120729090e-08 0.000000000000000000 -6.338354494805591433e-01 2.225880747262750249e-08 0.000000000000000000 -6.341904194705477726e-01 1.146253101085765795e-08 0.000000000000000000 -6.345453882531273404e-01 5.220561992614700117e-09 0.000000000000000000 -6.349003558276220538e-01 4.439948366344225791e-09 0.000000000000000000 -6.352553221933558980e-01 9.328496650380643250e-09 0.000000000000000000 -6.356102873496536354e-01 1.936401084035280249e-08 0.000000000000000000 -6.359652512958385850e-01 3.335645030283580740e-08 0.000000000000000000 -6.363202140312358424e-01 4.959545529518608308e-08 0.000000000000000000 -6.366751755551693925e-01 6.606493627224355835e-08 0.000000000000000000 -6.370301358669627767e-01 8.069792581265687441e-08 0.000000000000000000 -6.373850949659409793e-01 9.163971369705191680e-08 0.000000000000000000 -6.377400528514277633e-01 9.748608269300368168e-08 0.000000000000000000 -6.380950095227476693e-01 9.746640138882521307e-08 0.000000000000000000 -6.384499649792244602e-01 9.154806513423569480e-08 0.000000000000000000 -6.388049192201827875e-01 8.044848914982932258e-08 0.000000000000000000 -6.391598722449467473e-01 6.555235826522582039e-08 0.000000000000000000 -6.395148240528405470e-01 4.874370636458737423e-08 0.000000000000000000 -6.398697746431881717e-01 3.217316169338512918e-08 0.000000000000000000 -6.402247240153141616e-01 1.798900492051849606e-08 0.000000000000000000 -6.405796721685426132e-01 8.065492364087766319e-09 0.000000000000000000 -6.409346191021977335e-01 3.762570208815701187e-09 0.000000000000000000 -6.412895648156039519e-01 5.747526567247088872e-09 0.000000000000000000 -6.416445093080851425e-01 1.390170217390238753e-08 0.000000000000000000 -6.419994525789658457e-01 2.732499274696444072e-08 0.000000000000000000 -6.423543946275701577e-01 4.443878722298027856e-08 0.000000000000000000 -6.427093354532223968e-01 6.317568004293899849e-08 0.000000000000000000 -6.430642750552468812e-01 8.123329873889953593e-08 0.000000000000000000 -6.434192134329674850e-01 9.636128114331919095e-08 0.000000000000000000 -6.437741505857088598e-01 1.066458832425271056e-07 0.000000000000000000 -6.441290865127949905e-01 1.107565106699341337e-07 0.000000000000000000 -6.444840212135504176e-01 1.081227231040403778e-07 0.000000000000000000 -6.448389546872991263e-01 9.901849165593755111e-08 0.000000000000000000 -6.451938869333654347e-01 8.454172731914613854e-08 0.000000000000000000 -6.455488179510737723e-01 6.648999150234111047e-08 0.000000000000000000 -6.459037477397481242e-01 4.714627215159521186e-08 0.000000000000000000 -6.462586762987130307e-01 2.900015336888334227e-08 0.000000000000000000 -6.466136036272923659e-01 1.443818058172094096e-08 0.000000000000000000 -6.469685297248108924e-01 5.441630509742956471e-09 0.000000000000000000 -6.473234545905924842e-01 3.329624374088330823e-09 0.000000000000000000 -6.476783782239616816e-01 8.580531263148812898e-09 0.000000000000000000 -6.480333006242425808e-01 2.075543598661902307e-08 0.000000000000000000 -6.483882217907596113e-01 3.853515705535421956e-08 0.000000000000000000 -6.487431417228369801e-01 5.986836331024574575e-08 0.000000000000000000 -6.490980604197988946e-01 8.221444870608610374e-08 0.000000000000000000 -6.494529778809697840e-01 1.028527043215601761e-07 0.000000000000000000 -6.498078941056737445e-01 1.192205080003383579e-07 0.000000000000000000 -6.501628090932354276e-01 1.292388891021710243e-07 0.000000000000000000 -6.505177228429784853e-01 1.315845446022088043e-07 0.000000000000000000 -6.508726353542280130e-01 1.258731944175723080e-07 0.000000000000000000 -6.512275466263075518e-01 1.127294518104190726e-07 0.000000000000000000 -6.515824566585418642e-01 9.373196841044034780e-08 0.000000000000000000 -6.519373654502552684e-01 7.123788213981573281e-08 0.000000000000000000 -6.522922730007718606e-01 4.810569860883418370e-08 0.000000000000000000 -6.526471793094159590e-01 2.734880252541571376e-08 0.000000000000000000 -6.530020843755118820e-01 1.176116632854932189e-08 0.000000000000000000 -6.533569881983841698e-01 3.561258563619280753e-09 0.000000000000000000 -6.537118907773566967e-01 4.098994565910464977e-09 0.000000000000000000 -6.540667921117543360e-01 1.366383070031492727e-08 0.000000000000000000 -6.544216922009007398e-01 3.142048169315009995e-08 0.000000000000000000 -6.547765910441210035e-01 5.548355608344123529e-08 0.000000000000000000 -6.551314886407390015e-01 8.312544435393015685e-08 0.000000000000000000 -6.554863849900788297e-01 1.110951058843428562e-07 0.000000000000000000 -6.558412800914653618e-01 1.360110489170399042e-07 0.000000000000000000 -6.561961739442224717e-01 1.547816105973593756e-07 0.000000000000000000 -6.565510665476746999e-01 1.650009845447776883e-07 0.000000000000000000 -6.569059579011463645e-01 1.652710300355077810e-07 0.000000000000000000 -6.572608480039618950e-01 1.554067003978299151e-07 0.000000000000000000 -6.576157368554454985e-01 1.364961557632102358e-07 0.000000000000000000 -6.579706244549214933e-01 1.108037976726447674e-07 0.000000000000000000 -6.583255108017141977e-01 8.152357742416220072e-08 0.000000000000000000 -6.586803958951480409e-01 5.240869074727435336e-08 0.000000000000000000 -6.590352797345476743e-01 2.731986218629269564e-08 0.000000000000000000 -6.593901623192366390e-01 9.745788787154113946e-09 0.000000000000000000 -6.597450436485402525e-01 2.354419110044078995e-09 0.000000000000000000 -6.600999237217821669e-01 6.631776331329846291e-09 0.000000000000000000 -6.604548025382869225e-01 2.265602042100949857e-08 0.000000000000000000 -6.608096800973791707e-01 4.903927339417317206e-08 0.000000000000000000 -6.611645563983830076e-01 8.305007186344925178e-08 0.000000000000000000 -6.615194314406226406e-01 1.209074302475650294e-07 0.000000000000000000 -6.618743052234228319e-01 1.582160051892335234e-07 0.000000000000000000 -6.622291777461075668e-01 1.904933909474218586e-07 0.000000000000000000 -6.625840490080014966e-01 2.137275054116740506e-07 0.000000000000000000 -6.629389190084290506e-01 2.248961251132224782e-07 0.000000000000000000 -6.632937877467142140e-01 2.223828588568259199e-07 0.000000000000000000 -6.636486552221817492e-01 2.062342196579201290e-07 0.000000000000000000 -6.640035214341560854e-01 1.782199806524107402e-07 0.000000000000000000 -6.643583863819609858e-01 1.416817968783782871e-07 0.000000000000000000 -6.647132500649217679e-01 1.011805508266665232e-07 0.000000000000000000 -6.650681124823617507e-01 6.197802923628726556e-08 0.000000000000000000 -6.654229736336063628e-01 2.941028854323340630e-08 0.000000000000000000 -6.657778335179794782e-01 8.225644685096029698e-09 0.000000000000000000 -6.661326921348054153e-01 1.967503333423111422e-09 0.000000000000000000 -6.664875494834090475e-01 1.248002739516622158e-08 0.000000000000000000 -6.668424055631140268e-01 3.960282037727276565e-08 0.000000000000000000 -6.671972603732453377e-01 8.110044180849870854e-08 0.000000000000000000 -6.675521139131271875e-01 1.328457893591700800e-07 0.000000000000000000 -6.679069661820842274e-01 1.892461618199566402e-07 0.000000000000000000 -6.682618171794402206e-01 2.438706685603150612e-07 0.000000000000000000 -6.686166669045205957e-01 2.902112164315921054e-07 0.000000000000000000 -6.689715153566486716e-01 3.224899275935096047e-07 0.000000000000000000 -6.693263625351496549e-01 3.364161559102603232e-07 0.000000000000000000 -6.696812084393478637e-01 3.297978596050759916e-07 0.000000000000000000 -6.700360530685670613e-01 3.029252578647283393e-07 0.000000000000000000 -6.703908964221327871e-01 2.586683852843770093e-07 0.000000000000000000 -6.707457384993684713e-01 2.022619994419817766e-07 0.000000000000000000 -6.711005792995989871e-01 1.407878607034080007e-07 0.000000000000000000 -6.714554188221486530e-01 8.240154572640456607e-08 0.000000000000000000 -6.718102570663422313e-01 3.538427990954685801e-08 0.000000000000000000 -6.721650940315034850e-01 7.125634921383378850e-09 0.000000000000000000 -6.725199297169576207e-01 3.156940779817525424e-09 0.000000000000000000 -6.728747641220286235e-01 2.635569243891584593e-08 0.000000000000000000 -6.732295972460408118e-01 7.642736291402532864e-08 0.000000000000000000 -6.735844290883191698e-01 1.497437830908723426e-07 0.000000000000000000 -6.739392596481875719e-01 2.395791338845689048e-07 0.000000000000000000 -6.742940889249708913e-01 3.367395276775452159e-07 0.000000000000000000 -6.746489169179933354e-01 4.305350395032131612e-07 0.000000000000000000 -6.750037436265796664e-01 5.099992694355774644e-07 0.000000000000000000 -6.753585690500539807e-01 5.652263436602756905e-07 0.000000000000000000 -6.757133931877408184e-01 5.886732348689778454e-07 0.000000000000000000 -6.760682160389648310e-01 5.762696683775752839e-07 0.000000000000000000 -6.764230376030502256e-01 5.281902375824515451e-07 0.000000000000000000 -6.767778578793219868e-01 4.491732775261142066e-07 0.000000000000000000 -6.771326768671038776e-01 3.483161263401599753e-07 0.000000000000000000 -6.774874945657207714e-01 2.383323967867089020e-07 0.000000000000000000 -6.778423109744969866e-01 1.343180954835292866e-07 0.000000000000000000 -6.781971260927572853e-01 5.213329714928292602e-08 0.000000000000000000 -6.785519399198258750e-01 6.557842614936761977e-09 0.000000000000000000 -6.789067524550272958e-01 9.416960829089678940e-09 0.000000000000000000 -6.792615636976863103e-01 6.789084335766930541e-08 0.000000000000000000 -6.796163736471270145e-01 1.832179000018432771e-07 0.000000000000000000 -6.799711823026739488e-01 3.499738433880298899e-07 0.000000000000000000 -6.803259896636518755e-01 5.560595033261273928e-07 0.000000000000000000 -6.806807957293848910e-01 7.834633774959268025e-07 0.000000000000000000 -6.810356004991979795e-01 1.009786484082793178e-06 0.000000000000000000 -6.813904039724152373e-01 1.210434718682093645e-06 0.000000000000000000 -6.817452061483614267e-01 1.361306040239262548e-06 0.000000000000000000 -6.821000070263608661e-01 1.441734761401513620e-06 0.000000000000000000 -6.824548066057383178e-01 1.437410401516072747e-06 0.000000000000000000 -6.828096048858179890e-01 1.342969637729787250e-06 0.000000000000000000 -6.831644018659246420e-01 1.163970131324562443e-06 0.000000000000000000 -6.835191975453825952e-01 9.179948683779298552e-07 0.000000000000000000 -6.838739919235164999e-01 6.347026298881030801e-07 0.000000000000000000 -6.842287849996507854e-01 3.547289803235549456e-07 0.000000000000000000 -6.845835767731099919e-01 1.274450490429754141e-07 0.000000000000000000 -6.849383672432189929e-01 7.689013104348961068e-09 0.000000000000000000 -6.852931564093017736e-01 5.168741132194243346e-08 0.000000000000000000 -6.856479442706829852e-01 3.124702498300443199e-07 0.000000000000000000 -6.860027308266875012e-01 8.351464894336527380e-07 0.000000000000000000 -6.863575160766395289e-01 1.652438186092146679e-06 0.000000000000000000 -6.867123000198634974e-01 2.780868306576662507e-06 0.000000000000000000 -6.870670826556845023e-01 4.217958294192426203e-06 0.000000000000000000 -6.874218639834266398e-01 5.940719399286303381e-06 0.000000000000000000 -6.877766440024144501e-01 7.905622364402147082e-06 0.000000000000000000 -6.881314227119726956e-01 1.005011167531458192e-05 0.000000000000000000 -6.884862001114256946e-01 1.229560356406208357e-05 0.000000000000000000 -6.888409762000983205e-01 1.455178252378887522e-05 0.000000000000000000 -6.891957509773147805e-01 1.672190039569084494e-05 0.000000000000000000 -6.895505244423998370e-01 1.870869507805675487e-05 0.000000000000000000 -6.899052965946781413e-01 2.042049044340849492e-05 0.000000000000000000 -6.902600674334740116e-01 2.177702014935189832e-05 0.000000000000000000 -6.906148369581120994e-01 2.271453740307057415e-05 0.000000000000000000 -6.909696051679170559e-01 2.318982865287496010e-05 0.000000000000000000 -6.913243720622134214e-01 2.318283662343840706e-05 0.000000000000000000 -6.916791376403257363e-01 2.269770929951792711e-05 0.000000000000000000 -6.920339019015785409e-01 2.176221657248429041e-05 0.000000000000000000 -6.923886648452962644e-01 2.042560436325823535e-05 0.000000000000000000 -6.927434264708041134e-01 1.875507610052542674e-05 0.000000000000000000 -6.930981867774258509e-01 1.683119335314874388e-05 0.000000000000000000 -6.934529457644867945e-01 1.474256290245099887e-05 0.000000000000000000 -6.938077034313111513e-01 1.258022083866049750e-05 0.000000000000000000 -6.941624597772233507e-01 1.043213262203711571e-05 0.000000000000000000 -6.945172148015482660e-01 8.378201881748441741e-06 0.000000000000000000 -6.948719685036103266e-01 6.486123495259529022e-06 0.000000000000000000 -6.952267208827344058e-01 4.808334292377077544e-06 0.000000000000000000 -6.955814719382448219e-01 3.380215641939625228e-06 0.000000000000000000 -6.959362216694663372e-01 2.219595461493938630e-06 0.000000000000000000 -6.962909700757234921e-01 1.327492376218807748e-06 0.000000000000000000 -6.966457171563408268e-01 6.899507705571123048e-07 0.000000000000000000 -6.970004629106431038e-01 2.807398465524255528e-07 0.000000000000000000 -6.973552073379547522e-01 6.463801578872321338e-08 0.000000000000000000 -6.977099504376007566e-01 9.990546426951016417e-10 0.000000000000000000 -6.980646922089053241e-01 4.729889433496456379e-08 0.000000000000000000 -6.984194326511931061e-01 1.623896488439826829e-07 0.000000000000000000 -6.987741717637889760e-01 3.092362898077472084e-07 0.000000000000000000 -6.991289095460176961e-01 4.569753992960879823e-07 0.000000000000000000 -6.994836459972032516e-01 5.822078170711355135e-07 0.000000000000000000 -6.998383811166707380e-01 6.695106122036307051e-07 0.000000000000000000 -7.001931149037448066e-01 7.112219213820162719e-07 0.000000000000000000 -7.005478473577498866e-01 7.066090981626248295e-07 0.000000000000000000 -7.009025784780108514e-01 6.605720895669835783e-07 0.000000000000000000 -7.012573082638521305e-01 5.820575662663225347e-07 0.000000000000000000 -7.016120367145987080e-01 4.823645348587461643e-07 0.000000000000000000 -7.019667638295746803e-01 3.735102060393759349e-07 0.000000000000000000 -7.023214896081051428e-01 2.667985645742724157e-07 0.000000000000000000 -7.026762140495145248e-01 1.716973072981499932e-07 0.000000000000000000 -7.030309371531275886e-01 9.508616308080831059e-08 0.000000000000000000 -7.033856589182690966e-01 4.089581191802170028e-08 0.000000000000000000 -7.037403793442632560e-01 1.011607147464398172e-08 0.000000000000000000 -7.040950984304352733e-01 1.118364062367043026e-09 0.000000000000000000 -7.044498161761095778e-01 1.021331209054640798e-08 0.000000000000000000 -7.048045325806109318e-01 3.235101525108101128e-08 0.000000000000000000 -7.051592476432638756e-01 6.186927241594258659e-08 0.000000000000000000 -7.055139613633929496e-01 9.320271810906388317e-08 0.000000000000000000 -7.058686737403232492e-01 1.214816128081553766e-07 0.000000000000000000 -7.062233847733789815e-01 1.429702890574333918e-07 0.000000000000000000 -7.065780944618853532e-01 1.553191412659423236e-07 0.000000000000000000 -7.069328028051664603e-01 1.576277197123771287e-07 0.000000000000000000 -7.072875098025475094e-01 1.503374458555530972e-07 0.000000000000000000 -7.076422154533528186e-01 1.349887723810438449e-07 0.000000000000000000 -7.079969197569071504e-01 1.138880527102133007e-07 0.000000000000000000 -7.083516227125353781e-01 8.973352248045353983e-08 0.000000000000000000 -7.087063243195621531e-01 6.524793349596863932e-08 0.000000000000000000 -7.090610245773119047e-01 4.285845144187631695e-08 0.000000000000000000 -7.094157234851096172e-01 2.445382165863092364e-08 0.000000000000000000 -7.097704210422800530e-01 1.123616269676962751e-08 0.000000000000000000 -7.101251172481475304e-01 3.671743197969824324e-09 0.000000000000000000 -7.104798121020371449e-01 1.533254517962277503e-09 0.000000000000000000 -7.108345056032734366e-01 4.016616402417570813e-09 0.000000000000000000 \ No newline at end of file diff --git a/tests/test_data/ORSO/test_2.dat b/tests/test_data/ORSO/test_2.dat deleted file mode 100644 index 5cfc9e61..00000000 --- a/tests/test_data/ORSO/test_2.dat +++ /dev/null @@ -1,1001 +0,0 @@ -5.000000000000000104e-03 1.000000000000000222e+00 0.000000000000000000 -5.995000000000000329e-03 1.000000000000000222e+00 0.000000000000000000 -6.989999999999999686e-03 1.000000000000000222e+00 0.000000000000000000 -7.984999999999999043e-03 1.000000000000000000e+00 0.000000000000000000 -8.980000000000000135e-03 9.999999999999996669e-01 0.000000000000000000 -9.975000000000001227e-03 1.000000000000000222e+00 0.000000000000000000 -1.097000000000000058e-02 9.999999999999998890e-01 0.000000000000000000 -1.196499999999999994e-02 1.000000000000000222e+00 0.000000000000000000 -1.295999999999999930e-02 9.999999999999998890e-01 0.000000000000000000 -1.395499999999999866e-02 1.000000000000000000e+00 0.000000000000000000 -1.495000000000000148e-02 9.999999999999997780e-01 0.000000000000000000 -1.594500000000000084e-02 1.000000000000000222e+00 0.000000000000000000 -1.694000000000000020e-02 9.999999999999995559e-01 0.000000000000000000 -1.793499999999999955e-02 7.302544119277273316e-01 0.000000000000000000 -1.892999999999999891e-02 2.552815931521527082e-01 0.000000000000000000 -1.992500000000000174e-02 1.500207458923263903e-01 0.000000000000000000 -2.092000000000000109e-02 9.997793399278399884e-02 0.000000000000000000 -2.191500000000000045e-02 7.123912062170954795e-02 0.000000000000000000 -2.290999999999999981e-02 5.301614647186881496e-02 0.000000000000000000 -2.390500000000000264e-02 4.070644982790416755e-02 0.000000000000000000 -2.490000000000000199e-02 3.201044658983939750e-02 0.000000000000000000 -2.589500000000000135e-02 2.565627153557500234e-02 0.000000000000000000 -2.689000000000000071e-02 2.088803389193751026e-02 0.000000000000000000 -2.788500000000000006e-02 1.723156075999391149e-02 0.000000000000000000 -2.887999999999999942e-02 1.437654145720755616e-02 0.000000000000000000 -2.987500000000000225e-02 1.211283187244694554e-02 0.000000000000000000 -3.087000000000000161e-02 1.029403083215324477e-02 0.000000000000000000 -3.186499999999999749e-02 8.815675506561536021e-03 0.000000000000000000 -3.286000000000000032e-02 7.601682608979293439e-03 0.000000000000000000 -3.385499999999999621e-02 6.595641840799377348e-03 0.000000000000000000 -3.484999999999999903e-02 5.755068914451989294e-03 0.000000000000000000 -3.584500000000000186e-02 5.047520223740087873e-03 0.000000000000000000 -3.683999999999999775e-02 4.447910330864589430e-03 0.000000000000000000 -3.783500000000000058e-02 3.936625104166304942e-03 0.000000000000000000 -3.882999999999999646e-02 3.498172265099319146e-03 0.000000000000000000 -3.982499999999999929e-02 3.120201746921682021e-03 0.000000000000000000 -4.081999999999999518e-02 2.792784835982658510e-03 0.000000000000000000 -4.181499999999999800e-02 2.507877168229455909e-03 0.000000000000000000 -4.281000000000000083e-02 2.258914162673223303e-03 0.000000000000000000 -4.380499999999999672e-02 2.040503064564099227e-03 0.000000000000000000 -4.479999999999999954e-02 1.848186284179480438e-03 0.000000000000000000 -4.579499999999999543e-02 1.678257914894290374e-03 0.000000000000000000 -4.678999999999999826e-02 1.527620311455636605e-03 0.000000000000000000 -4.778500000000000109e-02 1.393671123873522957e-03 0.000000000000000000 -4.877999999999999697e-02 1.274213683683264901e-03 0.000000000000000000 -4.977499999999999980e-02 1.167385439427427989e-03 0.000000000000000000 -5.076999999999999569e-02 1.071600447070272973e-03 0.000000000000000000 -5.176499999999999851e-02 9.855028819590074245e-04 0.000000000000000000 -5.275999999999999440e-02 9.079292507786222884e-04 0.000000000000000000 -5.375499999999999723e-02 8.378775137522353079e-04 0.000000000000000000 -5.475000000000000006e-02 7.744817278207360121e-04 0.000000000000000000 -5.574499999999999594e-02 7.169911253934479513e-04 0.000000000000000000 -5.673999999999999877e-02 6.647527754462639578e-04 0.000000000000000000 -5.773499999999999466e-02 6.171971523537961302e-04 0.000000000000000000 -5.872999999999999748e-02 5.738260761141945280e-04 0.000000000000000000 -5.972500000000000031e-02 5.342025953163497161e-04 0.000000000000000000 -6.071999999999999620e-02 4.979424685541384383e-04 0.000000000000000000 -6.171499999999999903e-02 4.647069664291461882e-04 0.000000000000000000 -6.271000000000000185e-02 4.341967688803725391e-04 0.000000000000000000 -6.370499999999999774e-02 4.061467744268355633e-04 0.000000000000000000 -6.470000000000000751e-02 3.803216713614568584e-04 0.000000000000000000 -6.569500000000000339e-02 3.565121477980526233e-04 0.000000000000000000 -6.668999999999999928e-02 3.345316391388566393e-04 0.000000000000000000 -6.768500000000000905e-02 3.142135290765838492e-04 0.000000000000000000 -6.868000000000000493e-02 2.954087345123552772e-04 0.000000000000000000 -6.967500000000000082e-02 2.779836164163030222e-04 0.000000000000000000 -7.067000000000001059e-02 2.618181681981876160e-04 0.000000000000000000 -7.166500000000000647e-02 2.468044409991756983e-04 0.000000000000000000 -7.266000000000000236e-02 2.328451717867457689e-04 0.000000000000000000 -7.365499999999999825e-02 2.198525854904882944e-04 0.000000000000000000 -7.465000000000000802e-02 2.077473468635113445e-04 0.000000000000000000 -7.564500000000000390e-02 1.964576414578978456e-04 0.000000000000000000 -7.663999999999999979e-02 1.859183681963245624e-04 0.000000000000000000 -7.763500000000000956e-02 1.760704286136114403e-04 0.000000000000000000 -7.863000000000000544e-02 1.668601000190766644e-04 0.000000000000000000 -7.962500000000000133e-02 1.582384816641631969e-04 0.000000000000000000 -8.062000000000001110e-02 1.501610045482572255e-04 0.000000000000000000 -8.161500000000000699e-02 1.425869968064864129e-04 0.000000000000000000 -8.261000000000000287e-02 1.354792977357120428e-04 0.000000000000000000 -8.360499999999999876e-02 1.288039144612181271e-04 0.000000000000000000 -8.460000000000000853e-02 1.225297160532930944e-04 0.000000000000000000 -8.559500000000000441e-02 1.166281605923794913e-04 0.000000000000000000 -8.659000000000000030e-02 1.110730512716228780e-04 0.000000000000000000 -8.758500000000001007e-02 1.058403181323294158e-04 0.000000000000000000 -8.858000000000000596e-02 1.009078224632976368e-04 0.000000000000000000 -8.957500000000000184e-02 9.625518127027844306e-05 0.000000000000000000 -9.057000000000001161e-02 9.186360954578184804e-05 0.000000000000000000 -9.156500000000000750e-02 8.771577834949046066e-05 0.000000000000000000 -9.256000000000000338e-02 8.379568695238581060e-05 0.000000000000000000 -9.355499999999999927e-02 8.008854750826035064e-05 0.000000000000000000 -9.455000000000000904e-02 7.658068089951252906e-05 0.000000000000000000 -9.554500000000000492e-02 7.325942256365089748e-05 0.000000000000000000 -9.654000000000000081e-02 7.011303724606809810e-05 0.000000000000000000 -9.753500000000001058e-02 6.713064174628380202e-05 0.000000000000000000 -9.853000000000000647e-02 6.430213483124872734e-05 0.000000000000000000 -9.952500000000000235e-02 6.161813358258931778e-05 0.000000000000000000 -1.005199999999999982e-01 5.906991552652936407e-05 0.000000000000000000 -1.015150000000000080e-01 5.664936596722652709e-05 0.000000000000000000 -1.025100000000000039e-01 5.434893000757861324e-05 0.000000000000000000 -1.035049999999999998e-01 5.216156879745617451e-05 0.000000000000000000 -1.045000000000000095e-01 5.008071959859009475e-05 0.000000000000000000 -1.054950000000000054e-01 4.810025929894232714e-05 0.000000000000000000 -1.064900000000000013e-01 4.621447104794872937e-05 0.000000000000000000 -1.074850000000000111e-01 4.441801371822664884e-05 0.000000000000000000 -1.084800000000000070e-01 4.270589392966370960e-05 0.000000000000000000 -1.094750000000000029e-01 4.107344039873492037e-05 0.000000000000000000 -1.104699999999999988e-01 3.951628039990539470e-05 0.000000000000000000 -1.114650000000000085e-01 3.803031814727148062e-05 0.000000000000000000 -1.124600000000000044e-01 3.661171492366325104e-05 0.000000000000000000 -1.134550000000000003e-01 3.525687080139357449e-05 0.000000000000000000 -1.144500000000000101e-01 3.396240781400948852e-05 0.000000000000000000 -1.154450000000000059e-01 3.272515445200561756e-05 0.000000000000000000 -1.164400000000000018e-01 3.154213136757109493e-05 0.000000000000000000 -1.174350000000000116e-01 3.041053818437549486e-05 0.000000000000000000 -1.184300000000000075e-01 2.932774131814763082e-05 0.000000000000000000 -1.194250000000000034e-01 2.829126272259308120e-05 0.000000000000000000 -1.204199999999999993e-01 2.729876948309178597e-05 0.000000000000000000 -1.214150000000000090e-01 2.634806418770863114e-05 0.000000000000000000 -1.224100000000000049e-01 2.543707601145856189e-05 0.000000000000000000 -1.234050000000000008e-01 2.456385245553760122e-05 0.000000000000000000 -1.244000000000000106e-01 2.372655168842050194e-05 0.000000000000000000 -1.253950000000000065e-01 2.292343544045605906e-05 0.000000000000000000 -1.263900000000000023e-01 2.215286240780996405e-05 0.000000000000000000 -1.273849999999999982e-01 2.141328212547069355e-05 0.000000000000000000 -1.283799999999999941e-01 2.070322927252014994e-05 0.000000000000000000 -1.293749999999999900e-01 2.002131837599849124e-05 0.000000000000000000 -1.303700000000000137e-01 1.936623888259802600e-05 0.000000000000000000 -1.313650000000000095e-01 1.873675056998053514e-05 0.000000000000000000 -1.323600000000000054e-01 1.813167927190132041e-05 0.000000000000000000 -1.333550000000000013e-01 1.754991289344203385e-05 0.000000000000000000 -1.343499999999999972e-01 1.699039769464770946e-05 0.000000000000000000 -1.353449999999999931e-01 1.645213482259845323e-05 0.000000000000000000 -1.363400000000000167e-01 1.593417707359521767e-05 0.000000000000000000 -1.373350000000000126e-01 1.543562586860838427e-05 0.000000000000000000 -1.383300000000000085e-01 1.495562842648808664e-05 0.000000000000000000 -1.393250000000000044e-01 1.449337512065626627e-05 0.000000000000000000 -1.403200000000000003e-01 1.404809700615483821e-05 0.000000000000000000 -1.413149999999999962e-01 1.361906350491213202e-05 0.000000000000000000 -1.423099999999999921e-01 1.320558023807027655e-05 0.000000000000000000 -1.433050000000000157e-01 1.280698699505669096e-05 0.000000000000000000 -1.443000000000000116e-01 1.242265582987766277e-05 0.000000000000000000 -1.452950000000000075e-01 1.205198927583547193e-05 0.000000000000000000 -1.462900000000000034e-01 1.169441867055197280e-05 0.000000000000000000 -1.472849999999999993e-01 1.134940258375420816e-05 0.000000000000000000 -1.482799999999999951e-01 1.101642534088488612e-05 0.000000000000000000 -1.492750000000000188e-01 1.069499563607656409e-05 0.000000000000000000 -1.502700000000000147e-01 1.038464522852731763e-05 0.000000000000000000 -1.512650000000000106e-01 1.008492771673922509e-05 0.000000000000000000 -1.522600000000000064e-01 9.795417385487658167e-06 0.000000000000000000 -1.532550000000000023e-01 9.515708120754915602e-06 0.000000000000000000 -1.542499999999999982e-01 9.245412388214926215e-06 0.000000000000000000 -1.552449999999999941e-01 8.984160271147430192e-06 0.000000000000000000 -1.562400000000000178e-01 8.731598563979155208e-06 0.000000000000000000 -1.572350000000000136e-01 8.487389917891189619e-06 0.000000000000000000 -1.582300000000000095e-01 8.251212035195819211e-06 0.000000000000000000 -1.592250000000000054e-01 8.022756909411819735e-06 0.000000000000000000 -1.602200000000000013e-01 7.801730108172303166e-06 0.000000000000000000 -1.612149999999999972e-01 7.587850096304319501e-06 0.000000000000000000 -1.622099999999999931e-01 7.380847596593427883e-06 0.000000000000000000 -1.632050000000000167e-01 7.180464985919699528e-06 0.000000000000000000 -1.642000000000000126e-01 6.986455724602389345e-06 0.000000000000000000 -1.651950000000000085e-01 6.798583816938923489e-06 0.000000000000000000 -1.661900000000000044e-01 6.616623301054710733e-06 0.000000000000000000 -1.671850000000000003e-01 6.440357766307891073e-06 0.000000000000000000 -1.681799999999999962e-01 6.269579896604869611e-06 0.000000000000000000 -1.691749999999999921e-01 6.104091038089564868e-06 0.000000000000000000 -1.701700000000000157e-01 5.943700789772575947e-06 0.000000000000000000 -1.711650000000000116e-01 5.788226615756587192e-06 0.000000000000000000 -1.721600000000000075e-01 5.637493477799012715e-06 0.000000000000000000 -1.731550000000000034e-01 5.491333487035706967e-06 0.000000000000000000 -1.741499999999999992e-01 5.349585573761062137e-06 0.000000000000000000 -1.751449999999999951e-01 5.212095174233773578e-06 0.000000000000000000 -1.761400000000000188e-01 5.078713933538307867e-06 0.000000000000000000 -1.771350000000000147e-01 4.949299423590993852e-06 0.000000000000000000 -1.781300000000000106e-01 4.823714875442655119e-06 0.000000000000000000 -1.791250000000000064e-01 4.701828925074577255e-06 0.000000000000000000 -1.801200000000000023e-01 4.583515371940636223e-06 0.000000000000000000 -1.811149999999999982e-01 4.468652949545531132e-06 0.000000000000000000 -1.821099999999999941e-01 4.357125107399881593e-06 0.000000000000000000 -1.831050000000000177e-01 4.248819803728705652e-06 0.000000000000000000 -1.841000000000000136e-01 4.143629308349770852e-06 0.000000000000000000 -1.850950000000000095e-01 4.041450015165261868e-06 0.000000000000000000 -1.860900000000000054e-01 3.942182263758992194e-06 0.000000000000000000 -1.870850000000000013e-01 3.845730169599192739e-06 0.000000000000000000 -1.880799999999999972e-01 3.752001462399423300e-06 0.000000000000000000 -1.890749999999999931e-01 3.660907332198875170e-06 0.000000000000000000 -1.900700000000000167e-01 3.572362282757150113e-06 0.000000000000000000 -1.910650000000000126e-01 3.486283991877368194e-06 0.000000000000000000 -1.920600000000000085e-01 3.402593178302982697e-06 0.000000000000000000 -1.930550000000000044e-01 3.321213474835895762e-06 0.000000000000000000 -1.940500000000000003e-01 3.242071307366984273e-06 0.000000000000000000 -1.950449999999999962e-01 3.165095779504616941e-06 0.000000000000000000 -1.960399999999999920e-01 3.090218562523206605e-06 0.000000000000000000 -1.970350000000000157e-01 3.017373790355003906e-06 0.000000000000000000 -1.980300000000000116e-01 2.946497959373940888e-06 0.000000000000000000 -1.990250000000000075e-01 2.877529832728726358e-06 0.000000000000000000 -2.000200000000000033e-01 2.810410348997253469e-06 0.000000000000000000 -2.010149999999999992e-01 2.745082534945871258e-06 0.000000000000000000 -2.020099999999999951e-01 2.681491422194076088e-06 0.000000000000000000 -2.030050000000000188e-01 2.619583967585816721e-06 0.000000000000000000 -2.040000000000000147e-01 2.559308977088196519e-06 0.000000000000000000 -2.049950000000000105e-01 2.500617033048890839e-06 0.000000000000000000 -2.059900000000000064e-01 2.443460424640982012e-06 0.000000000000000000 -2.069850000000000023e-01 2.387793081346400505e-06 0.000000000000000000 -2.079799999999999982e-01 2.333570509331725681e-06 0.000000000000000000 -2.089749999999999941e-01 2.280749730574460933e-06 0.000000000000000000 -2.099700000000000177e-01 2.229289224610072797e-06 0.000000000000000000 -2.109650000000000136e-01 2.179148872777007317e-06 0.000000000000000000 -2.119600000000000095e-01 2.130289904837552500e-06 0.000000000000000000 -2.129550000000000054e-01 2.082674847866944899e-06 0.000000000000000000 -2.139500000000000013e-01 2.036267477302419947e-06 0.000000000000000000 -2.149449999999999972e-01 1.991032770050237681e-06 0.000000000000000000 -2.159399999999999931e-01 1.946936859557188785e-06 0.000000000000000000 -2.169350000000000167e-01 1.903946992756716464e-06 0.000000000000000000 -2.179300000000000126e-01 1.862031488799201211e-06 0.000000000000000000 -2.189250000000000085e-01 1.821159699489077939e-06 0.000000000000000000 -2.199200000000000044e-01 1.781301971348607896e-06 0.000000000000000000 -2.209150000000000003e-01 1.742429609236075048e-06 0.000000000000000000 -2.219099999999999961e-01 1.704514841445228144e-06 0.000000000000000000 -2.229050000000000198e-01 1.667530786223389054e-06 0.000000000000000000 -2.239000000000000157e-01 1.631451419641829289e-06 0.000000000000000000 -2.248950000000000116e-01 1.596251544758542627e-06 0.000000000000000000 -2.258900000000000075e-01 1.561906762016576218e-06 0.000000000000000000 -2.268850000000000033e-01 1.528393440823871229e-06 0.000000000000000000 -2.278799999999999992e-01 1.495688692261441789e-06 0.000000000000000000 -2.288749999999999951e-01 1.463770342870089032e-06 0.000000000000000000 -2.298700000000000188e-01 1.432616909471420088e-06 0.000000000000000000 -2.308650000000000146e-01 1.402207574973502849e-06 0.000000000000000000 -2.318600000000000105e-01 1.372522165124398464e-06 0.000000000000000000 -2.328550000000000064e-01 1.343541126166518876e-06 0.000000000000000000 -2.338500000000000023e-01 1.315245503359037064e-06 0.000000000000000000 -2.348449999999999982e-01 1.287616920326394123e-06 0.000000000000000000 -2.358399999999999941e-01 1.260637559201489898e-06 0.000000000000000000 -2.368350000000000177e-01 1.234290141526865827e-06 0.000000000000000000 -2.378300000000000136e-01 1.208557909884525645e-06 0.000000000000000000 -2.388250000000000095e-01 1.183424610222043002e-06 0.000000000000000000 -2.398200000000000054e-01 1.158874474846250690e-06 0.000000000000000000 -2.408150000000000013e-01 1.134892206056985017e-06 0.000000000000000000 -2.418099999999999972e-01 1.111462960394385494e-06 0.000000000000000000 -2.428049999999999931e-01 1.088572333473516146e-06 0.000000000000000000 -2.438000000000000167e-01 1.066206345383700941e-06 0.000000000000000000 -2.447950000000000126e-01 1.044351426627338742e-06 0.000000000000000000 -2.457900000000000085e-01 1.022994404578400489e-06 0.000000000000000000 -2.467850000000000044e-01 1.002122490437704232e-06 0.000000000000000000 -2.477800000000000002e-01 9.817232666657718879e-07 0.000000000000000000 -2.487749999999999961e-01 9.617846748736519515e-07 0.000000000000000000 -2.497700000000000198e-01 9.422950041539083708e-07 0.000000000000000000 -2.507650000000000157e-01 9.232428798323453051e-07 0.000000000000000000 -2.517599999999999838e-01 9.046172526266390979e-07 0.000000000000000000 -2.527550000000000074e-01 8.864073881929345266e-07 0.000000000000000000 -2.537499999999999756e-01 8.686028570467542300e-07 0.000000000000000000 -2.547449999999999992e-01 8.511935248416559944e-07 0.000000000000000000 -2.557400000000000229e-01 8.341695429956798617e-07 0.000000000000000000 -2.567349999999999910e-01 8.175213396454100065e-07 0.000000000000000000 -2.577300000000000146e-01 8.012396109212888927e-07 0.000000000000000000 -2.587249999999999828e-01 7.853153125282533498e-07 0.000000000000000000 -2.597200000000000064e-01 7.697396516203173399e-07 0.000000000000000000 -2.607150000000000301e-01 7.545040789584628936e-07 0.000000000000000000 -2.617099999999999982e-01 7.396002813402122049e-07 0.000000000000000000 -2.627050000000000218e-01 7.250201742916859191e-07 0.000000000000000000 -2.636999999999999900e-01 7.107558950102262601e-07 0.000000000000000000 -2.646950000000000136e-01 6.967997955505304836e-07 0.000000000000000000 -2.656899999999999817e-01 6.831444362421918255e-07 0.000000000000000000 -2.666850000000000054e-01 6.697825793328290410e-07 0.000000000000000000 -2.676800000000000290e-01 6.567071828464906383e-07 0.000000000000000000 -2.686749999999999972e-01 6.439113946490282237e-07 0.000000000000000000 -2.696700000000000208e-01 6.313885467153174819e-07 0.000000000000000000 -2.706649999999999889e-01 6.191321495868240811e-07 0.000000000000000000 -2.716600000000000126e-01 6.071358870161023394e-07 0.000000000000000000 -2.726549999999999807e-01 5.953936107895076103e-07 0.000000000000000000 -2.736500000000000044e-01 5.838993357212978451e-07 0.000000000000000000 -2.746450000000000280e-01 5.726472348147212419e-07 0.000000000000000000 -2.756399999999999961e-01 5.616316345813571775e-07 0.000000000000000000 -2.766350000000000198e-01 5.508470105157720654e-07 0.000000000000000000 -2.776299999999999879e-01 5.402879827167730058e-07 0.000000000000000000 -2.786250000000000115e-01 5.299493116534244488e-07 0.000000000000000000 -2.796199999999999797e-01 5.198258940675015360e-07 0.000000000000000000 -2.806150000000000033e-01 5.099127590094127535e-07 0.000000000000000000 -2.816100000000000270e-01 5.002050640022411882e-07 0.000000000000000000 -2.826049999999999951e-01 4.906980913288911179e-07 0.000000000000000000 -2.836000000000000187e-01 4.813872444391793366e-07 0.000000000000000000 -2.845949999999999869e-01 4.722680444710293888e-07 0.000000000000000000 -2.855900000000000105e-01 4.633361268832067542e-07 0.000000000000000000 -2.865850000000000342e-01 4.545872381946849999e-07 0.000000000000000000 -2.875800000000000023e-01 4.460172328274867991e-07 0.000000000000000000 -2.885750000000000259e-01 4.376220700492397344e-07 0.000000000000000000 -2.895699999999999941e-01 4.293978110113955783e-07 0.000000000000000000 -2.905650000000000177e-01 4.213406158812215202e-07 0.000000000000000000 -2.915599999999999858e-01 4.134467410625320186e-07 0.000000000000000000 -2.925550000000000095e-01 4.057125365037572669e-07 0.000000000000000000 -2.935500000000000331e-01 3.981344430887845665e-07 0.000000000000000000 -2.945450000000000013e-01 3.907089901094955503e-07 0.000000000000000000 -2.955400000000000249e-01 3.834327928155199364e-07 0.000000000000000000 -2.965349999999999930e-01 3.763025500396661164e-07 0.000000000000000000 -2.975300000000000167e-01 3.693150418962285531e-07 0.000000000000000000 -2.985249999999999848e-01 3.624671275491292328e-07 0.000000000000000000 -2.995200000000000085e-01 3.557557430487765712e-07 0.000000000000000000 -3.005150000000000321e-01 3.491778992339947667e-07 0.000000000000000000 -3.015100000000000002e-01 3.427306796976922247e-07 0.000000000000000000 -3.025050000000000239e-01 3.364112388139378583e-07 0.000000000000000000 -3.034999999999999920e-01 3.302167998242062930e-07 0.000000000000000000 -3.044950000000000156e-01 3.241446529812717644e-07 0.000000000000000000 -3.054899999999999838e-01 3.181921537481003399e-07 0.000000000000000000 -3.064850000000000074e-01 3.123567210511762908e-07 0.000000000000000000 -3.074800000000000311e-01 3.066358355846650517e-07 0.000000000000000000 -3.084749999999999992e-01 3.010270381660337490e-07 0.000000000000000000 -3.094700000000000228e-01 2.955279281388950346e-07 0.000000000000000000 -3.104649999999999910e-01 2.901361618240254941e-07 0.000000000000000000 -3.114600000000000146e-01 2.848494510149534469e-07 0.000000000000000000 -3.124549999999999828e-01 2.796655615181440895e-07 0.000000000000000000 -3.134500000000000064e-01 2.745823117354215134e-07 0.000000000000000000 -3.144450000000000300e-01 2.695975712878325508e-07 0.000000000000000000 -3.154399999999999982e-01 2.647092596790410133e-07 0.000000000000000000 -3.164350000000000218e-01 2.599153449978837568e-07 0.000000000000000000 -3.174299999999999899e-01 2.552138426577992562e-07 0.000000000000000000 -3.184250000000000136e-01 2.506028141727277769e-07 0.000000000000000000 -3.194199999999999817e-01 2.460803659680998870e-07 0.000000000000000000 -3.204150000000000054e-01 2.416446482256505412e-07 0.000000000000000000 -3.214100000000000290e-01 2.372938537613893963e-07 0.000000000000000000 -3.224049999999999971e-01 2.330262169348859350e-07 0.000000000000000000 -3.234000000000000208e-01 2.288400125900244041e-07 0.000000000000000000 -3.243949999999999889e-01 2.247335550253473878e-07 0.000000000000000000 -3.253900000000000126e-01 2.207051969933976064e-07 0.000000000000000000 -3.263849999999999807e-01 2.167533287283641152e-07 0.000000000000000000 -3.273800000000000043e-01 2.128763770004190671e-07 0.000000000000000000 -3.283750000000000280e-01 2.090728041971626540e-07 0.000000000000000000 -3.293699999999999961e-01 2.053411074299329102e-07 0.000000000000000000 -3.303650000000000198e-01 2.016798176654320889e-07 0.000000000000000000 -3.313599999999999879e-01 1.980874988810449717e-07 0.000000000000000000 -3.323550000000000115e-01 1.945627472435601437e-07 0.000000000000000000 -3.333499999999999797e-01 1.911041903105379646e-07 0.000000000000000000 -3.343450000000000033e-01 1.877104862536845619e-07 0.000000000000000000 -3.353400000000000269e-01 1.843803231029639430e-07 0.000000000000000000 -3.363349999999999951e-01 1.811124180120913374e-07 0.000000000000000000 -3.373300000000000187e-01 1.779055165433834375e-07 0.000000000000000000 -3.383249999999999869e-01 1.747583919723379171e-07 0.000000000000000000 -3.393200000000000105e-01 1.716698446108473038e-07 0.000000000000000000 -3.403150000000000341e-01 1.686387011487514324e-07 0.000000000000000000 -3.413100000000000023e-01 1.656638140131796811e-07 0.000000000000000000 -3.423050000000000259e-01 1.627440607449233080e-07 0.000000000000000000 -3.432999999999999940e-01 1.598783433915807615e-07 0.000000000000000000 -3.442950000000000177e-01 1.570655879169011439e-07 0.000000000000000000 -3.452899999999999858e-01 1.543047436258950896e-07 0.000000000000000000 -3.462850000000000095e-01 1.515947826050264808e-07 0.000000000000000000 -3.472800000000000331e-01 1.489346991773542697e-07 0.000000000000000000 -3.482750000000000012e-01 1.463235093721429985e-07 0.000000000000000000 -3.492700000000000249e-01 1.437602504082063715e-07 0.000000000000000000 -3.502649999999999930e-01 1.412439801910185004e-07 0.000000000000000000 -3.512600000000000167e-01 1.387737768228775831e-07 0.000000000000000000 -3.522549999999999848e-01 1.363487381259259015e-07 0.000000000000000000 -3.532500000000000084e-01 1.339679811775864490e-07 0.000000000000000000 -3.542450000000000321e-01 1.316306418580024381e-07 0.000000000000000000 -3.552400000000000002e-01 1.293358744093316699e-07 0.000000000000000000 -3.562350000000000239e-01 1.270828510063341282e-07 0.000000000000000000 -3.572299999999999920e-01 1.248707613379087200e-07 0.000000000000000000 -3.582250000000000156e-01 1.226988121998597123e-07 0.000000000000000000 -3.592199999999999838e-01 1.205662270974316575e-07 0.000000000000000000 -3.602150000000000074e-01 1.184722458585421587e-07 0.000000000000000000 -3.612100000000000311e-01 1.164161242567355819e-07 0.000000000000000000 -3.622049999999999992e-01 1.143971336435086992e-07 0.000000000000000000 -3.632000000000000228e-01 1.124145605904174832e-07 0.000000000000000000 -3.641949999999999910e-01 1.104677065397677744e-07 0.000000000000000000 -3.651900000000000146e-01 1.085558874643744278e-07 0.000000000000000000 -3.661849999999999827e-01 1.066784335360411807e-07 0.000000000000000000 -3.671800000000000064e-01 1.048346888019738436e-07 0.000000000000000000 -3.681750000000000300e-01 1.030240108696256120e-07 0.000000000000000000 -3.691699999999999982e-01 1.012457705992769268e-07 0.000000000000000000 -3.701650000000000218e-01 9.949935180445753679e-08 0.000000000000000000 -3.711599999999999899e-01 9.778415095948028884e-08 0.000000000000000000 -3.721550000000000136e-01 9.609957691461342208e-08 0.000000000000000000 -3.731499999999999817e-01 9.444505061804599980e-08 0.000000000000000000 -3.741450000000000053e-01 9.282000484481748754e-08 0.000000000000000000 -3.751400000000000290e-01 9.122388393244832792e-08 0.000000000000000000 -3.761349999999999971e-01 8.965614352301605240e-08 0.000000000000000000 -3.771300000000000208e-01 8.811625031155657185e-08 0.000000000000000000 -3.781249999999999889e-01 8.660368180062064381e-08 0.000000000000000000 -3.791200000000000125e-01 8.511792606090979959e-08 0.000000000000000000 -3.801149999999999807e-01 8.365848149753766865e-08 0.000000000000000000 -3.811100000000000043e-01 8.222485662219406386e-08 0.000000000000000000 -3.821050000000000280e-01 8.081656983069726827e-08 0.000000000000000000 -3.830999999999999961e-01 7.943314918590569788e-08 0.000000000000000000 -3.840950000000000197e-01 7.807413220591217810e-08 0.000000000000000000 -3.850899999999999879e-01 7.673906565739948301e-08 0.000000000000000000 -3.860850000000000115e-01 7.542750535373204618e-08 0.000000000000000000 -3.870799999999999796e-01 7.413901595817632364e-08 0.000000000000000000 -3.880750000000000033e-01 7.287317079158164557e-08 0.000000000000000000 -3.890700000000000269e-01 7.162955164475418635e-08 0.000000000000000000 -3.900649999999999951e-01 7.040774859527686503e-08 0.000000000000000000 -3.910600000000000187e-01 6.920735982860711948e-08 0.000000000000000000 -3.920549999999999868e-01 6.802799146356765812e-08 0.000000000000000000 -3.930500000000000105e-01 6.686925738177639130e-08 0.000000000000000000 -3.940450000000000341e-01 6.573077906118054173e-08 0.000000000000000000 -3.950400000000000023e-01 6.461218541347500975e-08 0.000000000000000000 -3.960350000000000259e-01 6.351311262541379473e-08 0.000000000000000000 -3.970299999999999940e-01 6.243320400370203637e-08 0.000000000000000000 -3.980250000000000177e-01 6.137210982358970926e-08 0.000000000000000000 -3.990199999999999858e-01 6.032948718098469951e-08 0.000000000000000000 -4.000150000000000095e-01 5.930499984799508768e-08 0.000000000000000000 -4.010100000000000331e-01 5.829831813179890142e-08 0.000000000000000000 -4.020050000000000012e-01 5.730911873679025764e-08 0.000000000000000000 -4.030000000000000249e-01 5.633708462991893812e-08 0.000000000000000000 -4.039949999999999930e-01 5.538190490915735624e-08 0.000000000000000000 -4.049900000000000166e-01 5.444327467487663858e-08 0.000000000000000000 -4.059849999999999848e-01 5.352089490429422662e-08 0.000000000000000000 -4.069800000000000084e-01 5.261447232878746078e-08 0.000000000000000000 -4.079750000000000321e-01 5.172371931388542301e-08 0.000000000000000000 -4.089700000000000002e-01 5.084835374211253429e-08 0.000000000000000000 -4.099650000000000238e-01 4.998809889844755150e-08 0.000000000000000000 -4.109599999999999920e-01 4.914268335846344356e-08 0.000000000000000000 -4.119550000000000156e-01 4.831184087875673132e-08 0.000000000000000000 -4.129499999999999837e-01 4.749531029020172877e-08 0.000000000000000000 -4.139450000000000074e-01 4.669283539330103853e-08 0.000000000000000000 -4.149400000000000310e-01 4.590416485605566593e-08 0.000000000000000000 -4.159349999999999992e-01 4.512905211408358873e-08 0.000000000000000000 -4.169300000000000228e-01 4.436725527296136481e-08 0.000000000000000000 -4.179249999999999909e-01 4.361853701276109034e-08 0.000000000000000000 -4.189200000000000146e-01 4.288266449474032394e-08 0.000000000000000000 -4.199149999999999827e-01 4.215940926999557206e-08 0.000000000000000000 -4.209100000000000064e-01 4.144854719035587216e-08 0.000000000000000000 -4.219050000000000300e-01 4.074985832100385988e-08 0.000000000000000000 -4.228999999999999981e-01 4.006312685518982154e-08 0.000000000000000000 -4.238950000000000218e-01 3.938814103081402333e-08 0.000000000000000000 -4.248899999999999899e-01 3.872469304875328655e-08 0.000000000000000000 -4.258850000000000136e-01 3.807257899308821213e-08 0.000000000000000000 -4.268799999999999817e-01 3.743159875300075409e-08 0.000000000000000000 -4.278750000000000053e-01 3.680155594641652206e-08 0.000000000000000000 -4.288700000000000290e-01 3.618225784535955942e-08 0.000000000000000000 -4.298649999999999971e-01 3.557351530280438460e-08 0.000000000000000000 -4.308600000000000207e-01 3.497514268124120271e-08 0.000000000000000000 -4.318549999999999889e-01 3.438695778272888431e-08 0.000000000000000000 -4.328500000000000125e-01 3.380878178052697901e-08 0.000000000000000000 -4.338449999999999807e-01 3.324043915208500011e-08 0.000000000000000000 -4.348400000000000043e-01 3.268175761362234442e-08 0.000000000000000000 -4.358350000000000279e-01 3.213256805597840426e-08 0.000000000000000000 -4.368299999999999961e-01 3.159270448196308571e-08 0.000000000000000000 -4.378250000000000197e-01 3.106200394495490724e-08 0.000000000000000000 -4.388199999999999878e-01 3.054030648889349978e-08 0.000000000000000000 -4.398150000000000115e-01 3.002745508947083052e-08 0.000000000000000000 -4.408100000000000351e-01 2.952329559662719818e-08 0.000000000000000000 -4.418050000000000033e-01 2.902767667829952025e-08 0.000000000000000000 -4.428000000000000269e-01 2.854044976526795720e-08 0.000000000000000000 -4.437949999999999950e-01 2.806146899727338396e-08 0.000000000000000000 -4.447900000000000187e-01 2.759059117018932799e-08 0.000000000000000000 -4.457849999999999868e-01 2.712767568439074514e-08 0.000000000000000000 -4.467800000000000105e-01 2.667258449415284049e-08 0.000000000000000000 -4.477750000000000341e-01 2.622518205811867270e-08 0.000000000000000000 -4.487700000000000022e-01 2.578533529082613517e-08 0.000000000000000000 -4.497650000000000259e-01 2.535291351522951938e-08 0.000000000000000000 -4.507599999999999940e-01 2.492778841627287470e-08 0.000000000000000000 -4.517550000000000177e-01 2.450983399531671096e-08 0.000000000000000000 -4.527499999999999858e-01 2.409892652562846511e-08 0.000000000000000000 -4.537450000000000094e-01 2.369494450875368376e-08 0.000000000000000000 -4.547400000000000331e-01 2.329776863176683936e-08 0.000000000000000000 -4.557350000000000012e-01 2.290728172544141217e-08 0.000000000000000000 -4.567300000000000249e-01 2.252336872328070319e-08 0.000000000000000000 -4.577249999999999930e-01 2.214591662139746355e-08 0.000000000000000000 -4.587200000000000166e-01 2.177481443920168254e-08 0.000000000000000000 -4.597149999999999848e-01 2.140995318088074199e-08 0.000000000000000000 -4.607100000000000084e-01 2.105122579775599487e-08 0.000000000000000000 -4.617050000000000320e-01 2.069852715129059986e-08 0.000000000000000000 -4.627000000000000002e-01 2.035175397696612041e-08 0.000000000000000000 -4.636950000000000238e-01 2.001080484878018436e-08 0.000000000000000000 -4.646899999999999920e-01 1.967558014460917590e-08 0.000000000000000000 -4.656850000000000156e-01 1.934598201213554117e-08 0.000000000000000000 -4.666799999999999837e-01 1.902191433555517809e-08 0.000000000000000000 -4.676750000000000074e-01 1.870328270293666115e-08 0.000000000000000000 -4.686700000000000310e-01 1.838999437423243993e-08 0.000000000000000000 -4.696649999999999991e-01 1.808195824993965897e-08 0.000000000000000000 -4.706600000000000228e-01 1.777908484038484727e-08 0.000000000000000000 -4.716549999999999909e-01 1.748128623567682730e-08 0.000000000000000000 -4.726500000000000146e-01 1.718847607616211987e-08 0.000000000000000000 -4.736449999999999827e-01 1.690056952359754085e-08 0.000000000000000000 -4.746400000000000063e-01 1.661748323278907984e-08 0.000000000000000000 -4.756350000000000300e-01 1.633913532386936203e-08 0.000000000000000000 -4.766299999999999981e-01 1.606544535509242241e-08 0.000000000000000000 -4.776250000000000218e-01 1.579633429619561801e-08 0.000000000000000000 -4.786199999999999899e-01 1.553172450226774170e-08 0.000000000000000000 -4.796150000000000135e-01 1.527153968812958752e-08 0.000000000000000000 -4.806099999999999817e-01 1.501570490329198411e-08 0.000000000000000000 -4.816050000000000053e-01 1.476414650728518093e-08 0.000000000000000000 -4.826000000000000290e-01 1.451679214561021136e-08 0.000000000000000000 -4.835949999999999971e-01 1.427357072605299284e-08 0.000000000000000000 -4.845900000000000207e-01 1.403441239554192092e-08 0.000000000000000000 -4.855849999999999889e-01 1.379924851741501211e-08 0.000000000000000000 -4.865800000000000125e-01 1.356801164916471703e-08 0.000000000000000000 -4.875749999999999806e-01 1.334063552058006977e-08 0.000000000000000000 -4.885700000000000043e-01 1.311705501236100186e-08 0.000000000000000000 -4.895650000000000279e-01 1.289720613511240166e-08 0.000000000000000000 -4.905599999999999961e-01 1.268102600878624253e-08 0.000000000000000000 -4.915550000000000197e-01 1.246845284246573869e-08 0.000000000000000000 -4.925499999999999878e-01 1.225942591461487445e-08 0.000000000000000000 -4.935450000000000115e-01 1.205388555364954470e-08 0.000000000000000000 -4.945400000000000351e-01 1.185177311892213667e-08 0.000000000000000000 -4.955350000000000033e-01 1.165303098206406425e-08 0.000000000000000000 -4.965300000000000269e-01 1.145760250866327575e-08 0.000000000000000000 -4.975249999999999950e-01 1.126543204035432285e-08 0.000000000000000000 -4.985200000000000187e-01 1.107646487718022137e-08 0.000000000000000000 -4.995149999999999868e-01 1.089064726035936574e-08 0.000000000000000000 -5.005100000000000104e-01 1.070792635533893917e-08 0.000000000000000000 -5.015049999999999786e-01 1.052825023518430476e-08 0.000000000000000000 -5.024999999999999467e-01 1.035156786429983128e-08 0.000000000000000000 -5.034950000000000259e-01 1.017782908245194928e-08 0.000000000000000000 -5.044899999999999940e-01 1.000698458908213401e-08 0.000000000000000000 -5.054849999999999621e-01 9.838985927942606211e-09 0.000000000000000000 -5.064800000000000413e-01 9.673785472016118153e-09 0.000000000000000000 -5.074750000000000094e-01 9.511336408707597594e-09 0.000000000000000000 -5.084699999999999775e-01 9.351592725336316339e-09 0.000000000000000000 -5.094650000000000567e-01 9.194509194901617369e-09 0.000000000000000000 -5.104600000000000248e-01 9.040041362103622041e-09 0.000000000000000000 -5.114549999999999930e-01 8.888145529627538254e-09 0.000000000000000000 -5.124499999999999611e-01 8.738778744717595970e-09 0.000000000000000000 -5.134450000000000403e-01 8.591898785946051782e-09 0.000000000000000000 -5.144400000000000084e-01 8.447464150305248862e-09 0.000000000000000000 -5.154349999999999765e-01 8.305434040478789650e-09 0.000000000000000000 -5.164300000000000557e-01 8.165768352358212425e-09 0.000000000000000000 -5.174250000000000238e-01 8.028427662851563377e-09 0.000000000000000000 -5.184199999999999919e-01 7.893373217842216118e-09 0.000000000000000000 -5.194149999999999601e-01 7.760566920435978511e-09 0.000000000000000000 -5.204100000000000392e-01 7.629971319358478376e-09 0.000000000000000000 -5.214050000000000074e-01 7.501549597652244998e-09 0.000000000000000000 -5.223999999999999755e-01 7.375265561526750397e-09 0.000000000000000000 -5.233950000000000546e-01 7.251083629405264984e-09 0.000000000000000000 -5.243900000000000228e-01 7.128968821243475963e-09 0.000000000000000000 -5.253849999999999909e-01 7.008886747960125850e-09 0.000000000000000000 -5.263799999999999590e-01 6.890803601115932548e-09 0.000000000000000000 -5.273750000000000382e-01 6.774686142796504578e-09 0.000000000000000000 -5.283700000000000063e-01 6.660501695615936994e-09 0.000000000000000000 -5.293649999999999745e-01 6.548218132964528978e-09 0.000000000000000000 -5.303600000000000536e-01 6.437803869424564685e-09 0.000000000000000000 -5.313550000000000217e-01 6.329227851337567396e-09 0.000000000000000000 -5.323499999999999899e-01 6.222459547568204285e-09 0.000000000000000000 -5.333449999999999580e-01 6.117468940427315924e-09 0.000000000000000000 -5.343400000000000372e-01 6.014226516756166591e-09 0.000000000000000000 -5.353350000000000053e-01 5.912703259200147065e-09 0.000000000000000000 -5.363299999999999734e-01 5.812870637596286722e-09 0.000000000000000000 -5.373250000000000526e-01 5.714700600562036045e-09 0.000000000000000000 -5.383200000000000207e-01 5.618165567214210133e-09 0.000000000000000000 -5.393149999999999888e-01 5.523238419030037714e-09 0.000000000000000000 -5.403099999999999570e-01 5.429892491889169139e-09 0.000000000000000000 -5.413050000000000361e-01 5.338101568217842023e-09 0.000000000000000000 -5.423000000000000043e-01 5.247839869312100044e-09 0.000000000000000000 -5.432949999999999724e-01 5.159082047782700767e-09 0.000000000000000000 -5.442900000000000515e-01 5.071803180117107580e-09 0.000000000000000000 -5.452850000000000197e-01 4.985978759425942900e-09 0.000000000000000000 -5.462799999999999878e-01 4.901584688272952708e-09 0.000000000000000000 -5.472749999999999559e-01 4.818597271653313524e-09 0.000000000000000000 -5.482700000000000351e-01 4.736993210097703913e-09 0.000000000000000000 -5.492650000000000032e-01 4.656749592899734273e-09 0.000000000000000000 -5.502599999999999714e-01 4.577843891457445651e-09 0.000000000000000000 -5.512550000000000505e-01 4.500253952754923854e-09 0.000000000000000000 -5.522500000000000187e-01 4.423957992928620999e-09 0.000000000000000000 -5.532449999999999868e-01 4.348934590969638247e-09 0.000000000000000000 -5.542399999999999549e-01 4.275162682547729828e-09 0.000000000000000000 -5.552350000000000341e-01 4.202621553908566314e-09 0.000000000000000000 -5.562300000000000022e-01 4.131290835932150873e-09 0.000000000000000000 -5.572249999999999703e-01 4.061150498237967917e-09 0.000000000000000000 -5.582200000000000495e-01 3.992180843446344811e-09 0.000000000000000000 -5.592150000000000176e-01 3.924362501509357965e-09 0.000000000000000000 -5.602099999999999858e-01 3.857676424154716910e-09 0.000000000000000000 -5.612049999999999539e-01 3.792103879430714948e-09 0.000000000000000000 -5.622000000000000330e-01 3.727626446332447825e-09 0.000000000000000000 -5.631950000000000012e-01 3.664226009549415779e-09 0.000000000000000000 -5.641899999999999693e-01 3.601884754267642989e-09 0.000000000000000000 -5.651850000000000485e-01 3.540585161106631196e-09 0.000000000000000000 -5.661800000000000166e-01 3.480310001116348841e-09 0.000000000000000000 -5.671749999999999847e-01 3.421042330867932332e-09 0.000000000000000000 -5.681700000000000639e-01 3.362765487628045872e-09 0.000000000000000000 -5.691650000000000320e-01 3.305463084633811144e-09 0.000000000000000000 -5.701600000000000001e-01 3.249119006439248004e-09 0.000000000000000000 -5.711549999999999683e-01 3.193717404330445612e-09 0.000000000000000000 -5.721500000000000474e-01 3.139242691846669754e-09 0.000000000000000000 -5.731450000000000156e-01 3.085679540359040699e-09 0.000000000000000000 -5.741399999999999837e-01 3.033012874741313056e-09 0.000000000000000000 -5.751350000000000628e-01 2.981227869103609884e-09 0.000000000000000000 -5.761300000000000310e-01 2.930309942605486299e-09 0.000000000000000000 -5.771249999999999991e-01 2.880244755344017550e-09 0.000000000000000000 -5.781199999999999672e-01 2.831018204320024633e-09 0.000000000000000000 -5.791150000000000464e-01 2.782616419444479799e-09 0.000000000000000000 -5.801100000000000145e-01 2.735025759662029664e-09 0.000000000000000000 -5.811049999999999827e-01 2.688232809096205337e-09 0.000000000000000000 -5.821000000000000618e-01 2.642224373286249017e-09 0.000000000000000000 -5.830950000000000299e-01 2.596987475486436551e-09 0.000000000000000000 -5.840899999999999981e-01 2.552509353022799725e-09 0.000000000000000000 -5.850849999999999662e-01 2.508777453719068253e-09 0.000000000000000000 -5.860800000000000454e-01 2.465779432375947976e-09 0.000000000000000000 -5.870750000000000135e-01 2.423503147329195027e-09 0.000000000000000000 -5.880699999999999816e-01 2.381936657034776456e-09 0.000000000000000000 -5.890650000000000608e-01 2.341068216750600869e-09 0.000000000000000000 -5.900600000000000289e-01 2.300886275249319634e-09 0.000000000000000000 -5.910549999999999971e-01 2.261379471589899679e-09 0.000000000000000000 -5.920499999999999652e-01 2.222536631965092181e-09 0.000000000000000000 -5.930450000000000443e-01 2.184346766572887835e-09 0.000000000000000000 -5.940400000000000125e-01 2.146799066563923027e-09 0.000000000000000000 -5.950349999999999806e-01 2.109882901029975367e-09 0.000000000000000000 -5.960300000000000598e-01 2.073587814052807845e-09 0.000000000000000000 -5.970250000000000279e-01 2.037903521796197191e-09 0.000000000000000000 -5.980199999999999960e-01 2.002819909644348453e-09 0.000000000000000000 -5.990149999999999642e-01 1.968327029405863638e-09 0.000000000000000000 -6.000100000000000433e-01 1.934415096543460493e-09 0.000000000000000000 -6.010050000000000114e-01 1.901074487462710610e-09 0.000000000000000000 -6.019999999999999796e-01 1.868295736852988358e-09 0.000000000000000000 -6.029950000000000587e-01 1.836069535059167139e-09 0.000000000000000000 -6.039900000000000269e-01 1.804386725507524731e-09 0.000000000000000000 -6.049849999999999950e-01 1.773238302172079969e-09 0.000000000000000000 -6.059799999999999631e-01 1.742615407085404039e-09 0.000000000000000000 -6.069750000000000423e-01 1.712509327890016968e-09 0.000000000000000000 -6.079700000000000104e-01 1.682911495434136928e-09 0.000000000000000000 -6.089649999999999785e-01 1.653813481399450726e-09 0.000000000000000000 -6.099600000000000577e-01 1.625206995987396573e-09 0.000000000000000000 -6.109550000000000258e-01 1.597083885620513122e-09 0.000000000000000000 -6.119499999999999940e-01 1.569436130702139067e-09 0.000000000000000000 -6.129449999999999621e-01 1.542255843404127068e-09 0.000000000000000000 -6.139400000000000412e-01 1.515535265493257126e-09 0.000000000000000000 -6.149350000000000094e-01 1.489266766199405405e-09 0.000000000000000000 -6.159299999999999775e-01 1.463442840109179879e-09 0.000000000000000000 -6.169250000000000567e-01 1.438056105105303416e-09 0.000000000000000000 -6.179200000000000248e-01 1.413099300335438690e-09 0.000000000000000000 -6.189149999999999929e-01 1.388565284219914378e-09 0.000000000000000000 -6.199099999999999611e-01 1.364447032482016621e-09 0.000000000000000000 -6.209050000000000402e-01 1.340737636223382316e-09 0.000000000000000000 -6.219000000000000083e-01 1.317430300025572456e-09 0.000000000000000000 -6.228949999999999765e-01 1.294518340085705259e-09 0.000000000000000000 -6.238900000000000556e-01 1.271995182379897042e-09 0.000000000000000000 -6.248850000000000238e-01 1.249854360861907686e-09 0.000000000000000000 -6.258799999999999919e-01 1.228089515688482748e-09 0.000000000000000000 -6.268749999999999600e-01 1.206694391477565856e-09 0.000000000000000000 -6.278700000000000392e-01 1.185662835590238378e-09 0.000000000000000000 -6.288650000000000073e-01 1.164988796445623888e-09 0.000000000000000000 -6.298599999999999755e-01 1.144666321867794175e-09 0.000000000000000000 -6.308550000000000546e-01 1.124689557446997487e-09 0.000000000000000000 -6.318500000000000227e-01 1.105052744945311523e-09 0.000000000000000000 -6.328449999999999909e-01 1.085750220710908845e-09 0.000000000000000000 -6.338399999999999590e-01 1.066776414137267750e-09 0.000000000000000000 -6.348350000000000382e-01 1.048125846132423263e-09 0.000000000000000000 -6.358300000000000063e-01 1.029793127619577583e-09 0.000000000000000000 -6.368249999999999744e-01 1.011772958067064884e-09 0.000000000000000000 -6.378200000000000536e-01 9.940601240353204801e-10 0.000000000000000000 -6.388150000000000217e-01 9.766494977525064135e-10 0.000000000000000000 -6.398099999999999898e-01 9.595360357101928669e-10 0.000000000000000000 -6.408049999999999580e-01 9.427147772883389336e-10 0.000000000000000000 -6.418000000000000371e-01 9.261808433944503319e-10 0.000000000000000000 -6.427950000000000053e-01 9.099294351329261107e-10 0.000000000000000000 -6.437899999999999734e-01 8.939558324953548407e-10 0.000000000000000000 -6.447850000000000525e-01 8.782553930644280603e-10 0.000000000000000000 -6.457800000000000207e-01 8.628235507521241244e-10 0.000000000000000000 -6.467749999999999888e-01 8.476558145459802247e-10 0.000000000000000000 -6.477699999999999569e-01 8.327477672877727265e-10 0.000000000000000000 -6.487650000000000361e-01 8.180950644622847663e-10 0.000000000000000000 -6.497600000000000042e-01 8.036934330121838051e-10 0.000000000000000000 -6.507549999999999724e-01 7.895386701715532421e-10 0.000000000000000000 -6.517500000000000515e-01 7.756266423150475058e-10 0.000000000000000000 -6.527450000000000196e-01 7.619532838310401384e-10 0.000000000000000000 -6.537399999999999878e-01 7.485145960110557591e-10 0.000000000000000000 -6.547349999999999559e-01 7.353066459561349298e-10 0.000000000000000000 -6.557300000000000351e-01 7.223255655019091240e-10 0.000000000000000000 -6.567250000000000032e-01 7.095675501633230957e-10 0.000000000000000000 -6.577199999999999713e-01 6.970288580952831633e-10 0.000000000000000000 -6.587150000000000505e-01 6.847058090697376434e-10 0.000000000000000000 -6.597100000000000186e-01 6.725947834695765550e-10 0.000000000000000000 -6.607049999999999867e-01 6.606922213008890459e-10 0.000000000000000000 -6.616999999999999549e-01 6.489946212177306857e-10 0.000000000000000000 -6.626950000000000340e-01 6.374985395695149751e-10 0.000000000000000000 -6.636900000000000022e-01 6.262005894555813714e-10 0.000000000000000000 -6.646849999999999703e-01 6.150974398006807465e-10 0.000000000000000000 -6.656800000000000495e-01 6.041858144460597144e-10 0.000000000000000000 -6.666750000000000176e-01 5.934624912519768004e-10 0.000000000000000000 -6.676699999999999857e-01 5.829243012166442471e-10 0.000000000000000000 -6.686650000000000649e-01 5.725681276106499875e-10 0.000000000000000000 -6.696600000000000330e-01 5.623909051228168385e-10 0.000000000000000000 -6.706550000000000011e-01 5.523896190237439203e-10 0.000000000000000000 -6.716499999999999693e-01 5.425613043398145989e-10 0.000000000000000000 -6.726450000000000484e-01 5.329030450417581546e-10 0.000000000000000000 -6.736400000000000166e-01 5.234119732464745679e-10 0.000000000000000000 -6.746349999999999847e-01 5.140852684323522755e-10 0.000000000000000000 -6.756300000000000638e-01 5.049201566664096458e-10 0.000000000000000000 -6.766250000000000320e-01 4.959139098454811543e-10 0.000000000000000000 -6.776200000000000001e-01 4.870638449487790499e-10 0.000000000000000000 -6.786149999999999682e-01 4.783673233012896401e-10 0.000000000000000000 -6.796100000000000474e-01 4.698217498523995215e-10 0.000000000000000000 -6.806050000000000155e-01 4.614245724643800463e-10 0.000000000000000000 -6.815999999999999837e-01 4.531732812111723066e-10 0.000000000000000000 -6.825950000000000628e-01 4.450654076920853576e-10 0.000000000000000000 -6.835900000000000309e-01 4.370985243527584836e-10 0.000000000000000000 -6.845849999999999991e-01 4.292702438197627921e-10 0.000000000000000000 -6.855799999999999672e-01 4.215782182455686226e-10 0.000000000000000000 -6.865750000000000464e-01 4.140201386645318280e-10 0.000000000000000000 -6.875700000000000145e-01 4.065937343561940905e-10 0.000000000000000000 -6.885649999999999826e-01 3.992967722240903926e-10 0.000000000000000000 -6.895600000000000618e-01 3.921270561814422491e-10 0.000000000000000000 -6.905550000000000299e-01 3.850824265461304586e-10 0.000000000000000000 -6.915499999999999980e-01 3.781607594477758664e-10 0.000000000000000000 -6.925449999999999662e-01 3.713599662443719948e-10 0.000000000000000000 -6.935400000000000453e-01 3.646779929451460856e-10 0.000000000000000000 -6.945350000000000135e-01 3.581128196474731658e-10 0.000000000000000000 -6.955299999999999816e-01 3.516624599789905450e-10 0.000000000000000000 -6.965250000000000608e-01 3.453249605512386629e-10 0.000000000000000000 -6.975200000000000289e-01 3.390984004204496542e-10 0.000000000000000000 -6.985149999999999970e-01 3.329808905590815081e-10 0.000000000000000000 -6.995099999999999651e-01 3.269705733336090213e-10 0.000000000000000000 -7.005050000000000443e-01 3.210656219930606029e-10 0.000000000000000000 -7.015000000000000124e-01 3.152642401639120136e-10 0.000000000000000000 -7.024949999999999806e-01 3.095646613535301542e-10 0.000000000000000000 -7.034900000000000597e-01 3.039651484643836440e-10 0.000000000000000000 -7.044850000000000279e-01 2.984639933103836991e-10 0.000000000000000000 -7.054799999999999960e-01 2.930595161482421644e-10 0.000000000000000000 -7.064749999999999641e-01 2.877500652096199171e-10 0.000000000000000000 -7.074700000000000433e-01 2.825340162463892363e-10 0.000000000000000000 -7.084650000000000114e-01 2.774097720789625829e-10 0.000000000000000000 -7.094599999999999795e-01 2.723757621550416838e-10 0.000000000000000000 -7.104550000000000587e-01 2.674304421138305059e-10 0.000000000000000000 -7.114500000000000268e-01 2.625722933581207666e-10 0.000000000000000000 -7.124449999999999950e-01 2.577998226317362304e-10 0.000000000000000000 -7.134399999999999631e-01 2.531115616069366224e-10 0.000000000000000000 -7.144350000000000422e-01 2.485060664753810539e-10 0.000000000000000000 -7.154300000000000104e-01 2.439819175467779222e-10 0.000000000000000000 -7.164249999999999785e-01 2.395377188552389620e-10 0.000000000000000000 -7.174200000000000577e-01 2.351720977695691270e-10 0.000000000000000000 -7.184150000000000258e-01 2.308837046132094100e-10 0.000000000000000000 -7.194099999999999939e-01 2.266712122853988755e-10 0.000000000000000000 -7.204049999999999621e-01 2.225333158951815671e-10 0.000000000000000000 -7.214000000000000412e-01 2.184687323937923984e-10 0.000000000000000000 -7.223950000000000093e-01 2.144762002199834842e-10 0.000000000000000000 -7.233899999999999775e-01 2.105544789457397629e-10 0.000000000000000000 -7.243850000000000566e-01 2.067023489314449509e-10 0.000000000000000000 -7.253800000000000248e-01 2.029186109836347890e-10 0.000000000000000000 -7.263749999999999929e-01 1.992020860208143683e-10 0.000000000000000000 -7.273699999999999610e-01 1.955516147432110017e-10 0.000000000000000000 -7.283650000000000402e-01 1.919660573080928565e-10 0.000000000000000000 -7.293600000000000083e-01 1.884442930107386533e-10 0.000000000000000000 -7.303549999999999764e-01 1.849852199707302973e-10 0.000000000000000000 -7.313500000000000556e-01 1.815877548214458977e-10 0.000000000000000000 -7.323450000000000237e-01 1.782508324083276738e-10 0.000000000000000000 -7.333399999999999919e-01 1.749734054871994406e-10 0.000000000000000000 -7.343349999999999600e-01 1.717544444327696856e-10 0.000000000000000000 -7.353300000000000392e-01 1.685929369464436664e-10 0.000000000000000000 -7.363250000000000073e-01 1.654878877736655847e-10 0.000000000000000000 -7.373199999999999754e-01 1.624383184224845999e-10 0.000000000000000000 -7.383150000000000546e-01 1.594432668877642051e-10 0.000000000000000000 -7.393100000000000227e-01 1.565017873814703209e-10 0.000000000000000000 -7.403049999999999908e-01 1.536129500638754654e-10 0.000000000000000000 -7.412999999999999590e-01 1.507758407823909257e-10 0.000000000000000000 -7.422950000000000381e-01 1.479895608131337696e-10 0.000000000000000000 -7.432900000000000063e-01 1.452532266062458961e-10 0.000000000000000000 -7.442849999999999744e-01 1.425659695365616108e-10 0.000000000000000000 -7.452800000000000535e-01 1.399269356573926378e-10 0.000000000000000000 -7.462750000000000217e-01 1.373352854587497921e-10 0.000000000000000000 -7.472699999999999898e-01 1.347901936294661017e-10 0.000000000000000000 -7.482649999999999579e-01 1.322908488223341237e-10 0.000000000000000000 -7.492600000000000371e-01 1.298364534248632290e-10 0.000000000000000000 -7.502550000000000052e-01 1.274262233316630721e-10 0.000000000000000000 -7.512499999999999734e-01 1.250593877217680957e-10 0.000000000000000000 -7.522450000000000525e-01 1.227351888398047800e-10 0.000000000000000000 -7.532400000000000206e-01 1.204528817793964409e-10 0.000000000000000000 -7.542349999999999888e-01 1.182117342713846246e-10 0.000000000000000000 -7.552299999999999569e-01 1.160110264747073532e-10 0.000000000000000000 -7.562250000000000361e-01 1.138500507714065408e-10 0.000000000000000000 -7.572200000000000042e-01 1.117281115635054185e-10 0.000000000000000000 -7.582149999999999723e-01 1.096445250754567631e-10 0.000000000000000000 -7.592100000000000515e-01 1.075986191572987652e-10 0.000000000000000000 -7.602050000000000196e-01 1.055897330930012879e-10 0.000000000000000000 -7.611999999999999877e-01 1.036172174105339540e-10 0.000000000000000000 -7.621949999999999559e-01 1.016804336962519086e-10 0.000000000000000000 -7.631900000000000350e-01 9.977875441096356335e-11 0.000000000000000000 -7.641850000000000032e-01 9.791156271008344962e-11 0.000000000000000000 -7.651799999999999713e-01 9.607825226625470990e-11 0.000000000000000000 -7.661750000000000504e-01 9.427822709455359464e-11 0.000000000000000000 -7.671700000000000186e-01 9.251090138124984059e-11 0.000000000000000000 -7.681649999999999867e-01 9.077569931482582088e-11 0.000000000000000000 -7.691599999999999548e-01 8.907205491965810509e-11 0.000000000000000000 -7.701550000000000340e-01 8.739941189288420762e-11 0.000000000000000000 -7.711500000000000021e-01 8.575722344352985258e-11 0.000000000000000000 -7.721449999999999703e-01 8.414495213434765917e-11 0.000000000000000000 -7.731400000000000494e-01 8.256206972622971592e-11 0.000000000000000000 -7.741350000000000176e-01 8.100805702532533275e-11 0.000000000000000000 -7.751299999999999857e-01 7.948240373228508669e-11 0.000000000000000000 -7.761250000000000648e-01 7.798460829422891543e-11 0.000000000000000000 -7.771200000000000330e-01 7.651417775903194526e-11 0.000000000000000000 -7.781150000000000011e-01 7.507062763206356851e-11 0.000000000000000000 -7.791099999999999692e-01 7.365348173517222601e-11 0.000000000000000000 -7.801050000000000484e-01 7.226227206788986404e-11 0.000000000000000000 -7.811000000000000165e-01 7.089653867113503250e-11 0.000000000000000000 -7.820949999999999847e-01 6.955582949297110040e-11 0.000000000000000000 -7.830900000000000638e-01 6.823970025633168779e-11 0.000000000000000000 -7.840850000000000319e-01 6.694771432965168588e-11 0.000000000000000000 -7.850800000000000001e-01 6.567944259862998955e-11 0.000000000000000000 -7.860749999999999682e-01 6.443446334061711945e-11 0.000000000000000000 -7.870700000000000474e-01 6.321236210132198715e-11 0.000000000000000000 -7.880650000000000155e-01 6.201273157282145684e-11 0.000000000000000000 -7.890599999999999836e-01 6.083517147412531346e-11 0.000000000000000000 -7.900550000000000628e-01 5.967928843341275616e-11 0.000000000000000000 -7.910500000000000309e-01 5.854469587245565986e-11 0.000000000000000000 -7.920449999999999990e-01 5.743101389234423935e-11 0.000000000000000000 -7.930399999999999672e-01 5.633786916210906675e-11 0.000000000000000000 -7.940350000000000463e-01 5.526489480788727048e-11 0.000000000000000000 -7.950300000000000145e-01 5.421173030509729357e-11 0.000000000000000000 -7.960249999999999826e-01 5.317802137138497194e-11 0.000000000000000000 -7.970200000000000617e-01 5.216341986217019749e-11 0.000000000000000000 -7.980150000000000299e-01 5.116758366718568742e-11 0.000000000000000000 -7.990099999999999980e-01 5.019017660923670763e-11 0.000000000000000000 -8.000049999999999661e-01 4.923086834421724464e-11 0.000000000000000000 -8.010000000000000453e-01 4.828933426320927044e-11 0.000000000000000000 -8.019950000000000134e-01 4.736525539558188763e-11 0.000000000000000000 -8.029899999999999816e-01 4.645831831438245641e-11 0.000000000000000000 -8.039850000000000607e-01 4.556821504268652730e-11 0.000000000000000000 -8.049800000000000288e-01 4.469464296170416256e-11 0.000000000000000000 -8.059749999999999970e-01 4.383730472068802512e-11 0.000000000000000000 -8.069699999999999651e-01 4.299590814766838308e-11 0.000000000000000000 -8.079650000000000443e-01 4.217016616230079168e-11 0.000000000000000000 -8.089600000000000124e-01 4.135979668960845514e-11 0.000000000000000000 -8.099549999999999805e-01 4.056452257571198034e-11 0.000000000000000000 -8.109500000000000597e-01 3.978407150433260260e-11 0.000000000000000000 -8.119450000000000278e-01 3.901817591526678961e-11 0.000000000000000000 -8.129399999999999959e-01 3.826657292356815587e-11 0.000000000000000000 -8.139349999999999641e-01 3.752900424059828834e-11 0.000000000000000000 -8.149300000000000432e-01 3.680521609627443136e-11 0.000000000000000000 -8.159250000000000114e-01 3.609495916209530939e-11 0.000000000000000000 -8.169199999999999795e-01 3.539798847631480826e-11 0.000000000000000000 -8.179150000000000587e-01 3.471406336951419588e-11 0.000000000000000000 -8.189100000000000268e-01 3.404294739185910951e-11 0.000000000000000000 -8.199049999999999949e-01 3.338440824150709322e-11 0.000000000000000000 -8.208999999999999631e-01 3.273821769404085850e-11 0.000000000000000000 -8.218950000000000422e-01 3.210415153329436856e-11 0.000000000000000000 -8.228900000000000103e-01 3.148198948294768353e-11 0.000000000000000000 -8.238849999999999785e-01 3.087151513973246205e-11 0.000000000000000000 -8.248800000000000576e-01 3.027251590737155331e-11 0.000000000000000000 -8.258750000000000258e-01 2.968478293185995294e-11 0.000000000000000000 -8.268699999999999939e-01 2.910811103743564697e-11 0.000000000000000000 -8.278649999999999620e-01 2.854229866422437845e-11 0.000000000000000000 -8.288600000000000412e-01 2.798714780617325204e-11 0.000000000000000000 -8.298550000000000093e-01 2.744246395074316365e-11 0.000000000000000000 -8.308499999999999774e-01 2.690805601903921905e-11 0.000000000000000000 -8.318450000000000566e-01 2.638373630713539760e-11 0.000000000000000000 -8.328400000000000247e-01 2.586932042855219276e-11 0.000000000000000000 -8.338349999999999929e-01 2.536462725737758588e-11 0.000000000000000000 -8.348299999999999610e-01 2.486947887248887770e-11 0.000000000000000000 -8.358250000000000401e-01 2.438370050272607173e-11 0.000000000000000000 -8.368200000000000083e-01 2.390712047288832168e-11 0.000000000000000000 -8.378149999999999764e-01 2.343957015071224223e-11 0.000000000000000000 -8.388100000000000556e-01 2.298088389467405944e-11 0.000000000000000000 -8.398050000000000237e-01 2.253089900258152798e-11 0.000000000000000000 -8.407999999999999918e-01 2.208945566131302509e-11 0.000000000000000000 -8.417949999999999600e-01 2.165639689701962011e-11 0.000000000000000000 -8.427900000000000391e-01 2.123156852639565456e-11 0.000000000000000000 -8.437850000000000072e-01 2.081481910870578539e-11 0.000000000000000000 -8.447799999999999754e-01 2.040599989851381981e-11 0.000000000000000000 -8.457750000000000545e-01 2.000496479944291845e-11 0.000000000000000000 -8.467700000000000227e-01 1.961157031843802305e-11 0.000000000000000000 -8.477649999999999908e-01 1.922567552086915531e-11 0.000000000000000000 -8.487599999999999589e-01 1.884714198652079419e-11 0.000000000000000000 -8.497550000000000381e-01 1.847583376615353297e-11 0.000000000000000000 -8.507500000000000062e-01 1.811161733888242197e-11 0.000000000000000000 -8.517449999999999743e-01 1.775436157018041761e-11 0.000000000000000000 -8.527400000000000535e-01 1.740393767069240377e-11 0.000000000000000000 -8.537350000000000216e-01 1.706021915565210826e-11 0.000000000000000000 -8.547299999999999898e-01 1.672308180502099934e-11 0.000000000000000000 -8.557249999999999579e-01 1.639240362433276411e-11 0.000000000000000000 -8.567200000000000371e-01 1.606806480605511399e-11 0.000000000000000000 -8.577150000000000052e-01 1.574994769175799766e-11 0.000000000000000000 -8.587099999999999733e-01 1.543793673481743599e-11 0.000000000000000000 -8.597050000000000525e-01 1.513191846380246931e-11 0.000000000000000000 -8.607000000000000206e-01 1.483178144642076169e-11 0.000000000000000000 -8.616949999999999887e-01 1.453741625408964590e-11 0.000000000000000000 -8.626899999999999569e-01 1.424871542717199542e-11 0.000000000000000000 -8.636850000000000360e-01 1.396557344067323184e-11 0.000000000000000000 -8.646800000000000042e-01 1.368788667062002115e-11 0.000000000000000000 -8.656749999999999723e-01 1.341555336091990615e-11 0.000000000000000000 -8.666700000000000514e-01 1.314847359090981869e-11 0.000000000000000000 -8.676650000000000196e-01 1.288654924319432812e-11 0.000000000000000000 -8.686599999999999877e-01 1.262968397242288672e-11 0.000000000000000000 -8.696549999999999558e-01 1.237778317413847121e-11 0.000000000000000000 -8.706500000000000350e-01 1.213075395458402982e-11 0.000000000000000000 -8.716450000000000031e-01 1.188850510063939789e-11 0.000000000000000000 -8.726399999999999713e-01 1.165094705056480650e-11 0.000000000000000000 -8.736350000000000504e-01 1.141799186504683717e-11 0.000000000000000000 -8.746300000000000185e-01 1.118955319883575737e-11 0.000000000000000000 -8.756249999999999867e-01 1.096554627279212947e-11 0.000000000000000000 -8.766200000000000658e-01 1.074588784648897165e-11 0.000000000000000000 -8.776150000000000340e-01 1.053049619119633637e-11 0.000000000000000000 -8.786100000000000021e-01 1.031929106337711392e-11 0.000000000000000000 -8.796049999999999702e-01 1.011219367860600992e-11 0.000000000000000000 -8.806000000000000494e-01 9.909126685931416669e-12 0.000000000000000000 -8.815950000000000175e-01 9.710014142709092467e-12 0.000000000000000000 -8.825899999999999856e-01 9.514781489789963117e-12 0.000000000000000000 -8.835850000000000648e-01 9.323355527214140165e-12 0.000000000000000000 -8.845800000000000329e-01 9.135664390280521159e-12 0.000000000000000000 -8.855750000000000011e-01 8.951637525956803811e-12 0.000000000000000000 -8.865699999999999692e-01 8.771205669848477140e-12 0.000000000000000000 -8.875650000000000484e-01 8.594300823370846695e-12 0.000000000000000000 -8.885600000000000165e-01 8.420856231485389200e-12 0.000000000000000000 -8.895549999999999846e-01 8.250806360685502162e-12 0.000000000000000000 -8.905500000000000638e-01 8.084086877442745888e-12 0.000000000000000000 -8.915450000000000319e-01 7.920634626948725029e-12 0.000000000000000000 -8.925400000000000000e-01 7.760387612281252380e-12 0.000000000000000000 -8.935349999999999682e-01 7.603284973905482060e-12 0.000000000000000000 -8.945300000000000473e-01 7.449266969506496546e-12 0.000000000000000000 -8.955250000000000155e-01 7.298274954195714714e-12 0.000000000000000000 -8.965199999999999836e-01 7.150251361045872353e-12 0.000000000000000000 -8.975150000000000627e-01 7.005139681932871316e-12 0.000000000000000000 -8.985100000000000309e-01 6.862884448759745745e-12 0.000000000000000000 -8.995049999999999990e-01 6.723431214957391286e-12 0.000000000000000000 -9.004999999999999671e-01 6.586726537320808128e-12 0.000000000000000000 -9.014950000000000463e-01 6.452717958148575220e-12 0.000000000000000000 -9.024900000000000144e-01 6.321353987697752509e-12 0.000000000000000000 -9.034849999999999826e-01 6.192584086955323570e-12 0.000000000000000000 -9.044800000000000617e-01 6.066358650650915654e-12 0.000000000000000000 -9.054750000000000298e-01 5.942628990640109593e-12 0.000000000000000000 -9.064699999999999980e-01 5.821347319489051845e-12 0.000000000000000000 -9.074649999999999661e-01 5.702466734432494170e-12 0.000000000000000000 -9.084600000000000453e-01 5.585941201518969179e-12 0.000000000000000000 -9.094550000000000134e-01 5.471725540095875727e-12 0.000000000000000000 -9.104499999999999815e-01 5.359775407532663075e-12 0.000000000000000000 -9.114450000000000607e-01 5.250047284201808633e-12 0.000000000000000000 -9.124400000000000288e-01 5.142498458759478234e-12 0.000000000000000000 -9.134349999999999969e-01 5.037087013620237808e-12 0.000000000000000000 -9.144299999999999651e-01 4.933771810723792127e-12 0.000000000000000000 -9.154250000000000442e-01 4.832512477559490473e-12 0.000000000000000000 -9.164200000000000124e-01 4.733269393382690548e-12 0.000000000000000000 -9.174149999999999805e-01 4.636003675708210934e-12 0.000000000000000000 -9.184100000000000597e-01 4.540677167043161048e-12 0.000000000000000000 -9.194050000000000278e-01 4.447252421825848935e-12 0.000000000000000000 -9.203999999999999959e-01 4.355692693609114473e-12 0.000000000000000000 -9.213949999999999640e-01 4.265961922438394138e-12 0.000000000000000000 -9.223900000000000432e-01 4.178024722488739340e-12 0.000000000000000000 -9.233850000000000113e-01 4.091846369909820615e-12 0.000000000000000000 -9.243799999999999795e-01 4.007392790829750474e-12 0.000000000000000000 -9.253750000000000586e-01 3.924630549657840782e-12 0.000000000000000000 -9.263700000000000268e-01 3.843526837507154298e-12 0.000000000000000000 -9.273649999999999949e-01 3.764049460866051308e-12 0.000000000000000000 -9.283599999999999630e-01 3.686166830456769560e-12 0.000000000000000000 -9.293550000000000422e-01 3.609847950283756110e-12 0.000000000000000000 -9.303500000000000103e-01 3.535062406887417040e-12 0.000000000000000000 -9.313449999999999784e-01 3.461780358757763444e-12 0.000000000000000000 -9.323400000000000576e-01 3.389972525956962532e-12 0.000000000000000000 -9.333350000000000257e-01 3.319610179935919121e-12 0.000000000000000000 -9.343299999999999939e-01 3.250665133472402609e-12 0.000000000000000000 -9.353249999999999620e-01 3.183109730872174957e-12 0.000000000000000000 -9.363200000000000411e-01 3.116916838239753724e-12 0.000000000000000000 -9.373150000000000093e-01 3.052059834024750229e-12 0.000000000000000000 -9.383099999999999774e-01 2.988512599643348278e-12 0.000000000000000000 -9.393050000000000566e-01 2.926249510337346485e-12 0.000000000000000000 -9.403000000000000247e-01 2.865245426127051678e-12 0.000000000000000000 -9.412949999999999928e-01 2.805475682992718501e-12 0.000000000000000000 -9.422899999999999610e-01 2.746916084139481357e-12 0.000000000000000000 -9.432850000000000401e-01 2.689542891490299806e-12 0.000000000000000000 -9.442800000000000082e-01 2.633332817262948029e-12 0.000000000000000000 -9.452749999999999764e-01 2.578263015732237005e-12 0.000000000000000000 -9.462700000000000555e-01 2.524311075133569463e-12 0.000000000000000000 -9.472650000000000237e-01 2.471455009705816204e-12 0.000000000000000000 -9.482599999999999918e-01 2.419673251862030195e-12 0.000000000000000000 -9.492549999999999599e-01 2.368944644531134214e-12 0.000000000000000000 -9.502500000000000391e-01 2.319248433593288717e-12 0.000000000000000000 -9.512450000000000072e-01 2.270564260484504975e-12 0.000000000000000000 -9.522399999999999753e-01 2.222872154916162812e-12 0.000000000000000000 -9.532350000000000545e-01 2.176152527732621461e-12 0.000000000000000000 -9.542300000000000226e-01 2.130386163866658255e-12 0.000000000000000000 -9.552249999999999908e-01 2.085554215469351149e-12 0.000000000000000000 -9.562199999999999589e-01 2.041638195121339581e-12 0.000000000000000000 -9.572150000000000380e-01 1.998619969182224490e-12 0.000000000000000000 -9.582100000000000062e-01 1.956481751250051619e-12 0.000000000000000000 -9.592049999999999743e-01 1.915206095750555943e-12 0.000000000000000000 -9.602000000000000535e-01 1.874775891624738814e-12 0.000000000000000000 -9.611950000000000216e-01 1.835174356137109269e-12 0.000000000000000000 -9.621899999999999897e-01 1.796385028799102358e-12 0.000000000000000000 -9.631849999999999579e-01 1.758391765391040215e-12 0.000000000000000000 -9.641800000000000370e-01 1.721178732095956176e-12 0.000000000000000000 -9.651750000000000052e-01 1.684730399735976772e-12 0.000000000000000000 -9.661699999999999733e-01 1.649031538118635951e-12 0.000000000000000000 -9.671650000000000524e-01 1.614067210475218385e-12 0.000000000000000000 -9.681600000000000206e-01 1.579822768003402259e-12 0.000000000000000000 -9.691549999999999887e-01 1.546283844509766956e-12 0.000000000000000000 -9.701499999999999568e-01 1.513436351142013283e-12 0.000000000000000000 -9.711450000000000360e-01 1.481266471218146186e-12 0.000000000000000000 -9.721400000000000041e-01 1.449760655162423748e-12 0.000000000000000000 -9.731349999999999723e-01 1.418905615502230981e-12 0.000000000000000000 -9.741300000000000514e-01 1.388688321986862196e-12 0.000000000000000000 -9.751250000000000195e-01 1.359095996768790642e-12 0.000000000000000000 -9.761199999999999877e-01 1.330116109690863912e-12 0.000000000000000000 -9.771150000000000668e-01 1.301736373650612545e-12 0.000000000000000000 -9.781100000000000350e-01 1.273944740041217820e-12 0.000000000000000000 -9.791050000000000031e-01 1.246729394289011297e-12 0.000000000000000000 -9.800999999999999712e-01 1.220078751455892882e-12 0.000000000000000000 -9.810950000000000504e-01 1.193981451939975580e-12 0.000000000000000000 -9.820900000000000185e-01 1.168426357233797262e-12 0.000000000000000000 -9.830849999999999866e-01 1.143402545775898413e-12 0.000000000000000000 -9.840800000000000658e-01 1.118899308866149742e-12 0.000000000000000000 -9.850750000000000339e-01 1.094906146664561621e-12 0.000000000000000000 -9.860700000000000021e-01 1.071412764247475544e-12 0.000000000000000000 -9.870649999999999702e-01 1.048409067760837229e-12 0.000000000000000000 -9.880600000000000493e-01 1.025885160616447765e-12 0.000000000000000000 -9.890550000000000175e-01 1.003831339770924548e-12 0.000000000000000000 -9.900499999999999856e-01 9.822380920748707792e-13 0.000000000000000000 -9.910450000000000648e-01 9.610960906801041221e-13 0.000000000000000000 -9.920400000000000329e-01 9.403961915179023274e-13 0.000000000000000000 -9.930350000000000010e-01 9.201294298374636062e-13 0.000000000000000000 -9.940299999999999692e-01 9.002870168152242337e-13 0.000000000000000000 -9.950250000000000483e-01 8.808603362145260253e-13 0.000000000000000000 -9.960200000000000164e-01 8.618409411153087119e-13 0.000000000000000000 -9.970149999999999846e-01 8.432205507020908809e-13 0.000000000000000000 -9.980100000000000637e-01 8.249910471071539138e-13 0.000000000000000000 -9.990050000000000319e-01 8.071444723139599604e-13 0.000000000000000000 -1.000000000000000000e+00 7.896730251172689431e-13 0.000000000000000000 \ No newline at end of file diff --git a/tests/test_data/ORSO/test_3.dat b/tests/test_data/ORSO/test_3.dat deleted file mode 100644 index 5cfc9e61..00000000 --- a/tests/test_data/ORSO/test_3.dat +++ /dev/null @@ -1,1001 +0,0 @@ -5.000000000000000104e-03 1.000000000000000222e+00 0.000000000000000000 -5.995000000000000329e-03 1.000000000000000222e+00 0.000000000000000000 -6.989999999999999686e-03 1.000000000000000222e+00 0.000000000000000000 -7.984999999999999043e-03 1.000000000000000000e+00 0.000000000000000000 -8.980000000000000135e-03 9.999999999999996669e-01 0.000000000000000000 -9.975000000000001227e-03 1.000000000000000222e+00 0.000000000000000000 -1.097000000000000058e-02 9.999999999999998890e-01 0.000000000000000000 -1.196499999999999994e-02 1.000000000000000222e+00 0.000000000000000000 -1.295999999999999930e-02 9.999999999999998890e-01 0.000000000000000000 -1.395499999999999866e-02 1.000000000000000000e+00 0.000000000000000000 -1.495000000000000148e-02 9.999999999999997780e-01 0.000000000000000000 -1.594500000000000084e-02 1.000000000000000222e+00 0.000000000000000000 -1.694000000000000020e-02 9.999999999999995559e-01 0.000000000000000000 -1.793499999999999955e-02 7.302544119277273316e-01 0.000000000000000000 -1.892999999999999891e-02 2.552815931521527082e-01 0.000000000000000000 -1.992500000000000174e-02 1.500207458923263903e-01 0.000000000000000000 -2.092000000000000109e-02 9.997793399278399884e-02 0.000000000000000000 -2.191500000000000045e-02 7.123912062170954795e-02 0.000000000000000000 -2.290999999999999981e-02 5.301614647186881496e-02 0.000000000000000000 -2.390500000000000264e-02 4.070644982790416755e-02 0.000000000000000000 -2.490000000000000199e-02 3.201044658983939750e-02 0.000000000000000000 -2.589500000000000135e-02 2.565627153557500234e-02 0.000000000000000000 -2.689000000000000071e-02 2.088803389193751026e-02 0.000000000000000000 -2.788500000000000006e-02 1.723156075999391149e-02 0.000000000000000000 -2.887999999999999942e-02 1.437654145720755616e-02 0.000000000000000000 -2.987500000000000225e-02 1.211283187244694554e-02 0.000000000000000000 -3.087000000000000161e-02 1.029403083215324477e-02 0.000000000000000000 -3.186499999999999749e-02 8.815675506561536021e-03 0.000000000000000000 -3.286000000000000032e-02 7.601682608979293439e-03 0.000000000000000000 -3.385499999999999621e-02 6.595641840799377348e-03 0.000000000000000000 -3.484999999999999903e-02 5.755068914451989294e-03 0.000000000000000000 -3.584500000000000186e-02 5.047520223740087873e-03 0.000000000000000000 -3.683999999999999775e-02 4.447910330864589430e-03 0.000000000000000000 -3.783500000000000058e-02 3.936625104166304942e-03 0.000000000000000000 -3.882999999999999646e-02 3.498172265099319146e-03 0.000000000000000000 -3.982499999999999929e-02 3.120201746921682021e-03 0.000000000000000000 -4.081999999999999518e-02 2.792784835982658510e-03 0.000000000000000000 -4.181499999999999800e-02 2.507877168229455909e-03 0.000000000000000000 -4.281000000000000083e-02 2.258914162673223303e-03 0.000000000000000000 -4.380499999999999672e-02 2.040503064564099227e-03 0.000000000000000000 -4.479999999999999954e-02 1.848186284179480438e-03 0.000000000000000000 -4.579499999999999543e-02 1.678257914894290374e-03 0.000000000000000000 -4.678999999999999826e-02 1.527620311455636605e-03 0.000000000000000000 -4.778500000000000109e-02 1.393671123873522957e-03 0.000000000000000000 -4.877999999999999697e-02 1.274213683683264901e-03 0.000000000000000000 -4.977499999999999980e-02 1.167385439427427989e-03 0.000000000000000000 -5.076999999999999569e-02 1.071600447070272973e-03 0.000000000000000000 -5.176499999999999851e-02 9.855028819590074245e-04 0.000000000000000000 -5.275999999999999440e-02 9.079292507786222884e-04 0.000000000000000000 -5.375499999999999723e-02 8.378775137522353079e-04 0.000000000000000000 -5.475000000000000006e-02 7.744817278207360121e-04 0.000000000000000000 -5.574499999999999594e-02 7.169911253934479513e-04 0.000000000000000000 -5.673999999999999877e-02 6.647527754462639578e-04 0.000000000000000000 -5.773499999999999466e-02 6.171971523537961302e-04 0.000000000000000000 -5.872999999999999748e-02 5.738260761141945280e-04 0.000000000000000000 -5.972500000000000031e-02 5.342025953163497161e-04 0.000000000000000000 -6.071999999999999620e-02 4.979424685541384383e-04 0.000000000000000000 -6.171499999999999903e-02 4.647069664291461882e-04 0.000000000000000000 -6.271000000000000185e-02 4.341967688803725391e-04 0.000000000000000000 -6.370499999999999774e-02 4.061467744268355633e-04 0.000000000000000000 -6.470000000000000751e-02 3.803216713614568584e-04 0.000000000000000000 -6.569500000000000339e-02 3.565121477980526233e-04 0.000000000000000000 -6.668999999999999928e-02 3.345316391388566393e-04 0.000000000000000000 -6.768500000000000905e-02 3.142135290765838492e-04 0.000000000000000000 -6.868000000000000493e-02 2.954087345123552772e-04 0.000000000000000000 -6.967500000000000082e-02 2.779836164163030222e-04 0.000000000000000000 -7.067000000000001059e-02 2.618181681981876160e-04 0.000000000000000000 -7.166500000000000647e-02 2.468044409991756983e-04 0.000000000000000000 -7.266000000000000236e-02 2.328451717867457689e-04 0.000000000000000000 -7.365499999999999825e-02 2.198525854904882944e-04 0.000000000000000000 -7.465000000000000802e-02 2.077473468635113445e-04 0.000000000000000000 -7.564500000000000390e-02 1.964576414578978456e-04 0.000000000000000000 -7.663999999999999979e-02 1.859183681963245624e-04 0.000000000000000000 -7.763500000000000956e-02 1.760704286136114403e-04 0.000000000000000000 -7.863000000000000544e-02 1.668601000190766644e-04 0.000000000000000000 -7.962500000000000133e-02 1.582384816641631969e-04 0.000000000000000000 -8.062000000000001110e-02 1.501610045482572255e-04 0.000000000000000000 -8.161500000000000699e-02 1.425869968064864129e-04 0.000000000000000000 -8.261000000000000287e-02 1.354792977357120428e-04 0.000000000000000000 -8.360499999999999876e-02 1.288039144612181271e-04 0.000000000000000000 -8.460000000000000853e-02 1.225297160532930944e-04 0.000000000000000000 -8.559500000000000441e-02 1.166281605923794913e-04 0.000000000000000000 -8.659000000000000030e-02 1.110730512716228780e-04 0.000000000000000000 -8.758500000000001007e-02 1.058403181323294158e-04 0.000000000000000000 -8.858000000000000596e-02 1.009078224632976368e-04 0.000000000000000000 -8.957500000000000184e-02 9.625518127027844306e-05 0.000000000000000000 -9.057000000000001161e-02 9.186360954578184804e-05 0.000000000000000000 -9.156500000000000750e-02 8.771577834949046066e-05 0.000000000000000000 -9.256000000000000338e-02 8.379568695238581060e-05 0.000000000000000000 -9.355499999999999927e-02 8.008854750826035064e-05 0.000000000000000000 -9.455000000000000904e-02 7.658068089951252906e-05 0.000000000000000000 -9.554500000000000492e-02 7.325942256365089748e-05 0.000000000000000000 -9.654000000000000081e-02 7.011303724606809810e-05 0.000000000000000000 -9.753500000000001058e-02 6.713064174628380202e-05 0.000000000000000000 -9.853000000000000647e-02 6.430213483124872734e-05 0.000000000000000000 -9.952500000000000235e-02 6.161813358258931778e-05 0.000000000000000000 -1.005199999999999982e-01 5.906991552652936407e-05 0.000000000000000000 -1.015150000000000080e-01 5.664936596722652709e-05 0.000000000000000000 -1.025100000000000039e-01 5.434893000757861324e-05 0.000000000000000000 -1.035049999999999998e-01 5.216156879745617451e-05 0.000000000000000000 -1.045000000000000095e-01 5.008071959859009475e-05 0.000000000000000000 -1.054950000000000054e-01 4.810025929894232714e-05 0.000000000000000000 -1.064900000000000013e-01 4.621447104794872937e-05 0.000000000000000000 -1.074850000000000111e-01 4.441801371822664884e-05 0.000000000000000000 -1.084800000000000070e-01 4.270589392966370960e-05 0.000000000000000000 -1.094750000000000029e-01 4.107344039873492037e-05 0.000000000000000000 -1.104699999999999988e-01 3.951628039990539470e-05 0.000000000000000000 -1.114650000000000085e-01 3.803031814727148062e-05 0.000000000000000000 -1.124600000000000044e-01 3.661171492366325104e-05 0.000000000000000000 -1.134550000000000003e-01 3.525687080139357449e-05 0.000000000000000000 -1.144500000000000101e-01 3.396240781400948852e-05 0.000000000000000000 -1.154450000000000059e-01 3.272515445200561756e-05 0.000000000000000000 -1.164400000000000018e-01 3.154213136757109493e-05 0.000000000000000000 -1.174350000000000116e-01 3.041053818437549486e-05 0.000000000000000000 -1.184300000000000075e-01 2.932774131814763082e-05 0.000000000000000000 -1.194250000000000034e-01 2.829126272259308120e-05 0.000000000000000000 -1.204199999999999993e-01 2.729876948309178597e-05 0.000000000000000000 -1.214150000000000090e-01 2.634806418770863114e-05 0.000000000000000000 -1.224100000000000049e-01 2.543707601145856189e-05 0.000000000000000000 -1.234050000000000008e-01 2.456385245553760122e-05 0.000000000000000000 -1.244000000000000106e-01 2.372655168842050194e-05 0.000000000000000000 -1.253950000000000065e-01 2.292343544045605906e-05 0.000000000000000000 -1.263900000000000023e-01 2.215286240780996405e-05 0.000000000000000000 -1.273849999999999982e-01 2.141328212547069355e-05 0.000000000000000000 -1.283799999999999941e-01 2.070322927252014994e-05 0.000000000000000000 -1.293749999999999900e-01 2.002131837599849124e-05 0.000000000000000000 -1.303700000000000137e-01 1.936623888259802600e-05 0.000000000000000000 -1.313650000000000095e-01 1.873675056998053514e-05 0.000000000000000000 -1.323600000000000054e-01 1.813167927190132041e-05 0.000000000000000000 -1.333550000000000013e-01 1.754991289344203385e-05 0.000000000000000000 -1.343499999999999972e-01 1.699039769464770946e-05 0.000000000000000000 -1.353449999999999931e-01 1.645213482259845323e-05 0.000000000000000000 -1.363400000000000167e-01 1.593417707359521767e-05 0.000000000000000000 -1.373350000000000126e-01 1.543562586860838427e-05 0.000000000000000000 -1.383300000000000085e-01 1.495562842648808664e-05 0.000000000000000000 -1.393250000000000044e-01 1.449337512065626627e-05 0.000000000000000000 -1.403200000000000003e-01 1.404809700615483821e-05 0.000000000000000000 -1.413149999999999962e-01 1.361906350491213202e-05 0.000000000000000000 -1.423099999999999921e-01 1.320558023807027655e-05 0.000000000000000000 -1.433050000000000157e-01 1.280698699505669096e-05 0.000000000000000000 -1.443000000000000116e-01 1.242265582987766277e-05 0.000000000000000000 -1.452950000000000075e-01 1.205198927583547193e-05 0.000000000000000000 -1.462900000000000034e-01 1.169441867055197280e-05 0.000000000000000000 -1.472849999999999993e-01 1.134940258375420816e-05 0.000000000000000000 -1.482799999999999951e-01 1.101642534088488612e-05 0.000000000000000000 -1.492750000000000188e-01 1.069499563607656409e-05 0.000000000000000000 -1.502700000000000147e-01 1.038464522852731763e-05 0.000000000000000000 -1.512650000000000106e-01 1.008492771673922509e-05 0.000000000000000000 -1.522600000000000064e-01 9.795417385487658167e-06 0.000000000000000000 -1.532550000000000023e-01 9.515708120754915602e-06 0.000000000000000000 -1.542499999999999982e-01 9.245412388214926215e-06 0.000000000000000000 -1.552449999999999941e-01 8.984160271147430192e-06 0.000000000000000000 -1.562400000000000178e-01 8.731598563979155208e-06 0.000000000000000000 -1.572350000000000136e-01 8.487389917891189619e-06 0.000000000000000000 -1.582300000000000095e-01 8.251212035195819211e-06 0.000000000000000000 -1.592250000000000054e-01 8.022756909411819735e-06 0.000000000000000000 -1.602200000000000013e-01 7.801730108172303166e-06 0.000000000000000000 -1.612149999999999972e-01 7.587850096304319501e-06 0.000000000000000000 -1.622099999999999931e-01 7.380847596593427883e-06 0.000000000000000000 -1.632050000000000167e-01 7.180464985919699528e-06 0.000000000000000000 -1.642000000000000126e-01 6.986455724602389345e-06 0.000000000000000000 -1.651950000000000085e-01 6.798583816938923489e-06 0.000000000000000000 -1.661900000000000044e-01 6.616623301054710733e-06 0.000000000000000000 -1.671850000000000003e-01 6.440357766307891073e-06 0.000000000000000000 -1.681799999999999962e-01 6.269579896604869611e-06 0.000000000000000000 -1.691749999999999921e-01 6.104091038089564868e-06 0.000000000000000000 -1.701700000000000157e-01 5.943700789772575947e-06 0.000000000000000000 -1.711650000000000116e-01 5.788226615756587192e-06 0.000000000000000000 -1.721600000000000075e-01 5.637493477799012715e-06 0.000000000000000000 -1.731550000000000034e-01 5.491333487035706967e-06 0.000000000000000000 -1.741499999999999992e-01 5.349585573761062137e-06 0.000000000000000000 -1.751449999999999951e-01 5.212095174233773578e-06 0.000000000000000000 -1.761400000000000188e-01 5.078713933538307867e-06 0.000000000000000000 -1.771350000000000147e-01 4.949299423590993852e-06 0.000000000000000000 -1.781300000000000106e-01 4.823714875442655119e-06 0.000000000000000000 -1.791250000000000064e-01 4.701828925074577255e-06 0.000000000000000000 -1.801200000000000023e-01 4.583515371940636223e-06 0.000000000000000000 -1.811149999999999982e-01 4.468652949545531132e-06 0.000000000000000000 -1.821099999999999941e-01 4.357125107399881593e-06 0.000000000000000000 -1.831050000000000177e-01 4.248819803728705652e-06 0.000000000000000000 -1.841000000000000136e-01 4.143629308349770852e-06 0.000000000000000000 -1.850950000000000095e-01 4.041450015165261868e-06 0.000000000000000000 -1.860900000000000054e-01 3.942182263758992194e-06 0.000000000000000000 -1.870850000000000013e-01 3.845730169599192739e-06 0.000000000000000000 -1.880799999999999972e-01 3.752001462399423300e-06 0.000000000000000000 -1.890749999999999931e-01 3.660907332198875170e-06 0.000000000000000000 -1.900700000000000167e-01 3.572362282757150113e-06 0.000000000000000000 -1.910650000000000126e-01 3.486283991877368194e-06 0.000000000000000000 -1.920600000000000085e-01 3.402593178302982697e-06 0.000000000000000000 -1.930550000000000044e-01 3.321213474835895762e-06 0.000000000000000000 -1.940500000000000003e-01 3.242071307366984273e-06 0.000000000000000000 -1.950449999999999962e-01 3.165095779504616941e-06 0.000000000000000000 -1.960399999999999920e-01 3.090218562523206605e-06 0.000000000000000000 -1.970350000000000157e-01 3.017373790355003906e-06 0.000000000000000000 -1.980300000000000116e-01 2.946497959373940888e-06 0.000000000000000000 -1.990250000000000075e-01 2.877529832728726358e-06 0.000000000000000000 -2.000200000000000033e-01 2.810410348997253469e-06 0.000000000000000000 -2.010149999999999992e-01 2.745082534945871258e-06 0.000000000000000000 -2.020099999999999951e-01 2.681491422194076088e-06 0.000000000000000000 -2.030050000000000188e-01 2.619583967585816721e-06 0.000000000000000000 -2.040000000000000147e-01 2.559308977088196519e-06 0.000000000000000000 -2.049950000000000105e-01 2.500617033048890839e-06 0.000000000000000000 -2.059900000000000064e-01 2.443460424640982012e-06 0.000000000000000000 -2.069850000000000023e-01 2.387793081346400505e-06 0.000000000000000000 -2.079799999999999982e-01 2.333570509331725681e-06 0.000000000000000000 -2.089749999999999941e-01 2.280749730574460933e-06 0.000000000000000000 -2.099700000000000177e-01 2.229289224610072797e-06 0.000000000000000000 -2.109650000000000136e-01 2.179148872777007317e-06 0.000000000000000000 -2.119600000000000095e-01 2.130289904837552500e-06 0.000000000000000000 -2.129550000000000054e-01 2.082674847866944899e-06 0.000000000000000000 -2.139500000000000013e-01 2.036267477302419947e-06 0.000000000000000000 -2.149449999999999972e-01 1.991032770050237681e-06 0.000000000000000000 -2.159399999999999931e-01 1.946936859557188785e-06 0.000000000000000000 -2.169350000000000167e-01 1.903946992756716464e-06 0.000000000000000000 -2.179300000000000126e-01 1.862031488799201211e-06 0.000000000000000000 -2.189250000000000085e-01 1.821159699489077939e-06 0.000000000000000000 -2.199200000000000044e-01 1.781301971348607896e-06 0.000000000000000000 -2.209150000000000003e-01 1.742429609236075048e-06 0.000000000000000000 -2.219099999999999961e-01 1.704514841445228144e-06 0.000000000000000000 -2.229050000000000198e-01 1.667530786223389054e-06 0.000000000000000000 -2.239000000000000157e-01 1.631451419641829289e-06 0.000000000000000000 -2.248950000000000116e-01 1.596251544758542627e-06 0.000000000000000000 -2.258900000000000075e-01 1.561906762016576218e-06 0.000000000000000000 -2.268850000000000033e-01 1.528393440823871229e-06 0.000000000000000000 -2.278799999999999992e-01 1.495688692261441789e-06 0.000000000000000000 -2.288749999999999951e-01 1.463770342870089032e-06 0.000000000000000000 -2.298700000000000188e-01 1.432616909471420088e-06 0.000000000000000000 -2.308650000000000146e-01 1.402207574973502849e-06 0.000000000000000000 -2.318600000000000105e-01 1.372522165124398464e-06 0.000000000000000000 -2.328550000000000064e-01 1.343541126166518876e-06 0.000000000000000000 -2.338500000000000023e-01 1.315245503359037064e-06 0.000000000000000000 -2.348449999999999982e-01 1.287616920326394123e-06 0.000000000000000000 -2.358399999999999941e-01 1.260637559201489898e-06 0.000000000000000000 -2.368350000000000177e-01 1.234290141526865827e-06 0.000000000000000000 -2.378300000000000136e-01 1.208557909884525645e-06 0.000000000000000000 -2.388250000000000095e-01 1.183424610222043002e-06 0.000000000000000000 -2.398200000000000054e-01 1.158874474846250690e-06 0.000000000000000000 -2.408150000000000013e-01 1.134892206056985017e-06 0.000000000000000000 -2.418099999999999972e-01 1.111462960394385494e-06 0.000000000000000000 -2.428049999999999931e-01 1.088572333473516146e-06 0.000000000000000000 -2.438000000000000167e-01 1.066206345383700941e-06 0.000000000000000000 -2.447950000000000126e-01 1.044351426627338742e-06 0.000000000000000000 -2.457900000000000085e-01 1.022994404578400489e-06 0.000000000000000000 -2.467850000000000044e-01 1.002122490437704232e-06 0.000000000000000000 -2.477800000000000002e-01 9.817232666657718879e-07 0.000000000000000000 -2.487749999999999961e-01 9.617846748736519515e-07 0.000000000000000000 -2.497700000000000198e-01 9.422950041539083708e-07 0.000000000000000000 -2.507650000000000157e-01 9.232428798323453051e-07 0.000000000000000000 -2.517599999999999838e-01 9.046172526266390979e-07 0.000000000000000000 -2.527550000000000074e-01 8.864073881929345266e-07 0.000000000000000000 -2.537499999999999756e-01 8.686028570467542300e-07 0.000000000000000000 -2.547449999999999992e-01 8.511935248416559944e-07 0.000000000000000000 -2.557400000000000229e-01 8.341695429956798617e-07 0.000000000000000000 -2.567349999999999910e-01 8.175213396454100065e-07 0.000000000000000000 -2.577300000000000146e-01 8.012396109212888927e-07 0.000000000000000000 -2.587249999999999828e-01 7.853153125282533498e-07 0.000000000000000000 -2.597200000000000064e-01 7.697396516203173399e-07 0.000000000000000000 -2.607150000000000301e-01 7.545040789584628936e-07 0.000000000000000000 -2.617099999999999982e-01 7.396002813402122049e-07 0.000000000000000000 -2.627050000000000218e-01 7.250201742916859191e-07 0.000000000000000000 -2.636999999999999900e-01 7.107558950102262601e-07 0.000000000000000000 -2.646950000000000136e-01 6.967997955505304836e-07 0.000000000000000000 -2.656899999999999817e-01 6.831444362421918255e-07 0.000000000000000000 -2.666850000000000054e-01 6.697825793328290410e-07 0.000000000000000000 -2.676800000000000290e-01 6.567071828464906383e-07 0.000000000000000000 -2.686749999999999972e-01 6.439113946490282237e-07 0.000000000000000000 -2.696700000000000208e-01 6.313885467153174819e-07 0.000000000000000000 -2.706649999999999889e-01 6.191321495868240811e-07 0.000000000000000000 -2.716600000000000126e-01 6.071358870161023394e-07 0.000000000000000000 -2.726549999999999807e-01 5.953936107895076103e-07 0.000000000000000000 -2.736500000000000044e-01 5.838993357212978451e-07 0.000000000000000000 -2.746450000000000280e-01 5.726472348147212419e-07 0.000000000000000000 -2.756399999999999961e-01 5.616316345813571775e-07 0.000000000000000000 -2.766350000000000198e-01 5.508470105157720654e-07 0.000000000000000000 -2.776299999999999879e-01 5.402879827167730058e-07 0.000000000000000000 -2.786250000000000115e-01 5.299493116534244488e-07 0.000000000000000000 -2.796199999999999797e-01 5.198258940675015360e-07 0.000000000000000000 -2.806150000000000033e-01 5.099127590094127535e-07 0.000000000000000000 -2.816100000000000270e-01 5.002050640022411882e-07 0.000000000000000000 -2.826049999999999951e-01 4.906980913288911179e-07 0.000000000000000000 -2.836000000000000187e-01 4.813872444391793366e-07 0.000000000000000000 -2.845949999999999869e-01 4.722680444710293888e-07 0.000000000000000000 -2.855900000000000105e-01 4.633361268832067542e-07 0.000000000000000000 -2.865850000000000342e-01 4.545872381946849999e-07 0.000000000000000000 -2.875800000000000023e-01 4.460172328274867991e-07 0.000000000000000000 -2.885750000000000259e-01 4.376220700492397344e-07 0.000000000000000000 -2.895699999999999941e-01 4.293978110113955783e-07 0.000000000000000000 -2.905650000000000177e-01 4.213406158812215202e-07 0.000000000000000000 -2.915599999999999858e-01 4.134467410625320186e-07 0.000000000000000000 -2.925550000000000095e-01 4.057125365037572669e-07 0.000000000000000000 -2.935500000000000331e-01 3.981344430887845665e-07 0.000000000000000000 -2.945450000000000013e-01 3.907089901094955503e-07 0.000000000000000000 -2.955400000000000249e-01 3.834327928155199364e-07 0.000000000000000000 -2.965349999999999930e-01 3.763025500396661164e-07 0.000000000000000000 -2.975300000000000167e-01 3.693150418962285531e-07 0.000000000000000000 -2.985249999999999848e-01 3.624671275491292328e-07 0.000000000000000000 -2.995200000000000085e-01 3.557557430487765712e-07 0.000000000000000000 -3.005150000000000321e-01 3.491778992339947667e-07 0.000000000000000000 -3.015100000000000002e-01 3.427306796976922247e-07 0.000000000000000000 -3.025050000000000239e-01 3.364112388139378583e-07 0.000000000000000000 -3.034999999999999920e-01 3.302167998242062930e-07 0.000000000000000000 -3.044950000000000156e-01 3.241446529812717644e-07 0.000000000000000000 -3.054899999999999838e-01 3.181921537481003399e-07 0.000000000000000000 -3.064850000000000074e-01 3.123567210511762908e-07 0.000000000000000000 -3.074800000000000311e-01 3.066358355846650517e-07 0.000000000000000000 -3.084749999999999992e-01 3.010270381660337490e-07 0.000000000000000000 -3.094700000000000228e-01 2.955279281388950346e-07 0.000000000000000000 -3.104649999999999910e-01 2.901361618240254941e-07 0.000000000000000000 -3.114600000000000146e-01 2.848494510149534469e-07 0.000000000000000000 -3.124549999999999828e-01 2.796655615181440895e-07 0.000000000000000000 -3.134500000000000064e-01 2.745823117354215134e-07 0.000000000000000000 -3.144450000000000300e-01 2.695975712878325508e-07 0.000000000000000000 -3.154399999999999982e-01 2.647092596790410133e-07 0.000000000000000000 -3.164350000000000218e-01 2.599153449978837568e-07 0.000000000000000000 -3.174299999999999899e-01 2.552138426577992562e-07 0.000000000000000000 -3.184250000000000136e-01 2.506028141727277769e-07 0.000000000000000000 -3.194199999999999817e-01 2.460803659680998870e-07 0.000000000000000000 -3.204150000000000054e-01 2.416446482256505412e-07 0.000000000000000000 -3.214100000000000290e-01 2.372938537613893963e-07 0.000000000000000000 -3.224049999999999971e-01 2.330262169348859350e-07 0.000000000000000000 -3.234000000000000208e-01 2.288400125900244041e-07 0.000000000000000000 -3.243949999999999889e-01 2.247335550253473878e-07 0.000000000000000000 -3.253900000000000126e-01 2.207051969933976064e-07 0.000000000000000000 -3.263849999999999807e-01 2.167533287283641152e-07 0.000000000000000000 -3.273800000000000043e-01 2.128763770004190671e-07 0.000000000000000000 -3.283750000000000280e-01 2.090728041971626540e-07 0.000000000000000000 -3.293699999999999961e-01 2.053411074299329102e-07 0.000000000000000000 -3.303650000000000198e-01 2.016798176654320889e-07 0.000000000000000000 -3.313599999999999879e-01 1.980874988810449717e-07 0.000000000000000000 -3.323550000000000115e-01 1.945627472435601437e-07 0.000000000000000000 -3.333499999999999797e-01 1.911041903105379646e-07 0.000000000000000000 -3.343450000000000033e-01 1.877104862536845619e-07 0.000000000000000000 -3.353400000000000269e-01 1.843803231029639430e-07 0.000000000000000000 -3.363349999999999951e-01 1.811124180120913374e-07 0.000000000000000000 -3.373300000000000187e-01 1.779055165433834375e-07 0.000000000000000000 -3.383249999999999869e-01 1.747583919723379171e-07 0.000000000000000000 -3.393200000000000105e-01 1.716698446108473038e-07 0.000000000000000000 -3.403150000000000341e-01 1.686387011487514324e-07 0.000000000000000000 -3.413100000000000023e-01 1.656638140131796811e-07 0.000000000000000000 -3.423050000000000259e-01 1.627440607449233080e-07 0.000000000000000000 -3.432999999999999940e-01 1.598783433915807615e-07 0.000000000000000000 -3.442950000000000177e-01 1.570655879169011439e-07 0.000000000000000000 -3.452899999999999858e-01 1.543047436258950896e-07 0.000000000000000000 -3.462850000000000095e-01 1.515947826050264808e-07 0.000000000000000000 -3.472800000000000331e-01 1.489346991773542697e-07 0.000000000000000000 -3.482750000000000012e-01 1.463235093721429985e-07 0.000000000000000000 -3.492700000000000249e-01 1.437602504082063715e-07 0.000000000000000000 -3.502649999999999930e-01 1.412439801910185004e-07 0.000000000000000000 -3.512600000000000167e-01 1.387737768228775831e-07 0.000000000000000000 -3.522549999999999848e-01 1.363487381259259015e-07 0.000000000000000000 -3.532500000000000084e-01 1.339679811775864490e-07 0.000000000000000000 -3.542450000000000321e-01 1.316306418580024381e-07 0.000000000000000000 -3.552400000000000002e-01 1.293358744093316699e-07 0.000000000000000000 -3.562350000000000239e-01 1.270828510063341282e-07 0.000000000000000000 -3.572299999999999920e-01 1.248707613379087200e-07 0.000000000000000000 -3.582250000000000156e-01 1.226988121998597123e-07 0.000000000000000000 -3.592199999999999838e-01 1.205662270974316575e-07 0.000000000000000000 -3.602150000000000074e-01 1.184722458585421587e-07 0.000000000000000000 -3.612100000000000311e-01 1.164161242567355819e-07 0.000000000000000000 -3.622049999999999992e-01 1.143971336435086992e-07 0.000000000000000000 -3.632000000000000228e-01 1.124145605904174832e-07 0.000000000000000000 -3.641949999999999910e-01 1.104677065397677744e-07 0.000000000000000000 -3.651900000000000146e-01 1.085558874643744278e-07 0.000000000000000000 -3.661849999999999827e-01 1.066784335360411807e-07 0.000000000000000000 -3.671800000000000064e-01 1.048346888019738436e-07 0.000000000000000000 -3.681750000000000300e-01 1.030240108696256120e-07 0.000000000000000000 -3.691699999999999982e-01 1.012457705992769268e-07 0.000000000000000000 -3.701650000000000218e-01 9.949935180445753679e-08 0.000000000000000000 -3.711599999999999899e-01 9.778415095948028884e-08 0.000000000000000000 -3.721550000000000136e-01 9.609957691461342208e-08 0.000000000000000000 -3.731499999999999817e-01 9.444505061804599980e-08 0.000000000000000000 -3.741450000000000053e-01 9.282000484481748754e-08 0.000000000000000000 -3.751400000000000290e-01 9.122388393244832792e-08 0.000000000000000000 -3.761349999999999971e-01 8.965614352301605240e-08 0.000000000000000000 -3.771300000000000208e-01 8.811625031155657185e-08 0.000000000000000000 -3.781249999999999889e-01 8.660368180062064381e-08 0.000000000000000000 -3.791200000000000125e-01 8.511792606090979959e-08 0.000000000000000000 -3.801149999999999807e-01 8.365848149753766865e-08 0.000000000000000000 -3.811100000000000043e-01 8.222485662219406386e-08 0.000000000000000000 -3.821050000000000280e-01 8.081656983069726827e-08 0.000000000000000000 -3.830999999999999961e-01 7.943314918590569788e-08 0.000000000000000000 -3.840950000000000197e-01 7.807413220591217810e-08 0.000000000000000000 -3.850899999999999879e-01 7.673906565739948301e-08 0.000000000000000000 -3.860850000000000115e-01 7.542750535373204618e-08 0.000000000000000000 -3.870799999999999796e-01 7.413901595817632364e-08 0.000000000000000000 -3.880750000000000033e-01 7.287317079158164557e-08 0.000000000000000000 -3.890700000000000269e-01 7.162955164475418635e-08 0.000000000000000000 -3.900649999999999951e-01 7.040774859527686503e-08 0.000000000000000000 -3.910600000000000187e-01 6.920735982860711948e-08 0.000000000000000000 -3.920549999999999868e-01 6.802799146356765812e-08 0.000000000000000000 -3.930500000000000105e-01 6.686925738177639130e-08 0.000000000000000000 -3.940450000000000341e-01 6.573077906118054173e-08 0.000000000000000000 -3.950400000000000023e-01 6.461218541347500975e-08 0.000000000000000000 -3.960350000000000259e-01 6.351311262541379473e-08 0.000000000000000000 -3.970299999999999940e-01 6.243320400370203637e-08 0.000000000000000000 -3.980250000000000177e-01 6.137210982358970926e-08 0.000000000000000000 -3.990199999999999858e-01 6.032948718098469951e-08 0.000000000000000000 -4.000150000000000095e-01 5.930499984799508768e-08 0.000000000000000000 -4.010100000000000331e-01 5.829831813179890142e-08 0.000000000000000000 -4.020050000000000012e-01 5.730911873679025764e-08 0.000000000000000000 -4.030000000000000249e-01 5.633708462991893812e-08 0.000000000000000000 -4.039949999999999930e-01 5.538190490915735624e-08 0.000000000000000000 -4.049900000000000166e-01 5.444327467487663858e-08 0.000000000000000000 -4.059849999999999848e-01 5.352089490429422662e-08 0.000000000000000000 -4.069800000000000084e-01 5.261447232878746078e-08 0.000000000000000000 -4.079750000000000321e-01 5.172371931388542301e-08 0.000000000000000000 -4.089700000000000002e-01 5.084835374211253429e-08 0.000000000000000000 -4.099650000000000238e-01 4.998809889844755150e-08 0.000000000000000000 -4.109599999999999920e-01 4.914268335846344356e-08 0.000000000000000000 -4.119550000000000156e-01 4.831184087875673132e-08 0.000000000000000000 -4.129499999999999837e-01 4.749531029020172877e-08 0.000000000000000000 -4.139450000000000074e-01 4.669283539330103853e-08 0.000000000000000000 -4.149400000000000310e-01 4.590416485605566593e-08 0.000000000000000000 -4.159349999999999992e-01 4.512905211408358873e-08 0.000000000000000000 -4.169300000000000228e-01 4.436725527296136481e-08 0.000000000000000000 -4.179249999999999909e-01 4.361853701276109034e-08 0.000000000000000000 -4.189200000000000146e-01 4.288266449474032394e-08 0.000000000000000000 -4.199149999999999827e-01 4.215940926999557206e-08 0.000000000000000000 -4.209100000000000064e-01 4.144854719035587216e-08 0.000000000000000000 -4.219050000000000300e-01 4.074985832100385988e-08 0.000000000000000000 -4.228999999999999981e-01 4.006312685518982154e-08 0.000000000000000000 -4.238950000000000218e-01 3.938814103081402333e-08 0.000000000000000000 -4.248899999999999899e-01 3.872469304875328655e-08 0.000000000000000000 -4.258850000000000136e-01 3.807257899308821213e-08 0.000000000000000000 -4.268799999999999817e-01 3.743159875300075409e-08 0.000000000000000000 -4.278750000000000053e-01 3.680155594641652206e-08 0.000000000000000000 -4.288700000000000290e-01 3.618225784535955942e-08 0.000000000000000000 -4.298649999999999971e-01 3.557351530280438460e-08 0.000000000000000000 -4.308600000000000207e-01 3.497514268124120271e-08 0.000000000000000000 -4.318549999999999889e-01 3.438695778272888431e-08 0.000000000000000000 -4.328500000000000125e-01 3.380878178052697901e-08 0.000000000000000000 -4.338449999999999807e-01 3.324043915208500011e-08 0.000000000000000000 -4.348400000000000043e-01 3.268175761362234442e-08 0.000000000000000000 -4.358350000000000279e-01 3.213256805597840426e-08 0.000000000000000000 -4.368299999999999961e-01 3.159270448196308571e-08 0.000000000000000000 -4.378250000000000197e-01 3.106200394495490724e-08 0.000000000000000000 -4.388199999999999878e-01 3.054030648889349978e-08 0.000000000000000000 -4.398150000000000115e-01 3.002745508947083052e-08 0.000000000000000000 -4.408100000000000351e-01 2.952329559662719818e-08 0.000000000000000000 -4.418050000000000033e-01 2.902767667829952025e-08 0.000000000000000000 -4.428000000000000269e-01 2.854044976526795720e-08 0.000000000000000000 -4.437949999999999950e-01 2.806146899727338396e-08 0.000000000000000000 -4.447900000000000187e-01 2.759059117018932799e-08 0.000000000000000000 -4.457849999999999868e-01 2.712767568439074514e-08 0.000000000000000000 -4.467800000000000105e-01 2.667258449415284049e-08 0.000000000000000000 -4.477750000000000341e-01 2.622518205811867270e-08 0.000000000000000000 -4.487700000000000022e-01 2.578533529082613517e-08 0.000000000000000000 -4.497650000000000259e-01 2.535291351522951938e-08 0.000000000000000000 -4.507599999999999940e-01 2.492778841627287470e-08 0.000000000000000000 -4.517550000000000177e-01 2.450983399531671096e-08 0.000000000000000000 -4.527499999999999858e-01 2.409892652562846511e-08 0.000000000000000000 -4.537450000000000094e-01 2.369494450875368376e-08 0.000000000000000000 -4.547400000000000331e-01 2.329776863176683936e-08 0.000000000000000000 -4.557350000000000012e-01 2.290728172544141217e-08 0.000000000000000000 -4.567300000000000249e-01 2.252336872328070319e-08 0.000000000000000000 -4.577249999999999930e-01 2.214591662139746355e-08 0.000000000000000000 -4.587200000000000166e-01 2.177481443920168254e-08 0.000000000000000000 -4.597149999999999848e-01 2.140995318088074199e-08 0.000000000000000000 -4.607100000000000084e-01 2.105122579775599487e-08 0.000000000000000000 -4.617050000000000320e-01 2.069852715129059986e-08 0.000000000000000000 -4.627000000000000002e-01 2.035175397696612041e-08 0.000000000000000000 -4.636950000000000238e-01 2.001080484878018436e-08 0.000000000000000000 -4.646899999999999920e-01 1.967558014460917590e-08 0.000000000000000000 -4.656850000000000156e-01 1.934598201213554117e-08 0.000000000000000000 -4.666799999999999837e-01 1.902191433555517809e-08 0.000000000000000000 -4.676750000000000074e-01 1.870328270293666115e-08 0.000000000000000000 -4.686700000000000310e-01 1.838999437423243993e-08 0.000000000000000000 -4.696649999999999991e-01 1.808195824993965897e-08 0.000000000000000000 -4.706600000000000228e-01 1.777908484038484727e-08 0.000000000000000000 -4.716549999999999909e-01 1.748128623567682730e-08 0.000000000000000000 -4.726500000000000146e-01 1.718847607616211987e-08 0.000000000000000000 -4.736449999999999827e-01 1.690056952359754085e-08 0.000000000000000000 -4.746400000000000063e-01 1.661748323278907984e-08 0.000000000000000000 -4.756350000000000300e-01 1.633913532386936203e-08 0.000000000000000000 -4.766299999999999981e-01 1.606544535509242241e-08 0.000000000000000000 -4.776250000000000218e-01 1.579633429619561801e-08 0.000000000000000000 -4.786199999999999899e-01 1.553172450226774170e-08 0.000000000000000000 -4.796150000000000135e-01 1.527153968812958752e-08 0.000000000000000000 -4.806099999999999817e-01 1.501570490329198411e-08 0.000000000000000000 -4.816050000000000053e-01 1.476414650728518093e-08 0.000000000000000000 -4.826000000000000290e-01 1.451679214561021136e-08 0.000000000000000000 -4.835949999999999971e-01 1.427357072605299284e-08 0.000000000000000000 -4.845900000000000207e-01 1.403441239554192092e-08 0.000000000000000000 -4.855849999999999889e-01 1.379924851741501211e-08 0.000000000000000000 -4.865800000000000125e-01 1.356801164916471703e-08 0.000000000000000000 -4.875749999999999806e-01 1.334063552058006977e-08 0.000000000000000000 -4.885700000000000043e-01 1.311705501236100186e-08 0.000000000000000000 -4.895650000000000279e-01 1.289720613511240166e-08 0.000000000000000000 -4.905599999999999961e-01 1.268102600878624253e-08 0.000000000000000000 -4.915550000000000197e-01 1.246845284246573869e-08 0.000000000000000000 -4.925499999999999878e-01 1.225942591461487445e-08 0.000000000000000000 -4.935450000000000115e-01 1.205388555364954470e-08 0.000000000000000000 -4.945400000000000351e-01 1.185177311892213667e-08 0.000000000000000000 -4.955350000000000033e-01 1.165303098206406425e-08 0.000000000000000000 -4.965300000000000269e-01 1.145760250866327575e-08 0.000000000000000000 -4.975249999999999950e-01 1.126543204035432285e-08 0.000000000000000000 -4.985200000000000187e-01 1.107646487718022137e-08 0.000000000000000000 -4.995149999999999868e-01 1.089064726035936574e-08 0.000000000000000000 -5.005100000000000104e-01 1.070792635533893917e-08 0.000000000000000000 -5.015049999999999786e-01 1.052825023518430476e-08 0.000000000000000000 -5.024999999999999467e-01 1.035156786429983128e-08 0.000000000000000000 -5.034950000000000259e-01 1.017782908245194928e-08 0.000000000000000000 -5.044899999999999940e-01 1.000698458908213401e-08 0.000000000000000000 -5.054849999999999621e-01 9.838985927942606211e-09 0.000000000000000000 -5.064800000000000413e-01 9.673785472016118153e-09 0.000000000000000000 -5.074750000000000094e-01 9.511336408707597594e-09 0.000000000000000000 -5.084699999999999775e-01 9.351592725336316339e-09 0.000000000000000000 -5.094650000000000567e-01 9.194509194901617369e-09 0.000000000000000000 -5.104600000000000248e-01 9.040041362103622041e-09 0.000000000000000000 -5.114549999999999930e-01 8.888145529627538254e-09 0.000000000000000000 -5.124499999999999611e-01 8.738778744717595970e-09 0.000000000000000000 -5.134450000000000403e-01 8.591898785946051782e-09 0.000000000000000000 -5.144400000000000084e-01 8.447464150305248862e-09 0.000000000000000000 -5.154349999999999765e-01 8.305434040478789650e-09 0.000000000000000000 -5.164300000000000557e-01 8.165768352358212425e-09 0.000000000000000000 -5.174250000000000238e-01 8.028427662851563377e-09 0.000000000000000000 -5.184199999999999919e-01 7.893373217842216118e-09 0.000000000000000000 -5.194149999999999601e-01 7.760566920435978511e-09 0.000000000000000000 -5.204100000000000392e-01 7.629971319358478376e-09 0.000000000000000000 -5.214050000000000074e-01 7.501549597652244998e-09 0.000000000000000000 -5.223999999999999755e-01 7.375265561526750397e-09 0.000000000000000000 -5.233950000000000546e-01 7.251083629405264984e-09 0.000000000000000000 -5.243900000000000228e-01 7.128968821243475963e-09 0.000000000000000000 -5.253849999999999909e-01 7.008886747960125850e-09 0.000000000000000000 -5.263799999999999590e-01 6.890803601115932548e-09 0.000000000000000000 -5.273750000000000382e-01 6.774686142796504578e-09 0.000000000000000000 -5.283700000000000063e-01 6.660501695615936994e-09 0.000000000000000000 -5.293649999999999745e-01 6.548218132964528978e-09 0.000000000000000000 -5.303600000000000536e-01 6.437803869424564685e-09 0.000000000000000000 -5.313550000000000217e-01 6.329227851337567396e-09 0.000000000000000000 -5.323499999999999899e-01 6.222459547568204285e-09 0.000000000000000000 -5.333449999999999580e-01 6.117468940427315924e-09 0.000000000000000000 -5.343400000000000372e-01 6.014226516756166591e-09 0.000000000000000000 -5.353350000000000053e-01 5.912703259200147065e-09 0.000000000000000000 -5.363299999999999734e-01 5.812870637596286722e-09 0.000000000000000000 -5.373250000000000526e-01 5.714700600562036045e-09 0.000000000000000000 -5.383200000000000207e-01 5.618165567214210133e-09 0.000000000000000000 -5.393149999999999888e-01 5.523238419030037714e-09 0.000000000000000000 -5.403099999999999570e-01 5.429892491889169139e-09 0.000000000000000000 -5.413050000000000361e-01 5.338101568217842023e-09 0.000000000000000000 -5.423000000000000043e-01 5.247839869312100044e-09 0.000000000000000000 -5.432949999999999724e-01 5.159082047782700767e-09 0.000000000000000000 -5.442900000000000515e-01 5.071803180117107580e-09 0.000000000000000000 -5.452850000000000197e-01 4.985978759425942900e-09 0.000000000000000000 -5.462799999999999878e-01 4.901584688272952708e-09 0.000000000000000000 -5.472749999999999559e-01 4.818597271653313524e-09 0.000000000000000000 -5.482700000000000351e-01 4.736993210097703913e-09 0.000000000000000000 -5.492650000000000032e-01 4.656749592899734273e-09 0.000000000000000000 -5.502599999999999714e-01 4.577843891457445651e-09 0.000000000000000000 -5.512550000000000505e-01 4.500253952754923854e-09 0.000000000000000000 -5.522500000000000187e-01 4.423957992928620999e-09 0.000000000000000000 -5.532449999999999868e-01 4.348934590969638247e-09 0.000000000000000000 -5.542399999999999549e-01 4.275162682547729828e-09 0.000000000000000000 -5.552350000000000341e-01 4.202621553908566314e-09 0.000000000000000000 -5.562300000000000022e-01 4.131290835932150873e-09 0.000000000000000000 -5.572249999999999703e-01 4.061150498237967917e-09 0.000000000000000000 -5.582200000000000495e-01 3.992180843446344811e-09 0.000000000000000000 -5.592150000000000176e-01 3.924362501509357965e-09 0.000000000000000000 -5.602099999999999858e-01 3.857676424154716910e-09 0.000000000000000000 -5.612049999999999539e-01 3.792103879430714948e-09 0.000000000000000000 -5.622000000000000330e-01 3.727626446332447825e-09 0.000000000000000000 -5.631950000000000012e-01 3.664226009549415779e-09 0.000000000000000000 -5.641899999999999693e-01 3.601884754267642989e-09 0.000000000000000000 -5.651850000000000485e-01 3.540585161106631196e-09 0.000000000000000000 -5.661800000000000166e-01 3.480310001116348841e-09 0.000000000000000000 -5.671749999999999847e-01 3.421042330867932332e-09 0.000000000000000000 -5.681700000000000639e-01 3.362765487628045872e-09 0.000000000000000000 -5.691650000000000320e-01 3.305463084633811144e-09 0.000000000000000000 -5.701600000000000001e-01 3.249119006439248004e-09 0.000000000000000000 -5.711549999999999683e-01 3.193717404330445612e-09 0.000000000000000000 -5.721500000000000474e-01 3.139242691846669754e-09 0.000000000000000000 -5.731450000000000156e-01 3.085679540359040699e-09 0.000000000000000000 -5.741399999999999837e-01 3.033012874741313056e-09 0.000000000000000000 -5.751350000000000628e-01 2.981227869103609884e-09 0.000000000000000000 -5.761300000000000310e-01 2.930309942605486299e-09 0.000000000000000000 -5.771249999999999991e-01 2.880244755344017550e-09 0.000000000000000000 -5.781199999999999672e-01 2.831018204320024633e-09 0.000000000000000000 -5.791150000000000464e-01 2.782616419444479799e-09 0.000000000000000000 -5.801100000000000145e-01 2.735025759662029664e-09 0.000000000000000000 -5.811049999999999827e-01 2.688232809096205337e-09 0.000000000000000000 -5.821000000000000618e-01 2.642224373286249017e-09 0.000000000000000000 -5.830950000000000299e-01 2.596987475486436551e-09 0.000000000000000000 -5.840899999999999981e-01 2.552509353022799725e-09 0.000000000000000000 -5.850849999999999662e-01 2.508777453719068253e-09 0.000000000000000000 -5.860800000000000454e-01 2.465779432375947976e-09 0.000000000000000000 -5.870750000000000135e-01 2.423503147329195027e-09 0.000000000000000000 -5.880699999999999816e-01 2.381936657034776456e-09 0.000000000000000000 -5.890650000000000608e-01 2.341068216750600869e-09 0.000000000000000000 -5.900600000000000289e-01 2.300886275249319634e-09 0.000000000000000000 -5.910549999999999971e-01 2.261379471589899679e-09 0.000000000000000000 -5.920499999999999652e-01 2.222536631965092181e-09 0.000000000000000000 -5.930450000000000443e-01 2.184346766572887835e-09 0.000000000000000000 -5.940400000000000125e-01 2.146799066563923027e-09 0.000000000000000000 -5.950349999999999806e-01 2.109882901029975367e-09 0.000000000000000000 -5.960300000000000598e-01 2.073587814052807845e-09 0.000000000000000000 -5.970250000000000279e-01 2.037903521796197191e-09 0.000000000000000000 -5.980199999999999960e-01 2.002819909644348453e-09 0.000000000000000000 -5.990149999999999642e-01 1.968327029405863638e-09 0.000000000000000000 -6.000100000000000433e-01 1.934415096543460493e-09 0.000000000000000000 -6.010050000000000114e-01 1.901074487462710610e-09 0.000000000000000000 -6.019999999999999796e-01 1.868295736852988358e-09 0.000000000000000000 -6.029950000000000587e-01 1.836069535059167139e-09 0.000000000000000000 -6.039900000000000269e-01 1.804386725507524731e-09 0.000000000000000000 -6.049849999999999950e-01 1.773238302172079969e-09 0.000000000000000000 -6.059799999999999631e-01 1.742615407085404039e-09 0.000000000000000000 -6.069750000000000423e-01 1.712509327890016968e-09 0.000000000000000000 -6.079700000000000104e-01 1.682911495434136928e-09 0.000000000000000000 -6.089649999999999785e-01 1.653813481399450726e-09 0.000000000000000000 -6.099600000000000577e-01 1.625206995987396573e-09 0.000000000000000000 -6.109550000000000258e-01 1.597083885620513122e-09 0.000000000000000000 -6.119499999999999940e-01 1.569436130702139067e-09 0.000000000000000000 -6.129449999999999621e-01 1.542255843404127068e-09 0.000000000000000000 -6.139400000000000412e-01 1.515535265493257126e-09 0.000000000000000000 -6.149350000000000094e-01 1.489266766199405405e-09 0.000000000000000000 -6.159299999999999775e-01 1.463442840109179879e-09 0.000000000000000000 -6.169250000000000567e-01 1.438056105105303416e-09 0.000000000000000000 -6.179200000000000248e-01 1.413099300335438690e-09 0.000000000000000000 -6.189149999999999929e-01 1.388565284219914378e-09 0.000000000000000000 -6.199099999999999611e-01 1.364447032482016621e-09 0.000000000000000000 -6.209050000000000402e-01 1.340737636223382316e-09 0.000000000000000000 -6.219000000000000083e-01 1.317430300025572456e-09 0.000000000000000000 -6.228949999999999765e-01 1.294518340085705259e-09 0.000000000000000000 -6.238900000000000556e-01 1.271995182379897042e-09 0.000000000000000000 -6.248850000000000238e-01 1.249854360861907686e-09 0.000000000000000000 -6.258799999999999919e-01 1.228089515688482748e-09 0.000000000000000000 -6.268749999999999600e-01 1.206694391477565856e-09 0.000000000000000000 -6.278700000000000392e-01 1.185662835590238378e-09 0.000000000000000000 -6.288650000000000073e-01 1.164988796445623888e-09 0.000000000000000000 -6.298599999999999755e-01 1.144666321867794175e-09 0.000000000000000000 -6.308550000000000546e-01 1.124689557446997487e-09 0.000000000000000000 -6.318500000000000227e-01 1.105052744945311523e-09 0.000000000000000000 -6.328449999999999909e-01 1.085750220710908845e-09 0.000000000000000000 -6.338399999999999590e-01 1.066776414137267750e-09 0.000000000000000000 -6.348350000000000382e-01 1.048125846132423263e-09 0.000000000000000000 -6.358300000000000063e-01 1.029793127619577583e-09 0.000000000000000000 -6.368249999999999744e-01 1.011772958067064884e-09 0.000000000000000000 -6.378200000000000536e-01 9.940601240353204801e-10 0.000000000000000000 -6.388150000000000217e-01 9.766494977525064135e-10 0.000000000000000000 -6.398099999999999898e-01 9.595360357101928669e-10 0.000000000000000000 -6.408049999999999580e-01 9.427147772883389336e-10 0.000000000000000000 -6.418000000000000371e-01 9.261808433944503319e-10 0.000000000000000000 -6.427950000000000053e-01 9.099294351329261107e-10 0.000000000000000000 -6.437899999999999734e-01 8.939558324953548407e-10 0.000000000000000000 -6.447850000000000525e-01 8.782553930644280603e-10 0.000000000000000000 -6.457800000000000207e-01 8.628235507521241244e-10 0.000000000000000000 -6.467749999999999888e-01 8.476558145459802247e-10 0.000000000000000000 -6.477699999999999569e-01 8.327477672877727265e-10 0.000000000000000000 -6.487650000000000361e-01 8.180950644622847663e-10 0.000000000000000000 -6.497600000000000042e-01 8.036934330121838051e-10 0.000000000000000000 -6.507549999999999724e-01 7.895386701715532421e-10 0.000000000000000000 -6.517500000000000515e-01 7.756266423150475058e-10 0.000000000000000000 -6.527450000000000196e-01 7.619532838310401384e-10 0.000000000000000000 -6.537399999999999878e-01 7.485145960110557591e-10 0.000000000000000000 -6.547349999999999559e-01 7.353066459561349298e-10 0.000000000000000000 -6.557300000000000351e-01 7.223255655019091240e-10 0.000000000000000000 -6.567250000000000032e-01 7.095675501633230957e-10 0.000000000000000000 -6.577199999999999713e-01 6.970288580952831633e-10 0.000000000000000000 -6.587150000000000505e-01 6.847058090697376434e-10 0.000000000000000000 -6.597100000000000186e-01 6.725947834695765550e-10 0.000000000000000000 -6.607049999999999867e-01 6.606922213008890459e-10 0.000000000000000000 -6.616999999999999549e-01 6.489946212177306857e-10 0.000000000000000000 -6.626950000000000340e-01 6.374985395695149751e-10 0.000000000000000000 -6.636900000000000022e-01 6.262005894555813714e-10 0.000000000000000000 -6.646849999999999703e-01 6.150974398006807465e-10 0.000000000000000000 -6.656800000000000495e-01 6.041858144460597144e-10 0.000000000000000000 -6.666750000000000176e-01 5.934624912519768004e-10 0.000000000000000000 -6.676699999999999857e-01 5.829243012166442471e-10 0.000000000000000000 -6.686650000000000649e-01 5.725681276106499875e-10 0.000000000000000000 -6.696600000000000330e-01 5.623909051228168385e-10 0.000000000000000000 -6.706550000000000011e-01 5.523896190237439203e-10 0.000000000000000000 -6.716499999999999693e-01 5.425613043398145989e-10 0.000000000000000000 -6.726450000000000484e-01 5.329030450417581546e-10 0.000000000000000000 -6.736400000000000166e-01 5.234119732464745679e-10 0.000000000000000000 -6.746349999999999847e-01 5.140852684323522755e-10 0.000000000000000000 -6.756300000000000638e-01 5.049201566664096458e-10 0.000000000000000000 -6.766250000000000320e-01 4.959139098454811543e-10 0.000000000000000000 -6.776200000000000001e-01 4.870638449487790499e-10 0.000000000000000000 -6.786149999999999682e-01 4.783673233012896401e-10 0.000000000000000000 -6.796100000000000474e-01 4.698217498523995215e-10 0.000000000000000000 -6.806050000000000155e-01 4.614245724643800463e-10 0.000000000000000000 -6.815999999999999837e-01 4.531732812111723066e-10 0.000000000000000000 -6.825950000000000628e-01 4.450654076920853576e-10 0.000000000000000000 -6.835900000000000309e-01 4.370985243527584836e-10 0.000000000000000000 -6.845849999999999991e-01 4.292702438197627921e-10 0.000000000000000000 -6.855799999999999672e-01 4.215782182455686226e-10 0.000000000000000000 -6.865750000000000464e-01 4.140201386645318280e-10 0.000000000000000000 -6.875700000000000145e-01 4.065937343561940905e-10 0.000000000000000000 -6.885649999999999826e-01 3.992967722240903926e-10 0.000000000000000000 -6.895600000000000618e-01 3.921270561814422491e-10 0.000000000000000000 -6.905550000000000299e-01 3.850824265461304586e-10 0.000000000000000000 -6.915499999999999980e-01 3.781607594477758664e-10 0.000000000000000000 -6.925449999999999662e-01 3.713599662443719948e-10 0.000000000000000000 -6.935400000000000453e-01 3.646779929451460856e-10 0.000000000000000000 -6.945350000000000135e-01 3.581128196474731658e-10 0.000000000000000000 -6.955299999999999816e-01 3.516624599789905450e-10 0.000000000000000000 -6.965250000000000608e-01 3.453249605512386629e-10 0.000000000000000000 -6.975200000000000289e-01 3.390984004204496542e-10 0.000000000000000000 -6.985149999999999970e-01 3.329808905590815081e-10 0.000000000000000000 -6.995099999999999651e-01 3.269705733336090213e-10 0.000000000000000000 -7.005050000000000443e-01 3.210656219930606029e-10 0.000000000000000000 -7.015000000000000124e-01 3.152642401639120136e-10 0.000000000000000000 -7.024949999999999806e-01 3.095646613535301542e-10 0.000000000000000000 -7.034900000000000597e-01 3.039651484643836440e-10 0.000000000000000000 -7.044850000000000279e-01 2.984639933103836991e-10 0.000000000000000000 -7.054799999999999960e-01 2.930595161482421644e-10 0.000000000000000000 -7.064749999999999641e-01 2.877500652096199171e-10 0.000000000000000000 -7.074700000000000433e-01 2.825340162463892363e-10 0.000000000000000000 -7.084650000000000114e-01 2.774097720789625829e-10 0.000000000000000000 -7.094599999999999795e-01 2.723757621550416838e-10 0.000000000000000000 -7.104550000000000587e-01 2.674304421138305059e-10 0.000000000000000000 -7.114500000000000268e-01 2.625722933581207666e-10 0.000000000000000000 -7.124449999999999950e-01 2.577998226317362304e-10 0.000000000000000000 -7.134399999999999631e-01 2.531115616069366224e-10 0.000000000000000000 -7.144350000000000422e-01 2.485060664753810539e-10 0.000000000000000000 -7.154300000000000104e-01 2.439819175467779222e-10 0.000000000000000000 -7.164249999999999785e-01 2.395377188552389620e-10 0.000000000000000000 -7.174200000000000577e-01 2.351720977695691270e-10 0.000000000000000000 -7.184150000000000258e-01 2.308837046132094100e-10 0.000000000000000000 -7.194099999999999939e-01 2.266712122853988755e-10 0.000000000000000000 -7.204049999999999621e-01 2.225333158951815671e-10 0.000000000000000000 -7.214000000000000412e-01 2.184687323937923984e-10 0.000000000000000000 -7.223950000000000093e-01 2.144762002199834842e-10 0.000000000000000000 -7.233899999999999775e-01 2.105544789457397629e-10 0.000000000000000000 -7.243850000000000566e-01 2.067023489314449509e-10 0.000000000000000000 -7.253800000000000248e-01 2.029186109836347890e-10 0.000000000000000000 -7.263749999999999929e-01 1.992020860208143683e-10 0.000000000000000000 -7.273699999999999610e-01 1.955516147432110017e-10 0.000000000000000000 -7.283650000000000402e-01 1.919660573080928565e-10 0.000000000000000000 -7.293600000000000083e-01 1.884442930107386533e-10 0.000000000000000000 -7.303549999999999764e-01 1.849852199707302973e-10 0.000000000000000000 -7.313500000000000556e-01 1.815877548214458977e-10 0.000000000000000000 -7.323450000000000237e-01 1.782508324083276738e-10 0.000000000000000000 -7.333399999999999919e-01 1.749734054871994406e-10 0.000000000000000000 -7.343349999999999600e-01 1.717544444327696856e-10 0.000000000000000000 -7.353300000000000392e-01 1.685929369464436664e-10 0.000000000000000000 -7.363250000000000073e-01 1.654878877736655847e-10 0.000000000000000000 -7.373199999999999754e-01 1.624383184224845999e-10 0.000000000000000000 -7.383150000000000546e-01 1.594432668877642051e-10 0.000000000000000000 -7.393100000000000227e-01 1.565017873814703209e-10 0.000000000000000000 -7.403049999999999908e-01 1.536129500638754654e-10 0.000000000000000000 -7.412999999999999590e-01 1.507758407823909257e-10 0.000000000000000000 -7.422950000000000381e-01 1.479895608131337696e-10 0.000000000000000000 -7.432900000000000063e-01 1.452532266062458961e-10 0.000000000000000000 -7.442849999999999744e-01 1.425659695365616108e-10 0.000000000000000000 -7.452800000000000535e-01 1.399269356573926378e-10 0.000000000000000000 -7.462750000000000217e-01 1.373352854587497921e-10 0.000000000000000000 -7.472699999999999898e-01 1.347901936294661017e-10 0.000000000000000000 -7.482649999999999579e-01 1.322908488223341237e-10 0.000000000000000000 -7.492600000000000371e-01 1.298364534248632290e-10 0.000000000000000000 -7.502550000000000052e-01 1.274262233316630721e-10 0.000000000000000000 -7.512499999999999734e-01 1.250593877217680957e-10 0.000000000000000000 -7.522450000000000525e-01 1.227351888398047800e-10 0.000000000000000000 -7.532400000000000206e-01 1.204528817793964409e-10 0.000000000000000000 -7.542349999999999888e-01 1.182117342713846246e-10 0.000000000000000000 -7.552299999999999569e-01 1.160110264747073532e-10 0.000000000000000000 -7.562250000000000361e-01 1.138500507714065408e-10 0.000000000000000000 -7.572200000000000042e-01 1.117281115635054185e-10 0.000000000000000000 -7.582149999999999723e-01 1.096445250754567631e-10 0.000000000000000000 -7.592100000000000515e-01 1.075986191572987652e-10 0.000000000000000000 -7.602050000000000196e-01 1.055897330930012879e-10 0.000000000000000000 -7.611999999999999877e-01 1.036172174105339540e-10 0.000000000000000000 -7.621949999999999559e-01 1.016804336962519086e-10 0.000000000000000000 -7.631900000000000350e-01 9.977875441096356335e-11 0.000000000000000000 -7.641850000000000032e-01 9.791156271008344962e-11 0.000000000000000000 -7.651799999999999713e-01 9.607825226625470990e-11 0.000000000000000000 -7.661750000000000504e-01 9.427822709455359464e-11 0.000000000000000000 -7.671700000000000186e-01 9.251090138124984059e-11 0.000000000000000000 -7.681649999999999867e-01 9.077569931482582088e-11 0.000000000000000000 -7.691599999999999548e-01 8.907205491965810509e-11 0.000000000000000000 -7.701550000000000340e-01 8.739941189288420762e-11 0.000000000000000000 -7.711500000000000021e-01 8.575722344352985258e-11 0.000000000000000000 -7.721449999999999703e-01 8.414495213434765917e-11 0.000000000000000000 -7.731400000000000494e-01 8.256206972622971592e-11 0.000000000000000000 -7.741350000000000176e-01 8.100805702532533275e-11 0.000000000000000000 -7.751299999999999857e-01 7.948240373228508669e-11 0.000000000000000000 -7.761250000000000648e-01 7.798460829422891543e-11 0.000000000000000000 -7.771200000000000330e-01 7.651417775903194526e-11 0.000000000000000000 -7.781150000000000011e-01 7.507062763206356851e-11 0.000000000000000000 -7.791099999999999692e-01 7.365348173517222601e-11 0.000000000000000000 -7.801050000000000484e-01 7.226227206788986404e-11 0.000000000000000000 -7.811000000000000165e-01 7.089653867113503250e-11 0.000000000000000000 -7.820949999999999847e-01 6.955582949297110040e-11 0.000000000000000000 -7.830900000000000638e-01 6.823970025633168779e-11 0.000000000000000000 -7.840850000000000319e-01 6.694771432965168588e-11 0.000000000000000000 -7.850800000000000001e-01 6.567944259862998955e-11 0.000000000000000000 -7.860749999999999682e-01 6.443446334061711945e-11 0.000000000000000000 -7.870700000000000474e-01 6.321236210132198715e-11 0.000000000000000000 -7.880650000000000155e-01 6.201273157282145684e-11 0.000000000000000000 -7.890599999999999836e-01 6.083517147412531346e-11 0.000000000000000000 -7.900550000000000628e-01 5.967928843341275616e-11 0.000000000000000000 -7.910500000000000309e-01 5.854469587245565986e-11 0.000000000000000000 -7.920449999999999990e-01 5.743101389234423935e-11 0.000000000000000000 -7.930399999999999672e-01 5.633786916210906675e-11 0.000000000000000000 -7.940350000000000463e-01 5.526489480788727048e-11 0.000000000000000000 -7.950300000000000145e-01 5.421173030509729357e-11 0.000000000000000000 -7.960249999999999826e-01 5.317802137138497194e-11 0.000000000000000000 -7.970200000000000617e-01 5.216341986217019749e-11 0.000000000000000000 -7.980150000000000299e-01 5.116758366718568742e-11 0.000000000000000000 -7.990099999999999980e-01 5.019017660923670763e-11 0.000000000000000000 -8.000049999999999661e-01 4.923086834421724464e-11 0.000000000000000000 -8.010000000000000453e-01 4.828933426320927044e-11 0.000000000000000000 -8.019950000000000134e-01 4.736525539558188763e-11 0.000000000000000000 -8.029899999999999816e-01 4.645831831438245641e-11 0.000000000000000000 -8.039850000000000607e-01 4.556821504268652730e-11 0.000000000000000000 -8.049800000000000288e-01 4.469464296170416256e-11 0.000000000000000000 -8.059749999999999970e-01 4.383730472068802512e-11 0.000000000000000000 -8.069699999999999651e-01 4.299590814766838308e-11 0.000000000000000000 -8.079650000000000443e-01 4.217016616230079168e-11 0.000000000000000000 -8.089600000000000124e-01 4.135979668960845514e-11 0.000000000000000000 -8.099549999999999805e-01 4.056452257571198034e-11 0.000000000000000000 -8.109500000000000597e-01 3.978407150433260260e-11 0.000000000000000000 -8.119450000000000278e-01 3.901817591526678961e-11 0.000000000000000000 -8.129399999999999959e-01 3.826657292356815587e-11 0.000000000000000000 -8.139349999999999641e-01 3.752900424059828834e-11 0.000000000000000000 -8.149300000000000432e-01 3.680521609627443136e-11 0.000000000000000000 -8.159250000000000114e-01 3.609495916209530939e-11 0.000000000000000000 -8.169199999999999795e-01 3.539798847631480826e-11 0.000000000000000000 -8.179150000000000587e-01 3.471406336951419588e-11 0.000000000000000000 -8.189100000000000268e-01 3.404294739185910951e-11 0.000000000000000000 -8.199049999999999949e-01 3.338440824150709322e-11 0.000000000000000000 -8.208999999999999631e-01 3.273821769404085850e-11 0.000000000000000000 -8.218950000000000422e-01 3.210415153329436856e-11 0.000000000000000000 -8.228900000000000103e-01 3.148198948294768353e-11 0.000000000000000000 -8.238849999999999785e-01 3.087151513973246205e-11 0.000000000000000000 -8.248800000000000576e-01 3.027251590737155331e-11 0.000000000000000000 -8.258750000000000258e-01 2.968478293185995294e-11 0.000000000000000000 -8.268699999999999939e-01 2.910811103743564697e-11 0.000000000000000000 -8.278649999999999620e-01 2.854229866422437845e-11 0.000000000000000000 -8.288600000000000412e-01 2.798714780617325204e-11 0.000000000000000000 -8.298550000000000093e-01 2.744246395074316365e-11 0.000000000000000000 -8.308499999999999774e-01 2.690805601903921905e-11 0.000000000000000000 -8.318450000000000566e-01 2.638373630713539760e-11 0.000000000000000000 -8.328400000000000247e-01 2.586932042855219276e-11 0.000000000000000000 -8.338349999999999929e-01 2.536462725737758588e-11 0.000000000000000000 -8.348299999999999610e-01 2.486947887248887770e-11 0.000000000000000000 -8.358250000000000401e-01 2.438370050272607173e-11 0.000000000000000000 -8.368200000000000083e-01 2.390712047288832168e-11 0.000000000000000000 -8.378149999999999764e-01 2.343957015071224223e-11 0.000000000000000000 -8.388100000000000556e-01 2.298088389467405944e-11 0.000000000000000000 -8.398050000000000237e-01 2.253089900258152798e-11 0.000000000000000000 -8.407999999999999918e-01 2.208945566131302509e-11 0.000000000000000000 -8.417949999999999600e-01 2.165639689701962011e-11 0.000000000000000000 -8.427900000000000391e-01 2.123156852639565456e-11 0.000000000000000000 -8.437850000000000072e-01 2.081481910870578539e-11 0.000000000000000000 -8.447799999999999754e-01 2.040599989851381981e-11 0.000000000000000000 -8.457750000000000545e-01 2.000496479944291845e-11 0.000000000000000000 -8.467700000000000227e-01 1.961157031843802305e-11 0.000000000000000000 -8.477649999999999908e-01 1.922567552086915531e-11 0.000000000000000000 -8.487599999999999589e-01 1.884714198652079419e-11 0.000000000000000000 -8.497550000000000381e-01 1.847583376615353297e-11 0.000000000000000000 -8.507500000000000062e-01 1.811161733888242197e-11 0.000000000000000000 -8.517449999999999743e-01 1.775436157018041761e-11 0.000000000000000000 -8.527400000000000535e-01 1.740393767069240377e-11 0.000000000000000000 -8.537350000000000216e-01 1.706021915565210826e-11 0.000000000000000000 -8.547299999999999898e-01 1.672308180502099934e-11 0.000000000000000000 -8.557249999999999579e-01 1.639240362433276411e-11 0.000000000000000000 -8.567200000000000371e-01 1.606806480605511399e-11 0.000000000000000000 -8.577150000000000052e-01 1.574994769175799766e-11 0.000000000000000000 -8.587099999999999733e-01 1.543793673481743599e-11 0.000000000000000000 -8.597050000000000525e-01 1.513191846380246931e-11 0.000000000000000000 -8.607000000000000206e-01 1.483178144642076169e-11 0.000000000000000000 -8.616949999999999887e-01 1.453741625408964590e-11 0.000000000000000000 -8.626899999999999569e-01 1.424871542717199542e-11 0.000000000000000000 -8.636850000000000360e-01 1.396557344067323184e-11 0.000000000000000000 -8.646800000000000042e-01 1.368788667062002115e-11 0.000000000000000000 -8.656749999999999723e-01 1.341555336091990615e-11 0.000000000000000000 -8.666700000000000514e-01 1.314847359090981869e-11 0.000000000000000000 -8.676650000000000196e-01 1.288654924319432812e-11 0.000000000000000000 -8.686599999999999877e-01 1.262968397242288672e-11 0.000000000000000000 -8.696549999999999558e-01 1.237778317413847121e-11 0.000000000000000000 -8.706500000000000350e-01 1.213075395458402982e-11 0.000000000000000000 -8.716450000000000031e-01 1.188850510063939789e-11 0.000000000000000000 -8.726399999999999713e-01 1.165094705056480650e-11 0.000000000000000000 -8.736350000000000504e-01 1.141799186504683717e-11 0.000000000000000000 -8.746300000000000185e-01 1.118955319883575737e-11 0.000000000000000000 -8.756249999999999867e-01 1.096554627279212947e-11 0.000000000000000000 -8.766200000000000658e-01 1.074588784648897165e-11 0.000000000000000000 -8.776150000000000340e-01 1.053049619119633637e-11 0.000000000000000000 -8.786100000000000021e-01 1.031929106337711392e-11 0.000000000000000000 -8.796049999999999702e-01 1.011219367860600992e-11 0.000000000000000000 -8.806000000000000494e-01 9.909126685931416669e-12 0.000000000000000000 -8.815950000000000175e-01 9.710014142709092467e-12 0.000000000000000000 -8.825899999999999856e-01 9.514781489789963117e-12 0.000000000000000000 -8.835850000000000648e-01 9.323355527214140165e-12 0.000000000000000000 -8.845800000000000329e-01 9.135664390280521159e-12 0.000000000000000000 -8.855750000000000011e-01 8.951637525956803811e-12 0.000000000000000000 -8.865699999999999692e-01 8.771205669848477140e-12 0.000000000000000000 -8.875650000000000484e-01 8.594300823370846695e-12 0.000000000000000000 -8.885600000000000165e-01 8.420856231485389200e-12 0.000000000000000000 -8.895549999999999846e-01 8.250806360685502162e-12 0.000000000000000000 -8.905500000000000638e-01 8.084086877442745888e-12 0.000000000000000000 -8.915450000000000319e-01 7.920634626948725029e-12 0.000000000000000000 -8.925400000000000000e-01 7.760387612281252380e-12 0.000000000000000000 -8.935349999999999682e-01 7.603284973905482060e-12 0.000000000000000000 -8.945300000000000473e-01 7.449266969506496546e-12 0.000000000000000000 -8.955250000000000155e-01 7.298274954195714714e-12 0.000000000000000000 -8.965199999999999836e-01 7.150251361045872353e-12 0.000000000000000000 -8.975150000000000627e-01 7.005139681932871316e-12 0.000000000000000000 -8.985100000000000309e-01 6.862884448759745745e-12 0.000000000000000000 -8.995049999999999990e-01 6.723431214957391286e-12 0.000000000000000000 -9.004999999999999671e-01 6.586726537320808128e-12 0.000000000000000000 -9.014950000000000463e-01 6.452717958148575220e-12 0.000000000000000000 -9.024900000000000144e-01 6.321353987697752509e-12 0.000000000000000000 -9.034849999999999826e-01 6.192584086955323570e-12 0.000000000000000000 -9.044800000000000617e-01 6.066358650650915654e-12 0.000000000000000000 -9.054750000000000298e-01 5.942628990640109593e-12 0.000000000000000000 -9.064699999999999980e-01 5.821347319489051845e-12 0.000000000000000000 -9.074649999999999661e-01 5.702466734432494170e-12 0.000000000000000000 -9.084600000000000453e-01 5.585941201518969179e-12 0.000000000000000000 -9.094550000000000134e-01 5.471725540095875727e-12 0.000000000000000000 -9.104499999999999815e-01 5.359775407532663075e-12 0.000000000000000000 -9.114450000000000607e-01 5.250047284201808633e-12 0.000000000000000000 -9.124400000000000288e-01 5.142498458759478234e-12 0.000000000000000000 -9.134349999999999969e-01 5.037087013620237808e-12 0.000000000000000000 -9.144299999999999651e-01 4.933771810723792127e-12 0.000000000000000000 -9.154250000000000442e-01 4.832512477559490473e-12 0.000000000000000000 -9.164200000000000124e-01 4.733269393382690548e-12 0.000000000000000000 -9.174149999999999805e-01 4.636003675708210934e-12 0.000000000000000000 -9.184100000000000597e-01 4.540677167043161048e-12 0.000000000000000000 -9.194050000000000278e-01 4.447252421825848935e-12 0.000000000000000000 -9.203999999999999959e-01 4.355692693609114473e-12 0.000000000000000000 -9.213949999999999640e-01 4.265961922438394138e-12 0.000000000000000000 -9.223900000000000432e-01 4.178024722488739340e-12 0.000000000000000000 -9.233850000000000113e-01 4.091846369909820615e-12 0.000000000000000000 -9.243799999999999795e-01 4.007392790829750474e-12 0.000000000000000000 -9.253750000000000586e-01 3.924630549657840782e-12 0.000000000000000000 -9.263700000000000268e-01 3.843526837507154298e-12 0.000000000000000000 -9.273649999999999949e-01 3.764049460866051308e-12 0.000000000000000000 -9.283599999999999630e-01 3.686166830456769560e-12 0.000000000000000000 -9.293550000000000422e-01 3.609847950283756110e-12 0.000000000000000000 -9.303500000000000103e-01 3.535062406887417040e-12 0.000000000000000000 -9.313449999999999784e-01 3.461780358757763444e-12 0.000000000000000000 -9.323400000000000576e-01 3.389972525956962532e-12 0.000000000000000000 -9.333350000000000257e-01 3.319610179935919121e-12 0.000000000000000000 -9.343299999999999939e-01 3.250665133472402609e-12 0.000000000000000000 -9.353249999999999620e-01 3.183109730872174957e-12 0.000000000000000000 -9.363200000000000411e-01 3.116916838239753724e-12 0.000000000000000000 -9.373150000000000093e-01 3.052059834024750229e-12 0.000000000000000000 -9.383099999999999774e-01 2.988512599643348278e-12 0.000000000000000000 -9.393050000000000566e-01 2.926249510337346485e-12 0.000000000000000000 -9.403000000000000247e-01 2.865245426127051678e-12 0.000000000000000000 -9.412949999999999928e-01 2.805475682992718501e-12 0.000000000000000000 -9.422899999999999610e-01 2.746916084139481357e-12 0.000000000000000000 -9.432850000000000401e-01 2.689542891490299806e-12 0.000000000000000000 -9.442800000000000082e-01 2.633332817262948029e-12 0.000000000000000000 -9.452749999999999764e-01 2.578263015732237005e-12 0.000000000000000000 -9.462700000000000555e-01 2.524311075133569463e-12 0.000000000000000000 -9.472650000000000237e-01 2.471455009705816204e-12 0.000000000000000000 -9.482599999999999918e-01 2.419673251862030195e-12 0.000000000000000000 -9.492549999999999599e-01 2.368944644531134214e-12 0.000000000000000000 -9.502500000000000391e-01 2.319248433593288717e-12 0.000000000000000000 -9.512450000000000072e-01 2.270564260484504975e-12 0.000000000000000000 -9.522399999999999753e-01 2.222872154916162812e-12 0.000000000000000000 -9.532350000000000545e-01 2.176152527732621461e-12 0.000000000000000000 -9.542300000000000226e-01 2.130386163866658255e-12 0.000000000000000000 -9.552249999999999908e-01 2.085554215469351149e-12 0.000000000000000000 -9.562199999999999589e-01 2.041638195121339581e-12 0.000000000000000000 -9.572150000000000380e-01 1.998619969182224490e-12 0.000000000000000000 -9.582100000000000062e-01 1.956481751250051619e-12 0.000000000000000000 -9.592049999999999743e-01 1.915206095750555943e-12 0.000000000000000000 -9.602000000000000535e-01 1.874775891624738814e-12 0.000000000000000000 -9.611950000000000216e-01 1.835174356137109269e-12 0.000000000000000000 -9.621899999999999897e-01 1.796385028799102358e-12 0.000000000000000000 -9.631849999999999579e-01 1.758391765391040215e-12 0.000000000000000000 -9.641800000000000370e-01 1.721178732095956176e-12 0.000000000000000000 -9.651750000000000052e-01 1.684730399735976772e-12 0.000000000000000000 -9.661699999999999733e-01 1.649031538118635951e-12 0.000000000000000000 -9.671650000000000524e-01 1.614067210475218385e-12 0.000000000000000000 -9.681600000000000206e-01 1.579822768003402259e-12 0.000000000000000000 -9.691549999999999887e-01 1.546283844509766956e-12 0.000000000000000000 -9.701499999999999568e-01 1.513436351142013283e-12 0.000000000000000000 -9.711450000000000360e-01 1.481266471218146186e-12 0.000000000000000000 -9.721400000000000041e-01 1.449760655162423748e-12 0.000000000000000000 -9.731349999999999723e-01 1.418905615502230981e-12 0.000000000000000000 -9.741300000000000514e-01 1.388688321986862196e-12 0.000000000000000000 -9.751250000000000195e-01 1.359095996768790642e-12 0.000000000000000000 -9.761199999999999877e-01 1.330116109690863912e-12 0.000000000000000000 -9.771150000000000668e-01 1.301736373650612545e-12 0.000000000000000000 -9.781100000000000350e-01 1.273944740041217820e-12 0.000000000000000000 -9.791050000000000031e-01 1.246729394289011297e-12 0.000000000000000000 -9.800999999999999712e-01 1.220078751455892882e-12 0.000000000000000000 -9.810950000000000504e-01 1.193981451939975580e-12 0.000000000000000000 -9.820900000000000185e-01 1.168426357233797262e-12 0.000000000000000000 -9.830849999999999866e-01 1.143402545775898413e-12 0.000000000000000000 -9.840800000000000658e-01 1.118899308866149742e-12 0.000000000000000000 -9.850750000000000339e-01 1.094906146664561621e-12 0.000000000000000000 -9.860700000000000021e-01 1.071412764247475544e-12 0.000000000000000000 -9.870649999999999702e-01 1.048409067760837229e-12 0.000000000000000000 -9.880600000000000493e-01 1.025885160616447765e-12 0.000000000000000000 -9.890550000000000175e-01 1.003831339770924548e-12 0.000000000000000000 -9.900499999999999856e-01 9.822380920748707792e-13 0.000000000000000000 -9.910450000000000648e-01 9.610960906801041221e-13 0.000000000000000000 -9.920400000000000329e-01 9.403961915179023274e-13 0.000000000000000000 -9.930350000000000010e-01 9.201294298374636062e-13 0.000000000000000000 -9.940299999999999692e-01 9.002870168152242337e-13 0.000000000000000000 -9.950250000000000483e-01 8.808603362145260253e-13 0.000000000000000000 -9.960200000000000164e-01 8.618409411153087119e-13 0.000000000000000000 -9.970149999999999846e-01 8.432205507020908809e-13 0.000000000000000000 -9.980100000000000637e-01 8.249910471071539138e-13 0.000000000000000000 -9.990050000000000319e-01 8.071444723139599604e-13 0.000000000000000000 -1.000000000000000000e+00 7.896730251172689431e-13 0.000000000000000000 \ No newline at end of file diff --git a/tests/test_data/ORSO/test_4.dat b/tests/test_data/ORSO/test_4.dat deleted file mode 100644 index 7b99cb86..00000000 --- a/tests/test_data/ORSO/test_4.dat +++ /dev/null @@ -1,101 +0,0 @@ -4.999999999999999237e-03 9.660499468321636085e-01 0.000000000000000000e+00 1.061652250360023761e-04 -5.208965929570049704e-03 9.646283312283907563e-01 0.000000000000000000e+00 1.106022080235347408e-04 -5.426665211084315613e-03 9.631435299315659337e-01 0.000000000000000000e+00 1.152246266659623608e-04 -5.653462839144248603e-03 9.615923806647335148e-01 0.000000000000000000e+00 1.200402309100852380e-04 -5.889739062638551202e-03 9.599715341545977942e-01 0.000000000000000000e+00 1.250570945976711191e-04 -6.135890022268412555e-03 9.582774463689063271e-01 0.000000000000000000e+00 1.302836290020575514e-04 -6.392328414716996060e-03 9.565063736552937845e-01 0.000000000000000000e+00 1.357285969304924749e-04 -6.659484184576673627e-03 9.546543728325473932e-01 0.000000000000000000e+00 1.414011274158563051e-04 -6.937805245194089872e-03 9.527173094019888433e-01 0.000000000000000000e+00 1.473107310223976691e-04 -7.227758229641680597e-03 9.506908787954021500e-01 0.000000000000000000e+00 1.534673157911454707e-04 -7.529829273074612438e-03 9.485706483542604150e-01 0.000000000000000000e+00 1.598812038517289096e-04 -7.844524827784976270e-03 9.463521322252024248e-01 0.000000000000000000e+00 1.665631487284599923e-04 -8.172372512319661317e-03 9.440309187595408158e-01 0.000000000000000000e+00 1.735243533696914056e-04 -8.513921996085575816e-03 9.416028824956215182e-01 0.000000000000000000e+00 1.807764889306791788e-04 -8.869745920925360336e-03 9.390645344556776131e-01 0.000000000000000000e+00 1.883317143414410305e-04 -9.240440861208627787e-03 9.364136032254166686e-01 0.000000000000000000e+00 1.962026966924171388e-04 -9.626628324048536189e-03 9.336500112051923095e-01 0.000000000000000000e+00 2.044026324721134858e-04 -1.002895579132056722e-02 9.307775499924635376e-01 0.000000000000000000e+00 2.129452696923334900e-04 -1.044809780523061650e-02 9.278068446083937992e-01 0.000000000000000000e+00 2.218449309380942302e-04 -1.088475709925237553e-02 9.247608214119300563e-01 0.000000000000000000e+00 2.311165373808706110e-04 -1.133966577633027141e-02 9.216853828676729865e-01 0.000000000000000000e+00 2.407756337954316216e-04 -1.181358653632318123e-02 9.186719597214783040e-01 0.000000000000000000e+00 2.508384146222077419e-04 -1.230731395474697620e-02 9.159110487636203946e-01 0.000000000000000000e+00 2.613217511188890515e-04 -1.282167581495980910e-02 9.138467828784078151e-01 0.000000000000000000e+00 2.722432196467755149e-04 -1.335753449602358582e-02 9.108355606753477662e-01 0.000000000000000000e+00 2.836211311393017432e-04 -1.391578841856870238e-02 7.335981045780506360e-01 0.000000000000000000e+00 2.954745618021484190e-04 -1.449737355108597463e-02 2.213862971885717790e-01 0.000000000000000000e+00 3.078233850964063527e-04 -1.510326497917135677e-02 5.065074610089120161e-02 0.000000000000000000e+00 3.206883050584202191e-04 -1.573447854035441712e-02 1.590368472895162949e-02 0.000000000000000000e+00 3.340908910121754400e-04 -1.639207252725145142e-02 4.800075501038165819e-03 0.000000000000000000e+00 3.480536137324245511e-04 -1.707714946189881067e-02 1.223948799745163416e-03 0.000000000000000000e+00 3.625998831191868982e-04 -1.779085794424128605e-02 5.046568494808504907e-04 0.000000000000000000e+00 3.777540874467854378e-04 -1.853439457787469519e-02 8.404754652332931120e-04 0.000000000000000000e+00 3.935416342532259133e-04 -1.930900597627142543e-02 1.458717108645946623e-03 0.000000000000000000e+00 4.099889929384741916e-04 -2.011599085285246946e-02 2.022184226696178543e-03 0.000000000000000000e+00 4.271237391430496191e-04 -2.095670219841026111e-02 2.397327154528816270e-03 0.000000000000000000e+00 4.449746009813422727e-04 -2.183254954953296745e-02 2.551634050707026792e-03 0.000000000000000000e+00 4.635715072071680543e-04 -2.274500135183342431e-02 2.503723878205208874e-03 0.000000000000000000e+00 4.829456373923148504e-04 -2.369558742194500037e-02 2.297014419596041072e-03 0.000000000000000000e+00 5.031294742022117319e-04 -2.468590151241202915e-02 1.984702877815211226e-03 0.000000000000000000e+00 5.241568578563629999e-04 -2.571760398377520920e-02 1.620535097096735370e-03 0.000000000000000000e+00 5.460630428648573405e-04 -2.679242458833201376e-02 1.252789959601383627e-03 0.000000000000000000e+00 5.688847571360784120e-04 -2.791216537023925512e-02 9.202954264280633354e-04 0.000000000000000000e+00 5.926602635547127294e-04 -2.907870368682024739e-02 6.499790081461440973e-04 0.000000000000000000e+00 6.174294241333008141e-04 -3.029399535614193950e-02 4.557902347035073598e-04 0.000000000000000000e+00 6.432337668448841412e-04 -3.156007793613933854e-02 3.389679007057118062e-04 0.000000000000000000e+00 6.701165552488013702e-04 -3.287907414078505841e-02 2.896305199626667578e-04 0.000000000000000000e+00 6.981228610263705585e-04 -3.425319539903139837e-02 2.895827802138814912e-04 0.000000000000000000e+00 7.272996395480660261e-04 -3.568474556249201513e-02 3.160833603894238047e-04 0.000000000000000000e+00 7.576958085988904973e-04 -3.717612476807939659e-02 3.461421601729252370e-04 0.000000000000000000e+00 7.893623303939302548e-04 -3.872983346207417577e-02 3.607471650414172397e-04 0.000000000000000000e+00 8.223522970216000675e-04 -4.034847659237329048e-02 3.483107825318375100e-04 0.000000000000000000e+00 8.567210194578371010e-04 -4.203476797594541542e-02 3.066260485666312411e-04 0.000000000000000000e+00 8.925261203004783862e-04 -4.379153484881635749e-02 2.427846473412773824e-04 0.000000000000000000e+00 9.298276303793059786e-04 -4.562172260621279868e-02 1.708603072276521735e-04 0.000000000000000000e+00 9.686880894037319147e-04 -4.752839974081164709e-02 1.076850793981012493e-04 0.000000000000000000e+00 1.009172650816869167e-03 -4.951476298737475523e-02 6.765012337432836328e-05 0.000000000000000000e+00 1.051349191031792632e-03 -5.158414268239425865e-02 5.796797455235872996e-05 0.000000000000000000e+00 1.095288423233128482e-03 -5.374000834773436097e-02 7.600076548404877867e-05 0.000000000000000000e+00 1.141064015934773043e-03 -5.598597450763168060e-02 1.098724565425083957e-04 0.000000000000000000e+00 1.188752716492522165e-03 -5.832580674880616378e-02 1.425800498622337880e-04 0.000000000000000000e+00 1.238434479778678654e-03 -6.076342803384361668e-02 1.584158826364232800e-04 0.000000000000000000e+00 1.290192602234388778e-03 -6.330292527843461858e-02 1.492439980337561915e-04 0.000000000000000000e+00 1.344113861524451250e-03 -6.594855620349690528e-02 1.177519033425392445e-04 0.000000000000000000e+00 1.400288662028740172e-03 -6.870475647367019212e-02 7.577842573871102763e-05 0.000000000000000000e+00 1.458811186414187651e-03 -7.157614713415108576e-02 3.813747620286129380e-05 0.000000000000000000e+00 1.519779553541433575e-03 -7.456754235833716604e-02 1.502718568743208691e-05 0.000000000000000000e+00 1.583295982970901261e-03 -7.768395751926998605e-02 7.432986794932621371e-06 0.000000000000000000e+00 1.649466966344109589e-03 -8.093061759840886049e-02 8.479436602724126006e-06 0.000000000000000000e+00 1.718403445927546482e-03 -8.431296594583481685e-02 9.720659036587660457e-06 0.000000000000000000e+00 1.790221000618471897e-03 -8.783667340657071165e-02 7.475971384271801476e-06 0.000000000000000000e+00 1.865040039724485304e-03 -9.150764782831966038e-02 4.045160813957839975e-06 0.000000000000000000e+00 1.942986004841762470e-03 -9.533204396656239088e-02 3.178505467676818043e-06 0.000000000000000000e+00 2.024189580170434287e-03 -9.931627380361947310e-02 4.953666565173862248e-06 0.000000000000000000e+00 2.108786911619698213e-03 -1.034670172989808762e-01 5.966968494098515925e-06 0.000000000000000000e+00 2.196919835070051605e-03 -1.077912335889252976e-01 4.395731401080907728e-06 0.000000000000000000e+00 2.288736114175310681e-03 -1.122961726542076877e-01 2.838663311476676714e-06 0.000000000000000000e+00 2.384389688103147591e-03 -1.169893874753767798e-01 4.376365975608713520e-06 0.000000000000000000e+00 2.484040929629491301e-03 -1.218787466961013116e-01 7.365431957590666160e-06 0.000000000000000000e+00 2.587856914019505839e-03 -1.269724478157380210e-01 7.444758004751446953e-06 0.000000000000000000e+00 2.696011699145979719e-03 -1.322790309332581016e-01 4.174506384415917617e-06 0.000000000000000000e+00 2.808686617314733527e-03 -1.378073930655767942e-01 1.378897368540984724e-06 0.000000000000000000e+00 2.926070579286359132e-03 -1.435668030642915372e-01 8.179962055944333663e-07 0.000000000000000000e+00 3.048360391003989995e-03 -1.495669171558374755e-01 7.196203711450000268e-07 0.000000000000000000e+00 3.175761083558122696e-03 -1.558177951311167375e-01 4.074965533304633985e-07 0.000000000000000000e+00 3.308486256941745463e-03 -1.623299172117425582e-01 5.697106402976437542e-07 0.000000000000000000e+00 3.446758438172057518e-03 -1.691142016211787946e-01 6.318259741325602534e-07 0.000000000000000000e+00 3.590809454379265478e-03 -1.761820228902321317e-01 5.884226632043859758e-07 0.000000000000000000e+00 3.740880821487923939e-03 -1.835452309275898974e-01 1.086074476142989135e-06 0.000000000000000000e+00 3.897224149142521597e-03 -1.912161708873765797e-01 1.080905569118702644e-06 0.000000000000000000e+00 4.060101562556204732e-03 -1.992077038670377609e-01 4.319349827800466143e-07 0.000000000000000000e+00 4.229786141989877457e-03 -2.075332284702559316e-01 1.748578430054353337e-07 0.000000000000000000e+00 4.406562380598564102e-03 -2.162067032710481007e-01 1.052279192866519288e-07 0.000000000000000000e+00 4.590726661412603340e-03 -2.252426702167101280e-01 1.207279972283447134e-07 0.000000000000000000e+00 4.782587754253420607e-03 -2.346562790088451700e-01 1.538042650955484403e-07 0.000000000000000000e+00 4.982467333417002313e-03 -2.444633125033515431e-01 2.521547835091313121e-07 0.000000000000000000e+00 5.190700516992979158e-03 -2.546802131719588802e-01 2.588416113893713325e-07 0.000000000000000000e+00 5.407636428723615156e-03 -2.653241106696743179e-01 9.730928539681922884e-08 0.000000000000000000e+00 5.633638783344635526e-03 -2.764128505543612668e-01 3.779049549799957986e-08 0.000000000000000000e+00 5.869086496389332337e-03 -2.879650242066011945e-01 3.707321909920906896e-08 0.000000000000000000e+00 6.114374319478338426e-03 -2.999999999999999334e-01 6.224636414855785008e-08 0.000000000000000000e+00 6.369913502160142078e-03 \ No newline at end of file diff --git a/tests/test_data/ORSO/test_5.dat b/tests/test_data/ORSO/test_5.dat deleted file mode 100644 index 66e943fc..00000000 --- a/tests/test_data/ORSO/test_5.dat +++ /dev/null @@ -1,101 +0,0 @@ -4.999999999999999237e-03 9.995347418414392004e-01 0.000000000000000000e+00 1.061652250360023761e-04 -5.208965929570049704e-03 9.995347418414394225e-01 0.000000000000000000e+00 1.106022080235347408e-04 -5.426665211084315613e-03 9.995347418414394225e-01 0.000000000000000000e+00 1.152246266659623608e-04 -5.653462839144248603e-03 9.995347418414394225e-01 0.000000000000000000e+00 1.200402309100852380e-04 -5.889739062638551202e-03 9.995347418414394225e-01 0.000000000000000000e+00 1.250570945976711191e-04 -6.135890022268412555e-03 9.995347418414394225e-01 0.000000000000000000e+00 1.302836290020575514e-04 -6.392328414716996060e-03 9.995347418414394225e-01 0.000000000000000000e+00 1.357285969304924749e-04 -6.659484184576673627e-03 9.995347418414394225e-01 0.000000000000000000e+00 1.414011274158563051e-04 -6.937805245194089872e-03 9.995347418414394225e-01 0.000000000000000000e+00 1.473107310223976691e-04 -7.227758229641680597e-03 9.995347418414394225e-01 0.000000000000000000e+00 1.534673157911454707e-04 -7.529829273074612438e-03 9.995347418414394225e-01 0.000000000000000000e+00 1.598812038517289096e-04 -7.844524827784976270e-03 9.995347418414394225e-01 0.000000000000000000e+00 1.665631487284599923e-04 -8.172372512319661317e-03 9.995347418414394225e-01 0.000000000000000000e+00 1.735243533696914056e-04 -8.513921996085575816e-03 9.995347418414394225e-01 0.000000000000000000e+00 1.807764889306791788e-04 -8.869745920925360336e-03 9.995347418414394225e-01 0.000000000000000000e+00 1.883317143414410305e-04 -9.240440861208627787e-03 9.995347418414394225e-01 0.000000000000000000e+00 1.962026966924171388e-04 -9.626628324048536189e-03 9.995347409441184272e-01 0.000000000000000000e+00 2.044026324721134858e-04 -1.002895579132056722e-02 9.995345972239910726e-01 0.000000000000000000e+00 2.129452696923334900e-04 -1.044809780523061650e-02 9.995335809338743438e-01 0.000000000000000000e+00 2.218449309380942302e-04 -1.088475709925237553e-02 9.995319376173226189e-01 0.000000000000000000e+00 2.311165373808706110e-04 -1.133966577633027141e-02 9.995294782765237196e-01 0.000000000000000000e+00 2.407756337954316216e-04 -1.181358653632318123e-02 9.995252951907817041e-01 0.000000000000000000e+00 2.508384146222077419e-04 -1.230731395474697620e-02 9.995177248225737276e-01 0.000000000000000000e+00 2.613217511188890515e-04 -1.282167581495980910e-02 9.995032338579179498e-01 0.000000000000000000e+00 2.722432196467755149e-04 -1.335753449602358582e-02 9.994736896749567556e-01 0.000000000000000000e+00 2.836211311393017432e-04 -1.391578841856870238e-02 9.994086786140352618e-01 0.000000000000000000e+00 2.954745618021484190e-04 -1.449737355108597463e-02 9.992511445455712904e-01 0.000000000000000000e+00 3.078233850964063527e-04 -1.510326497917135677e-02 9.988174516917052159e-01 0.000000000000000000e+00 3.206883050584202191e-04 -1.573447854035441712e-02 9.973868504651979272e-01 0.000000000000000000e+00 3.340908910121754400e-04 -1.639207252725145142e-02 9.910958762816924894e-01 0.000000000000000000e+00 3.480536137324245511e-04 -1.707714946189881067e-02 9.456679331164480340e-01 0.000000000000000000e+00 3.625998831191868982e-04 -1.779085794424128605e-02 6.239075595183121159e-01 0.000000000000000000e+00 3.777540874467854378e-04 -1.853439457787469519e-02 2.220532757094483278e-01 0.000000000000000000e+00 3.935416342532259133e-04 -1.930900597627142543e-02 3.395812773155912900e-01 0.000000000000000000e+00 4.099889929384741916e-04 -2.011599085285246946e-02 2.639596573194147311e-01 0.000000000000000000e+00 4.271237391430496191e-04 -2.095670219841026111e-02 7.370336814121217217e-02 0.000000000000000000e+00 4.449746009813422727e-04 -2.183254954953296745e-02 5.762829676915928734e-02 0.000000000000000000e+00 4.635715072071680543e-04 -2.274500135183342431e-02 1.289775859050606155e-01 0.000000000000000000e+00 4.829456373923148504e-04 -2.369558742194500037e-02 1.161359991837665612e-01 0.000000000000000000e+00 5.031294742022117319e-04 -2.468590151241202915e-02 4.324968283846475359e-02 0.000000000000000000e+00 5.241568578563629999e-04 -2.571760398377520920e-02 1.474300569008134970e-02 0.000000000000000000e+00 5.460630428648573405e-04 -2.679242458833201376e-02 4.585137031529725599e-02 0.000000000000000000e+00 5.688847571360784120e-04 -2.791216537023925512e-02 6.062808398501595697e-02 0.000000000000000000e+00 5.926602635547127294e-04 -2.907870368682024739e-02 3.224250745146049757e-02 0.000000000000000000e+00 6.174294241333008141e-04 -3.029399535614193950e-02 7.770236822814377206e-03 0.000000000000000000e+00 6.432337668448841412e-04 -3.156007793613933854e-02 1.995369062054090648e-02 0.000000000000000000e+00 6.701165552488013702e-04 -3.287907414078505841e-02 3.387854049698348080e-02 0.000000000000000000e+00 6.981228610263705585e-04 -3.425319539903139837e-02 1.989645066231699594e-02 0.000000000000000000e+00 7.272996395480660261e-04 -3.568474556249201513e-02 5.320064115781057701e-03 0.000000000000000000e+00 7.576958085988904973e-04 -3.717612476807939659e-02 1.517416261117541035e-02 0.000000000000000000e+00 7.893623303939302548e-04 -3.872983346207417577e-02 2.188266883156762474e-02 0.000000000000000000e+00 8.223522970216000675e-04 -4.034847659237329048e-02 9.035769538976985357e-03 0.000000000000000000e+00 8.567210194578371010e-04 -4.203476797594541542e-02 6.566239737102203683e-03 0.000000000000000000e+00 8.925261203004783862e-04 -4.379153484881635749e-02 1.737568809464553818e-02 0.000000000000000000e+00 9.298276303793059786e-04 -4.562172260621279868e-02 1.142390005087293506e-02 0.000000000000000000e+00 9.686880894037319147e-04 -4.752839974081164709e-02 5.661994425118474332e-03 0.000000000000000000e+00 1.009172650816869167e-03 -4.951476298737475523e-02 1.686894590267987853e-02 0.000000000000000000e+00 1.051349191031792632e-03 -5.158414268239425865e-02 1.193631975965038332e-02 0.000000000000000000e+00 1.095288423233128482e-03 -5.374000834773436097e-02 1.010241440505187972e-02 0.000000000000000000e+00 1.141064015934773043e-03 -5.598597450763168060e-02 2.645723338110145262e-02 0.000000000000000000e+00 1.188752716492522165e-03 -5.832580674880616378e-02 1.765555837309498721e-02 0.000000000000000000e+00 1.238434479778678654e-03 -6.076342803384361668e-02 8.395246909668385715e-02 0.000000000000000000e+00 1.290192602234388778e-03 -6.330292527843461858e-02 2.249088167590238829e-01 0.000000000000000000e+00 1.344113861524451250e-03 -6.594855620349690528e-02 2.273568286412138151e-01 0.000000000000000000e+00 1.400288662028740172e-03 -6.870475647367019212e-02 9.055756469547908416e-02 0.000000000000000000e+00 1.458811186414187651e-03 -7.157614713415108576e-02 1.074761298874900468e-02 0.000000000000000000e+00 1.519779553541433575e-03 -7.456754235833716604e-02 4.016535135742961907e-03 0.000000000000000000e+00 1.583295982970901261e-03 -7.768395751926998605e-02 1.055027197335543137e-03 0.000000000000000000e+00 1.649466966344109589e-03 -8.093061759840886049e-02 6.351678920636424225e-04 0.000000000000000000e+00 1.718403445927546482e-03 -8.431296594583481685e-02 1.882122845669426483e-04 0.000000000000000000e+00 1.790221000618471897e-03 -8.783667340657071165e-02 1.160349347707180187e-04 0.000000000000000000e+00 1.865040039724485304e-03 -9.150764782831966038e-02 4.994818959850997096e-05 0.000000000000000000e+00 1.942986004841762470e-03 -9.533204396656239088e-02 4.092940564544614144e-05 0.000000000000000000e+00 2.024189580170434287e-03 -9.931627380361947310e-02 5.922116090374987904e-05 0.000000000000000000e+00 2.108786911619698213e-03 -1.034670172989808762e-01 1.013197459580711347e-04 0.000000000000000000e+00 2.196919835070051605e-03 -1.077912335889252976e-01 1.540584654263765243e-04 0.000000000000000000e+00 2.288736114175310681e-03 -1.122961726542076877e-01 3.080120592576946490e-04 0.000000000000000000e+00 2.384389688103147591e-03 -1.169893874753767798e-01 8.442185366483938953e-04 0.000000000000000000e+00 2.484040929629491301e-03 -1.218787466961013116e-01 6.748312225586391815e-03 0.000000000000000000e+00 2.587856914019505839e-03 -1.269724478157380210e-01 1.821808508949064598e-02 0.000000000000000000e+00 2.696011699145979719e-03 -1.322790309332581016e-01 5.612466816999907814e-03 0.000000000000000000e+00 2.808686617314733527e-03 -1.378073930655767942e-01 5.615203002698456944e-04 0.000000000000000000e+00 2.926070579286359132e-03 -1.435668030642915372e-01 1.589729787112498021e-04 0.000000000000000000e+00 3.048360391003989995e-03 -1.495669171558374755e-01 6.609542839334061389e-05 0.000000000000000000e+00 3.175761083558122696e-03 -1.558177951311167375e-01 3.043696661106251805e-05 0.000000000000000000e+00 3.308486256941745463e-03 -1.623299172117425582e-01 1.391404828241209817e-05 0.000000000000000000e+00 3.446758438172057518e-03 -1.691142016211787946e-01 5.479625762064427952e-06 0.000000000000000000e+00 3.590809454379265478e-03 -1.761820228902321317e-01 3.690195637097416411e-06 0.000000000000000000e+00 3.740880821487923939e-03 -1.835452309275898974e-01 1.038156605558009023e-04 0.000000000000000000e+00 3.897224149142521597e-03 -1.912161708873765797e-01 2.663393318270543177e-04 0.000000000000000000e+00 4.060101562556204732e-03 -1.992077038670377609e-01 5.698905429184937657e-05 0.000000000000000000e+00 4.229786141989877457e-03 -2.075332284702559316e-01 1.442605642935067086e-05 0.000000000000000000e+00 4.406562380598564102e-03 -2.162067032710481007e-01 1.014307934844652567e-05 0.000000000000000000e+00 4.590726661412603340e-03 -2.252426702167101280e-01 1.027225286682177676e-05 0.000000000000000000e+00 4.782587754253420607e-03 -2.346562790088451700e-01 1.773114047801788005e-05 0.000000000000000000e+00 4.982467333417002313e-03 -2.444633125033515431e-01 1.466511552515621512e-04 0.000000000000000000e+00 5.190700516992979158e-03 -2.546802131719588802e-01 2.479837294688417367e-04 0.000000000000000000e+00 5.407636428723615156e-03 -2.653241106696743179e-01 2.307614876591286497e-05 0.000000000000000000e+00 5.633638783344635526e-03 -2.764128505543612668e-01 8.700467345332319597e-07 0.000000000000000000e+00 5.869086496389332337e-03 -2.879650242066011945e-01 2.489103699592064588e-06 0.000000000000000000e+00 6.114374319478338426e-03 -2.999999999999999334e-01 3.536911877545927558e-05 0.000000000000000000e+00 6.369913502160142078e-03 \ No newline at end of file diff --git a/tests/test_data/ORSO/test_6.dat b/tests/test_data/ORSO/test_6.dat deleted file mode 100644 index 8833a071..00000000 --- a/tests/test_data/ORSO/test_6.dat +++ /dev/null @@ -1,201 +0,0 @@ -4.999999999999999237e-03 9.939755665005451934e-01 0.000000000000000000 -5.103413528987262200e-03 9.938206872422250537e-01 0.000000000000000000 -5.208965929570049704e-03 9.936601836202287874e-01 0.000000000000000000 -5.316701439400301800e-03 9.934937175049458613e-01 0.000000000000000000 -5.426665211084315613e-03 9.933209194694191391e-01 0.000000000000000000 -5.538903331106443881e-03 9.931413848834969027e-01 0.000000000000000000 -5.653462839144248603e-03 9.929546693938089419e-01 0.000000000000000000 -5.770391747783105117e-03 9.927602836719287005e-01 0.000000000000000000 -5.889739062638551202e-03 9.925576872863686173e-01 0.000000000000000000 -6.011554802894874400e-03 9.923462815200732035e-01 0.000000000000000000 -6.135890022268412555e-03 9.921254009119249151e-01 0.000000000000000000 -6.262796830404514410e-03 9.918943032452941511e-01 0.000000000000000000 -6.392328414716996060e-03 9.916521576349313083e-01 0.000000000000000000 -6.524539062679283845e-03 9.913980302700486913e-01 0.000000000000000000 -6.659484184576673627e-03 9.911308672485296123e-01 0.000000000000000000 -6.797220336729060952e-03 9.908494737742563618e-01 0.000000000000000000 -6.937805245194089872e-03 9.905524887713003102e-01 0.000000000000000000 -7.081297829960469560e-03 9.902383536735351877e-01 0.000000000000000000 -7.227758229641680597e-03 9.899052737445386274e-01 0.000000000000000000 -7.377247826680483588e-03 9.895511697240637616e-01 0.000000000000000000 -7.529829273074612438e-03 9.891736168147553521e-01 0.000000000000000000 -7.685566516634660846e-03 9.887697669113257870e-01 0.000000000000000000 -7.844524827784976270e-03 9.883362483726991776e-01 0.000000000000000000 -8.006770826918864839e-03 9.878690352926330354e-01 0.000000000000000000 -8.172372512319661317e-03 9.873632747316588576e-01 0.000000000000000000 -8.341399288659158417e-03 9.868130550727606254e-01 0.000000000000000000 -8.513921996085575816e-03 9.862110904529330924e-01 0.000000000000000000 -8.690012939913081824e-03 9.855482832160168405e-01 0.000000000000000000 -8.869745920925360336e-03 9.848131052091352311e-01 0.000000000000000000 -9.053196266306023574e-03 9.839907034851622658e-01 0.000000000000000000 -9.240440861208627787e-03 9.830615752848420597e-01 0.000000000000000000 -9.431558180979763770e-03 9.819995490664760185e-01 0.000000000000000000 -9.626628324048536189e-03 9.807686081705797587e-01 0.000000000000000000 -9.825733045496255758e-03 9.793177063178200026e-01 0.000000000000000000 -1.002895579132056722e-02 9.775719355257010967e-01 0.000000000000000000 -1.023638173340811301e-02 9.754167044741799408e-01 0.000000000000000000 -1.044809780523061650e-02 9.726676468677111220e-01 0.000000000000000000 -1.066419273827921670e-02 9.690090864274675253e-01 0.000000000000000000 -1.088475709925237553e-02 9.638564236097431071e-01 0.000000000000000000 -1.110988332801295109e-02 9.560115404729649935e-01 0.000000000000000000 -1.133966577633027141e-02 9.426635155412600442e-01 0.000000000000000000 -1.157420074742355857e-02 9.158694970930539858e-01 0.000000000000000000 -1.181358653632318123e-02 8.467900563613481868e-01 0.000000000000000000 -1.205792347106669944e-02 6.216619932274364269e-01 0.000000000000000000 -1.230731395474697620e-02 5.821661115181411272e-01 0.000000000000000000 -1.256186250842989717e-02 8.435669905097354926e-01 0.000000000000000000 -1.282167581495980910e-02 9.092019434673695999e-01 0.000000000000000000 -1.308686276367094191e-02 9.210246389137153322e-01 0.000000000000000000 -1.335753449602358582e-02 9.120296586690502805e-01 0.000000000000000000 -1.363380445218417142e-02 8.849952669956724360e-01 0.000000000000000000 -1.391578841856870238e-02 8.385719278172414359e-01 0.000000000000000000 -1.420360457636956480e-02 8.139242773937437336e-01 0.000000000000000000 -1.449737355108597463e-02 8.715859644793091388e-01 0.000000000000000000 -1.479721846307885565e-02 4.985317241021904322e-01 0.000000000000000000 -1.510326497917135677e-02 3.401588009082476827e-01 0.000000000000000000 -1.541564136531653299e-02 2.676396693660294535e-01 0.000000000000000000 -1.573447854035441712e-02 2.020861609409263238e-01 0.000000000000000000 -1.605991013088091390e-02 1.367692338742153568e-01 0.000000000000000000 -1.639207252725145142e-02 7.721829415316711076e-02 0.000000000000000000 -1.673110494074310506e-02 3.187863256060462225e-02 0.000000000000000000 -1.707714946189881067e-02 6.543490785276955338e-03 0.000000000000000000 -1.743035112007838838e-02 9.464603379006008253e-04 0.000000000000000000 -1.779085794424128605e-02 9.227302773341827802e-03 0.000000000000000000 -1.815882102498629982e-02 2.327806831978219623e-02 0.000000000000000000 -1.853439457787469519e-02 3.604680504919670347e-02 0.000000000000000000 -1.891773600806278752e-02 4.314013305232745898e-02 0.000000000000000000 -1.930900597627142543e-02 4.297620226362990764e-02 0.000000000000000000 -1.970836846611992085e-02 3.630749034796362101e-02 0.000000000000000000 -2.011599085285246946e-02 2.556614766648357753e-02 0.000000000000000000 -2.053204397348627405e-02 1.406805422420995960e-02 0.000000000000000000 -2.095670219841026111e-02 5.020570085276109332e-03 0.000000000000000000 -2.139014350446480708e-02 4.957100751866040222e-04 0.000000000000000000 -2.183254954953296745e-02 7.833324323053738724e-04 0.000000000000000000 -2.228410574867426344e-02 4.477448759505670353e-03 0.000000000000000000 -2.274500135183342431e-02 9.237083924984949845e-03 0.000000000000000000 -2.321542952315606978e-02 1.278728511049758571e-02 0.000000000000000000 -2.369558742194500037e-02 1.370821722795012056e-02 0.000000000000000000 -2.418567628529092947e-02 1.179361709630874847e-02 0.000000000000000000 -2.468590151241202915e-02 7.964736427749346398e-03 0.000000000000000000 -2.519647275073814627e-02 3.812717426040292644e-03 0.000000000000000000 -2.571760398377520920e-02 9.082649390462809369e-04 0.000000000000000000 -2.624951362078702458e-02 1.285814593773583719e-04 0.000000000000000000 -2.679242458833201376e-02 1.313935667385258185e-03 0.000000000000000000 -2.734656442369291784e-02 3.436198959545269313e-03 0.000000000000000000 -2.791216537023925512e-02 5.175377989595004134e-03 0.000000000000000000 -2.848946447476177410e-02 5.581400584745706966e-03 0.000000000000000000 -2.907870368682024739e-02 4.495289227962314359e-03 0.000000000000000000 -2.968012996014608024e-02 2.554920873457094867e-03 0.000000000000000000 -3.029399535614193950e-02 7.994946887251992533e-04 0.000000000000000000 -3.092055714952243392e-02 7.093544504298202448e-05 0.000000000000000000 -3.156007793613933854e-02 5.421551181067894333e-04 0.000000000000000000 -3.221282574303718088e-02 1.662317796867772250e-03 0.000000000000000000 -3.287907414078505841e-02 2.552755307668288284e-03 0.000000000000000000 -3.355910235813154563e-02 2.585832748415986884e-03 0.000000000000000000 -3.425319539903139837e-02 1.768419442519352132e-03 0.000000000000000000 -3.496164416209223552e-02 6.893617187153074175e-04 0.000000000000000000 -3.568474556249201513e-02 7.049139753030966848e-05 0.000000000000000000 -3.642280265641802822e-02 2.342246593656592936e-04 0.000000000000000000 -3.717612476807939659e-02 8.868197312386969346e-04 0.000000000000000000 -3.794502761934698959e-02 1.390076202093149579e-03 0.000000000000000000 -3.872983346207417577e-02 1.297163603890422309e-03 0.000000000000000000 -3.953087121315458641e-02 7.071349944080154541e-04 0.000000000000000000 -4.034847659237329048e-02 1.424891080096753789e-04 0.000000000000000000 -4.118299226310875166e-02 5.705736586050726735e-05 0.000000000000000000 -4.203476797594541542e-02 4.213120510591815892e-04 0.000000000000000000 -4.290416071525609415e-02 7.827561206945531048e-04 0.000000000000000000 -4.379153484881635749e-02 7.412107776810452795e-04 0.000000000000000000 -4.469726228051336403e-02 3.520808896368878699e-04 0.000000000000000000 -4.562172260621279868e-02 3.660740338258279948e-05 0.000000000000000000 -4.656530327285011289e-02 9.711622317495926301e-05 0.000000000000000000 -4.752839974081164709e-02 3.825865652663160404e-04 0.000000000000000000 -4.851141564967457326e-02 4.966031497793727987e-04 0.000000000000000000 -4.951476298737475523e-02 2.935501171426769130e-04 0.000000000000000000 -5.053886226287324784e-02 4.237175408983848341e-05 0.000000000000000000 -5.158414268239425865e-02 4.952981199695478867e-05 0.000000000000000000 -5.265104232930806205e-02 2.462259720310629348e-04 0.000000000000000000 -5.374000834773436097e-02 3.106968633529766832e-04 0.000000000000000000 -5.485149712994322191e-02 1.461716150577979667e-04 0.000000000000000000 -5.598597450763168060e-02 6.347578354762725267e-06 0.000000000000000000 -5.714391594715673844e-02 8.205889274364191641e-05 0.000000000000000000 -5.832580674880616378e-02 2.055995142952439460e-04 0.000000000000000000 -5.953214225019079486e-02 1.515240343105891138e-04 0.000000000000000000 -6.076342803384361668e-02 1.904906210358529525e-05 0.000000000000000000 -6.202018013911232003e-02 3.352624828268177824e-05 0.000000000000000000 -6.330292527843461858e-02 1.335557340988029228e-04 0.000000000000000000 -6.461220105808664071e-02 1.086065805714583096e-04 0.000000000000000000 -6.594855620349690528e-02 1.129765048451848730e-05 0.000000000000000000 -6.731255078922063206e-02 3.063271737054765669e-05 0.000000000000000000 -6.870475647367019212e-02 9.887963123718823862e-05 0.000000000000000000 -7.012575673870077853e-02 5.632428773601654340e-05 0.000000000000000000 -7.157614713415108576e-02 6.527192722904570643e-07 0.000000000000000000 -7.305653552744191537e-02 4.669954817250492789e-05 0.000000000000000000 -7.456754235833716604e-02 6.576102432063088660e-05 0.000000000000000000 -7.610980089897377565e-02 9.673449514336654342e-06 0.000000000000000000 -7.768395751926998605e-02 1.635250774153107923e-05 0.000000000000000000 -7.929067195782288358e-02 5.193080616559815041e-05 0.000000000000000000 -8.093061759840886049e-02 1.572768833490181356e-05 0.000000000000000000 -8.260448175220293232e-02 6.592686908564736290e-06 0.000000000000000000 -8.431296594583481685e-02 3.795770900446226656e-05 0.000000000000000000 -8.605678621540320539e-02 1.285534691168955851e-05 0.000000000000000000 -8.783667340657071165e-02 5.453573693841068081e-06 0.000000000000000000 -8.965337348086573066e-02 2.854475199787521469e-05 0.000000000000000000 -9.150764782831966038e-02 5.814273755634897092e-06 0.000000000000000000 -9.340027358656974310e-02 8.553461155381284414e-06 0.000000000000000000 -9.533204396656239088e-02 1.978747016317828280e-05 0.000000000000000000 -9.730376858499266424e-02 3.305163845243520234e-07 0.000000000000000000 -9.931627380361947310e-02 1.335288284533154904e-05 0.000000000000000000 -1.013704030755990387e-01 8.197906491429931731e-06 0.000000000000000000 -1.034670172989808762e-01 2.616697893983120813e-06 0.000000000000000000 -1.056069951775156918e-01 1.210564653035881141e-05 0.000000000000000000 -1.077912335889252976e-01 1.113740938148492638e-07 0.000000000000000000 -1.100206479607895166e-01 9.123620766428273762e-06 0.000000000000000000 -1.122961726542076877e-01 2.170099724991137433e-06 0.000000000000000000 -1.146187613553946577e-01 4.931285843051425179e-06 0.000000000000000000 -1.169893874753767798e-01 3.897989970791964400e-06 0.000000000000000000 -1.194090445579542303e-01 2.362495177690372946e-06 0.000000000000000000 -1.218787466961013116e-01 4.200394525796327005e-06 0.000000000000000000 -1.243995289569790746e-01 1.292890626519598200e-06 0.000000000000000000 -1.269724478157380210e-01 3.643319459387689401e-06 0.000000000000000000 -1.295985815982934053e-01 1.026372630834993919e-06 0.000000000000000000 -1.322790309332581016e-01 2.739316080758487579e-06 0.000000000000000000 -1.350149192132228115e-01 1.182556523530242899e-06 0.000000000000000000 -1.378073930655767942e-01 1.688025655137954109e-06 0.000000000000000000 -1.406576228330660983e-01 1.578071958865053895e-06 0.000000000000000000 -1.435668030642915372e-01 6.759350727749671926e-07 0.000000000000000000 -1.465361530143510782e-01 1.876217032650562472e-06 0.000000000000000000 -1.495669171558374755e-01 1.558990616278469146e-07 0.000000000000000000 -1.526603657004036996e-01 1.523982276870081789e-06 0.000000000000000000 -1.558177951311167375e-01 5.241653454576845813e-07 0.000000000000000000 -1.590405287458214467e-01 5.401553921646178897e-07 0.000000000000000000 -1.623299172117425582e-01 1.067243554196275687e-06 0.000000000000000000 -1.656873391315579480e-01 1.921193577418163403e-07 0.000000000000000000 -1.691142016211787946e-01 5.611117239272481087e-07 0.000000000000000000 -1.726119408994808146e-01 7.059848770917984486e-07 0.000000000000000000 -1.761820228902321317e-01 1.757294548959623123e-07 0.000000000000000000 -1.798259438364708529e-01 3.292609637211258647e-07 0.000000000000000000 -1.835452309275898974e-01 5.279863247368908290e-07 0.000000000000000000 -1.873414429393908121e-01 2.618484755811921919e-07 0.000000000000000000 -1.912161708873765797e-01 1.300425120922733325e-07 0.000000000000000000 -1.951710386935557040e-01 2.683096600888571270e-07 0.000000000000000000 -1.992077038670377609e-01 3.186616700930325326e-07 0.000000000000000000 -2.033278581987058575e-01 2.080135430240364746e-07 0.000000000000000000 -2.075332284702559316e-01 1.119633461183070299e-07 0.000000000000000000 -2.118255771779018470e-01 1.094045752498844995e-07 0.000000000000000000 -2.162067032710481007e-01 1.462972910961180958e-07 0.000000000000000000 -2.206784429062403075e-01 1.628556908938313585e-07 0.000000000000000000 -2.252426702167101280e-01 1.488243833534163936e-07 0.000000000000000000 -2.299012980978350773e-01 1.212740015851626348e-07 0.000000000000000000 -2.346562790088451700e-01 9.571660091437348363e-08 0.000000000000000000 -2.395096057911101639e-01 7.762407045815986633e-08 0.000000000000000000 -2.444633125033515431e-01 6.607709715055563083e-08 0.000000000000000000 -2.495194752741292099e-01 5.852562871393658698e-08 0.000000000000000000 -2.546802131719588802e-01 5.303544318316800654e-08 0.000000000000000000 -2.599476890934271367e-01 4.864011236713956217e-08 0.000000000000000000 -2.653241106696743179e-01 4.500328267909314749e-08 0.000000000000000000 -2.708117311916259373e-01 4.201132773919712298e-08 0.000000000000000000 -2.764128505543612668e-01 3.946234683388756240e-08 0.000000000000000000 -2.821298162210124638e-01 3.690136829563254986e-08 0.000000000000000000 -2.879650242066011945e-01 3.371552854537424394e-08 0.000000000000000000 -2.939209200822227586e-01 2.959122548394927572e-08 0.000000000000000000 -2.999999999999999334e-01 2.508280697994873666e-08 0.000000000000000000 \ No newline at end of file diff --git a/tests/test_data/ORSO/test_7.dat b/tests/test_data/ORSO/test_7.dat deleted file mode 100644 index 00653f97..00000000 --- a/tests/test_data/ORSO/test_7.dat +++ /dev/null @@ -1,1001 +0,0 @@ -1.000000000000000021e-02 9.940562200389422287e-01 0.000000000000000000 -1.001610733752729410e-02 9.940395345738044508e-01 0.000000000000000000 -1.003224061968681011e-02 9.940227619654243840e-01 0.000000000000000000 -1.004839988826844270e-02 9.940059014156407136e-01 0.000000000000000000 -1.006458518512939361e-02 9.939889521157246888e-01 0.000000000000000000 -1.008079655219430194e-02 9.939719132462083717e-01 0.000000000000000000 -1.009703403145532051e-02 9.939547839766955661e-01 0.000000000000000000 -1.011329766497224246e-02 9.939375634656733016e-01 0.000000000000000000 -1.012958749487261403e-02 9.939202508603199870e-01 0.000000000000000000 -1.014590356335182998e-02 9.939028452963043492e-01 0.000000000000000000 -1.016224591267325325e-02 9.938853458975890343e-01 0.000000000000000000 -1.017861458516833295e-02 9.938677517762217750e-01 0.000000000000000000 -1.019500962323668762e-02 9.938500620321253365e-01 0.000000000000000000 -1.021143106934623707e-02 9.938322757528823548e-01 0.000000000000000000 -1.022787896603330297e-02 9.938143920135202869e-01 0.000000000000000000 -1.024435335590272340e-02 9.937964098762798182e-01 0.000000000000000000 -1.026085428162796208e-02 9.937783283903908194e-01 0.000000000000000000 -1.027738178595121420e-02 9.937601465918353139e-01 0.000000000000000000 -1.029393591168353134e-02 9.937418635031123326e-01 0.000000000000000000 -1.031051670170491340e-02 9.937234781329882249e-01 0.000000000000000000 -1.032712419896443003e-02 9.937049894762497448e-01 0.000000000000000000 -1.034375844648033164e-02 9.936863965134431487e-01 0.000000000000000000 -1.036041948734015700e-02 9.936676982106222855e-01 0.000000000000000000 -1.037710736470085111e-02 9.936488935190717076e-01 0.000000000000000000 -1.039382212178886766e-02 9.936299813750372190e-01 0.000000000000000000 -1.041056380190029905e-02 9.936109606994465437e-01 0.000000000000000000 -1.042733244840096142e-02 9.935918303976211119e-01 0.000000000000000000 -1.044412810472653171e-02 9.935725893589855140e-01 0.000000000000000000 -1.046095081438264476e-02 9.935532364567674080e-01 0.000000000000000000 -1.047780062094501308e-02 9.935337705476903203e-01 0.000000000000000000 -1.049467756805953431e-02 9.935141904716596750e-01 0.000000000000000000 -1.051158169944241966e-02 9.934944950514436046e-01 0.000000000000000000 -1.052851305888028409e-02 9.934746830923445460e-01 0.000000000000000000 -1.054547169023027468e-02 9.934547533818615106e-01 0.000000000000000000 -1.056245763742018166e-02 9.934347046893479138e-01 0.000000000000000000 -1.057947094444854942e-02 9.934145357656579689e-01 0.000000000000000000 -1.059651165538479274e-02 9.933942453427851982e-01 0.000000000000000000 -1.061357981436930609e-02 9.933738321334981691e-01 0.000000000000000000 -1.063067546561359891e-02 9.933532948309543587e-01 0.000000000000000000 -1.064779865340037372e-02 9.933326321083211230e-01 0.000000000000000000 -1.066494942208367352e-02 9.933118426183724647e-01 0.000000000000000000 -1.068212781608897551e-02 9.932909249930864659e-01 0.000000000000000000 -1.069933387991331940e-02 9.932698778432285103e-01 0.000000000000000000 -1.071656765812541157e-02 9.932486997579240695e-01 0.000000000000000000 -1.073382919536576378e-02 9.932273893042214974e-01 0.000000000000000000 -1.075111853634677130e-02 9.932059450266431666e-01 0.000000000000000000 -1.076843572585286027e-02 9.931843654467296112e-01 0.000000000000000000 -1.078578080874058841e-02 9.931626490625664605e-01 0.000000000000000000 -1.080315382993876812e-02 9.931407943483010481e-01 0.000000000000000000 -1.082055483444857927e-02 9.931187997536521372e-01 0.000000000000000000 -1.083798386734367847e-02 9.930966637033983302e-01 0.000000000000000000 -1.085544097377034653e-02 9.930743845968578176e-01 0.000000000000000000 -1.087292619894755959e-02 9.930519608073600235e-01 0.000000000000000000 -1.089043958816714175e-02 9.930293906816929361e-01 0.000000000000000000 -1.090798118679386225e-02 9.930066725395447769e-01 0.000000000000000000 -1.092555104026556902e-02 9.929838046729281276e-01 0.000000000000000000 -1.094314919409329276e-02 9.929607853455858502e-01 0.000000000000000000 -1.096077569386136666e-02 9.929376127923890127e-01 0.000000000000000000 -1.097843058522756515e-02 9.929142852187116119e-01 0.000000000000000000 -1.099611391392318893e-02 9.928908007997947482e-01 0.000000000000000000 -1.101382572575320198e-02 9.928671576800842669e-01 0.000000000000000000 -1.103156606659635303e-02 9.928433539725654011e-01 0.000000000000000000 -1.104933498240528479e-02 9.928193877580659965e-01 0.000000000000000000 -1.106713251920665199e-02 9.927952570845456348e-01 0.000000000000000000 -1.108495872310126876e-02 9.927709599663725459e-01 0.000000000000000000 -1.110281364026417979e-02 9.927464943835678790e-01 0.000000000000000000 -1.112069731694481818e-02 9.927218582810352077e-01 0.000000000000000000 -1.113860979946710780e-02 9.926970495677762685e-01 0.000000000000000000 -1.115655113422959165e-02 9.926720661160719494e-01 0.000000000000000000 -1.117452136770554806e-02 9.926469057606484014e-01 0.000000000000000000 -1.119252054644310178e-02 9.926215662978187249e-01 0.000000000000000000 -1.121054871706537483e-02 9.925960454845983438e-01 0.000000000000000000 -1.122860592627056980e-02 9.925703410377985092e-01 0.000000000000000000 -1.124669222083211038e-02 9.925444506330931560e-01 0.000000000000000000 -1.126480764759876449e-02 9.925183719040542307e-01 0.000000000000000000 -1.128295225349475704e-02 9.924921024411711423e-01 0.000000000000000000 -1.130112608551988966e-02 9.924656397908254712e-01 0.000000000000000000 -1.131932919074968638e-02 9.924389814542511346e-01 0.000000000000000000 -1.133756161633548386e-02 9.924121248864569145e-01 0.000000000000000000 -1.135582340950456494e-02 9.923850674951175677e-01 0.000000000000000000 -1.137411461756028877e-02 9.923578066394341812e-01 0.000000000000000000 -1.139243528788220529e-02 9.923303396289574474e-01 0.000000000000000000 -1.141078546792618359e-02 9.923026637223821833e-01 0.000000000000000000 -1.142916520522451948e-02 9.922747761262996624e-01 0.000000000000000000 -1.144757454738609681e-02 9.922466739939164171e-01 0.000000000000000000 -1.146601354209645686e-02 9.922183544237299646e-01 0.000000000000000000 -1.148448223711796487e-02 9.921898144581696721e-01 0.000000000000000000 -1.150298068028991240e-02 9.921610510821921025e-01 0.000000000000000000 -1.152150891952864915e-02 9.921320612218342827e-01 0.000000000000000000 -1.154006700282770616e-02 9.921028417427231183e-01 0.000000000000000000 -1.155865497825791545e-02 9.920733894485386228e-01 0.000000000000000000 -1.157727289396754886e-02 9.920437010794264099e-01 0.000000000000000000 -1.159592079818242208e-02 9.920137733103626676e-01 0.000000000000000000 -1.161459873920603174e-02 9.919836027494693953e-01 0.000000000000000000 -1.163330676541967854e-02 9.919531859362682447e-01 0.000000000000000000 -1.165204492528259562e-02 9.919225193398918394e-01 0.000000000000000000 -1.167081326733206137e-02 9.918915993572234857e-01 0.000000000000000000 -1.168961184018355547e-02 9.918604223109845908e-01 0.000000000000000000 -1.170844069253084568e-02 9.918289844477596873e-01 0.000000000000000000 -1.172729987314613531e-02 9.917972819359520686e-01 0.000000000000000000 -1.174618943088019153e-02 9.917653108636832471e-01 0.000000000000000000 -1.176510941466246338e-02 9.917330672366044819e-01 0.000000000000000000 -1.178405987350120837e-02 9.917005469756552394e-01 0.000000000000000000 -1.180304085648364171e-02 9.916677459147331675e-01 0.000000000000000000 -1.182205241277602473e-02 9.916346597982891309e-01 0.000000000000000000 -1.184109459162381930e-02 9.916012842788453074e-01 0.000000000000000000 -1.186016744235180928e-02 9.915676149144203588e-01 0.000000000000000000 -1.187927101436422710e-02 9.915336471658759976e-01 0.000000000000000000 -1.189840535714488390e-02 9.914993763941623017e-01 0.000000000000000000 -1.191757052025728750e-02 9.914647978574719911e-01 0.000000000000000000 -1.193676655334480023e-02 9.914299067082980033e-01 0.000000000000000000 -1.195599350613072397e-02 9.913946979903821566e-01 0.000000000000000000 -1.197525142841846142e-02 9.913591666355597853e-01 0.000000000000000000 -1.199454037009163761e-02 9.913233074604886896e-01 0.000000000000000000 -1.201386038111421951e-02 9.912871151632653977e-01 0.000000000000000000 -1.203321151153065836e-02 9.912505843199136413e-01 0.000000000000000000 -1.205259381146600757e-02 9.912137093807517063e-01 0.000000000000000000 -1.207200733112607366e-02 9.911764846666198947e-01 0.000000000000000000 -1.209145212079751515e-02 9.911389043649765362e-01 0.000000000000000000 -1.211092823084799520e-02 9.911009625258472289e-01 0.000000000000000000 -1.213043571172630480e-02 9.910626530576176485e-01 0.000000000000000000 -1.214997461396249805e-02 9.910239697226763678e-01 0.000000000000000000 -1.216954498816801185e-02 9.909849061328882547e-01 0.000000000000000000 -1.218914688503580819e-02 9.909454557449002277e-01 0.000000000000000000 -1.220878035534051116e-02 9.909056118552631576e-01 0.000000000000000000 -1.222844544993851798e-02 9.908653675953659201e-01 0.000000000000000000 -1.224814221976814471e-02 9.908247159261790449e-01 0.000000000000000000 -1.226787071584975464e-02 9.907836496327814269e-01 0.000000000000000000 -1.228763098928589530e-02 9.907421613186899734e-01 0.000000000000000000 -1.230742309126141645e-02 9.907002433999422264e-01 0.000000000000000000 -1.232724707304363142e-02 9.906578880989652669e-01 0.000000000000000000 -1.234710298598241766e-02 9.906150874381811633e-01 0.000000000000000000 -1.236699088151036602e-02 9.905718332333633969e-01 0.000000000000000000 -1.238691081114291249e-02 9.905281170867218377e-01 0.000000000000000000 -1.240686282647846840e-02 9.904839303797009498e-01 0.000000000000000000 -1.242684697919855565e-02 9.904392642654831214e-01 0.000000000000000000 -1.244686332106795419e-02 9.903941096611775796e-01 0.000000000000000000 -1.246691190393480787e-02 9.903484572396897834e-01 0.000000000000000000 -1.248699277973078052e-02 9.903022974212324359e-01 0.000000000000000000 -1.250710600047118086e-02 9.902556203644956589e-01 0.000000000000000000 -1.252725161825510476e-02 9.902084159574188194e-01 0.000000000000000000 -1.254742968526556188e-02 9.901606738075762193e-01 0.000000000000000000 -1.256764025376961268e-02 9.901123832321491181e-01 0.000000000000000000 -1.258788337611851937e-02 9.900635332474392314e-01 0.000000000000000000 -1.260815910474785521e-02 9.900141125579408063e-01 0.000000000000000000 -1.262846749217765539e-02 9.899641095449109862e-01 0.000000000000000000 -1.264880859101255237e-02 9.899135122544390208e-01 0.000000000000000000 -1.266918245394190942e-02 9.898623083849681370e-01 0.000000000000000000 -1.268958913373996120e-02 9.898104852742516391e-01 0.000000000000000000 -1.271002868326593857e-02 9.897580298857154846e-01 0.000000000000000000 -1.273050115546423347e-02 9.897049287941798168e-01 0.000000000000000000 -1.275100660336450122e-02 9.896511681709231345e-01 0.000000000000000000 -1.277154508008181664e-02 9.895967337680466880e-01 0.000000000000000000 -1.279211663881680942e-02 9.895416109020814810e-01 0.000000000000000000 -1.281272133285580282e-02 9.894857844368361022e-01 0.000000000000000000 -1.283335921557094382e-02 9.894292387653959020e-01 0.000000000000000000 -1.285403034042036444e-02 9.893719577912655216e-01 0.000000000000000000 -1.287473476094828755e-02 9.893139249085726172e-01 0.000000000000000000 -1.289547253078518647e-02 9.892551229813063562e-01 0.000000000000000000 -1.291624370364791684e-02 9.891955343215191876e-01 0.000000000000000000 -1.293704833333986226e-02 9.891351406664223855e-01 0.000000000000000000 -1.295788647375106448e-02 9.890739231543371757e-01 0.000000000000000000 -1.297875817885836384e-02 9.890118622994078512e-01 0.000000000000000000 -1.299966350272556415e-02 9.889489379650142631e-01 0.000000000000000000 -1.302060249950352973e-02 9.888851293357946437e-01 0.000000000000000000 -1.304157522343035204e-02 9.888204148882162592e-01 0.000000000000000000 -1.306258172883149188e-02 9.887547723595674354e-01 0.000000000000000000 -1.308362207011990776e-02 9.886881787153132262e-01 0.000000000000000000 -1.310469630179619815e-02 9.886206101146768344e-01 0.000000000000000000 -1.312580447844876978e-02 9.885520418743571902e-01 0.000000000000000000 -1.314694665475393473e-02 9.884824484302527914e-01 0.000000000000000000 -1.316812288547607873e-02 9.884118032970653500e-01 0.000000000000000000 -1.318933322546780515e-02 9.883400790256389179e-01 0.000000000000000000 -1.321057772967006161e-02 9.882672471579044826e-01 0.000000000000000000 -1.323185645311229612e-02 9.881932781792416298e-01 0.000000000000000000 -1.325316945091258719e-02 9.881181414681080577e-01 0.000000000000000000 -1.327451677827781555e-02 9.880418052427444309e-01 0.000000000000000000 -1.329589849050375958e-02 9.879642365047466290e-01 0.000000000000000000 -1.331731464297527916e-02 9.878854009793036628e-01 0.000000000000000000 -1.333876529116643714e-02 9.878052630518532329e-01 0.000000000000000000 -1.336025049064065370e-02 9.877237857009182331e-01 0.000000000000000000 -1.338177029705084863e-02 9.876409304268343181e-01 0.000000000000000000 -1.340332476613957310e-02 9.875566571760970858e-01 0.000000000000000000 -1.342491395373918844e-02 9.874709242609889248e-01 0.000000000000000000 -1.344653791577196493e-02 9.873836882741484633e-01 0.000000000000000000 -1.346819670825025531e-02 9.872949039977172436e-01 0.000000000000000000 -1.348989038727663181e-02 9.872045243066398523e-01 0.000000000000000000 -1.351161900904403884e-02 9.871125000656898463e-01 0.000000000000000000 -1.353338262983592652e-02 9.870187800197430805e-01 0.000000000000000000 -1.355518130602639815e-02 9.869233106767653085e-01 0.000000000000000000 -1.357701509408038194e-02 9.868260361829577221e-01 0.000000000000000000 -1.359888405055373513e-02 9.867268981894414814e-01 0.000000000000000000 -1.362078823209341566e-02 9.866258357097974496e-01 0.000000000000000000 -1.364272769543762795e-02 9.865227849677363769e-01 0.000000000000000000 -1.366470249741595817e-02 9.864176792340966227e-01 0.000000000000000000 -1.368671269494955295e-02 9.863104486522745740e-01 0.000000000000000000 -1.370875834505121821e-02 9.862010200511452940e-01 0.000000000000000000 -1.373083950482560309e-02 9.860893167444084728e-01 0.000000000000000000 -1.375295623146933523e-02 9.859752583152083805e-01 0.000000000000000000 -1.377510858227117344e-02 9.858587603847521752e-01 0.000000000000000000 -1.379729661461214993e-02 9.857397343635446729e-01 0.000000000000000000 -1.381952038596571952e-02 9.856180871836965895e-01 0.000000000000000000 -1.384177995389792616e-02 9.854937210106154977e-01 0.000000000000000000 -1.386407537606752262e-02 9.853665329322347510e-01 0.000000000000000000 -1.388640671022614050e-02 9.852364146237021503e-01 0.000000000000000000 -1.390877401421842900e-02 9.851032519852750413e-01 0.000000000000000000 -1.393117734598221628e-02 9.849669247509126313e-01 0.000000000000000000 -1.395361676354864994e-02 9.848273060647725341e-01 0.000000000000000000 -1.397609232504234099e-02 9.846842620225366716e-01 0.000000000000000000 -1.399860408868154951e-02 9.845376511741443792e-01 0.000000000000000000 -1.402115211277828524e-02 9.843873239841305356e-01 0.000000000000000000 -1.404373645573848972e-02 9.842331222453256645e-01 0.000000000000000000 -1.406635717606218548e-02 9.840748784412020056e-01 0.000000000000000000 -1.408901433234361657e-02 9.839124150516095346e-01 0.000000000000000000 -1.411170798327140985e-02 9.837455437959955473e-01 0.000000000000000000 -1.413443818762871902e-02 9.835740648075378401e-01 0.000000000000000000 -1.415720500429340153e-02 9.833977657308051734e-01 0.000000000000000000 -1.418000849223812615e-02 9.832164207346368867e-01 0.000000000000000000 -1.420284871053056376e-02 9.830297894309598661e-01 0.000000000000000000 -1.422572571833352444e-02 9.828376156890185067e-01 0.000000000000000000 -1.424863957490511528e-02 9.826396263332052294e-01 0.000000000000000000 -1.427159033959889134e-02 9.824355297111144747e-01 0.000000000000000000 -1.429457807186400309e-02 9.822250141166994908e-01 0.000000000000000000 -1.431760283124538027e-02 9.820077460513872980e-01 0.000000000000000000 -1.434066467738384122e-02 9.817833683036709669e-01 0.000000000000000000 -1.436376367001627845e-02 9.815514978250393652e-01 0.000000000000000000 -1.438689986897580264e-02 9.813117233769892422e-01 0.000000000000000000 -1.441007333419189358e-02 9.810636029202710606e-01 0.000000000000000000 -1.443328412569058229e-02 9.808066607133852921e-01 0.000000000000000000 -1.445653230359456552e-02 9.805403840824730155e-01 0.000000000000000000 -1.447981792812338790e-02 9.802642198191179324e-01 0.000000000000000000 -1.450314105959359286e-02 9.799775701559806373e-01 0.000000000000000000 -1.452650175841887700e-02 9.796797882624440623e-01 0.000000000000000000 -1.454990008511024453e-02 9.793701731934139065e-01 0.000000000000000000 -1.457333610027616508e-02 9.790479642136863392e-01 0.000000000000000000 -1.459680986462275065e-02 9.787123344077491849e-01 0.000000000000000000 -1.462032143895387187e-02 9.783623834698973454e-01 0.000000000000000000 -1.464387088417134879e-02 9.779971295518856689e-01 0.000000000000000000 -1.466745826127509485e-02 9.776155000242174875e-01 0.000000000000000000 -1.469108363136327998e-02 9.772163209820038388e-01 0.000000000000000000 -1.471474705563248844e-02 9.767983052961586310e-01 0.000000000000000000 -1.473844859537786454e-02 9.763600389744541141e-01 0.000000000000000000 -1.476218831199330693e-02 9.758999655532609729e-01 0.000000000000000000 -1.478596626697158134e-02 9.754163681879172154e-01 0.000000000000000000 -1.480978252190451143e-02 9.749073490454851498e-01 0.000000000000000000 -1.483363713848312448e-02 9.743708055254284295e-01 0.000000000000000000 -1.485753017849782143e-02 9.738044027380358125e-01 0.000000000000000000 -1.488146170383852253e-02 9.732055415529085041e-01 0.000000000000000000 -1.490543177649483915e-02 9.725713213848794503e-01 0.000000000000000000 -1.492944045855624374e-02 9.718984967052771706e-01 0.000000000000000000 -1.495348781221220516e-02 9.711834260432190558e-01 0.000000000000000000 -1.497757389975236386e-02 9.704220119626489893e-01 0.000000000000000000 -1.500169878356669324e-02 9.696096301507247661e-01 0.000000000000000000 -1.502586252614566444e-02 9.687410453113436404e-01 0.000000000000000000 -1.505006519008039202e-02 9.678103109975366714e-01 0.000000000000000000 -1.507430683806283180e-02 9.668106498024383599e-01 0.000000000000000000 -1.509858753288590046e-02 9.657343094136718875e-01 0.000000000000000000 -1.512290733744365949e-02 9.645723888566992699e-01 0.000000000000000000 -1.514726631473147823e-02 9.633146277241746436e-01 0.000000000000000000 -1.517166452784619868e-02 9.619491491949030415e-01 0.000000000000000000 -1.519610203998627944e-02 9.604621450303264529e-01 0.000000000000000000 -1.522057891445200567e-02 9.588374872824635409e-01 0.000000000000000000 -1.524509521464559487e-02 9.570562468565224634e-01 0.000000000000000000 -1.526965100407139814e-02 9.550960929296685720e-01 0.000000000000000000 -1.529424634633605451e-02 9.529305389558853090e-01 0.000000000000000000 -1.531888130514865755e-02 9.505279897729324023e-01 0.000000000000000000 -1.534355594432091664e-02 9.478505290258955052e-01 0.000000000000000000 -1.536827032776731834e-02 9.448523651135493084e-01 0.000000000000000000 -1.539302451950532238e-02 9.414778248587880594e-01 0.000000000000000000 -1.541781858365548138e-02 9.376587438728278823e-01 0.000000000000000000 -1.544265258444163513e-02 9.333110466073071265e-01 0.000000000000000000 -1.546752658619106845e-02 9.283302311648128358e-01 0.000000000000000000 -1.549244065333468638e-02 9.225853658482517927e-01 0.000000000000000000 -1.551739485040717036e-02 9.159110560735300721e-01 0.000000000000000000 -1.554238924204714295e-02 9.080966413106291713e-01 0.000000000000000000 -1.556742389299736566e-02 8.988716274248305105e-01 0.000000000000000000 -1.559249886810486381e-02 8.878860677540538759e-01 0.000000000000000000 -1.561761423232111562e-02 8.746843601801463919e-01 0.000000000000000000 -1.564277005070222396e-02 8.586709865800404851e-01 0.000000000000000000 -1.566796638840907419e-02 8.390677845138969637e-01 0.000000000000000000 -1.569320331070751459e-02 8.148661622090488388e-01 0.000000000000000000 -1.571848088296850729e-02 7.847883936518198489e-01 0.000000000000000000 -1.574379917066833640e-02 7.472988432733710384e-01 0.000000000000000000 -1.576915823938872599e-02 7.007658386828663488e-01 0.000000000000000000 -1.579455815481704134e-02 6.439892781247459341e-01 0.000000000000000000 -1.581999898274645197e-02 5.774576900379768674e-01 0.000000000000000000 -1.584548078907610860e-02 5.056427377844019411e-01 0.000000000000000000 -1.587100363981128887e-02 4.396235641851662379e-01 0.000000000000000000 -1.589656760106362629e-02 3.966991097101011943e-01 0.000000000000000000 -1.592217273905120398e-02 3.925698079642124250e-01 0.000000000000000000 -1.594781912009878011e-02 4.296123793399831414e-01 0.000000000000000000 -1.597350681063794756e-02 4.945868106718255275e-01 0.000000000000000000 -1.599923587720729692e-02 5.690160140720793569e-01 0.000000000000000000 -1.602500638645258310e-02 6.394431378073742733e-01 0.000000000000000000 -1.605081840512694730e-02 6.997695626570558103e-01 0.000000000000000000 -1.607667200009101766e-02 7.488763884389497694e-01 0.000000000000000000 -1.610256723831312436e-02 7.879150245504279448e-01 0.000000000000000000 -1.612850418686946966e-02 8.186887252991870145e-01 0.000000000000000000 -1.615448291294429781e-02 8.429423881623353543e-01 0.000000000000000000 -1.618050348383006862e-02 8.621339303238243490e-01 0.000000000000000000 -1.620656596692762047e-02 8.774088049729275030e-01 0.000000000000000000 -1.623267042974638544e-02 8.896430768743078810e-01 0.000000000000000000 -1.625881693990451071e-02 8.994999793796369936e-01 0.000000000000000000 -1.628500556512906330e-02 9.074808656390431771e-01 0.000000000000000000 -1.631123637325620351e-02 9.139658992415667926e-01 0.000000000000000000 -1.633750943223135493e-02 9.192449249978390524e-01 0.000000000000000000 -1.636382481010938486e-02 9.235403579677438080e-01 0.000000000000000000 -1.639018257505477083e-02 9.270240005266869865e-01 0.000000000000000000 -1.641658279534181225e-02 9.298293767208087868e-01 0.000000000000000000 -1.644302553935474490e-02 9.320607995604727192e-01 0.000000000000000000 -1.646951087558797683e-02 9.338000661774862321e-01 0.000000000000000000 -1.649603887264623064e-02 9.351114280525631983e-01 0.000000000000000000 -1.652260959924473777e-02 9.360453010045299838e-01 0.000000000000000000 -1.654922312420941191e-02 9.366410481315422532e-01 0.000000000000000000 -1.657587951647701910e-02 9.369290750758679787e-01 0.000000000000000000 -1.660257884509538234e-02 9.369324102437187607e-01 0.000000000000000000 -1.662932117922353084e-02 9.366678950852094232e-01 0.000000000000000000 -1.665610658813188386e-02 9.361470755902192575e-01 0.000000000000000000 -1.668293514120244500e-02 9.353768618183803119e-01 0.000000000000000000 -1.670980690792896878e-02 9.343600047986874158e-01 0.000000000000000000 -1.673672195791716180e-02 9.330954276116429913e-01 0.000000000000000000 -1.676368036088482505e-02 9.315784386282468521e-01 0.000000000000000000 -1.679068218666206896e-02 9.298008489039230051e-01 0.000000000000000000 -1.681772750519147999e-02 9.277510121416029376e-01 0.000000000000000000 -1.684481638652829752e-02 9.254138042728138336e-01 0.000000000000000000 -1.687194890084060817e-02 9.227705606634446500e-01 0.000000000000000000 -1.689912511840950884e-02 9.197989926316789688e-01 0.000000000000000000 -1.692634510962932881e-02 9.164731121102367428e-01 0.000000000000000000 -1.695360894500775456e-02 9.127632050476167658e-01 0.000000000000000000 -1.698091669516605534e-02 9.086359121772977776e-01 0.000000000000000000 -1.700826843083924622e-02 9.040545023158205185e-01 0.000000000000000000 -1.703566422287627891e-02 8.989794611700537841e-01 0.000000000000000000 -1.706310414224023256e-02 8.933695708676211433e-01 0.000000000000000000 -1.709058826000846645e-02 8.871837248187680602e-01 0.000000000000000000 -1.711811664737286284e-02 8.803838097438310140e-01 0.000000000000000000 -1.714568937563994491e-02 8.729390868741854215e-01 0.000000000000000000 -1.717330651623110230e-02 8.648326005897848390e-01 0.000000000000000000 -1.720096814068276456e-02 8.560701955960102749e-01 0.000000000000000000 -1.722867432064658505e-02 8.466926558178456963e-01 0.000000000000000000 -1.725642512788963523e-02 8.367911578899470681e-01 0.000000000000000000 -1.728422063429456423e-02 8.265254687226619712e-01 0.000000000000000000 -1.731206091185984522e-02 8.161428972821311856e-01 0.000000000000000000 -1.733994603269988638e-02 8.059938308258028927e-01 0.000000000000000000 -1.736787606904526340e-02 7.965370230300987675e-01 0.000000000000000000 -1.739585109324289641e-02 7.883256966392956366e-01 0.000000000000000000 -1.742387117775623731e-02 7.819659866141922544e-01 0.000000000000000000 -1.745193639516545714e-02 7.780446799691850268e-01 0.000000000000000000 -1.748004681816762995e-02 7.770344752131898014e-01 0.000000000000000000 -1.750820251957694099e-02 7.791988262097384599e-01 0.000000000000000000 -1.753640357232484626e-02 7.845269120091042936e-01 0.000000000000000000 -1.756465004946027378e-02 7.927242038190153162e-01 0.000000000000000000 -1.759294202414982133e-02 8.032647439348401530e-01 0.000000000000000000 -1.762127956967792300e-02 8.154875284989805406e-01 0.000000000000000000 -1.764966275944708507e-02 8.287051441358848081e-01 0.000000000000000000 -1.767809166697801790e-02 8.422947864143098817e-01 0.000000000000000000 -1.770656636590986141e-02 8.557555424504237340e-01 0.000000000000000000 -1.773508693000037592e-02 8.687315613459980490e-01 0.000000000000000000 -1.776365343312611908e-02 8.810115946331938952e-01 0.000000000000000000 -1.779226594928264363e-02 8.925213279664037103e-01 0.000000000000000000 -1.782092455258468128e-02 9.033352912671933632e-01 0.000000000000000000 -1.784962931726637517e-02 9.138047506597195557e-01 0.000000000000000000 -1.787838031768140476e-02 9.266153715817254666e-01 0.000000000000000000 -1.790717762830322871e-02 6.775176493896506447e-01 0.000000000000000000 -1.793602132372525484e-02 6.018475785521723020e-01 0.000000000000000000 -1.796491147866105531e-02 5.554174544314203210e-01 0.000000000000000000 -1.799384816794452960e-02 5.226572367654968021e-01 0.000000000000000000 -1.802283146653011967e-02 4.977945722840035336e-01 0.000000000000000000 -1.805186144949301116e-02 4.779850261475416806e-01 0.000000000000000000 -1.808093819202930691e-02 4.616079513347511876e-01 0.000000000000000000 -1.811006176945622118e-02 4.476531530688140359e-01 0.000000000000000000 -1.813923225721229826e-02 4.354510387369498470e-01 0.000000000000000000 -1.816844973085758944e-02 4.245374818760679902e-01 0.000000000000000000 -1.819771426607385070e-02 4.145796768998394888e-01 0.000000000000000000 -1.822702593866473014e-02 4.053325875157672287e-01 0.000000000000000000 -1.825638482455601425e-02 3.966119749957613405e-01 0.000000000000000000 -1.828579099979574241e-02 3.882769730393704211e-01 0.000000000000000000 -1.831524454055447060e-02 3.802184347972591416e-01 0.000000000000000000 -1.834474552312543444e-02 3.723509133738286958e-01 0.000000000000000000 -1.837429402392475389e-02 3.646070081598016821e-01 0.000000000000000000 -1.840389011949167264e-02 3.569332965399628077e-01 0.000000000000000000 -1.843353388648865179e-02 3.492873545951443170e-01 0.000000000000000000 -1.846322540170170293e-02 3.416355420678682253e-01 0.000000000000000000 -1.849296474204047483e-02 3.339513338367857687e-01 0.000000000000000000 -1.852275198453851371e-02 3.262140486419027319e-01 0.000000000000000000 -1.855258720635344707e-02 3.184078707210553638e-01 0.000000000000000000 -1.858247048476716415e-02 3.105210901048606198e-01 0.000000000000000000 -1.861240189718608648e-02 3.025455078550745025e-01 0.000000000000000000 -1.864238152114124081e-02 2.944759667913020018e-01 0.000000000000000000 -1.867240943428860253e-02 2.863099783054011138e-01 0.000000000000000000 -1.870248571440919286e-02 2.780474230530058932e-01 0.000000000000000000 -1.873261043940933207e-02 2.696903085198437688e-01 0.000000000000000000 -1.876278368732081994e-02 2.612425702804748728e-01 0.000000000000000000 -1.879300553630114043e-02 2.527099066019058426e-01 0.000000000000000000 -1.882327606463369066e-02 2.440996381741200039e-01 0.000000000000000000 -1.885359535072794052e-02 2.354205863699268542e-01 0.000000000000000000 -1.888396347311966164e-02 2.266829646870217874e-01 0.000000000000000000 -1.891438051047112517e-02 2.178982790064369623e-01 0.000000000000000000 -1.894484654157130646e-02 2.090792330863608106e-01 0.000000000000000000 -1.897536164533609668e-02 2.002396363525043299e-01 0.000000000000000000 -1.900592590080847633e-02 1.913943115851661769e-01 0.000000000000000000 -1.903653938715878235e-02 1.825590005682446726e-01 0.000000000000000000 -1.906720218368484002e-02 1.737502661783084101e-01 0.000000000000000000 -1.909791436981221960e-02 1.649853897677093784e-01 0.000000000000000000 -1.912867602509440990e-02 1.562822630460526385e-01 0.000000000000000000 -1.915948722921305761e-02 1.476592739958036415e-01 0.000000000000000000 -1.919034806197813733e-02 1.391351866750305533e-01 0.000000000000000000 -1.922125860332818403e-02 1.307290150644814797e-01 0.000000000000000000 -1.925221893333050466e-02 1.224598914073051215e-01 0.000000000000000000 -1.928322913218135509e-02 1.143469297653379735e-01 0.000000000000000000 -1.931428928020617608e-02 1.064090857726608108e-01 0.000000000000000000 -1.934539945785978404e-02 9.866501380072824345e-02 0.000000000000000000 -1.937655974572658271e-02 9.113292295463991388e-02 0.000000000000000000 -1.940777022452081294e-02 8.383043349198707195e-02 0.000000000000000000 -1.943903097508665329e-02 7.677443538909384246e-02 0.000000000000000000 -1.947034207839858089e-02 6.998095086964359335e-02 0.000000000000000000 -1.950170361556144427e-02 6.346500275453788309e-02 0.000000000000000000 -1.953311566781075481e-02 5.724049048605062140e-02 0.000000000000000000 -1.956457831651286366e-02 5.132007562378638338e-02 0.000000000000000000 -1.959609164316518035e-02 4.571507850443509713e-02 0.000000000000000000 -1.962765572939640518e-02 4.043538760450624686e-02 0.000000000000000000 -1.965927065696669584e-02 3.548938294890888190e-02 0.000000000000000000 -1.969093650776791715e-02 3.088387467390504154e-02 0.000000000000000000 -1.972265336382382842e-02 2.662405758771792252e-02 0.000000000000000000 -1.975442130729032283e-02 2.271348228381557879e-02 0.000000000000000000 -1.978624042045561485e-02 1.915404305970301591e-02 0.000000000000000000 -1.981811078574045176e-02 1.594598258715149500e-02 0.000000000000000000 -1.985003248569837397e-02 1.308791297764429727e-02 0.000000000000000000 -1.988200560301586414e-02 1.057685259840362643e-02 0.000000000000000000 -1.991403022051259700e-02 8.408277727886423469e-03 0.000000000000000000 -1.994610642114165097e-02 6.576187902432598965e-03 0.000000000000000000 -1.997823428798971637e-02 5.073183603543953736e-03 0.000000000000000000 -2.001041390427731742e-02 3.890554772492665816e-03 0.000000000000000000 -2.004264535335901348e-02 3.018378518327578287e-03 0.000000000000000000 -2.007492871872365234e-02 2.445624307944856655e-03 0.000000000000000000 -2.010726408399453671e-02 2.160264892285386918e-03 0.000000000000000000 -2.013965153292967061e-02 2.149391228991257442e-03 0.000000000000000000 -2.017209114942197096e-02 2.399329705904938628e-03 0.000000000000000000 -2.020458301749947921e-02 2.895760047461747467e-03 0.000000000000000000 -2.023712722132559039e-02 3.623832392453384035e-03 0.000000000000000000 -2.026972384519924730e-02 4.568282161456970088e-03 0.000000000000000000 -2.030237297355521470e-02 5.713541479852985404e-03 0.000000000000000000 -2.033507469096422146e-02 7.043846082215088344e-03 0.000000000000000000 -2.036782908213323126e-02 8.543336790629647154e-03 0.000000000000000000 -2.040063623190564723e-02 1.019615482819375384e-02 0.000000000000000000 -2.043349622526152015e-02 1.198653039517281506e-02 0.000000000000000000 -2.046640914731782945e-02 1.389886409523213850e-02 0.000000000000000000 -2.049937508332857344e-02 1.591780094964790129e-02 0.000000000000000000 -2.053239411868515094e-02 1.802829687606424813e-02 0.000000000000000000 -2.056546633891646186e-02 2.021567763327374728e-02 0.000000000000000000 -2.059859182968917443e-02 2.246569034370637236e-02 0.000000000000000000 -2.063177067680795063e-02 2.476454780005069023e-02 0.000000000000000000 -2.066500296621564745e-02 2.709896584176091708e-02 0.000000000000000000 -2.069828878399358404e-02 2.945619415144215200e-02 0.000000000000000000 -2.073162821636170480e-02 3.182404087092162437e-02 0.000000000000000000 -2.076502134967883606e-02 3.419089147326195843e-02 0.000000000000000000 -2.079846827044291163e-02 3.654572235110705586e-02 0.000000000000000000 -2.083196906529118445e-02 3.887810959495084651e-02 0.000000000000000000 -2.086552382100046593e-02 4.117823343847951123e-02 0.000000000000000000 -2.089913262448732031e-02 4.343687884343003236e-02 0.000000000000000000 -2.093279556280834910e-02 4.564543268478633842e-02 0.000000000000000000 -2.096651272316035070e-02 4.779587797982252223e-02 0.000000000000000000 -2.100028419288057363e-02 4.988078558275625685e-02 0.000000000000000000 -2.103411005944695600e-02 5.189330374160541076e-02 0.000000000000000000 -2.106799041047833360e-02 5.382714588625758106e-02 0.000000000000000000 -2.110192533373467239e-02 5.567657698763359836e-02 0.000000000000000000 -2.113591491711728360e-02 5.743639879783765667e-02 0.000000000000000000 -2.116995924866910128e-02 5.910193425102180237e-02 0.000000000000000000 -2.120405841657483845e-02 6.066901127480865685e-02 0.000000000000000000 -2.123821250916126113e-02 6.213394623300408370e-02 0.000000000000000000 -2.127242161489740699e-02 6.349352719222720043e-02 0.000000000000000000 -2.130668582239481426e-02 6.474499717832669921e-02 0.000000000000000000 -2.134100522040774731e-02 6.588603756315698778e-02 0.000000000000000000 -2.137537989783342210e-02 6.691475169860013061e-02 0.000000000000000000 -2.140980994371227686e-02 6.782964889270751141e-02 0.000000000000000000 -2.144429544722813510e-02 6.862962880251272102e-02 0.000000000000000000 -2.147883649770848669e-02 6.931396629945783816e-02 0.000000000000000000 -2.151343318462470289e-02 6.988229684640079320e-02 0.000000000000000000 -2.154808559759225500e-02 7.033460240983729905e-02 0.000000000000000000 -2.158279382637101271e-02 7.067119791716562627e-02 0.000000000000000000 -2.161755796086533774e-02 7.089271825649855197e-02 0.000000000000000000 -2.165237809112448633e-02 7.100010580560729700e-02 0.000000000000000000 -2.168725430734272028e-02 7.099459846696178078e-02 0.000000000000000000 -2.172218669985958445e-02 7.087771817747723357e-02 0.000000000000000000 -2.175717535916013579e-02 7.065125985436224165e-02 0.000000000000000000 -2.179222037587517924e-02 7.031728073236519216e-02 0.000000000000000000 -2.182732184078151755e-02 6.987809004263391410e-02 0.000000000000000000 -2.186247984480215248e-02 6.933623897930769886e-02 0.000000000000000000 -2.189769447900654156e-02 6.869451089677766631e-02 0.000000000000000000 -2.193296583461083402e-02 6.795591167825965062e-02 0.000000000000000000 -2.196829400297810320e-02 6.712366021486611267e-02 0.000000000000000000 -2.200367907561858252e-02 6.620117893372223783e-02 0.000000000000000000 -2.203912114418989793e-02 6.519208431381658120e-02 0.000000000000000000 -2.207462030049733848e-02 6.410017732918144029e-02 0.000000000000000000 -2.211017663649403331e-02 6.292943376065886218e-02 0.000000000000000000 -2.214579024428124307e-02 6.168399431988198095e-02 0.000000000000000000 -2.218146121610857502e-02 6.036815453221046346e-02 0.000000000000000000 -2.221718964437421895e-02 5.898635432914560439e-02 0.000000000000000000 -2.225297562162520393e-02 5.754316730522892470e-02 0.000000000000000000 -2.228881924055760647e-02 5.604328959956503958e-02 0.000000000000000000 -2.232472059401685929e-02 5.449152836786089193e-02 0.000000000000000000 -2.236067977499789708e-02 5.289278981726330126e-02 0.000000000000000000 -2.239669687664545827e-02 5.125206678316865383e-02 0.000000000000000000 -2.243277199225432103e-02 4.957442583464641284e-02 0.000000000000000000 -2.246890521526951831e-02 4.786499390299898959e-02 0.000000000000000000 -2.250509663928663973e-02 4.612894443626860963e-02 0.000000000000000000 -2.254134635805196685e-02 4.437148309111829669e-02 0.000000000000000000 -2.257765446546284444e-02 4.259783298232392573e-02 0.000000000000000000 -2.261402105556782616e-02 4.081321951911906498e-02 0.000000000000000000 -2.265044622256696602e-02 3.902285486660649755e-02 0.000000000000000000 -2.268693006081203695e-02 3.723192207939168830e-02 0.000000000000000000 -2.272347266480678404e-02 3.544555896330729705e-02 0.000000000000000000 -2.276007412920722645e-02 3.366884172949598242e-02 0.000000000000000000 -2.279673454882175099e-02 3.190676851307557016e-02 0.000000000000000000 -2.283345401861155283e-02 3.016424283593699060e-02 0.000000000000000000 -2.287023263369072565e-02 2.844605709993438050e-02 0.000000000000000000 -2.290707048932658432e-02 2.675687620248052082e-02 0.000000000000000000 -2.294396768093989389e-02 2.510122137147208221e-02 0.000000000000000000 -2.298092430410510548e-02 2.348345432024575435e-02 0.000000000000000000 -2.301794045455064774e-02 2.190776182592023280e-02 0.000000000000000000 -2.305501622815910728e-02 2.037814083589424216e-02 0.000000000000000000 -2.309215172096753046e-02 1.889838420736438332e-02 0.000000000000000000 -2.312934702916763854e-02 1.747206718351152627e-02 0.000000000000000000 -2.316660224910611215e-02 1.610253470739056447e-02 0.000000000000000000 -2.320391747728480294e-02 1.479288967061029823e-02 0.000000000000000000 -2.324129281036100420e-02 1.354598218858274992e-02 0.000000000000000000 -2.327872834514771797e-02 1.236439998754786107e-02 0.000000000000000000 -2.331622417861386673e-02 1.125045998077988871e-02 0.000000000000000000 -2.335378040788456747e-02 1.020620110247278008e-02 0.000000000000000000 -2.339139713024137798e-02 9.233378457899649172e-03 0.000000000000000000 -2.342907444312255713e-02 8.333458837681028894e-03 0.000000000000000000 -2.346681244412330419e-02 7.507617632532500619e-03 0.000000000000000000 -2.350461123099601216e-02 6.756737172869813589e-03 0.000000000000000000 -2.354247090165055914e-02 6.081406505298862786e-03 0.000000000000000000 -2.358039155415449922e-02 5.481922605507743955e-03 0.000000000000000000 -2.361837328673335040e-02 4.958293014574076223e-03 0.000000000000000000 -2.365641619777085480e-02 4.510239873419991802e-03 0.000000000000000000 -2.369452038580920766e-02 4.137205318237484677e-03 0.000000000000000000 -2.373268594954937652e-02 3.838358188365355046e-03 0.000000000000000000 -2.377091298785123305e-02 3.612601987469502875e-03 0.000000000000000000 -2.380920159973395900e-02 3.458584029102660610e-03 0.000000000000000000 -2.384755188437618842e-02 3.374705688937303018e-03 0.000000000000000000 -2.388596394111631993e-02 3.359133678252480913e-03 0.000000000000000000 -2.392443786945275264e-02 3.409812246719241737e-03 0.000000000000000000 -2.396297376904414633e-02 3.524476217206966733e-03 0.000000000000000000 -2.400157173970972682e-02 3.700664751270946705e-03 0.000000000000000000 -2.404023188142942469e-02 3.935735741180448714e-03 0.000000000000000000 -2.407895429434428469e-02 4.226880722805153104e-03 0.000000000000000000 -2.411773907875661149e-02 4.571140203347527631e-03 0.000000000000000000 -2.415658633513028883e-02 4.965419298756387247e-03 0.000000000000000000 -2.419549616409100504e-02 5.406503577591974252e-03 0.000000000000000000 -2.423446866642652714e-02 5.891075011067794208e-03 0.000000000000000000 -2.427350394308700615e-02 6.415727932861009335e-03 0.000000000000000000 -2.431260209518514709e-02 6.976984916956278579e-03 0.000000000000000000 -2.435176322399653856e-02 7.571312487165676036e-03 0.000000000000000000 -2.439098743095990604e-02 8.195136577908518349e-03 0.000000000000000000 -2.443027481767735126e-02 8.844857672246077621e-03 0.000000000000000000 -2.446962548591464018e-02 9.516865549912247035e-03 0.000000000000000000 -2.450903953760143889e-02 1.020755358505242433e-02 0.000000000000000000 -2.454851707483163281e-02 1.091333254046931989e-02 0.000000000000000000 -2.458805819986352101e-02 1.163064381227017600e-02 0.000000000000000000 -2.462766301512011452e-02 1.235597208582463365e-02 0.000000000000000000 -2.466733162318941394e-02 1.308585737078308414e-02 0.000000000000000000 -2.470706412682465575e-02 1.381690638949594450e-02 0.000000000000000000 -2.474686062894458291e-02 1.454580329945831356e-02 0.000000000000000000 -2.478672123263370164e-02 1.526931973631066169e-02 0.000000000000000000 -2.482664604114260057e-02 1.598432416942360129e-02 0.000000000000000000 -2.486663515788813464e-02 1.668779056713417738e-02 0.000000000000000000 -2.490668868645375122e-02 1.737680637327905162e-02 0.000000000000000000 -2.494680673058974688e-02 1.804857980074217605e-02 0.000000000000000000 -2.498698939421351364e-02 1.870044645131787794e-02 0.000000000000000000 -2.502723678140987909e-02 1.932987527428086175e-02 0.000000000000000000 -2.506754899643123466e-02 1.993447387864179937e-02 0.000000000000000000 -2.510792614369798323e-02 2.051199321620550062e-02 0.000000000000000000 -2.514836832779867443e-02 2.106033165420233277e-02 0.000000000000000000 -2.518887565349033075e-02 2.157753845751880784e-02 0.000000000000000000 -2.522944822569871473e-02 2.206181670138525688e-02 0.000000000000000000 -2.527008614951857177e-02 2.251152563585242031e-02 0.000000000000000000 -2.531078953021399444e-02 2.292518252352535729e-02 0.000000000000000000 -2.535155847321853007e-02 2.330146397185289472e-02 0.000000000000000000 -2.539239308413563517e-02 2.363920678085301361e-02 0.000000000000000000 -2.543329346873882471e-02 2.393740832648488109e-02 0.000000000000000000 -2.547425973297199470e-02 2.419522649904511449e-02 0.000000000000000000 -2.551529198294968936e-02 2.441197921495901618e-02 0.000000000000000000 -2.555639032495736138e-02 2.458714351922370450e-02 0.000000000000000000 -2.559755486545169795e-02 2.472035429455992500e-02 0.000000000000000000 -2.563878571106082208e-02 2.481140259207790383e-02 0.000000000000000000 -2.568008296858462561e-02 2.486023359699795002e-02 0.000000000000000000 -2.572144674499501557e-02 2.486694424171001505e-02 0.000000000000000000 -2.576287714743621254e-02 2.483178047724211510e-02 0.000000000000000000 -2.580437428322500740e-02 2.475513421306101483e-02 0.000000000000000000 -2.584593825985104926e-02 2.463753993407323192e-02 0.000000000000000000 -2.588756918497715082e-02 2.447967100275066921e-02 0.000000000000000000 -2.592926716643951385e-02 2.428233565349808762e-02 0.000000000000000000 -2.597103231224803452e-02 2.404647268571842578e-02 0.000000000000000000 -2.601286473058659829e-02 2.377314686154139919e-02 0.000000000000000000 -2.605476452981334012e-02 2.346354401386457900e-02 0.000000000000000000 -2.609673181846092899e-02 2.311896587022915089e-02 0.000000000000000000 -2.613876670523683846e-02 2.274082459812173940e-02 0.000000000000000000 -2.618086929902368326e-02 2.233063707756040989e-02 0.000000000000000000 -2.622303970887941704e-02 2.189001890729603758e-02 0.000000000000000000 -2.626527804403767236e-02 2.142067815162520053e-02 0.000000000000000000 -2.630758441390802782e-02 2.092440883568306639e-02 0.000000000000000000 -2.634995892807627527e-02 2.040308419813899321e-02 0.000000000000000000 -2.639240169630477362e-02 1.985864971145204910e-02 0.000000000000000000 -2.643491282853259114e-02 1.929311588125566870e-02 0.000000000000000000 -2.647749243487597035e-02 1.870855083798069959e-02 0.000000000000000000 -2.652014062562845984e-02 1.810707273553530811e-02 0.000000000000000000 -2.656285751126129246e-02 1.749084197364038709e-02 0.000000000000000000 -2.660564320242362127e-02 1.686205326232371668e-02 0.000000000000000000 -2.664849780994282824e-02 1.622292754901808950e-02 0.000000000000000000 -2.669142144482484005e-02 1.557570383069803790e-02 0.000000000000000000 -2.673441421825434663e-02 1.492263087548128392e-02 0.000000000000000000 -2.677747624159513770e-02 1.426595888007766051e-02 0.000000000000000000 -2.682060762639038379e-02 1.360793109137827320e-02 0.000000000000000000 -2.686380848436292421e-02 1.295077542228293722e-02 0.000000000000000000 -2.690707892741554461e-02 1.229669609355025887e-02 0.000000000000000000 -2.695041906763127534e-02 1.164786533497862327e-02 0.000000000000000000 -2.699382901727371067e-02 1.100641518055823359e-02 0.000000000000000000 -2.703730888878724120e-02 1.037442939335044521e-02 0.000000000000000000 -2.708085879479738001e-02 9.753935556703254711e-03 0.000000000000000000 -2.712447884811106102e-02 9.146897369002577813e-03 0.000000000000000000 -2.716816916171690618e-02 8.555207179437770634e-03 0.000000000000000000 -2.721192984878554808e-02 7.980678802223421103e-03 0.000000000000000000 -2.725576102266987627e-02 7.425040646350414102e-03 0.000000000000000000 -2.729966279690541897e-02 6.889929197215264450e-03 0.000000000000000000 -2.734363528521052689e-02 6.376882885414298686e-03 0.000000000000000000 -2.738767860148673752e-02 5.887336376554217453e-03 0.000000000000000000 -2.743179285981905968e-02 5.422615314166004397e-03 0.000000000000000000 -2.747597817447625101e-02 4.983931545688307513e-03 0.000000000000000000 -2.752023465991113721e-02 4.572378859048091548e-03 0.000000000000000000 -2.756456243076087567e-02 4.188929254620730840e-03 0.000000000000000000 -2.760896160184731982e-02 3.834429774322565578e-03 0.000000000000000000 -2.765343228817722376e-02 3.509599906313364600e-03 0.000000000000000000 -2.769797460494261010e-02 3.215029580283281386e-03 0.000000000000000000 -2.774258866752103356e-02 2.951177764626358030e-03 0.000000000000000000 -2.778727459147588286e-02 2.718371672977558905e-03 0.000000000000000000 -2.783203249255674847e-02 2.516806583675111619e-03 0.000000000000000000 -2.787686248669955791e-02 2.346546271736095566e-03 0.000000000000000000 -2.792176469002708231e-02 2.207524048947260512e-03 0.000000000000000000 -2.796673921884907515e-02 2.099544403730324409e-03 0.000000000000000000 -2.801178618966265743e-02 2.022285228567139576e-03 0.000000000000000000 -2.805690571915258821e-02 1.975300619026921448e-03 0.000000000000000000 -2.810209792419155958e-02 1.958024224853248483e-03 0.000000000000000000 -2.814736292184056091e-02 1.969773130184807996e-03 0.000000000000000000 -2.819270082934909397e-02 2.009752236836478013e-03 0.000000000000000000 -2.823811176415553029e-02 2.077059121683625439e-03 0.000000000000000000 -2.828359584388740258e-02 2.170689336600787993e-03 0.000000000000000000 -2.832915318636170660e-02 2.289542117126247816e-03 0.000000000000000000 -2.837478390958522376e-02 2.432426464072867927e-03 0.000000000000000000 -2.842048813175478139e-02 2.598067560693938672e-03 0.000000000000000000 -2.846626597125764477e-02 2.785113486748134505e-03 0.000000000000000000 -2.851211754667172180e-02 2.992142189886877642e-03 0.000000000000000000 -2.855804297676593426e-02 3.217668674214346162e-03 0.000000000000000000 -2.860404238050050924e-02 3.460152365626669325e-03 0.000000000000000000 -2.865011587702728443e-02 3.718004613618798148e-03 0.000000000000000000 -2.869626358569002042e-02 3.989596289633929455e-03 0.000000000000000000 -2.874248562602469553e-02 4.273265442701628010e-03 0.000000000000000000 -2.878878211775987364e-02 4.567324974046876353e-03 0.000000000000000000 -2.883515318081692272e-02 4.870070293523640938e-03 0.000000000000000000 -2.888159893531038955e-02 5.179786922113726981e-03 0.000000000000000000 -2.892811950154828768e-02 5.494758006296680819e-03 0.000000000000000000 -2.897471500003240621e-02 5.813271711820962480e-03 0.000000000000000000 -2.902138555145868798e-02 6.133628466254326290e-03 0.000000000000000000 -2.906813127671738217e-02 6.454148021635246375e-03 0.000000000000000000 -2.911495229689356132e-02 6.773176310568311195e-03 0.000000000000000000 -2.916184873326727392e-02 7.089092071156097470e-03 0.000000000000000000 -2.920882070731393651e-02 7.400313218246456874e-03 0.000000000000000000 -2.925586834070462855e-02 7.705302940538501059e-03 0.000000000000000000 -2.930299175530639774e-02 8.002575505141476878e-03 0.000000000000000000 -2.935019107318263473e-02 8.290701753180421824e-03 0.000000000000000000 -2.939746641659325352e-02 8.568314271982700736e-03 0.000000000000000000 -2.944481790799519105e-02 8.834112231251250655e-03 0.000000000000000000 -2.949224567004257030e-02 9.086865872404106814e-03 0.000000000000000000 -2.953974982558709578e-02 9.325420641957472487e-03 0.000000000000000000 -2.958733049767835188e-02 9.548700961411060381e-03 0.000000000000000000 -2.963498780956410478e-02 9.755713627585196543e-03 0.000000000000000000 -2.968272188469069789e-02 9.945550838740968222e-03 0.000000000000000000 -2.973053284670324620e-02 1.011739284309340348e-02 0.000000000000000000 -2.977842081944606298e-02 1.027051020751274663e-02 0.000000000000000000 -2.982638592696292695e-02 1.040426570529215909e-02 0.000000000000000000 -2.987442829349741882e-02 1.051811582286316452e-02 0.000000000000000000 -2.992254804349325087e-02 1.061161188625930202e-02 0.000000000000000000 -2.997074530159455491e-02 1.068440080898054069e-02 0.000000000000000000 -3.001902019264629171e-02 1.073622546370132241e-02 0.000000000000000000 -3.006737284169445218e-02 1.076692468100773174e-02 0.000000000000000000 -3.011580337398647028e-02 1.077643287905432658e-02 0.000000000000000000 -3.016431191497151096e-02 1.076477932870881747e-02 0.000000000000000000 -3.021289859030081362e-02 1.073208705941724322e-02 0.000000000000000000 -3.026156352582800441e-02 1.067857141168151655e-02 0.000000000000000000 -3.031030684760940494e-02 1.060453824270854960e-02 0.000000000000000000 -3.035912868190443481e-02 1.051038179247282094e-02 0.000000000000000000 -3.040802915517583360e-02 1.039658221814425930e-02 0.000000000000000000 -3.045700839409005642e-02 1.026370280557406707e-02 0.000000000000000000 -3.050606652551757919e-02 1.011238686731416592e-02 0.000000000000000000 -3.055520367653322480e-02 9.943354337472381371e-03 0.000000000000000000 -3.060441997441655515e-02 9.757398074579919089e-03 0.000000000000000000 -3.065371554665203765e-02 9.555379884573729499e-03 0.000000000000000000 -3.070309052092959692e-02 9.338226276968484424e-03 0.000000000000000000 -3.075254502514476393e-02 9.106923968319503848e-03 0.000000000000000000 -3.080207918739909581e-02 8.862515148140714602e-03 0.000000000000000000 -3.085169313600048466e-02 8.606092523549607395e-03 0.000000000000000000 -3.090138699946347670e-02 8.338794160046323484e-03 0.000000000000000000 -3.095116090650968169e-02 8.061798136991822628e-03 0.000000000000000000 -3.100101498606793946e-02 7.776317037519342272e-03 0.000000000000000000 -3.105094936727487154e-02 7.483592293775536732e-03 0.000000000000000000 -3.110096417947503383e-02 7.184888409543249525e-03 0.000000000000000000 -3.115105955222133988e-02 6.881487083408898212e-03 0.000000000000000000 -3.120123561527538697e-02 6.574681256710715807e-03 0.000000000000000000 -3.125149249860775802e-02 6.265769111506288604e-03 0.000000000000000000 -3.130183033239843787e-02 5.956048044717139958e-03 0.000000000000000000 -3.135224924703704230e-02 5.646808645428477713e-03 0.000000000000000000 -3.140274937312322739e-02 5.339328703018546111e-03 0.000000000000000000 -3.145333084146702263e-02 5.034867274356671224e-03 0.000000000000000000 -3.150399378308913617e-02 4.734658838716398511e-03 0.000000000000000000 -3.155473832922133653e-02 4.439907569288346380e-03 0.000000000000000000 -3.160556461130674399e-02 4.151781750234635922e-03 0.000000000000000000 -3.165647276100026081e-02 3.871408368083425512e-03 0.000000000000000000 -3.170746291016874469e-02 3.599867905918751124e-03 0.000000000000000000 -3.175853519089157084e-02 3.338189368252815047e-03 0.000000000000000000 -3.180968973546078465e-02 3.087345563694490844e-03 0.000000000000000000 -3.186092667638152492e-02 2.848248671514397312e-03 0.000000000000000000 -3.191224614637242635e-02 2.621746116986055711e-03 0.000000000000000000 -3.196364827836578604e-02 2.408616778934434023e-03 0.000000000000000000 -3.201513320550811864e-02 2.209567551261618339e-03 0.000000000000000000 -3.206670106116035757e-02 2.025230278361591849e-03 0.000000000000000000 -3.211835197889825744e-02 1.856159082278215295e-03 0.000000000000000000 -3.217008609251270634e-02 1.702828097234771213e-03 0.000000000000000000 -3.222190353601011442e-02 1.565629624775653544e-03 0.000000000000000000 -3.227380444361277467e-02 1.444872720239199050e-03 0.000000000000000000 -3.232578894975907113e-02 1.340782218643237628e-03 0.000000000000000000 -3.237785718910405480e-02 1.253498205337536279e-03 0.000000000000000000 -3.243000929651960323e-02 1.183075933990474383e-03 0.000000000000000000 -3.248224540709483688e-02 1.129486191647330025e-03 0.000000000000000000 -3.253456565613647988e-02 1.092616107765679656e-03 0.000000000000000000 -3.258697017916919320e-02 1.072270401315302771e-03 0.000000000000000000 -3.263945911193598393e-02 1.068173057261730249e-03 0.000000000000000000 -3.269203259039839965e-02 1.079969421055653085e-03 0.000000000000000000 -3.274469075073708352e-02 1.107228697153142538e-03 0.000000000000000000 -3.279743372935198242e-02 1.149446835117847636e-03 0.000000000000000000 -3.285026166286275640e-02 1.206049784526501542e-03 0.000000000000000000 -3.290317468810911861e-02 1.276397097735791760e-03 0.000000000000000000 -3.295617294215119619e-02 1.359785857586975249e-03 0.000000000000000000 -3.300925656226991883e-02 1.455454905341176282e-03 0.000000000000000000 -3.306242568596725467e-02 1.562589342563321104e-03 0.000000000000000000 -3.311568045096675156e-02 1.680325279317966417e-03 0.000000000000000000 -3.316902099521372438e-02 1.807754799906571928e-03 0.000000000000000000 -3.322244745687569223e-02 1.943931116474035582e-03 0.000000000000000000 -3.327595997434278086e-02 2.087873880133959709e-03 0.000000000000000000 -3.332955868622791001e-02 2.238574618810595766e-03 0.000000000000000000 -3.338324373136741102e-02 2.395002270765942028e-03 0.000000000000000000 -3.343701524882109616e-02 2.556108782756344629e-03 0.000000000000000000 -3.349087337787290397e-02 2.720834741952422343e-03 0.000000000000000000 -3.354481825803103112e-02 2.888115011123676759e-03 0.000000000000000000 -3.359885002902839729e-02 3.056884337148164151e-03 0.000000000000000000 -3.365296883082306151e-02 3.226082903620016394e-03 0.000000000000000000 -3.370717480359840257e-02 3.394661799195068403e-03 0.000000000000000000 -3.376146808776370883e-02 3.561588374316403474e-03 0.000000000000000000 -3.381584882395437253e-02 3.725851460074903164e-03 0.000000000000000000 -3.387031715303230606e-02 3.886466424183882343e-03 0.000000000000000000 -3.392487321608634449e-02 4.042480040350544292e-03 0.000000000000000000 -3.397951715443254389e-02 4.192975148706035160e-03 0.000000000000000000 -3.403424910961465322e-02 4.337075086393132363e-03 0.000000000000000000 -3.408906922340429468e-02 4.473947868890285062e-03 0.000000000000000000 -3.414397763780156053e-02 4.602810104168631768e-03 0.000000000000000000 -3.419897449503520731e-02 4.722930623312474735e-03 0.000000000000000000 -3.425405993756309303e-02 4.833633812788707372e-03 0.000000000000000000 -3.430923410807254492e-02 4.934302635106132401e-03 0.000000000000000000 -3.436449714948069251e-02 5.024381326163254897e-03 0.000000000000000000 -3.441984920493495331e-02 5.103377759135651996e-03 0.000000000000000000 -3.447529041781318554e-02 5.170865466296200620e-03 0.000000000000000000 -3.453082093172430561e-02 5.226485311695578534e-03 0.000000000000000000 -3.458644089050848941e-02 5.269946809148253787e-03 0.000000000000000000 -3.464215043823760942e-02 5.301029081478725313e-03 0.000000000000000000 -3.469794971921560944e-02 5.319581458477841071e-03 0.000000000000000000 -3.475383887797883764e-02 5.325523712504671124e-03 0.000000000000000000 -3.480981805929653922e-02 5.318845932146545712e-03 0.000000000000000000 -3.486588740817100213e-02 5.299608035820135843e-03 0.000000000000000000 -3.492204706983820239e-02 5.267938928662235440e-03 0.000000000000000000 -3.497829718976799840e-02 5.224035307522393971e-03 0.000000000000000000 -3.503463791366454028e-02 5.168160120332280366e-03 0.000000000000000000 -3.509106938746674870e-02 5.100640687588859148e-03 0.000000000000000000 -3.514759175734849528e-02 5.021866495152886405e-03 0.000000000000000000 -3.520420516971921321e-02 4.932286669026311049e-03 0.000000000000000000 -3.526090977122409154e-02 4.832407144236078311e-03 0.000000000000000000 -3.531770570874454701e-02 4.722787541408321813e-03 0.000000000000000000 -3.537459312939858491e-02 4.604037766067938311e-03 0.000000000000000000 -3.543157218054115987e-02 4.476814347135110554e-03 0.000000000000000000 -3.548864300976464770e-02 4.341816532507068900e-03 0.000000000000000000 -3.554580576489901889e-02 4.199782161003831789e-03 0.000000000000000000 -3.560306059401250472e-02 4.051483331305676290e-03 0.000000000000000000 -3.566040764541175689e-02 3.897721889819424565e-03 0.000000000000000000 -3.571784706764231238e-02 3.739324760651190939e-03 0.000000000000000000 -3.577537900948898897e-02 3.577139142038494261e-03 0.000000000000000000 -3.583300361997623917e-02 3.412027594683166628e-03 0.000000000000000000 -3.589072104836862898e-02 3.244863048411390522e-03 0.000000000000000000 -3.594853144417101826e-02 3.076523754464603050e-03 0.000000000000000000 -3.600643495712919917e-02 2.907888211464095332e-03 0.000000000000000000 -3.606443173723010431e-02 2.739830093699082737e-03 0.000000000000000000 -3.612252193470226469e-02 2.573213210824921732e-03 0.000000000000000000 -3.618070570001619829e-02 2.408886528333467961e-03 0.000000000000000000 -3.623898318388476397e-02 2.247679278244637223e-03 0.000000000000000000 -3.629735453726366107e-02 2.090396189360209812e-03 0.000000000000000000 -3.635581991135159591e-02 1.937812866113860447e-03 0.000000000000000000 -3.641437945759096878e-02 1.790671344524867375e-03 0.000000000000000000 -3.647303332766800577e-02 1.649675853030999973e-03 0.000000000000000000 -3.653178167351330691e-02 1.515488805012835203e-03 0.000000000000000000 -3.659062464730217235e-02 1.388727048650275622e-03 0.000000000000000000 -3.664956240145501865e-02 1.269958398355912343e-03 0.000000000000000000 -3.670859508863782289e-02 1.159698470426518725e-03 0.000000000000000000 -3.676772286176235166e-02 1.058407843747266423e-03 0.000000000000000000 -3.682694587398679248e-02 9.664895643812686709e-04 0.000000000000000000 -3.688626427871596197e-02 8.842870107033496503e-04 0.000000000000000000 -3.694567822960177078e-02 8.120821333941030500e-04 0.000000000000000000 -3.700518788054368846e-02 7.500940821306905726e-04 0.000000000000000000 -3.706479338568895165e-02 6.984782282068638772e-04 0.000000000000000000 -3.712449489943322328e-02 6.573255896112733783e-04 0.000000000000000000 -3.718429257642077296e-02 6.266626623188324263e-04 0.000000000000000000 -3.724418657154498352e-02 6.064516587231715342e-04 0.000000000000000000 -3.730417703994871881e-02 5.965911512924706788e-04 0.000000000000000000 -3.736426413702473998e-02 5.969171166893548789e-04 0.000000000000000000 -3.742444801841616348e-02 6.072043727858239884e-04 0.000000000000000000 -3.748472884001667615e-02 6.271683982529537233e-04 0.000000000000000000 -3.754510675797120139e-02 6.564675217384336944e-04 0.000000000000000000 -3.760558192867609340e-02 6.947054650865297238e-04 0.000000000000000000 -3.766615450877964372e-02 7.414342226283800489e-04 0.000000000000000000 -3.772682465518245598e-02 7.961572562961228075e-04 0.000000000000000000 -3.778759252503784138e-02 8.583329842113257818e-04 0.000000000000000000 -3.784845827575232524e-02 9.273785384833851302e-04 0.000000000000000000 -3.790942206498583433e-02 1.002673766239268799e-03 0.000000000000000000 -3.797048405065236998e-02 1.083565446406913697e-03 0.000000000000000000 -3.803164439092023008e-02 1.169371693493731620e-03 0.000000000000000000 -3.809290324421248791e-02 1.259386518551686976e-03 0.000000000000000000 -3.815426076920739457e-02 1.352884516697892316e-03 0.000000000000000000 -3.821571712483878142e-02 1.449125649969686472e-03 0.000000000000000000 -3.827727247029653890e-02 1.547360093931796814e-03 0.000000000000000000 -3.833892696502684549e-02 1.646833116315851589e-03 0.000000000000000000 -3.840068076873284081e-02 1.746789956056304114e-03 0.000000000000000000 -3.846253404137482679e-02 1.846480671377013832e-03 0.000000000000000000 -3.852448694317075345e-02 1.945164926079466028e-03 0.000000000000000000 -3.858653963459672542e-02 2.042116683866339495e-03 0.000000000000000000 -3.864869227638717541e-02 2.136628781397737972e-03 0.000000000000000000 -3.871094502953562749e-02 2.228017351808918040e-03 0.000000000000000000 -3.877329805529473178e-02 2.315626071598732034e-03 0.000000000000000000 -3.883575151517703467e-02 2.398830205126633794e-03 0.000000000000000000 -3.889830557095514535e-02 2.477040422404233784e-03 0.000000000000000000 -3.896096038466224237e-02 2.549706367438597451e-03 0.000000000000000000 -3.902371611859259404e-02 2.616319956053624052e-03 0.000000000000000000 -3.908657293530172494e-02 2.676418383878331753e-03 0.000000000000000000 -3.914953099760713068e-02 2.729586827035892452e-03 0.000000000000000000 -3.921259046858850683e-02 2.775460819978815743e-03 0.000000000000000000 -3.927575151158821387e-02 2.813728296892390596e-03 0.000000000000000000 -3.933901429021174206e-02 2.844131285115007735e-03 0.000000000000000000 -3.940237896832807230e-02 2.866467241095592422e-03 0.000000000000000000 -3.946584571007021730e-02 2.880590021517362258e-03 0.000000000000000000 -3.952941467983541596e-02 2.886410484355637039e-03 0.000000000000000000 -3.959308604228586881e-02 2.883896716799728022e-03 0.000000000000000000 -3.965685996234889765e-02 2.873073889148603996e-03 0.000000000000000000 -3.972073660521751454e-02 2.854023735980815591e-03 0.000000000000000000 -3.978471613635081727e-02 2.826883668094466121e-03 0.000000000000000000 -3.984879872147437108e-02 2.791845520907082923e-03 0.000000000000000000 -3.991298452658079143e-02 2.749153947189869347e-03 0.000000000000000000 -3.997727371792990370e-02 2.699104464179946129e-03 0.000000000000000000 -4.004166646204947860e-02 2.642041167257557985e-03 0.000000000000000000 -4.010616292573543351e-02 2.578354124486210985e-03 0.000000000000000000 -4.017076327605238056e-02 2.508476468379393799e-03 0.000000000000000000 -4.023546768033402221e-02 2.432881203269236965e-03 0.000000000000000000 -4.030027630618356754e-02 2.352077748596845264e-03 0.000000000000000000 -4.036518932147428046e-02 2.266608240308456545e-03 0.000000000000000000 -4.043020689434967396e-02 2.177043614311887851e-03 0.000000000000000000 -4.049532919322423180e-02 2.083979497608674444e-03 0.000000000000000000 -4.056055638678365133e-02 1.988031934255511841e-03 0.000000000000000000 -4.062588864398530841e-02 1.889832974704139376e-03 0.000000000000000000 -4.069132613405881949e-02 1.790026158309202453e-03 0.000000000000000000 -4.075686902650624971e-02 1.689261919861657609e-03 0.000000000000000000 -4.082251749110283462e-02 1.588192951880986782e-03 0.000000000000000000 -4.088827169789711891e-02 1.487469555076492093e-03 0.000000000000000000 -4.095413181721169193e-02 1.387735009838586726e-03 0.000000000000000000 -4.102009801964340979e-02 1.289621001847101591e-03 0.000000000000000000 -4.108617047606389489e-02 1.193743134859370130e-03 0.000000000000000000 -4.115234935762010493e-02 1.100696563466432984e-03 0.000000000000000000 -4.121863483573452031e-02 1.011051778070516443e-03 0.000000000000000000 -4.128502708210586569e-02 9.253505735321177622e-04 0.000000000000000000 -4.135152626870935988e-02 8.441022318676846695e-04 0.000000000000000000 -4.141813256779725005e-02 7.677799480388445945e-04 0.000000000000000000 -4.148484615189922120e-02 6.968175262758248599e-04 0.000000000000000000 -4.155166719382284712e-02 6.316063725207356639e-04 0.000000000000000000 -4.161859586665413863e-02 5.724928064772778291e-04 0.000000000000000000 -4.168563234375774473e-02 5.197757144227579213e-04 0.000000000000000000 -4.175277679877770209e-02 4.737045613948068657e-04 0.000000000000000000 -4.182002940563767091e-02 4.344777786309194051e-04 0.000000000000000000 -4.188739033854146920e-02 4.022415392339047206e-04 0.000000000000000000 -4.195485977197351002e-02 3.770889319900375862e-04 0.000000000000000000 -4.202243788069923852e-02 3.590595401058738765e-04 0.000000000000000000 -4.209012483976568020e-02 3.481394283832682252e-04 0.000000000000000000 -4.215792082450166289e-02 3.442615390548187972e-04 0.000000000000000000 -4.222582601051858009e-02 3.473064931824063973e-04 0.000000000000000000 -4.229384057371059907e-02 3.571037912159646531e-04 0.000000000000000000 -4.236196469025523687e-02 3.734334030484301350e-04 0.000000000000000000 -4.243019853661376267e-02 3.960277347200352131e-04 0.000000000000000000 -4.249854228953167667e-02 4.245739558508711937e-04 0.000000000000000000 -4.256699612603924432e-02 4.587166689456494877e-04 0.000000000000000000 -4.263556022345173224e-02 4.980608989457250809e-04 0.000000000000000000 -4.270423475937017849e-02 5.421753788281151367e-04 0.000000000000000000 -4.277301991168157291e-02 5.905961046897250776e-04 0.000000000000000000 -4.284191585855946782e-02 6.428301316314747596e-04 0.000000000000000000 -4.291092277846446368e-02 6.983595798844536738e-04 0.000000000000000000 -4.298004085014447972e-02 7.566458190160214696e-04 0.000000000000000000 -4.304927025263551726e-02 8.171337967279896242e-04 0.000000000000000000 -4.311861116526178456e-02 8.792564777167911731e-04 0.000000000000000000 -4.318806376763648786e-02 9.424393573171931885e-04 0.000000000000000000 -4.325762823966205345e-02 1.006105014190203676e-03 0.000000000000000000 -4.332730476153067584e-02 1.069677666149407552e-03 0.000000000000000000 -4.339709351372488672e-02 1.132587693337406588e-03 0.000000000000000000 -4.346699467701777703e-02 1.194276093361901518e-03 0.000000000000000000 -4.353700843247376023e-02 1.254198833672293947e-03 0.000000000000000000 -4.360713496144880824e-02 1.311831067386976055e-03 0.000000000000000000 -4.367737444559104121e-02 1.366671179963341830e-03 0.000000000000000000 -4.374772706684115775e-02 1.418244635518045669e-03 0.000000000000000000 -4.381819300743289292e-02 1.466107593243553588e-03 0.000000000000000000 -4.388877244989360105e-02 1.509850266211925631e-03 0.000000000000000000 -4.395946557704447782e-02 1.549099996892497550e-03 0.000000000000000000 -4.403027257200137212e-02 1.583524025922241349e-03 0.000000000000000000 -4.410119361817497335e-02 1.612831933036395224e-03 0.000000000000000000 -4.417222889927142210e-02 1.636777731581298863e-03 0.000000000000000000 -4.424337859929276806e-02 1.655161600669515908e-03 0.000000000000000000 -4.431464290253741417e-02 1.667831241786872035e-03 0.000000000000000000 -4.438602199360070638e-02 1.674682849503645416e-03 0.000000000000000000 -4.445751605737516265e-02 1.675661688861882197e-03 0.000000000000000000 -4.452912527905129175e-02 1.670762274991136748e-03 0.000000000000000000 -4.460084984411777365e-02 1.660028153529445692e-03 0.000000000000000000 -4.467268993836211177e-02 1.643551283476948986e-03 0.000000000000000000 -4.474464574787104937e-02 1.621471027170770388e-03 0.000000000000000000 -4.481671745903104132e-02 1.593972755121191411e-03 0.000000000000000000 -4.488890525852886476e-02 1.561286076474832814e-03 0.000000000000000000 -4.496120933335182729e-02 1.523682708849639304e-03 0.000000000000000000 -4.503362987078858570e-02 1.481474004198986630e-03 0.000000000000000000 -4.510616705842938889e-02 1.435008150190131586e-03 0.000000000000000000 -4.517882108416663295e-02 1.384667069299975279e-03 0.000000000000000000 -4.525159213619544402e-02 1.330863040420994514e-03 0.000000000000000000 -4.532448040301393505e-02 1.274035070207542222e-03 0.000000000000000000 -4.539748607342401765e-02 1.214645043653967468e-03 0.000000000000000000 -4.547060933653152004e-02 1.153173685462312954e-03 0.000000000000000000 -4.554385038174704747e-02 1.090116365598868152e-03 0.000000000000000000 -4.561720939878618347e-02 1.025978784042460602e-03 0.000000000000000000 -4.569068657767011432e-02 9.612725710615330167e-04 0.000000000000000000 -4.576428210872617031e-02 8.965108404104832774e-04 0.000000000000000000 -4.583799618258810327e-02 8.322037335833511835e-04 0.000000000000000000 -4.591182899019688457e-02 7.688539936901050325e-04 0.000000000000000000 -4.598578072280093409e-02 7.069526076156769064e-04 0.000000000000000000 -4.605985157195675861e-02 6.469745548676157513e-04 0.000000000000000000 -4.613404172952941668e-02 5.893747009124998461e-04 0.000000000000000000 -4.620835138769297662e-02 5.345838718359871263e-04 0.000000000000000000 -4.628278073893114103e-02 4.830051458367050723e-04 0.000000000000000000 -4.635732997603748962e-02 4.350103953857861207e-04 0.000000000000000000 -4.643199929211630494e-02 3.909371118560530669e-04 0.000000000000000000 -4.650678888058282223e-02 3.510855420662196600e-04 0.000000000000000000 -4.658169893516383997e-02 3.157161635057313177e-04 0.000000000000000000 -4.665672964989819177e-02 2.850475220347417930e-04 0.000000000000000000 -4.673188121913722515e-02 2.592544526107154489e-04 0.000000000000000000 -4.680715383754546072e-02 2.384667001127284826e-04 0.000000000000000000 -4.688254770010076566e-02 2.227679536487619182e-04 0.000000000000000000 -4.695806300209526968e-02 2.121953038767527644e-04 0.000000000000000000 -4.703369993913553843e-02 2.067391288897609523e-04 0.000000000000000000 -4.710945870714324663e-02 2.063434101469426127e-04 0.000000000000000000 -4.718533950235565683e-02 2.109064758238981489e-04 0.000000000000000000 -4.726134252132607738e-02 2.202821648488739476e-04 0.000000000000000000 -4.733746796092450776e-02 2.342814008327644701e-04 0.000000000000000000 -4.741371601833788835e-02 2.526741611345303474e-04 0.000000000000000000 -4.749008689107095393e-02 2.751918224728520197e-04 0.000000000000000000 -4.756658077694645576e-02 3.015298608413290258e-04 0.000000000000000000 -4.764319787410578599e-02 3.313508800481517608e-04 0.000000000000000000 -4.771993838100960228e-02 3.642879400174973037e-04 0.000000000000000000 -4.779680249643803586e-02 3.999481530926096750e-04 0.000000000000000000 -4.787379041949159364e-02 4.379165139995928879e-04 0.000000000000000000 -4.795090234959135944e-02 4.777599268896272431e-04 0.000000000000000000 -4.802813848647968092e-02 5.190313909999198175e-04 0.000000000000000000 -4.810549903022061369e-02 5.612743049735653428e-04 0.000000000000000000 -4.818298418120046250e-02 6.040268487704387188e-04 0.000000000000000000 -4.826059414012837112e-02 6.468264013917196433e-04 0.000000000000000000 -4.833832910803662758e-02 6.892139523334332935e-04 0.000000000000000000 -4.841618928628148300e-02 7.307384647800957943e-04 0.000000000000000000 -4.849417487654343606e-02 7.709611490409045299e-04 0.000000000000000000 -4.857228608082784366e-02 8.094596056137555451e-04 0.000000000000000000 -4.865052310146546211e-02 8.458317985214627247e-04 0.000000000000000000 -4.872888614111291206e-02 8.796998211878513966e-04 0.000000000000000000 -4.880737540275333769e-02 9.107134190908514927e-04 0.000000000000000000 -4.888599108969666346e-02 9.385532357254891067e-04 0.000000000000000000 -4.896473340558046838e-02 9.629337510110858034e-04 0.000000000000000000 -4.904360255437023586e-02 9.836058841584027681e-04 0.000000000000000000 -4.912259874036000590e-02 1.000359236151715948e-03 0.000000000000000000 -4.920172216817288863e-02 1.013023950368015019e-03 0.000000000000000000 -4.928097304276155000e-02 1.021472173425439856e-03 0.000000000000000000 -4.936035156940889873e-02 1.025619102095132445e-03 0.000000000000000000 -4.943985795372831532e-02 1.025423605995544893e-03 0.000000000000000000 -4.951949240166453325e-02 1.020888419784884548e-03 0.000000000000000000 -4.959925511949392352e-02 1.012059902643778131e-03 0.000000000000000000 -4.967914631382512602e-02 9.990273669634817250e-04 0.000000000000000000 -4.975916619159959087e-02 9.819219822922449058e-04 0.000000000000000000 -4.983931496009204321e-02 9.609152647082178133e-04 0.000000000000000000 -4.991959282691120492e-02 9.362171658475176156e-04 0.000000000000000000 -4.999999999999999584e-02 9.080737797844798441e-04 0.000000000000000000 \ No newline at end of file diff --git a/tests/test_data/R1DSPCBilayer.mat b/tests/test_data/R1DSPCBilayer.mat deleted file mode 100644 index 596eb814..00000000 Binary files a/tests/test_data/R1DSPCBilayer.mat and /dev/null differ diff --git a/tests/test_data/R1DoubleBilayerVolumeModel.mat b/tests/test_data/R1DoubleBilayerVolumeModel.mat deleted file mode 100644 index c65b170a..00000000 Binary files a/tests/test_data/R1DoubleBilayerVolumeModel.mat and /dev/null differ diff --git a/tests/test_data/R1Monolayer_8_contrasts.mat b/tests/test_data/R1Monolayer_8_contrasts.mat deleted file mode 100644 index da9de417..00000000 Binary files a/tests/test_data/R1Monolayer_8_contrasts.mat and /dev/null differ diff --git a/tests/test_data/R1defaultProject.mat b/tests/test_data/R1defaultProject.mat deleted file mode 100644 index 774199b0..00000000 Binary files a/tests/test_data/R1defaultProject.mat and /dev/null differ diff --git a/tests/test_data/R1monolayerVolumeModel.mat b/tests/test_data/R1monolayerVolumeModel.mat deleted file mode 100644 index e6604917..00000000 Binary files a/tests/test_data/R1monolayerVolumeModel.mat and /dev/null differ diff --git a/tests/test_data/R1motofitBenchMark.mat b/tests/test_data/R1motofitBenchMark.mat deleted file mode 100644 index 449362a5..00000000 Binary files a/tests/test_data/R1motofitBenchMark.mat and /dev/null differ diff --git a/tests/test_data/R1orsoPolymerExample.mat b/tests/test_data/R1orsoPolymerExample.mat deleted file mode 100644 index 48bc10f6..00000000 Binary files a/tests/test_data/R1orsoPolymerExample.mat and /dev/null differ diff --git a/tests/test_data/bare_substrate.json b/tests/test_data/bare_substrate.json deleted file mode 100644 index 65e405c2..00000000 --- a/tests/test_data/bare_substrate.json +++ /dev/null @@ -1 +0,0 @@ -{"name": "substrate", "calculation": "normal", "model": "standard layers", "geometry": "air/substrate", "absorption": false, "parameters": [{"name": "Substrate Roughness", "min": 1.0, "value": 3.0, "max": 5.0, "fit": true, "prior_type": "uniform", "mu": 0.0, "sigma": Infinity, "show_priors": false}], "bulk_in": [{"name": "air SLD", "min": 4.42927130586151e-09, "value": 4.42927130586151e-09, "max": 4.42927130586151e-09, "fit": false, "prior_type": "uniform", "mu": 0.0, "sigma": Infinity, "show_priors": false}], "bulk_out": [{"name": "D2O SLD", "min": 6.360408603667384e-06, "value": 6.360408603667384e-06, "max": 6.360408603667384e-06, "fit": false, "prior_type": "uniform", "mu": 0.0, "sigma": Infinity, "show_priors": false}], "scalefactors": [{"name": "Scalefactor 1", "min": 0.02, "value": 0.23, "max": 0.25, "fit": false, "prior_type": "uniform", "mu": 0.0, "sigma": Infinity, "show_priors": false}], "domain_ratios": [], "background_parameters": [{"name": "Background Param 1", "min": 1e-07, "value": 1e-06, "max": 1e-05, "fit": false, "prior_type": "uniform", "mu": 0.0, "sigma": Infinity, "show_priors": false}], "backgrounds": [{"name": "Background 1", "type": "constant", "source": "Background Param 1", "value_1": "", "value_2": "", "value_3": "", "value_4": "", "value_5": ""}], "resolution_parameters": [{"name": "Resolution Param 1", "min": 0.01, "value": 0.03, "max": 0.05, "fit": false, "prior_type": "uniform", "mu": 0.0, "sigma": Infinity, "show_priors": false}], "resolutions": [{"name": "Resolution 1", "type": "constant", "source": "Resolution Param 1", "value_1": "", "value_2": "", "value_3": "", "value_4": "", "value_5": ""}], "custom_files": [], "data": [{"name": "Simulation", "data": [], "data_range": [], "simulation_range": [0.005, 0.7]}, {"name": "D2O substrate", "data": [[0.048866, 0.00012343, 1.3213e-06, 0.03], [0.051309, 0.00010063, 1.0803e-06, 0.03], [0.053874, 8.2165e-05, 8.8779e-07, 0.03], [0.056568, 6.4993e-05, 7.2018e-07, 0.03], [0.059396, 5.3958e-05, 6.0015e-07, 0.03], [0.062366, 4.359e-05, 5.0129e-07, 0.03], [0.065485, 3.578e-05, 4.1957e-07, 0.03], [0.068759, 2.913e-05, 3.5171e-07, 0.03], [0.072197, 2.3481e-05, 3.0586e-07, 0.03], [0.075807, 1.8906e-05, 2.6344e-07, 0.03], [0.079597, 1.4642e-05, 2.2314e-07, 0.03], [0.083577, 1.1589e-05, 1.8938e-07, 0.03], [0.087756, 9.5418e-06, 1.622e-07, 0.03], [0.092143, 7.5694e-06, 1.3809e-07, 0.03], [0.096751, 6.3831e-06, 1.2097e-07, 0.03], [0.10159, 5.0708e-06, 1.0333e-07, 0.03], [0.10667, 4.1041e-06, 8.9548e-08, 0.03], [0.112, 3.4253e-06, 7.983e-08, 0.03], [0.1176, 2.8116e-06, 7.1554e-08, 0.03], [0.12348, 2.3767e-06, 6.3738e-08, 0.03], [0.12966, 1.9241e-06, 5.6586e-08, 0.03], [0.13614, 1.5642e-06, 5.2778e-08, 0.03], [0.14294, 1.2922e-06, 4.973e-08, 0.03], [0.15009, 1.1694e-06, 5.1175e-08, 0.03], [0.1576, 9.7837e-07, 5.0755e-08, 0.03], [0.16548, 8.9138e-07, 5.3542e-08, 0.03], [0.17375, 7.942e-07, 5.4857e-08, 0.03], [0.18244, 7.9131e-07, 5.8067e-08, 0.03], [0.19156, 6.5358e-07, 5.7717e-08, 0.03], [0.20114, 6.297e-07, 5.7951e-08, 0.03], [0.21119, 5.013e-07, 5.5262e-08, 0.03], [0.22175, 5.0218e-07, 5.6461e-08, 0.03], [0.23284, 3.9299e-07, 5.0685e-08, 0.03], [0.24448, 3.5324e-07, 5.0194e-08, 0.03], [0.25671, 4.4475e-07, 5.6485e-08, 0.03], [0.26954, 5.1338e-07, 6.2247e-08, 0.03], [0.28302, 3.4918e-07, 4.9745e-08, 0.03], [0.29717, 4.3037e-07, 5.5488e-08, 0.03], [0.31203, 4.0099e-07, 5.3591e-08, 0.03], [0.32763, 3.8397e-07, 5.1303e-08, 0.03], [0.34401, 3.0995e-07, 4.5965e-08, 0.03], [0.36121, 3.9357e-07, 5.0135e-08, 0.03], [0.37927, 3.0997e-07, 4.368e-08, 0.03], [0.39824, 2.9656e-07, 4.2432e-08, 0.03], [0.41815, 2.1909e-07, 3.6117e-08, 0.03], [0.43906, 2.3153e-07, 3.6307e-08, 0.03], [0.46101, 3.3428e-07, 4.3874e-08, 0.03], [0.48406, 2.3441e-07, 3.7488e-08, 0.03], [0.50826, 1.5496e-07, 3.0585e-08, 0.03], [0.53368, 2.4708e-07, 3.9376e-08, 0.03], [0.56036, 2.2157e-07, 3.8258e-08, 0.03], [0.58838, 2.2798e-07, 4.6976e-08, 0.03], [0.61169, 6.0272e-07, 2.3239e-07, 0.03]], "data_range": [0.048866, 0.61169], "simulation_range": [0.048866, 0.61169]}], "layers": [], "domain_contrasts": [], "contrasts": []} \ No newline at end of file diff --git a/tests/test_data/bare_substrate.ort b/tests/test_data/bare_substrate.ort deleted file mode 100644 index 7e4ffb52..00000000 --- a/tests/test_data/bare_substrate.ort +++ /dev/null @@ -1,83 +0,0 @@ -# # ORSO reflectivity data file | 1.1 standard | YAML encoding | https://www.reflectometry.org/ -# # handwritten test file header created to test RAT orsopy integration! -# data_source: -# owner: -# name: null -# affiliation: null -# measurement: -# instrument_settings: null -# data_files: null -# experiment: -# title: Bare D2O substrate -# probe: neutron -# instrument: None -# start_date: 1970-01-01T00:00:00 -# sample: -# name: D2O substrate -# model: -# stack: air | D2O -# reduction: -# software: null -# timestamp: null -# data_set: 0 -# columns: -# - {name: Qz, unit: 1/angstrom, physical_quantity: normal momentum transfer} -# - {name: R, unit: '', physical_quantity: specular reflectivity} -# - {error_of: R, error_type: uncertainty, value_is: sigma} -# - {error_of: Qz, error_type: resolution, value_is: sigma} -# # Qz (1/angstrom) R () sR sQz -4.8866e-02 1.2343e-04 1.3213e-06 0.03 -5.1309e-02 1.0063e-04 1.0803e-06 0.03 -5.3874e-02 8.2165e-05 8.8779e-07 0.03 -5.6568e-02 6.4993e-05 7.2018e-07 0.03 -5.9396e-02 5.3958e-05 6.0015e-07 0.03 -6.2366e-02 4.3590e-05 5.0129e-07 0.03 -6.5485e-02 3.5780e-05 4.1957e-07 0.03 -6.8759e-02 2.9130e-05 3.5171e-07 0.03 -7.2197e-02 2.3481e-05 3.0586e-07 0.03 -7.5807e-02 1.8906e-05 2.6344e-07 0.03 -7.9597e-02 1.4642e-05 2.2314e-07 0.03 -8.3577e-02 1.1589e-05 1.8938e-07 0.03 -8.7756e-02 9.5418e-06 1.6220e-07 0.03 -9.2143e-02 7.5694e-06 1.3809e-07 0.03 -9.6751e-02 6.3831e-06 1.2097e-07 0.03 -1.0159e-01 5.0708e-06 1.0333e-07 0.03 -1.0667e-01 4.1041e-06 8.9548e-08 0.03 -1.1200e-01 3.4253e-06 7.9830e-08 0.03 -1.1760e-01 2.8116e-06 7.1554e-08 0.03 -1.2348e-01 2.3767e-06 6.3738e-08 0.03 -1.2966e-01 1.9241e-06 5.6586e-08 0.03 -1.3614e-01 1.5642e-06 5.2778e-08 0.03 -1.4294e-01 1.2922e-06 4.9730e-08 0.03 -1.5009e-01 1.1694e-06 5.1175e-08 0.03 -1.5760e-01 9.7837e-07 5.0755e-08 0.03 -1.6548e-01 8.9138e-07 5.3542e-08 0.03 -1.7375e-01 7.9420e-07 5.4857e-08 0.03 -1.8244e-01 7.9131e-07 5.8067e-08 0.03 -1.9156e-01 6.5358e-07 5.7717e-08 0.03 -2.0114e-01 6.2970e-07 5.7951e-08 0.03 -2.1119e-01 5.0130e-07 5.5262e-08 0.03 -2.2175e-01 5.0218e-07 5.6461e-08 0.03 -2.3284e-01 3.9299e-07 5.0685e-08 0.03 -2.4448e-01 3.5324e-07 5.0194e-08 0.03 -2.5671e-01 4.4475e-07 5.6485e-08 0.03 -2.6954e-01 5.1338e-07 6.2247e-08 0.03 -2.8302e-01 3.4918e-07 4.9745e-08 0.03 -2.9717e-01 4.3037e-07 5.5488e-08 0.03 -3.1203e-01 4.0099e-07 5.3591e-08 0.03 -3.2763e-01 3.8397e-07 5.1303e-08 0.03 -3.4401e-01 3.0995e-07 4.5965e-08 0.03 -3.6121e-01 3.9357e-07 5.0135e-08 0.03 -3.7927e-01 3.0997e-07 4.3680e-08 0.03 -3.9824e-01 2.9656e-07 4.2432e-08 0.03 -4.1815e-01 2.1909e-07 3.6117e-08 0.03 -4.3906e-01 2.3153e-07 3.6307e-08 0.03 -4.6101e-01 3.3428e-07 4.3874e-08 0.03 -4.8406e-01 2.3441e-07 3.7488e-08 0.03 -5.0826e-01 1.5496e-07 3.0585e-08 0.03 -5.3368e-01 2.4708e-07 3.9376e-08 0.03 -5.6036e-01 2.2157e-07 3.8258e-08 0.03 -5.8838e-01 2.2798e-07 4.6976e-08 0.03 -6.1169e-01 6.0272e-07 2.3239e-07 0.03 - - diff --git a/tests/test_data/moto.dat b/tests/test_data/moto.dat deleted file mode 100644 index bacdb1ea..00000000 --- a/tests/test_data/moto.dat +++ /dev/null @@ -1,400 +0,0 @@ -2.000000000000000042e-02 9.999599999999999600e-01 9.999800000000000041e-05 -2.143300000000000066e-02 1.000199999999999978e+00 1.000099999999999996e-04 -2.286699999999999844e-02 9.998500000000000165e-01 9.999200000000000080e-05 -2.429999999999999868e-02 9.999400000000000510e-01 9.999699999999999821e-05 -2.573299999999999893e-02 1.000099999999999989e+00 1.000000000000000048e-04 -2.716599999999999918e-02 9.998799999999999910e-01 9.999400000000000519e-05 -2.860000000000000042e-02 9.999900000000000455e-01 9.999900000000000260e-05 -3.003300000000000067e-02 9.999299999999999855e-01 9.999599999999999602e-05 -3.146600000000000091e-02 9.998899999999999455e-01 9.999400000000000519e-05 -3.289999999999999869e-02 3.114100000000000201e-01 5.580400000000000307e-05 -3.433300000000000241e-02 1.969499999999999862e-01 4.437900000000000319e-05 -3.576599999999999918e-02 1.030900000000000011e-01 3.210700000000000278e-05 -3.719999999999999696e-02 3.366899999999999754e-02 1.834899999999999999e-05 -3.863300000000000067e-02 5.127699999999999793e-03 7.160800000000000117e-06 -4.006599999999999745e-02 8.905400000000000815e-03 9.436899999999999382e-06 -4.149900000000000116e-02 2.294799999999999965e-02 1.514900000000000014e-05 -4.293299999999999894e-02 3.121600000000000069e-02 1.766800000000000092e-05 -4.436600000000000266e-02 2.888500000000000095e-02 1.699600000000000126e-05 -4.579899999999999943e-02 1.918999999999999873e-02 1.385299999999999933e-05 -4.723299999999999721e-02 8.333600000000000035e-03 9.128899999999999959e-06 -4.866600000000000092e-02 1.518000000000000035e-03 3.896200000000000067e-06 -5.009899999999999770e-02 4.664700000000000248e-04 2.159800000000000057e-06 -5.153200000000000142e-02 3.377900000000000087e-03 5.811999999999999580e-06 -5.296599999999999919e-02 7.010100000000000012e-03 8.372600000000000102e-06 -5.439900000000000291e-02 8.816299999999999137e-03 9.389500000000000480e-06 -5.583199999999999968e-02 7.962399999999999686e-03 8.923199999999999540e-06 -5.726599999999999746e-02 5.249099999999999600e-03 7.245100000000000310e-06 -5.869900000000000118e-02 2.273400000000000074e-03 4.767999999999999920e-06 -6.013199999999999795e-02 3.864399999999999931e-04 1.965799999999999881e-06 -6.156600000000000267e-02 1.337800000000000100e-04 1.156600000000000073e-06 -6.299899999999999944e-02 1.111199999999999905e-03 3.333400000000000137e-06 -6.443200000000000316e-02 2.436600000000000137e-03 4.936200000000000274e-06 -6.586500000000000687e-02 3.236399999999999954e-03 5.688899999999999861e-06 -6.729899999999999771e-02 3.133500000000000001e-03 5.597699999999999786e-06 -6.873200000000000143e-02 2.268200000000000164e-03 4.762499999999999718e-06 -7.016500000000000514e-02 1.132900000000000053e-03 3.365800000000000030e-06 -7.159899999999999598e-02 2.832499999999999732e-04 1.683000000000000022e-06 -7.303199999999999970e-02 1.961999999999999850e-05 4.429400000000000210e-07 -7.446500000000000341e-02 3.102399999999999841e-04 1.761399999999999983e-06 -7.589899999999999425e-02 8.720800000000000123e-04 2.953100000000000152e-06 -7.733199999999999796e-02 1.345499999999999908e-03 3.668100000000000083e-06 -7.876500000000000168e-02 1.461800000000000078e-03 3.823300000000000308e-06 -8.019800000000000539e-02 1.217100000000000039e-03 3.488700000000000157e-06 -8.163199999999999623e-02 7.391700000000000397e-04 2.718800000000000126e-06 -8.306499999999999995e-02 2.771000000000000134e-04 1.664599999999999910e-06 -8.449800000000000366e-02 2.859499999999999981e-05 5.347000000000000432e-07 -8.593199999999999450e-02 5.878500000000000045e-05 7.666799999999999804e-07 -8.736499999999999821e-02 2.926000000000000107e-04 1.710599999999999978e-06 -8.879800000000000193e-02 5.642299999999999833e-04 2.375400000000000161e-06 -9.023100000000000565e-02 7.333899999999999968e-04 2.708099999999999957e-06 -9.166499999999999648e-02 7.032800000000000292e-04 2.651899999999999970e-06 -9.309800000000000020e-02 5.188299999999999640e-04 2.277800000000000028e-06 -9.453100000000000391e-02 2.686100000000000185e-04 1.638900000000000097e-06 -9.596499999999999475e-02 7.123199999999999834e-05 8.439799999999999645e-07 -9.739799999999999847e-02 4.900099999999999892e-06 2.213599999999999916e-07 -9.883100000000000218e-02 7.526500000000000529e-05 8.675800000000000435e-07 -1.002600000000000019e-01 2.236399999999999933e-04 1.495499999999999912e-06 -1.016999999999999987e-01 3.596000000000000130e-04 1.896299999999999954e-06 -1.031299999999999994e-01 4.167500000000000197e-04 2.041400000000000055e-06 -1.045600000000000002e-01 3.655099999999999886e-04 1.911800000000000059e-06 -1.059999999999999970e-01 2.410900000000000109e-04 1.552699999999999974e-06 -1.074299999999999977e-01 1.041799999999999953e-04 1.020700000000000028e-06 -1.088599999999999984e-01 1.688000000000000101e-05 4.108500000000000030e-07 -1.102999999999999953e-01 9.166900000000000273e-06 3.028200000000000077e-07 -1.117299999999999960e-01 7.323700000000000370e-05 8.558000000000000267e-07 -1.131599999999999967e-01 1.670800000000000063e-04 1.292599999999999915e-06 -1.145999999999999935e-01 2.342599999999999967e-04 1.530600000000000008e-06 -1.160299999999999943e-01 2.498700000000000183e-04 1.580699999999999960e-06 -1.174599999999999950e-01 2.000700000000000004e-04 1.414499999999999967e-06 -1.189000000000000057e-01 1.178000000000000038e-04 1.085400000000000018e-06 -1.203300000000000064e-01 4.043399999999999946e-05 6.358500000000000192e-07 -1.217599999999999932e-01 2.313200000000000146e-06 1.519899999999999998e-07 -1.232000000000000040e-01 1.488200000000000083e-05 3.857500000000000230e-07 -1.246300000000000047e-01 6.628099999999999780e-05 8.141300000000000513e-07 -1.260600000000000054e-01 1.229900000000000134e-04 1.109000000000000097e-06 -1.275000000000000022e-01 1.606099999999999954e-04 1.267299999999999920e-06 -1.289299999999999891e-01 1.550500000000000012e-04 1.245199999999999953e-06 -1.303600000000000037e-01 1.143000000000000000e-04 1.069100000000000064e-06 -1.318000000000000005e-01 5.900299999999999734e-05 7.681099999999999608e-07 -1.332299999999999873e-01 1.461000000000000073e-05 3.822300000000000021e-07 -1.346600000000000019e-01 5.125699999999999900e-07 7.141399999999999348e-08 -1.360999999999999988e-01 1.844700000000000143e-05 4.295300000000000088e-07 -1.375300000000000133e-01 5.764800000000000100e-05 7.592799999999999539e-07 -1.389600000000000002e-01 9.192999999999999566e-05 9.588000000000000358e-07 -1.403999999999999970e-01 1.091400000000000020e-04 1.044699999999999925e-06 -1.418300000000000116e-01 9.775500000000000172e-05 9.887399999999999982e-07 -1.432599999999999985e-01 6.527600000000000318e-05 8.079599999999999901e-07 -1.446999999999999953e-01 2.882299999999999831e-05 5.368400000000000346e-07 -1.461300000000000099e-01 4.040099999999999655e-06 2.010000000000000131e-07 -1.475599999999999967e-01 2.138600000000000158e-06 1.462899999999999951e-07 -1.489999999999999936e-01 2.075500000000000034e-05 4.556300000000000109e-07 -1.504300000000000082e-01 4.759300000000000325e-05 6.898600000000000112e-07 -1.518599999999999950e-01 6.952499999999999587e-05 8.338499999999999658e-07 -1.532999999999999918e-01 7.418100000000000009e-05 8.612799999999999937e-07 -1.547300000000000064e-01 6.195100000000000368e-05 7.870800000000000307e-07 -1.561599999999999933e-01 3.649500000000000210e-05 6.041499999999999670e-07 -1.575999999999999901e-01 1.217000000000000037e-05 3.488600000000000150e-07 -1.590300000000000047e-01 5.659999999999999596e-07 7.549800000000000543e-08 -1.604599999999999915e-01 5.112000000000000353e-06 2.260499999999999893e-07 -1.618999999999999884e-01 2.135600000000000017e-05 4.621700000000000152e-07 -1.633300000000000030e-01 4.103899999999999790e-05 6.406199999999999753e-07 -1.647599999999999898e-01 5.290800000000000234e-05 7.273899999999999509e-07 -1.661999999999999866e-01 4.904200000000000242e-05 7.002900000000000325e-07 -1.676300000000000012e-01 3.763099999999999936e-05 6.134300000000000077e-07 -1.690599999999999881e-01 1.891899999999999962e-05 4.349699999999999834e-07 -1.705000000000000127e-01 4.593799999999999961e-06 2.142399999999999914e-07 -1.719299999999999995e-01 2.185900000000000006e-07 4.690400000000000098e-08 -1.733599999999999863e-01 6.528100000000000229e-06 2.555400000000000237e-07 -1.748000000000000109e-01 1.911799999999999890e-05 4.372599999999999860e-07 -1.762299999999999978e-01 3.301699999999999915e-05 5.746299999999999515e-07 -1.776600000000000124e-01 3.653399999999999953e-05 6.043999999999999858e-07 -1.791000000000000092e-01 3.191599999999999732e-05 5.649799999999999676e-07 -1.805299999999999960e-01 2.190000000000000039e-05 4.679699999999999745e-07 -1.819600000000000106e-01 9.374399999999999557e-06 3.061000000000000212e-07 -1.834000000000000075e-01 1.398600000000000043e-06 1.183200000000000033e-07 -1.848299999999999943e-01 9.713900000000000711e-07 9.848900000000000266e-08 -1.862600000000000089e-01 7.569100000000000087e-06 2.751400000000000140e-07 -1.877000000000000057e-01 1.738800000000000022e-05 4.170099999999999999e-07 -1.891299999999999926e-01 2.432699999999999934e-05 4.932499999999999996e-07 -1.905600000000000072e-01 2.685400000000000073e-05 5.181699999999999872e-07 -1.920000000000000040e-01 2.062299999999999889e-05 4.540900000000000116e-07 -1.934299999999999908e-01 1.225100000000000010e-05 3.499999999999999842e-07 -1.948600000000000054e-01 4.253799999999999828e-06 2.061599999999999879e-07 -1.963000000000000023e-01 2.845600000000000017e-07 5.291500000000000101e-08 -1.977299999999999891e-01 1.850300000000000098e-06 1.360100000000000115e-07 -1.991600000000000037e-01 7.572300000000000328e-06 2.751400000000000140e-07 -2.006000000000000005e-01 1.419299999999999947e-05 3.766999999999999784e-07 -2.020299999999999874e-01 1.730800000000000098e-05 4.160500000000000230e-07 -2.034600000000000020e-01 1.686900000000000061e-05 4.107300000000000257e-07 -2.048999999999999988e-01 1.341799999999999926e-05 3.663300000000000252e-07 -2.063300000000000134e-01 6.591800000000000144e-06 2.567099999999999740e-07 -2.077600000000000002e-01 1.779100000000000042e-06 1.334200000000000128e-07 -2.091899999999999871e-01 2.154999999999999908e-07 4.690400000000000098e-08 -2.106300000000000117e-01 2.475000000000000020e-06 1.571600000000000123e-07 -2.120599999999999985e-01 6.593400000000000264e-06 2.567099999999999740e-07 -2.134900000000000131e-01 1.094300000000000009e-05 3.307599999999999786e-07 -2.149300000000000099e-01 1.274899999999999940e-05 3.570700000000000071e-07 -2.163599999999999968e-01 1.167999999999999998e-05 3.417600000000000110e-07 -2.177900000000000114e-01 7.430800000000000073e-06 2.725800000000000228e-07 -2.192300000000000082e-01 3.389800000000000139e-06 1.841200000000000102e-07 -2.206599999999999950e-01 6.721299999999999709e-07 8.185399999999999961e-08 -2.220900000000000096e-01 3.908300000000000129e-07 6.244999999999999342e-08 -2.235300000000000065e-01 2.378500000000000182e-06 1.542699999999999911e-07 -2.249599999999999933e-01 5.754199999999999897e-06 2.397900000000000051e-07 -2.263900000000000079e-01 8.293100000000000271e-06 2.879200000000000000e-07 -2.278300000000000047e-01 8.377099999999999805e-06 2.894800000000000219e-07 -2.292599999999999916e-01 7.302399999999999744e-06 2.701900000000000126e-07 -2.306900000000000062e-01 4.315199999999999783e-06 2.078499999999999984e-07 -2.321300000000000030e-01 1.769699999999999971e-06 1.330400000000000055e-07 -2.335599999999999898e-01 2.779000000000000201e-07 5.291500000000000101e-08 -2.349900000000000044e-01 5.284499999999999972e-07 7.280100000000000451e-08 -2.364300000000000013e-01 2.592399999999999947e-06 1.609299999999999991e-07 -2.378599999999999881e-01 4.344199999999999844e-06 2.083299999999999868e-07 -2.392900000000000027e-01 6.215399999999999818e-06 2.493999999999999965e-07 -2.407299999999999995e-01 6.025100000000000132e-06 2.455599999999999833e-07 -2.421599999999999864e-01 4.653500000000000423e-06 2.156399999999999907e-07 -2.435900000000000010e-01 2.756399999999999986e-06 1.661299999999999927e-07 -2.450299999999999978e-01 9.029900000000000145e-07 9.486799999999999955e-08 -2.464600000000000124e-01 2.107899999999999969e-07 4.582600000000000285e-08 -2.478899999999999992e-01 8.002999999999999863e-07 8.944300000000000226e-08 -2.493299999999999961e-01 2.008800000000000147e-06 1.417700000000000049e-07 -2.507599999999999829e-01 3.498199999999999812e-06 1.870800000000000050e-07 -2.521900000000000253e-01 4.081499999999999801e-06 2.019899999999999975e-07 -2.536300000000000221e-01 3.672999999999999816e-06 1.915699999999999876e-07 -2.550600000000000089e-01 3.029000000000000137e-06 1.740699999999999963e-07 -2.564899999999999958e-01 1.488600000000000029e-06 1.220700000000000071e-07 -2.579299999999999926e-01 5.013900000000000183e-07 7.071100000000000366e-08 -2.593599999999999794e-01 2.381100000000000060e-07 4.898999999999999730e-08 -2.607900000000000218e-01 8.394400000000000046e-07 9.165200000000000569e-08 -2.622300000000000186e-01 1.744599999999999992e-06 1.319099999999999947e-07 -2.636600000000000055e-01 2.846500000000000190e-06 1.688199999999999989e-07 -2.650899999999999923e-01 3.200399999999999885e-06 1.788900000000000090e-07 -2.665299999999999891e-01 2.711499999999999789e-06 1.646200000000000010e-07 -2.679599999999999760e-01 2.075699999999999879e-06 1.442200000000000037e-07 -2.693900000000000183e-01 9.190299999999999914e-07 9.591699999999999789e-08 -2.708300000000000152e-01 3.300500000000000206e-07 5.744599999999999705e-08 -2.722600000000000020e-01 2.427800000000000074e-07 4.898999999999999730e-08 -2.736899999999999888e-01 7.507300000000000527e-07 8.660299999999999800e-08 -2.751299999999999857e-01 1.289799999999999916e-06 1.135800000000000019e-07 -2.765599999999999725e-01 2.175799999999999988e-06 1.476500000000000019e-07 -2.779900000000000149e-01 2.173500000000000027e-06 1.473099999999999870e-07 -2.794300000000000117e-01 1.704299999999999928e-06 1.303800000000000068e-07 -2.808599999999999985e-01 1.293399999999999975e-06 1.135800000000000019e-07 -2.822899999999999854e-01 6.768399999999999648e-07 8.246200000000000082e-08 -2.837299999999999822e-01 2.092100000000000053e-07 4.582600000000000285e-08 -2.851600000000000246e-01 2.089899999999999940e-07 4.582600000000000285e-08 -2.865900000000000114e-01 7.006000000000000134e-07 8.366600000000000287e-08 -2.880300000000000082e-01 1.200699999999999998e-06 1.095400000000000002e-07 -2.894599999999999951e-01 1.598700000000000042e-06 1.264899999999999898e-07 -2.908899999999999819e-01 1.713499999999999984e-06 1.307699999999999990e-07 -2.923299999999999788e-01 1.479199999999999958e-06 1.216599999999999922e-07 -2.937600000000000211e-01 8.770699999999999518e-07 9.380800000000000197e-08 -2.951900000000000079e-01 5.017900000000000483e-07 7.071100000000000366e-08 -2.966300000000000048e-01 1.249400000000000057e-07 3.464099999999999897e-08 -2.980599999999999916e-01 3.192899999999999957e-07 5.656900000000000183e-08 -2.994899999999999785e-01 5.400099999999999763e-07 7.348499999999999925e-08 -3.009299999999999753e-01 9.167800000000000341e-07 9.591699999999999789e-08 -3.023600000000000176e-01 1.091600000000000060e-06 1.043999999999999952e-07 -3.037900000000000045e-01 1.114899999999999905e-06 1.053599999999999985e-07 -3.052300000000000013e-01 9.849099999999999434e-07 9.899499999999999409e-08 -3.066599999999999882e-01 5.490900000000000020e-07 7.416199999999999929e-08 -3.080899999999999750e-01 3.416999999999999959e-07 5.830999999999999737e-08 -3.095300000000000273e-01 1.432499999999999890e-07 3.741699999999999683e-08 -3.109600000000000142e-01 2.503500000000000150e-07 4.999999999999999774e-08 -3.123900000000000010e-01 4.171299999999999771e-07 6.480700000000000585e-08 -3.138299999999999979e-01 9.677600000000000313e-07 9.848900000000000266e-08 -3.152599999999999847e-01 1.076900000000000015e-06 1.039199999999999935e-07 -3.166900000000000270e-01 1.102100000000000002e-06 1.048799999999999968e-07 -3.181300000000000239e-01 7.944699999999999930e-07 8.888200000000000140e-08 -3.195600000000000107e-01 6.477999999999999641e-07 8.062299999999999342e-08 -3.209899999999999975e-01 3.333600000000000152e-07 5.744599999999999705e-08 -3.224299999999999944e-01 1.998799999999999872e-07 4.472100000000000056e-08 -3.238599999999999812e-01 1.082500000000000065e-07 3.316600000000000065e-08 -3.252900000000000236e-01 4.829499999999999670e-07 6.928199999999999795e-08 -3.267300000000000204e-01 4.738000000000000207e-07 6.855699999999999642e-08 -3.281600000000000072e-01 7.670899999999999689e-07 8.775000000000000159e-08 -3.295899999999999941e-01 8.786399999999999851e-07 9.380800000000000197e-08 -3.310299999999999909e-01 5.818999999999999894e-07 7.615799999999999943e-08 -3.324599999999999778e-01 3.664899999999999948e-07 6.082799999999999385e-08 -3.338900000000000201e-01 1.812200000000000041e-07 4.242599999999999887e-08 -3.353200000000000069e-01 2.487500000000000007e-07 4.999999999999999774e-08 -3.367600000000000038e-01 1.971099999999999962e-07 4.472100000000000056e-08 -3.381899999999999906e-01 4.357900000000000132e-07 6.633200000000000131e-08 -3.396199999999999775e-01 4.189199999999999951e-07 6.480700000000000585e-08 -3.410599999999999743e-01 6.466600000000000479e-07 8.062299999999999342e-08 -3.424900000000000166e-01 6.991799999999999914e-07 8.366600000000000287e-08 -3.439200000000000035e-01 5.755199999999999548e-07 7.615799999999999943e-08 -3.453600000000000003e-01 3.603500000000000206e-07 5.999999999999999464e-08 -3.467899999999999872e-01 1.908699999999999879e-07 4.358900000000000075e-08 -3.482199999999999740e-01 1.215699999999999961e-07 3.464099999999999897e-08 -3.496600000000000263e-01 2.594900000000000029e-07 5.099000000000000197e-08 -3.510900000000000132e-01 4.234200000000000156e-07 6.480700000000000585e-08 -3.525200000000000000e-01 5.051399999999999824e-07 7.141399999999999348e-08 -3.539599999999999969e-01 5.445300000000000194e-07 7.348499999999999925e-08 -3.553899999999999837e-01 5.015700000000000106e-07 7.071100000000000366e-08 -3.568200000000000260e-01 3.772199999999999857e-07 6.164400000000000592e-08 -3.582600000000000229e-01 2.957999999999999885e-07 5.477200000000000235e-08 -3.596900000000000097e-01 2.358000000000000071e-07 4.898999999999999730e-08 -3.611199999999999966e-01 2.356400000000000110e-07 4.898999999999999730e-08 -3.625599999999999934e-01 3.554699999999999928e-07 5.999999999999999464e-08 -3.639899999999999802e-01 3.051100000000000103e-07 5.567799999999999736e-08 -3.654200000000000226e-01 5.067300000000000383e-07 7.141399999999999348e-08 -3.668600000000000194e-01 4.637399999999999955e-07 6.782299999999999792e-08 -3.682900000000000063e-01 4.123100000000000174e-07 6.403099999999999943e-08 -3.697199999999999931e-01 3.372199999999999981e-07 5.830999999999999737e-08 -3.711599999999999899e-01 1.999900000000000061e-07 4.472100000000000056e-08 -3.725899999999999768e-01 1.626799999999999982e-07 4.000000000000000084e-08 -3.740200000000000191e-01 2.533499999999999757e-07 4.999999999999999774e-08 -3.754600000000000160e-01 2.250499999999999936e-07 4.795799999999999838e-08 -3.768900000000000028e-01 2.792699999999999854e-07 5.291500000000000101e-08 -3.783199999999999896e-01 5.591900000000000197e-07 7.483300000000000576e-08 -3.797599999999999865e-01 2.937700000000000160e-07 5.385199999999999808e-08 -3.811899999999999733e-01 2.764299999999999944e-07 5.291500000000000101e-08 -3.826200000000000156e-01 1.937699999999999941e-07 4.358900000000000075e-08 -3.840600000000000125e-01 1.970000000000000038e-07 4.472100000000000056e-08 -3.854899999999999993e-01 1.628899999999999981e-07 4.000000000000000084e-08 -3.869199999999999862e-01 2.141100000000000028e-07 4.582600000000000285e-08 -3.883599999999999830e-01 2.244199999999999939e-07 4.690400000000000098e-08 -3.897900000000000253e-01 2.390900000000000055e-07 4.898999999999999730e-08 -3.912200000000000122e-01 3.728600000000000181e-07 6.082799999999999385e-08 -3.926600000000000090e-01 2.364599999999999879e-07 4.898999999999999730e-08 -3.940899999999999959e-01 2.442599999999999916e-07 4.898999999999999730e-08 -3.955199999999999827e-01 1.591200000000000113e-07 4.000000000000000084e-08 -3.969599999999999795e-01 1.592899999999999924e-07 4.000000000000000084e-08 -3.983900000000000219e-01 1.133700000000000020e-07 3.316600000000000065e-08 -3.998200000000000087e-01 1.962300000000000042e-07 4.472100000000000056e-08 -4.012600000000000056e-01 1.410599999999999939e-07 3.741699999999999683e-08 -4.026899999999999924e-01 2.510299999999999920e-07 4.999999999999999774e-08 -4.041199999999999792e-01 2.820400000000000029e-07 5.291500000000000101e-08 -4.055599999999999761e-01 3.117400000000000108e-07 5.567799999999999736e-08 -4.069900000000000184e-01 1.021300000000000020e-07 3.162299999999999802e-08 -4.084200000000000053e-01 1.329700000000000055e-07 3.605600000000000205e-08 -4.098600000000000021e-01 1.103000000000000017e-07 3.316600000000000065e-08 -4.112899999999999889e-01 1.326200000000000057e-07 3.605600000000000205e-08 -4.127199999999999758e-01 1.460700000000000103e-07 3.872999999999999674e-08 -4.141599999999999726e-01 1.917399999999999951e-07 4.358900000000000075e-08 -4.155900000000000150e-01 2.328800000000000048e-07 4.795799999999999838e-08 -4.170200000000000018e-01 2.353300000000000036e-07 4.898999999999999730e-08 -4.184599999999999986e-01 2.429300000000000187e-07 4.898999999999999730e-08 -4.198899999999999855e-01 1.760600000000000029e-07 4.242599999999999887e-08 -4.213199999999999723e-01 1.400799999999999944e-07 3.741699999999999683e-08 -4.227600000000000247e-01 2.440299999999999954e-07 4.898999999999999730e-08 -4.241900000000000115e-01 1.158800000000000027e-07 3.464099999999999897e-08 -4.256199999999999983e-01 1.759999999999999878e-07 4.242599999999999887e-08 -4.270599999999999952e-01 7.706599999999999671e-08 2.828400000000000035e-08 -4.284899999999999820e-01 2.745499999999999802e-07 5.196199999999999903e-08 -4.299200000000000244e-01 1.284000000000000116e-07 3.605600000000000205e-08 -4.313600000000000212e-01 1.833299999999999879e-07 4.242599999999999887e-08 -4.327900000000000080e-01 1.847599999999999948e-07 4.242599999999999887e-08 -4.342199999999999949e-01 1.731500000000000119e-07 4.123100000000000041e-08 -4.356599999999999917e-01 9.118400000000000441e-08 2.999999999999999732e-08 -4.370899999999999785e-01 1.957499999999999893e-07 4.472100000000000056e-08 -4.385200000000000209e-01 1.920399999999999911e-07 4.358900000000000075e-08 -4.399600000000000177e-01 1.945599999999999899e-07 4.358900000000000075e-08 -4.413900000000000046e-01 1.568700000000000011e-07 4.000000000000000084e-08 -4.428199999999999914e-01 1.953500000000000122e-07 4.472100000000000056e-08 -4.442599999999999882e-01 1.654200000000000082e-07 4.123100000000000041e-08 -4.456899999999999751e-01 1.368599999999999960e-07 3.741699999999999683e-08 -4.471200000000000174e-01 2.139000000000000029e-07 4.582600000000000285e-08 -4.485600000000000143e-01 1.256499999999999902e-07 3.605600000000000205e-08 -4.499900000000000011e-01 8.671100000000000135e-08 2.999999999999999732e-08 -4.514199999999999879e-01 2.137699999999999879e-07 4.582600000000000285e-08 -4.528599999999999848e-01 1.410599999999999939e-07 3.741699999999999683e-08 -4.542900000000000271e-01 1.612900000000000103e-07 4.000000000000000084e-08 -4.557200000000000140e-01 1.604000000000000069e-07 4.000000000000000084e-08 -4.571600000000000108e-01 1.167399999999999985e-07 3.464099999999999897e-08 -4.585899999999999976e-01 1.624699999999999983e-07 4.000000000000000084e-08 -4.600199999999999845e-01 1.695099999999999873e-07 4.123100000000000041e-08 -4.614500000000000268e-01 1.064199999999999961e-07 3.316600000000000065e-08 -4.628900000000000237e-01 9.822699999999999674e-08 3.162299999999999802e-08 -4.643200000000000105e-01 1.886799999999999928e-07 4.358900000000000075e-08 -4.657499999999999973e-01 1.214299999999999961e-07 3.464099999999999897e-08 -4.671899999999999942e-01 1.188599999999999936e-07 3.464099999999999897e-08 -4.686199999999999810e-01 1.647799999999999972e-07 4.000000000000000084e-08 -4.700500000000000234e-01 1.168099999999999984e-07 3.464099999999999897e-08 -4.714900000000000202e-01 1.719899999999999936e-07 4.123100000000000041e-08 -4.729200000000000070e-01 9.757199999999999517e-08 3.162299999999999802e-08 -4.743499999999999939e-01 1.612600000000000027e-07 4.000000000000000084e-08 -4.757899999999999907e-01 2.017200000000000090e-07 4.472100000000000056e-08 -4.772199999999999775e-01 1.734099999999999891e-07 4.123100000000000041e-08 -4.786500000000000199e-01 1.175899999999999962e-07 3.464099999999999897e-08 -4.800900000000000167e-01 1.819299999999999886e-07 4.242599999999999887e-08 -4.815200000000000036e-01 1.103700000000000016e-07 3.316600000000000065e-08 -4.829499999999999904e-01 1.772899999999999947e-07 4.242599999999999887e-08 -4.843899999999999872e-01 1.506200000000000080e-07 3.872999999999999674e-08 -4.858199999999999741e-01 1.333799999999999939e-07 3.605600000000000205e-08 -4.872500000000000164e-01 1.528600000000000069e-07 3.872999999999999674e-08 -4.886900000000000133e-01 1.639799999999999900e-07 4.000000000000000084e-08 -4.901200000000000001e-01 1.014599999999999966e-07 3.162299999999999802e-08 -4.915499999999999869e-01 2.166400000000000129e-07 4.690400000000000098e-08 -4.929899999999999838e-01 1.104300000000000035e-07 3.316600000000000065e-08 -4.944200000000000261e-01 1.644900000000000125e-07 4.000000000000000084e-08 -4.958500000000000130e-01 2.125700000000000036e-07 4.582600000000000285e-08 -4.972900000000000098e-01 1.332899999999999978e-07 3.605600000000000205e-08 -4.987199999999999966e-01 1.907200000000000031e-07 4.358900000000000075e-08 -5.001499999999999835e-01 1.103899999999999979e-07 3.316600000000000065e-08 -5.015899999999999803e-01 1.628099999999999868e-07 4.000000000000000084e-08 -5.030200000000000227e-01 1.564699999999999975e-07 4.000000000000000084e-08 -5.044499999999999540e-01 2.116999999999999965e-07 4.582600000000000285e-08 -5.058899999999999508e-01 1.125200000000000044e-07 3.316600000000000065e-08 -5.073199999999999932e-01 1.239199999999999873e-07 3.464099999999999897e-08 -5.087500000000000355e-01 1.728600000000000007e-07 4.123100000000000041e-08 -5.101900000000000324e-01 1.738400000000000002e-07 4.123100000000000041e-08 -5.116199999999999637e-01 1.037300000000000031e-07 3.162299999999999802e-08 -5.130500000000000060e-01 1.545200000000000099e-07 3.872999999999999674e-08 -5.144900000000000029e-01 2.247199999999999900e-07 4.690400000000000098e-08 -5.159200000000000452e-01 1.780599999999999943e-07 4.242599999999999887e-08 -5.173499999999999766e-01 8.477199999999999967e-08 2.828400000000000035e-08 -5.187899999999999734e-01 1.513000000000000115e-07 3.872999999999999674e-08 -5.202200000000000157e-01 1.958499999999999968e-07 4.472100000000000056e-08 -5.216499999999999471e-01 9.982499999999999556e-08 3.162299999999999802e-08 -5.230900000000000549e-01 1.309099999999999990e-07 3.605600000000000205e-08 -5.245199999999999863e-01 1.317600000000000099e-07 3.605600000000000205e-08 -5.259500000000000286e-01 1.400799999999999944e-07 3.741699999999999683e-08 -5.273900000000000254e-01 1.935900000000000017e-07 4.358900000000000075e-08 -5.288199999999999568e-01 1.446999999999999921e-07 3.741699999999999683e-08 -5.302499999999999991e-01 1.913599999999999877e-07 4.358900000000000075e-08 -5.316899999999999959e-01 1.878800000000000121e-07 4.358900000000000075e-08 -5.331200000000000383e-01 8.692899999999999708e-08 2.999999999999999732e-08 -5.345499999999999696e-01 1.305200000000000067e-07 3.605600000000000205e-08 -5.359899999999999665e-01 1.802600000000000008e-07 4.242599999999999887e-08 -5.374200000000000088e-01 1.069199999999999939e-07 3.316600000000000065e-08 -5.388500000000000512e-01 1.900799999999999921e-07 4.358900000000000075e-08 -5.402900000000000480e-01 1.831199999999999880e-07 4.242599999999999887e-08 -5.417199999999999793e-01 1.681099999999999880e-07 4.123100000000000041e-08 -5.431500000000000217e-01 1.333900000000000053e-07 3.605600000000000205e-08 -5.445900000000000185e-01 1.158100000000000027e-07 3.464099999999999897e-08 -5.460199999999999498e-01 1.890099999999999964e-07 4.358900000000000075e-08 -5.474499999999999922e-01 5.076999999999999735e-08 2.236100000000000085e-08 -5.488899999999999890e-01 1.515800000000000113e-07 3.872999999999999674e-08 -5.503200000000000314e-01 1.764199999999999876e-07 4.242599999999999887e-08 -5.517499999999999627e-01 1.254399999999999903e-07 3.605600000000000205e-08 -5.531899999999999595e-01 7.189599999999999740e-08 2.645800000000000107e-08 -5.546200000000000019e-01 1.533399999999999953e-07 3.872999999999999674e-08 -5.560500000000000442e-01 2.005300000000000096e-07 4.472100000000000056e-08 -5.574900000000000411e-01 1.467200000000000062e-07 3.872999999999999674e-08 -5.589199999999999724e-01 1.129899999999999947e-07 3.316600000000000065e-08 -5.603500000000000147e-01 1.063900000000000017e-07 3.316600000000000065e-08 -5.617900000000000116e-01 7.993799999999999755e-08 2.828400000000000035e-08 -5.632200000000000539e-01 1.288999999999999962e-07 3.605600000000000205e-08 -5.646499999999999853e-01 1.651499999999999932e-07 4.123100000000000041e-08 -5.660899999999999821e-01 1.030900000000000053e-07 3.162299999999999802e-08 -5.675200000000000244e-01 1.426699999999999931e-07 3.741699999999999683e-08 -5.689499999999999558e-01 1.464099999999999988e-07 3.872999999999999674e-08 -5.703899999999999526e-01 1.396900000000000021e-07 3.741699999999999683e-08 -5.718199999999999950e-01 1.245999999999999908e-07 3.464099999999999897e-08 -5.732500000000000373e-01 1.078500000000000029e-07 3.316600000000000065e-08 -5.746900000000000341e-01 1.481999999999999903e-07 3.872999999999999674e-08 -5.761199999999999655e-01 1.322200000000000021e-07 3.605600000000000205e-08 -5.775500000000000078e-01 1.317399999999999872e-07 3.605600000000000205e-08 -5.789900000000000047e-01 8.568300000000000035e-08 2.999999999999999732e-08 -5.804200000000000470e-01 4.987799999999999837e-08 2.236100000000000085e-08 -5.818499999999999783e-01 1.980500000000000033e-07 4.472100000000000056e-08 -5.832899999999999752e-01 1.649700000000000009e-07 4.000000000000000084e-08 -5.847200000000000175e-01 1.235900000000000102e-07 3.464099999999999897e-08 -5.861499999999999488e-01 1.132400000000000002e-07 3.316600000000000065e-08 -5.875799999999999912e-01 1.552400000000000057e-07 4.000000000000000084e-08 -5.890199999999999880e-01 1.425600000000000007e-07 3.741699999999999683e-08 -5.904500000000000304e-01 1.441899999999999961e-07 3.741699999999999683e-08 -5.918799999999999617e-01 2.349600000000000075e-07 4.795799999999999838e-08 diff --git a/tests/test_data/nonUniqueContrast.mat b/tests/test_data/nonUniqueContrast.mat deleted file mode 100644 index 41375134..00000000 Binary files a/tests/test_data/nonUniqueContrast.mat and /dev/null differ diff --git a/tests/test_data/orso_poly.dat b/tests/test_data/orso_poly.dat deleted file mode 100644 index 4187f29a..00000000 --- a/tests/test_data/orso_poly.dat +++ /dev/null @@ -1,408 +0,0 @@ -8.060200000000000004e-03 7.095799999999999885e-01 8.506800000000000472e-02 -8.136600000000000776e-03 8.622800000000000464e-01 1.123699999999999977e-01 -8.263799999999999965e-03 9.086499999999999577e-01 7.900500000000000578e-02 -8.370700000000000016e-03 7.732900000000000329e-01 7.927299999999999625e-02 -8.450300000000000866e-03 1.058000000000000052e+00 1.259599999999999886e-01 -8.530799999999999841e-03 1.015700000000000047e+00 1.132999999999999979e-01 -8.612200000000000411e-03 7.347200000000000397e-01 6.115700000000000303e-02 -8.694399999999999698e-03 7.692200000000000149e-01 6.170599999999999696e-02 -8.777399999999999439e-03 1.115699999999999914e+00 1.127299999999999969e-01 -8.861400000000000179e-03 9.723000000000000531e-01 8.971600000000000408e-02 -8.946199999999999639e-03 7.512100000000000444e-01 5.493900000000000172e-02 -9.031799999999999551e-03 7.976499999999999702e-01 5.671199999999999852e-02 -9.118400000000000463e-03 9.221899999999999542e-01 6.858400000000000607e-02 -9.205899999999999500e-03 9.757599999999999607e-01 7.294000000000000483e-02 -9.294300000000000131e-03 8.195000000000000062e-01 5.216200000000000003e-02 -9.383600000000000621e-03 7.883200000000000207e-01 4.794699999999999657e-02 -9.473900000000000376e-03 7.946999999999999620e-01 4.602200000000000041e-02 -9.565099999999999991e-03 8.743999999999999551e-01 5.151599999999999929e-02 -9.657199999999999465e-03 8.396599999999999620e-01 4.742799999999999794e-02 -9.750299999999999939e-03 8.008699999999999708e-01 4.399600000000000039e-02 -9.844399999999999679e-03 1.117099999999999982e+00 7.373300000000000687e-02 -9.939399999999999277e-03 8.884100000000000330e-01 4.954100000000000170e-02 -1.003500000000000052e-02 7.791299999999999892e-01 3.898700000000000082e-02 -1.013200000000000038e-02 7.999699999999999589e-01 3.899699999999999694e-02 -1.022999999999999951e-02 8.431199999999999806e-01 4.159800000000000303e-02 -1.032899999999999964e-02 9.613300000000000178e-01 4.925399999999999917e-02 -1.048699999999999979e-02 8.805399999999999894e-01 2.990800000000000056e-02 -1.063300000000000009e-02 7.557399999999999674e-01 3.208500000000000241e-02 -1.073600000000000075e-02 9.712300000000000377e-01 4.534799999999999942e-02 -1.084000000000000068e-02 8.955499999999999572e-01 3.905399999999999844e-02 -1.094499999999999987e-02 8.625899999999999679e-01 3.580699999999999855e-02 -1.105199999999999932e-02 8.909899999999999487e-01 3.612599999999999839e-02 -1.115900000000000052e-02 9.003499999999999837e-01 3.679199999999999832e-02 -1.126800000000000024e-02 8.459299999999999597e-01 3.218800000000000133e-02 -1.137799999999999923e-02 9.431500000000000439e-01 3.655300000000000216e-02 -1.148799999999999995e-02 9.956300000000000150e-01 3.901199999999999807e-02 -1.159999999999999920e-02 9.695899999999999519e-01 3.636199999999999849e-02 -1.171299999999999945e-02 9.051799999999999846e-01 3.204100000000000004e-02 -1.182799999999999997e-02 8.933799999999999519e-01 3.061200000000000032e-02 -1.194300000000000049e-02 9.195999999999999730e-01 3.146800000000000291e-02 -1.205999999999999954e-02 9.190000000000000391e-01 3.060999999999999832e-02 -1.217799999999999959e-02 7.810599999999999765e-01 2.355399999999999855e-02 -1.229700000000000064e-02 8.649099999999999566e-01 2.720300000000000148e-02 -1.241699999999999922e-02 8.435200000000000475e-01 2.550099999999999936e-02 -1.253800000000000053e-02 9.984199999999999742e-01 3.197200000000000042e-02 -1.266100000000000038e-02 8.812600000000000433e-01 2.602700000000000152e-02 -1.278499999999999949e-02 8.835699999999999665e-01 2.558600000000000110e-02 -1.291100000000000060e-02 9.376700000000000035e-01 2.746499999999999983e-02 -1.303699999999999998e-02 1.019200000000000106e+00 3.051099999999999993e-02 -1.316499999999999962e-02 8.455300000000000038e-01 2.262700000000000128e-02 -1.329400000000000026e-02 8.738000000000000211e-01 2.324700000000000030e-02 -1.342400000000000017e-02 8.659499999999999975e-01 2.249100000000000057e-02 -1.355600000000000034e-02 8.779799999999999827e-01 2.244900000000000020e-02 -1.368899999999999978e-02 9.475400000000000489e-01 2.489900000000000099e-02 -1.382399999999999948e-02 8.881499999999999950e-01 2.209600000000000106e-02 -1.395899999999999919e-02 8.913600000000000412e-01 2.181500000000000106e-02 -1.409700000000000016e-02 8.884600000000000275e-01 2.150900000000000034e-02 -1.423499999999999939e-02 9.137199999999999767e-01 2.225900000000000101e-02 -1.437500000000000062e-02 8.103599999999999692e-01 1.882899999999999852e-02 -1.451700000000000039e-02 7.385500000000000398e-01 1.688299999999999870e-02 -1.465999999999999942e-02 6.865099999999999536e-01 1.597399999999999862e-02 -1.480399999999999945e-02 5.822399999999999798e-01 1.350200000000000011e-02 -1.494999999999999975e-02 4.468599999999999794e-01 1.006300000000000076e-02 -1.509699999999999931e-02 3.924599999999999755e-01 9.155500000000000443e-03 -1.524599999999999914e-02 3.205200000000000271e-01 7.319599999999999891e-03 -1.539599999999999996e-02 2.810099999999999820e-01 6.399099999999999580e-03 -1.554799999999999932e-02 2.401000000000000079e-01 5.442400000000000015e-03 -1.570099999999999968e-02 2.208799999999999930e-01 5.024400000000000047e-03 -1.585599999999999857e-02 1.920300000000000062e-01 4.314400000000000353e-03 -1.601299999999999946e-02 1.798500000000000099e-01 4.051599999999999820e-03 -1.617100000000000135e-02 1.600699999999999901e-01 3.562000000000000062e-03 -1.633000000000000076e-02 1.531299999999999883e-01 3.467800000000000049e-03 -1.649199999999999972e-02 1.342200000000000060e-01 3.016000000000000018e-03 -1.665399999999999867e-02 1.283299999999999996e-01 2.888500000000000009e-03 -1.681900000000000062e-02 1.247899999999999981e-01 2.861799999999999847e-03 -1.698500000000000010e-02 1.091300000000000048e-01 2.483099999999999804e-03 -1.715300000000000158e-02 1.044299999999999951e-01 2.353899999999999916e-03 -1.732300000000000159e-02 9.468300000000000327e-02 2.091599999999999883e-03 -1.758799999999999947e-02 8.969100000000000683e-02 1.439399999999999968e-03 -1.784200000000000022e-02 8.091399999999999981e-02 1.872799999999999986e-03 -1.801799999999999929e-02 7.465399999999999814e-02 1.714199999999999925e-03 -1.819700000000000137e-02 7.036599999999999799e-02 1.634199999999999932e-03 -1.837700000000000097e-02 6.904399999999999427e-02 1.605300000000000043e-03 -1.855899999999999911e-02 6.270499999999999685e-02 1.461499999999999909e-03 -1.874299999999999924e-02 5.939099999999999935e-02 1.400100000000000042e-03 -1.892800000000000038e-02 5.754800000000000193e-02 1.361000000000000014e-03 -1.911600000000000105e-02 5.138299999999999812e-02 1.226700000000000056e-03 -1.930499999999999924e-02 4.922699999999999992e-02 1.178199999999999907e-03 -1.949700000000000044e-02 4.521700000000000025e-02 1.079600000000000004e-03 -1.968999999999999917e-02 4.245600000000000068e-02 1.022200000000000018e-03 -1.988499999999999990e-02 4.126099999999999907e-02 9.947800000000000132e-04 -2.008199999999999916e-02 3.523300000000000043e-02 8.777900000000000372e-04 -2.028200000000000142e-02 3.352700000000000125e-02 8.367500000000000372e-04 -2.048300000000000121e-02 3.326799999999999896e-02 8.339600000000000181e-04 -2.068599999999999953e-02 3.166399999999999770e-02 7.898900000000000149e-04 -2.089099999999999985e-02 2.915999999999999842e-02 7.496099999999999465e-04 -2.109799999999999870e-02 2.651999999999999844e-02 7.063800000000000504e-04 -2.130800000000000055e-02 2.518300000000000052e-02 6.713900000000000076e-04 -2.152000000000000093e-02 2.387600000000000139e-02 6.426900000000000147e-04 -2.173299999999999885e-02 2.289300000000000015e-02 6.330700000000000086e-04 -2.194899999999999976e-02 2.086500000000000160e-02 5.931299999999999810e-04 -2.216699999999999920e-02 2.087699999999999972e-02 5.920100000000000189e-04 -2.238700000000000065e-02 1.822299999999999962e-02 5.292100000000000103e-04 -2.261000000000000162e-02 1.773500000000000076e-02 5.251500000000000525e-04 -2.283400000000000013e-02 1.587099999999999969e-02 4.818800000000000145e-04 -2.306100000000000164e-02 1.432499999999999919e-02 4.516200000000000162e-04 -2.329000000000000167e-02 1.427800000000000076e-02 4.522500000000000153e-04 -2.352200000000000124e-02 1.266199999999999964e-02 4.198499999999999867e-04 -2.375499999999999834e-02 1.221299999999999990e-02 4.137899999999999803e-04 -2.399199999999999944e-02 1.046099999999999981e-02 3.745299999999999801e-04 -2.423000000000000154e-02 1.061299999999999917e-02 3.810500000000000193e-04 -2.447099999999999970e-02 9.879000000000000628e-03 3.641299999999999984e-04 -2.471500000000000086e-02 8.371999999999999234e-03 3.313899999999999832e-04 -2.495999999999999955e-02 7.670500000000000235e-03 3.077099999999999931e-04 -2.520899999999999877e-02 7.344899999999999693e-03 3.049799999999999972e-04 -2.545899999999999899e-02 6.798600000000000129e-03 2.898700000000000148e-04 -2.571299999999999975e-02 5.916300000000000205e-03 2.671800000000000000e-04 -2.596800000000000150e-02 5.344999999999999925e-03 2.515400000000000210e-04 -2.622700000000000031e-02 5.122699999999999997e-03 2.474099999999999910e-04 -2.648800000000000113e-02 4.750299999999999835e-03 2.379500000000000105e-04 -2.675200000000000147e-02 4.307199999999999744e-03 2.238499999999999930e-04 -2.701800000000000035e-02 4.018200000000000417e-03 2.200500000000000090e-04 -2.728699999999999876e-02 3.539200000000000158e-03 2.046499999999999871e-04 -2.755799999999999916e-02 3.818199999999999893e-03 2.079399999999999912e-04 -2.783300000000000010e-02 2.864799999999999812e-03 1.819199999999999930e-04 -2.810999999999999957e-02 2.795800000000000195e-03 1.766899999999999905e-04 -2.838999999999999857e-02 2.621500000000000132e-03 1.749999999999999982e-04 -2.867300000000000057e-02 2.484800000000000116e-03 1.694599999999999937e-04 -2.895800000000000110e-02 2.420100000000000116e-03 1.709199999999999966e-04 -2.924699999999999869e-02 2.359299999999999939e-03 1.700600000000000082e-04 -2.953799999999999829e-02 1.978600000000000064e-03 1.600200000000000027e-04 -2.983200000000000088e-02 1.947200000000000059e-03 1.582800000000000092e-04 -3.013000000000000053e-02 1.735900000000000073e-03 1.527300000000000098e-04 -3.042999999999999872e-02 1.894599999999999973e-03 1.602999999999999933e-04 -3.073299999999999990e-02 1.696699999999999988e-03 1.525700000000000114e-04 -3.103900000000000062e-02 1.793700000000000069e-03 1.592400000000000000e-04 -3.134900000000000186e-02 1.786899999999999903e-03 1.552000000000000048e-04 -3.166100000000000164e-02 1.871999999999999966e-03 1.584000000000000013e-04 -3.197699999999999848e-02 1.688199999999999944e-03 1.499799999999999972e-04 -3.229499999999999732e-02 1.732400000000000042e-03 1.543199999999999997e-04 -3.261700000000000016e-02 1.537600000000000078e-03 1.454000000000000106e-04 -3.294199999999999906e-02 1.541300000000000005e-03 1.497600000000000027e-04 -3.327100000000000196e-02 1.700300000000000075e-03 1.572099999999999941e-04 -3.360300000000000092e-02 2.142199999999999920e-03 1.728900000000000066e-04 -3.393800000000000289e-02 1.943999999999999981e-03 1.686900000000000129e-04 -3.422100000000000142e-02 1.913999999999999903e-03 1.077099999999999970e-04 -3.466500000000000137e-02 1.986400000000000145e-03 1.438300000000000104e-04 -3.502199999999999758e-02 1.849699999999999912e-03 1.279700000000000097e-04 -3.538499999999999979e-02 1.932600000000000030e-03 1.227099999999999957e-04 -3.571599999999999775e-02 2.188999999999999974e-03 1.496000000000000042e-04 -3.607699999999999796e-02 2.314300000000000038e-03 1.503400000000000005e-04 -3.646800000000000042e-02 1.831799999999999965e-03 1.041600000000000056e-04 -3.682599999999999763e-02 1.797100000000000043e-03 1.012900000000000009e-04 -3.716200000000000059e-02 2.278699999999999823e-03 1.417300000000000135e-04 -3.754199999999999898e-02 2.183399999999999837e-03 1.294599999999999972e-04 -3.794000000000000150e-02 1.799000000000000035e-03 9.624999999999999496e-05 -3.831299999999999983e-02 1.828100000000000037e-03 9.734599999999999937e-05 -3.868400000000000311e-02 1.949800000000000014e-03 1.082599999999999969e-04 -3.906899999999999956e-02 2.042099999999999818e-03 1.122399999999999960e-04 -3.947300000000000114e-02 1.659499999999999951e-03 8.395500000000000510e-05 -3.986300000000000260e-02 1.620300000000000082e-03 8.073400000000000324e-05 -4.026600000000000318e-02 1.588599999999999908e-03 7.617699999999999927e-05 -4.066100000000000270e-02 1.582499999999999922e-03 7.829099999999999970e-05 -4.107000000000000234e-02 1.429900000000000008e-03 7.034400000000000277e-05 -4.147800000000000098e-02 1.336100000000000005e-03 6.498799999999999510e-05 -4.187400000000000150e-02 1.721899999999999950e-03 9.200100000000000226e-05 -4.230500000000000232e-02 1.404899999999999942e-03 6.788199999999999822e-05 -4.273199999999999915e-02 1.146499999999999950e-03 5.315200000000000203e-05 -4.315499999999999892e-02 1.030099999999999939e-03 4.872799999999999831e-05 -4.358299999999999674e-02 1.018599999999999931e-03 4.851600000000000102e-05 -4.401499999999999857e-02 1.060200000000000075e-03 5.148900000000000118e-05 -4.445500000000000146e-02 9.115599999999999528e-04 4.517699999999999792e-05 -4.489800000000000041e-02 7.795400000000000072e-04 3.746800000000000109e-05 -4.534699999999999842e-02 5.957599999999999745e-04 2.867799999999999885e-05 -4.579500000000000237e-02 6.476399999999999995e-04 3.286700000000000228e-05 -4.625100000000000044e-02 5.268399999999999906e-04 2.666199999999999985e-05 -4.671199999999999658e-02 4.365500000000000131e-04 2.240899999999999839e-05 -4.717799999999999772e-02 3.696099999999999798e-04 1.929699999999999837e-05 -4.764700000000000185e-02 3.315600000000000036e-04 1.808599999999999929e-05 -4.812099999999999711e-02 2.545800000000000190e-04 1.440600000000000065e-05 -4.859900000000000331e-02 2.090799999999999972e-04 1.312400000000000005e-05 -4.908300000000000163e-02 1.929400000000000060e-04 1.261600000000000084e-05 -4.957099999999999701e-02 1.309200000000000001e-04 9.992200000000000656e-06 -5.006399999999999739e-02 1.098200000000000023e-04 9.080500000000000558e-06 -5.056200000000000278e-02 9.565500000000000489e-05 8.370099999999999703e-06 -5.106499999999999928e-02 7.925700000000000366e-05 7.699100000000000537e-06 -5.157300000000000079e-02 7.956000000000000398e-05 6.898600000000000324e-06 -5.208600000000000035e-02 7.224999999999999435e-05 6.102700000000000033e-06 -5.260399999999999798e-02 7.825099999999999330e-05 6.391400000000000335e-06 -5.312800000000000161e-02 8.637100000000000365e-05 6.561899999999999804e-06 -5.365700000000000330e-02 1.331600000000000058e-04 8.789800000000000106e-06 -5.419100000000000306e-02 1.436300000000000055e-04 8.178800000000000366e-06 -5.473000000000000087e-02 1.586799999999999918e-04 8.565300000000000816e-06 -5.527399999999999675e-02 1.900100000000000053e-04 9.755199999999999367e-06 -5.582499999999999962e-02 2.354199999999999923e-04 1.141699999999999928e-05 -5.637999999999999956e-02 2.339300000000000049e-04 1.034500000000000006e-05 -5.694199999999999956e-02 2.433900000000000126e-04 1.059599999999999986e-05 -5.750899999999999762e-02 2.708599999999999918e-04 1.125099999999999951e-05 -5.808100000000000068e-02 3.109699999999999856e-04 1.233600000000000014e-05 -5.865999999999999687e-02 3.483299999999999938e-04 1.357899999999999992e-05 -5.924399999999999805e-02 3.329599999999999834e-04 1.275599999999999950e-05 -5.983399999999999830e-02 3.546600000000000230e-04 1.322400000000000078e-05 -6.042999999999999761e-02 3.544700000000000129e-04 1.306599999999999992e-05 -6.103200000000000292e-02 3.855199999999999816e-04 1.408900000000000012e-05 -6.164000000000000035e-02 3.325099999999999996e-04 1.201800000000000081e-05 -6.225399999999999684e-02 3.330900000000000245e-04 1.197199999999999989e-05 -6.287399999999999933e-02 3.303100000000000003e-04 1.197199999999999989e-05 -6.350100000000000189e-02 3.224699999999999941e-04 1.162899999999999996e-05 -6.413399999999999657e-02 2.744600000000000251e-04 9.948800000000000360e-06 -6.477299999999999724e-02 2.792399999999999895e-04 1.025400000000000042e-05 -6.541800000000000392e-02 2.389400000000000128e-04 8.960899999999999196e-06 -6.607000000000000373e-02 2.330300000000000101e-04 8.726700000000000659e-06 -6.672899999999999665e-02 1.863400000000000082e-04 7.236100000000000057e-06 -6.739399999999999558e-02 1.649499999999999979e-04 6.619499999999999896e-06 -6.806600000000000150e-02 1.332399999999999915e-04 5.541599999999999594e-06 -6.874500000000000055e-02 1.153799999999999965e-04 4.971599999999999969e-06 -6.943000000000000560e-02 8.250300000000000613e-05 3.951200000000000388e-06 -7.012200000000000377e-02 6.719200000000000313e-05 3.570200000000000139e-06 -7.082099999999999507e-02 5.033199999999999854e-05 2.926200000000000037e-06 -7.152799999999999436e-02 3.336100000000000128e-05 2.509699999999999874e-06 -7.224099999999999966e-02 2.290499999999999839e-05 2.116400000000000184e-06 -7.293399999999999883e-02 1.879399999999999997e-05 1.860500000000000017e-06 -7.366799999999999737e-02 1.553400000000000069e-05 1.798199999999999995e-06 -7.440099999999999492e-02 1.824499999999999896e-05 1.951800000000000100e-06 -7.513999999999999846e-02 2.235600000000000076e-05 1.800999999999999994e-06 -7.587199999999999500e-02 2.773600000000000007e-05 1.890099999999999911e-06 -7.663999999999999979e-02 3.931000000000000141e-05 2.300899999999999858e-06 -7.739600000000000646e-02 4.596700000000000222e-05 2.332399999999999895e-06 -7.810599999999999488e-02 5.541299999999999953e-05 2.459299999999999900e-06 -7.886799999999999367e-02 6.726000000000000316e-05 2.729600000000000090e-06 -7.979500000000000481e-02 7.650600000000000239e-05 2.773100000000000182e-06 -8.072899999999999521e-02 7.794700000000000435e-05 2.857399999999999951e-06 -8.153299999999999437e-02 8.505400000000000254e-05 2.990400000000000202e-06 -8.233200000000000240e-02 9.685699999999999778e-05 3.222700000000000078e-06 -8.315999999999999781e-02 9.462399999999999392e-05 3.166199999999999857e-06 -8.402500000000000246e-02 8.585599999999999927e-05 2.824499999999999808e-06 -8.486499999999999599e-02 8.101399999999999379e-05 2.662499999999999919e-06 -8.573400000000000465e-02 7.655899999999999663e-05 2.549800000000000134e-06 -8.655500000000000693e-02 7.385400000000000135e-05 2.485799999999999985e-06 -8.743700000000000083e-02 6.249699999999999472e-05 2.190900000000000064e-06 -8.831600000000000561e-02 5.495400000000000274e-05 2.001299999999999795e-06 -8.911099999999999577e-02 5.694499999999999774e-05 2.081600000000000111e-06 -9.004199999999999704e-02 4.229200000000000098e-05 1.729699999999999931e-06 -9.095499999999999419e-02 3.367499999999999861e-05 1.458899999999999915e-06 -9.185000000000000109e-02 2.545600000000000158e-05 1.249600000000000072e-06 -9.274399999999999311e-02 2.092200000000000060e-05 1.159800000000000102e-06 -9.362900000000000389e-02 1.531099999999999960e-05 1.060100000000000023e-06 -9.455299999999999816e-02 1.265600000000000046e-05 9.577500000000000628e-07 -9.551800000000000568e-02 9.331199999999999700e-06 8.621400000000000160e-07 -9.647699999999999332e-02 8.901499999999999392e-06 7.828999999999999496e-07 -9.741900000000000559e-02 1.079100000000000053e-05 8.938500000000000266e-07 -9.842599999999999960e-02 1.213699999999999916e-05 9.113100000000000255e-07 -9.941999999999999449e-02 1.540799999999999885e-05 9.077799999999999932e-07 -1.004300000000000054e-01 1.938000000000000080e-05 9.602500000000000389e-07 -1.014300000000000063e-01 2.091199999999999900e-05 1.040900000000000063e-06 -1.024999999999999939e-01 2.519199999999999868e-05 1.078399999999999916e-06 -1.034999999999999948e-01 2.818799999999999846e-05 1.132199999999999934e-06 -1.045500000000000040e-01 2.998099999999999976e-05 1.178500000000000024e-06 -1.056099999999999955e-01 3.056299999999999859e-05 1.150500000000000038e-06 -1.066799999999999971e-01 2.818999999999999945e-05 1.099099999999999988e-06 -1.077599999999999947e-01 2.692599999999999936e-05 1.037400000000000012e-06 -1.088299999999999962e-01 2.541899999999999837e-05 1.012600000000000054e-06 -1.099200000000000038e-01 2.282700000000000015e-05 9.367100000000000279e-07 -1.110399999999999998e-01 1.769199999999999934e-05 7.904499999999999875e-07 -1.121199999999999974e-01 1.547500000000000007e-05 7.625400000000000506e-07 -1.132399999999999934e-01 1.172599999999999920e-05 6.687999999999999536e-07 -1.143200000000000049e-01 1.050299999999999922e-05 6.598099999999999770e-07 -1.154599999999999932e-01 8.121500000000000084e-06 5.846999999999999880e-07 -1.166399999999999937e-01 4.988800000000000415e-06 5.267199999999999943e-07 -1.177600000000000036e-01 4.909999999999999577e-06 5.361000000000000426e-07 -1.189299999999999941e-01 5.304300000000000189e-06 5.240799999999999654e-07 -1.201300000000000007e-01 5.689100000000000300e-06 4.912300000000000385e-07 -1.213499999999999995e-01 6.444700000000000316e-06 5.061099999999999705e-07 -1.225900000000000045e-01 7.456199999999999864e-06 5.057999999999999896e-07 -1.238199999999999995e-01 8.248400000000000512e-06 5.025600000000000215e-07 -1.250900000000000067e-01 1.067500000000000028e-05 5.845400000000000184e-07 -1.263600000000000001e-01 1.131599999999999974e-05 5.722299999999999829e-07 -1.276400000000000035e-01 1.104399999999999963e-05 5.762600000000000528e-07 -1.289299999999999891e-01 1.062599999999999957e-05 5.655300000000000090e-07 -1.302099999999999924e-01 9.337700000000000400e-06 5.254700000000000063e-07 -1.315500000000000003e-01 8.922800000000000357e-06 5.000700000000000038e-07 -1.328499999999999959e-01 6.436100000000000093e-06 4.446899999999999936e-07 -1.341600000000000015e-01 6.181099999999999994e-06 4.556199999999999995e-07 -1.355099999999999916e-01 4.685699999999999878e-06 4.034800000000000104e-07 -1.368199999999999972e-01 4.667499999999999781e-06 3.809300000000000103e-07 -1.381999999999999895e-01 4.262500000000000270e-06 3.763000000000000013e-07 -1.395899999999999919e-01 3.884300000000000232e-06 3.571600000000000033e-07 -1.409900000000000042e-01 3.699499999999999901e-06 3.796599999999999996e-07 -1.424300000000000010e-01 3.659899999999999890e-06 3.543399999999999820e-07 -1.438500000000000056e-01 4.559399999999999918e-06 3.665699999999999797e-07 -1.452600000000000002e-01 4.580899999999999627e-06 3.470599999999999856e-07 -1.467499999999999916e-01 4.829299999999999655e-06 3.503900000000000029e-07 -1.482199999999999906e-01 4.930899999999999665e-06 3.533300000000000014e-07 -1.497100000000000097e-01 4.780999999999999626e-06 3.612599999999999937e-07 -1.512199999999999933e-01 4.644799999999999981e-06 3.397100000000000158e-07 -1.527399999999999869e-01 4.365099999999999932e-06 3.324600000000000005e-07 -1.542600000000000082e-01 3.807099999999999938e-06 3.253800000000000191e-07 -1.558199999999999863e-01 3.544199999999999880e-06 3.053900000000000102e-07 -1.573700000000000099e-01 2.632699999999999798e-06 2.773599999999999902e-07 -1.589399999999999979e-01 2.129700000000000125e-06 2.570600000000000003e-07 -1.605100000000000138e-01 2.509099999999999829e-06 2.684200000000000173e-07 -1.621400000000000063e-01 2.606299999999999932e-06 2.683499999999999909e-07 -1.637599999999999889e-01 2.467999999999999918e-06 2.618099999999999866e-07 -1.653999999999999915e-01 2.437699999999999971e-06 2.457099999999999946e-07 -1.670300000000000118e-01 2.818500000000000204e-06 2.626300000000000164e-07 -1.687400000000000011e-01 3.201900000000000210e-06 2.677200000000000177e-07 -1.704100000000000059e-01 3.020999999999999960e-06 2.548700000000000052e-07 -1.721199999999999952e-01 2.398600000000000210e-06 2.324600000000000050e-07 -1.738399999999999945e-01 2.458200000000000029e-06 2.385499999999999755e-07 -1.755700000000000038e-01 2.033700000000000112e-06 2.231999999999999869e-07 -1.773399999999999976e-01 1.684000000000000097e-06 2.048299999999999885e-07 -1.790899999999999992e-01 1.293800000000000005e-06 2.007699999999999906e-07 -1.809099999999999875e-01 1.439699999999999955e-06 1.882099999999999893e-07 -1.827100000000000113e-01 1.540200000000000094e-06 1.999999999999999909e-07 -1.845400000000000096e-01 1.338499999999999975e-06 1.864800000000000128e-07 -1.863799999999999901e-01 1.616000000000000071e-06 1.863699999999999940e-07 -1.882500000000000007e-01 1.493499999999999973e-06 1.883900000000000081e-07 -1.901299999999999935e-01 2.059699999999999948e-06 1.920699999999999987e-07 -1.920399999999999885e-01 1.690199999999999928e-06 1.767699999999999874e-07 -1.939500000000000113e-01 1.488400000000000014e-06 1.792699999999999900e-07 -1.958999999999999908e-01 1.403800000000000010e-06 1.747300000000000036e-07 -1.978600000000000081e-01 1.346899999999999971e-06 1.705699999999999981e-07 -1.998399999999999899e-01 9.477100000000000073e-07 1.617800000000000100e-07 -2.018300000000000094e-01 1.089599999999999910e-06 1.735000000000000117e-07 -2.038600000000000134e-01 1.246300000000000036e-06 1.654700000000000120e-07 -2.058999999999999997e-01 1.227400000000000098e-06 1.644900000000000125e-07 -2.079600000000000060e-01 1.168999999999999946e-06 1.584600000000000041e-07 -2.100400000000000045e-01 1.161700000000000033e-06 1.521999999999999997e-07 -2.121399999999999952e-01 1.216899999999999945e-06 1.588499999999999964e-07 -2.142600000000000060e-01 1.317600000000000099e-06 1.546100000000000060e-07 -2.164000000000000090e-01 1.032800000000000090e-06 1.472899999999999908e-07 -2.185699999999999865e-01 1.030699999999999932e-06 1.514699999999999925e-07 -2.207800000000000040e-01 5.945299999999999642e-07 1.511699999999999964e-07 -2.229899999999999938e-01 7.279999999999999544e-07 1.429299999999999967e-07 -2.252200000000000035e-01 7.806299999999999697e-07 1.485200000000000091e-07 -2.274700000000000055e-01 1.063400000000000059e-06 1.499299999999999932e-07 -2.297399999999999998e-01 6.527000000000000146e-07 1.296699999999999958e-07 -2.320399999999999963e-01 1.074400000000000039e-06 1.484500000000000091e-07 -2.343600000000000128e-01 8.687600000000000051e-07 1.468600000000000061e-07 -2.366999999999999937e-01 9.218700000000000353e-07 1.450799999999999994e-07 -2.390599999999999947e-01 6.471500000000000212e-07 1.368099999999999922e-07 -2.414499999999999980e-01 5.363900000000000008e-07 1.356899999999999928e-07 -2.438700000000000034e-01 6.337199999999999863e-07 1.304000000000000030e-07 -2.462999999999999912e-01 6.292699999999999696e-07 1.365599999999999999e-07 -2.487699999999999911e-01 6.332899999999999751e-07 1.224499999999999881e-07 -2.512499999999999734e-01 1.037099999999999989e-06 1.354099999999999929e-07 -2.537599999999999856e-01 8.252900000000000003e-07 1.431599999999999928e-07 -2.562999999999999723e-01 6.268299999999999557e-07 1.192599999999999972e-07 -2.588599999999999790e-01 5.252600000000000328e-07 1.227399999999999993e-07 -2.614500000000000157e-01 5.218300000000000081e-07 1.309200000000000103e-07 -2.640600000000000169e-01 3.916600000000000012e-07 1.213700000000000075e-07 -2.666999999999999926e-01 4.724400000000000138e-07 1.399700000000000020e-07 -2.693699999999999983e-01 5.595400000000000460e-07 1.391499999999999986e-07 -2.720600000000000240e-01 6.640700000000000430e-07 1.448699999999999996e-07 -2.747800000000000242e-01 4.593799999999999750e-07 1.514699999999999925e-07 -2.775299999999999989e-01 3.669599999999999984e-07 1.435500000000000116e-07 -2.802999999999999936e-01 5.315299999999999957e-07 1.483100000000000092e-07 -2.831000000000000183e-01 4.289099999999999939e-07 1.361500000000000115e-07 -2.859300000000000175e-01 5.520100000000000308e-07 1.419800000000000048e-07 -2.887899999999999912e-01 5.702600000000000255e-07 1.528999999999999993e-07 -2.916799999999999948e-01 5.047299999999999939e-07 1.364300000000000113e-07 -2.945999999999999730e-01 6.619199999999999873e-07 1.407900000000000054e-07 -2.975400000000000267e-01 7.601300000000000177e-07 1.607199999999999992e-07 -3.005200000000000093e-01 4.685299999999999742e-07 1.348900000000000121e-07 -3.035200000000000120e-01 4.428599999999999832e-07 1.471299999999999946e-07 -3.065499999999999892e-01 4.899800000000000504e-07 1.404299999999999942e-07 -3.096200000000000063e-01 3.601600000000000169e-07 1.337299999999999938e-07 -3.127099999999999880e-01 2.905599999999999760e-07 1.480599999999999904e-07 -3.158400000000000096e-01 5.199599999999999523e-07 1.515599999999999887e-07 -3.190000000000000058e-01 4.666699999999999827e-07 1.562599999999999977e-07 -3.221899999999999764e-01 3.888800000000000253e-07 1.570100000000000011e-07 -3.254099999999999770e-01 4.467799999999999812e-07 1.555099999999999942e-07 -3.286600000000000077e-01 3.238800000000000123e-07 1.525899999999999919e-07 -3.319500000000000228e-01 3.787400000000000152e-07 1.581800000000000043e-07 -3.352700000000000125e-01 3.881999999999999954e-07 1.539100000000000064e-07 -3.386199999999999766e-01 4.428800000000000059e-07 1.491000000000000050e-07 -3.420000000000000262e-01 2.477900000000000238e-07 1.463200000000000026e-07 -3.454200000000000048e-01 2.857699999999999973e-07 1.351299999999999931e-07 -3.488800000000000234e-01 4.759599999999999818e-07 1.536599999999999876e-07 -3.523600000000000065e-01 4.496399999999999949e-07 1.539600000000000101e-07 -3.558899999999999841e-01 2.471499999999999863e-07 1.443200000000000112e-07 -3.594499999999999917e-01 2.167599999999999901e-07 1.491799999999999898e-07 -3.630399999999999738e-01 5.205899999999999784e-07 1.573700000000000122e-07 -3.666699999999999959e-01 5.247000000000000331e-07 1.545400000000000061e-07 -3.703400000000000025e-01 3.644000000000000072e-07 1.550199999999999945e-07 -3.740399999999999836e-01 4.597500000000000239e-07 1.653099999999999894e-07 -3.777800000000000047e-01 5.359200000000000502e-07 1.820400000000000075e-07 -3.815500000000000003e-01 4.268099999999999950e-07 1.770000000000000100e-07 -3.853699999999999903e-01 4.036700000000000141e-07 1.811100000000000117e-07 -3.892200000000000104e-01 2.554499999999999746e-07 1.597299999999999884e-07 -3.931100000000000150e-01 9.269699999999999950e-08 1.654000000000000120e-07 -3.970400000000000040e-01 1.106699999999999977e-07 1.808900000000000005e-07 -4.010099999999999776e-01 4.521599999999999937e-07 1.731900000000000043e-07 -4.050199999999999911e-01 3.780699999999999966e-07 1.516000000000000075e-07 -4.090699999999999892e-01 3.091399999999999743e-07 1.571899999999999934e-07 -4.131600000000000272e-01 3.417700000000000223e-07 1.448199999999999958e-07 -4.172899999999999943e-01 3.449199999999999943e-07 1.595800000000000036e-07 -4.214700000000000113e-01 2.518400000000000105e-07 1.597599999999999959e-07 -4.256800000000000028e-01 4.017399999999999962e-07 1.538099999999999989e-07 -4.299399999999999888e-01 3.172799999999999929e-07 1.691300000000000064e-07 -4.342300000000000049e-01 5.506299999999999483e-07 1.611399999999999990e-07 -4.385800000000000254e-01 5.085100000000000450e-07 1.649899999999999971e-07 -4.429600000000000204e-01 6.025899999999999980e-07 1.738299999999999889e-07 -4.473900000000000099e-01 4.384500000000000119e-07 1.653500000000000082e-07 -4.518699999999999939e-01 3.387599999999999973e-07 1.876400000000000047e-07 -4.563800000000000079e-01 4.358499999999999754e-07 1.978299999999999920e-07 -4.609500000000000264e-01 3.855799999999999891e-07 1.761399999999999877e-07 -4.655500000000000194e-01 3.834100000000000166e-07 1.884499999999999967e-07 diff --git a/tests/test_data/plotting_data.pickle b/tests/test_data/plotting_data.pickle deleted file mode 100644 index 7e05cab1..00000000 Binary files a/tests/test_data/plotting_data.pickle and /dev/null differ diff --git a/tests/test_data/prist.json b/tests/test_data/prist.json deleted file mode 100644 index 3b36893e..00000000 --- a/tests/test_data/prist.json +++ /dev/null @@ -1 +0,0 @@ -{"name": "Example Project", "calculation": "normal", "model": "standard layers", "geometry": "air/substrate", "absorption": false, "parameters": [{"name": "Substrate Roughness", "min": 1.0, "value": 3.0, "max": 5.0, "fit": true, "prior_type": "uniform", "mu": 0.0, "sigma": Infinity, "show_priors": false}, {"name": "Al2O3 Thickness", "min": 20.0, "value": 20.0, "max": 20.0, "fit": false, "prior_type": "uniform", "mu": 0.0, "sigma": Infinity, "show_priors": false}, {"name": "Al2O3 Roughness", "min": 3.0, "value": 3.0, "max": 3.0, "fit": false, "prior_type": "uniform", "mu": 0.0, "sigma": Infinity, "show_priors": false}, {"name": "Al2O3 SLD", "min": 5.715275837467511e-06, "value": 5.715275837467511e-06, "max": 5.715275837467511e-06, "fit": false, "prior_type": "uniform", "mu": 0.0, "sigma": Infinity, "show_priors": false}, {"name": "Ti0.27Co0.73 Thickness", "min": 93.0, "value": 93.0, "max": 93.0, "fit": false, "prior_type": "uniform", "mu": 0.0, "sigma": Infinity, "show_priors": false}, {"name": "Ti0.27Co0.73 Roughness", "min": 3.0, "value": 3.0, "max": 3.0, "fit": false, "prior_type": "uniform", "mu": 0.0, "sigma": Infinity, "show_priors": false}, {"name": "Ti0.27Co0.73 SLD", "min": 6.720584953375607e-07, "value": 6.720584953375607e-07, "max": 6.720584953375607e-07, "fit": false, "prior_type": "uniform", "mu": 0.0, "sigma": Infinity, "show_priors": false}], "bulk_in": [{"name": "vacuum SLD", "min": 0.0, "value": 0.0, "max": 0.0, "fit": false, "prior_type": "uniform", "mu": 0.0, "sigma": Infinity, "show_priors": false}], "bulk_out": [{"name": "Si SLD", "min": 2.07370547828562e-06, "value": 2.07370547828562e-06, "max": 2.07370547828562e-06, "fit": false, "prior_type": "uniform", "mu": 0.0, "sigma": Infinity, "show_priors": false}], "scalefactors": [{"name": "Scalefactor", "min": 0.0, "value": 1.0, "max": 1.5, "fit": true, "prior_type": "uniform", "mu": 0.0, "sigma": Infinity, "show_priors": false}], "domain_ratios": [], "background_parameters": [{"name": "Background Parameter", "min": 0.0, "value": 0.025, "max": 1.0, "fit": true, "prior_type": "uniform", "mu": 0.0, "sigma": Infinity, "show_priors": false}], "backgrounds": [{"name": "Background", "type": "constant", "source": "Background Parameter", "value_1": "", "value_2": "", "value_3": "", "value_4": "", "value_5": ""}], "resolution_parameters": [{"name": "Resolution Param 1", "min": 0.01, "value": 0.03, "max": 0.05, "fit": false, "prior_type": "uniform", "mu": 0.0, "sigma": Infinity, "show_priors": false}], "resolutions": [{"name": "Data Resolution", "type": "data", "source": "", "value_1": "", "value_2": "", "value_3": "", "value_4": "", "value_5": ""}], "custom_files": [], "data": [{"name": "Simulation", "data": [], "data_range": [], "simulation_range": [0.005, 0.7]}, {"name": "prist4", "data": [[0.0021999999999999997, 0.004724119389721505, 0.004724119389721505, 0.00019999999999999987], [0.0026, 0.0, 0.0, 0.0002000000000000001], [0.003, 0.0049441079014990305, 0.0028632759811688313, 0.0002000000000000001], [0.0034000000000000002, 0.00539571466421478, 0.0027033018099334193, 0.00019999999999999987], [0.0038, 0.011948517768746966, 0.0037903477990210636, 0.0002000000000000001], [0.004200000000000001, 0.016302332669940297, 0.003972317564845323, 0.0002000000000000001], [0.0046, 0.02265216487165058, 0.0045763672802481776, 0.0002000000000000001], [0.005, 0.023020814468949415, 0.00425372711337262, 0.00019999999999999966], [0.0054, 0.027305557750665344, 0.004428700971127359, 0.0002000000000000001], [0.0058, 0.019457945835850306, 0.0037817426451169783, 0.0002000000000000001], [0.006200000000000001, 0.027645506109865266, 0.004267993991409073, 0.0002000000000000001], [0.0066, 0.024223034347324195, 0.0037655052701117517, 0.0002000000000000001], [0.007, 0.028408308819418325, 0.0037377941755602716, 0.00019999999999999966], [0.0074, 0.057460495308053604, 0.0052154049057105455, 0.0002000000000000001], [0.0078, 0.1489883351950982, 0.00754789840356179, 0.0002000000000000001], [0.008199999999999999, 0.3520480929443021, 0.011146891694516669, 0.00019999999999999966], [0.0086, 0.5317657760789548, 0.01351725179531962, 0.00019999999999999966], [0.009, 0.7914500646501588, 0.016276277463585134, 0.00020000000000000052], [0.009399999999999999, 0.9680331047846104, 0.01782748799306378, 0.00019999999999999966], [0.0098, 1.0324643310179094, 0.018104900945963596, 0.00020000000000000052], [0.010204081632653062, 0.6287661683321234, 0.013873373556929145, 0.00020408163265306107], [0.010620574760516453, 0.3506955915110479, 0.010136613757789808, 0.00021241149521033023], [0.011054067607884473, 0.23477751708069897, 0.008109962639928676, 0.000221081352157689], [0.011505254040859348, 0.18964302712880826, 0.007180573014831645, 0.00023010508081718756], [0.011974856246608712, 0.14285208497806512, 0.006016224926747713, 0.00023949712493217482], [0.012463625889327434, 0.12188457497836602, 0.005435279585343197, 0.00024927251778654805], [0.012972345313381616, 0.10530945504618572, 0.005027517945960155, 0.00025944690626763297], [0.013501828795560456, 0.08038795087657985, 0.004197556276825506, 0.0002700365759112089], [0.014052923848440476, 0.07313672279549625, 0.003958200398418697, 0.00028105847696880976], [0.01462651257694825, 0.06129841978151465, 0.0034783001152817426, 0.0002925302515389659], [0.01522351309029308, 0.06240905936586468, 0.003479800062460076, 0.000304470261805862], [0.015844880971529533, 0.05651280096554304, 0.0032223775371921573, 0.00031689761943059103], [0.016491610807102167, 0.05044073793552524, 0.00290210672478378, 0.0003298322161420439], [0.017164737778820625, 0.0502775250441711, 0.002825286449304508, 0.00034329475557641313], [0.0178653393208133, 0.05168970509722787, 0.002811814341605395, 0.0003573067864162654], [0.018594536844111803, 0.0530076187705834, 0.0027685413804410695, 0.00037189073688223724], [0.019353497531626573, 0.0490707566771454, 0.0025677593751218504, 0.00038706995063253133], [0.020143436206386842, 0.04687883170966378, 0.0024119133732668076, 0.0004028687241277376], [0.020965617276035284, 0.04919955377214455, 0.0024276503561561644, 0.0004193123455207056], [0.021821356756689787, 0.05204111270310913, 0.00245561515567379, 0.00043642713513379616], [0.022712024379411822, 0.04925178172610669, 0.0023335505076022252, 0.00045424048758823873], [0.02363904578265312, 0.04317260894774357, 0.00211385396560445, 0.0004727809156530611], [0.024603904794189984, 0.0383043276355005, 0.0019158755178575817, 0.0004920780958838009], [0.02560814580619774, 0.04444220010645997, 0.002018641932709427, 0.0005121629161239545], [0.026653376247267036, 0.039587001147536376, 0.0018488058581743547, 0.0005330675249453423], [0.027741269155318757, 0.036677858215866437, 0.0017473224966445143, 0.0005548253831063766], [0.028873565855535847, 0.037663512267048754, 0.0017682821318945074, 0.0005774713171107174], [0.030052078747598535, 0.036755569252809664, 0.0017350440273063527, 0.0006010415749519698], [0.03127869420668419, 0.03854639441776167, 0.0017965558626918197, 0.0006255738841336837], [0.032555375602875386, 0.032866785139061716, 0.0016217721152892931, 0.000651107512057509], [0.03388416644380907, 0.0315131968037535, 0.0016061232808323794, 0.0006776833288761816], [0.0352671936455972, 0.030280345918169513, 0.0015885947028228238, 0.0007053438729119448], [0.03670667093725423, 0.025036982048446406, 0.0014176844815086535, 0.0007341334187450851], [0.038204902404080934, 0.02083180456328542, 0.001280336546816776, 0.0007640980480816198], [0.03976428617567608, 0.019376976329704945, 0.0012712203272554497, 0.0007952857235135231], [0.04138731826447918, 0.016729675515039004, 0.0011715497338181137, 0.000827746365289584], [0.04307659656098854, 0.013996303090353096, 0.0010654383375290077, 0.0008615319312197701], [0.0448348249920493, 0.010621480384334052, 0.0009246807782300395, 0.0008966964998409904], [0.04666481784886764, 0.007820332463525126, 0.0008093102454836752, 0.000933296356977354], [0.04856950429167857, 0.0060428022894521575, 0.0007183835413384203, 0.0009713900858335685], [0.050551933038277694, 0.004095892971484393, 0.0005841670446995313, 0.0010110386607655557], [0.05261527724392169, 0.005111525161941947, 0.0006658003030884043, 0.0010523055448784409], [0.05476283958040829, 0.0020207116612746484, 0.0004143866059231477, 0.0010952567916081637], [0.05699805752246577, 0.001711568931414378, 0.00038529038925611664, 0.0011399611504493146], [0.05932450884991336, 0.0008496305883131249, 0.00027095330976641694, 0.001186490176998272], [0.06174591737439962, 0.0008142116035177235, 0.00027251395576638693, 0.0012349183474879948], [0.06426615889988532, 8.92042382623096e-05, 8.920423826322552e-05, 0.0012853231779977048], [0.06688926742641126, 9.339736346561163e-05, 9.339736346489978e-05, 0.0013377853485282282], [0.06961944160708111, 0.00040599169078880156, 0.0002030320824188672, 0.0013923888321416208], [0.07246105146859462, 0.0002183257352075823, 0.00015439324988622013, 0.0014492210293718943], [0.07541864540608828, 0.00012684339163879, 0.00012684339163797725, 0.001508372908121773], [0.07849695746347965, 0.0, 0.0, 0.001569939149269589], [0.08170091491096862, 0.0, 0.0, 0.0016340182982193738], [0.08503564613182449, 0.0004165748322677754, 0.00024090333523406435, 0.001700712922636495], [0.08850648883108263, 0.0, 0.0, 0.0017701297766216512], [0.09211899857929008, 0.0, 0.0, 0.001842379971585803], [0.0958789577049754, 0.0, 0.0, 0.0019175791540995135], [0.09979238455007644, 0.0, 0.0, 0.001995847691001529], [0.10386554310314079, 0.0, 0.0, 0.0020773108620628228]], "data_range": [0.0021999999999999997, 0.10386554310314079], "simulation_range": [0.0021999999999999997, 0.10386554310314079]}], "layers": [{"name": "Al2O3", "thickness": "Al2O3 Thickness", "SLD": "Al2O3 SLD", "roughness": "Al2O3 Roughness", "hydration": "", "hydrate_with": "bulk out"}, {"name": "Ti0.27Co0.73", "thickness": "Ti0.27Co0.73 Thickness", "SLD": "Ti0.27Co0.73 SLD", "roughness": "Ti0.27Co0.73 Roughness", "hydration": "", "hydrate_with": "bulk out"}], "domain_contrasts": [], "contrasts": [{"name": "prist4", "data": "prist4", "background": "Background", "background_action": "add", "bulk_in": "vacuum SLD", "bulk_out": "Si SLD", "scalefactor": "Scalefactor", "resolution": "Data Resolution", "resample": false, "model": ["Al2O3", "Ti0.27Co0.73"]}]} \ No newline at end of file diff --git a/tests/test_data/prist5_10K_m_025.Rqz.ort b/tests/test_data/prist5_10K_m_025.Rqz.ort deleted file mode 100644 index 5b60b8fc..00000000 --- a/tests/test_data/prist5_10K_m_025.Rqz.ort +++ /dev/null @@ -1,124 +0,0 @@ -# # ORSO reflectivity data file | 1.0 standard | YAML encoding | https://www.reflectometry.org/ -# data_source: -# owner: -# name: Artur Glavic -# affiliation: null -# contact: b'' -# experiment: -# title: Structural evolution of the CO2/Water interface -# instrument: Amor -# start_date: 2023-11-29T10:12:45 -# probe: neutron -# facility: SINQ@PSI -# proposalID: '20230368' -# sample: -# name: prist4 -# sample_parameters: -# tempMean: {magnitude: -9999.0} -# model: -# stack: vacuum | Al2O3 2 | Ti0.27Co0.73 9.3 | Si -# measurement: -# instrument_settings: -# incident_angle: {min: 0.0950000000000002, max: 1.495, unit: deg} -# wavelength: {min: 3.0, max: 12.0, unit: angstrom} -# mu: {magnitude: 0.25, unit: deg, comment: sample angle to referece direction} -# nu: {magnitude: 1.0450000000000002, unit: deg, comment: detector angle to referece -# direction} -# data_files: -# - file: raw/amor2023n000848.hdf -# timestamp: 2023-11-29T10:12:45 -# amor_monitor: 1792.443302905 -# scheme: angle- and energy-dispersive -# references: [] -# amor_monitor: 1792.443302905 -# reduction: -# software: {name: eos, version: '2.0'} -# timestamp: 2023-11-29T10:57:48.480339 -# computer: amor.psi.ch -# call: eos.py -a 0.04 -F 0.0093,0.0101 -n 848 prist5_10K_m_025 -# data_set: 0 -# columns: -# - {name: Qz, unit: 1/angstrom, physical_quantity: normal momentum transfer} -# - {name: R, unit: '', physical_quantity: specular reflectivity} -# - {error_of: R, error_type: uncertainty, value_is: sigma} -# - {error_of: Qz, error_type: resolution, value_is: sigma} -# # Qz (1/angstrom) R () sR sQz -2.1999999999999997e-03 4.7241193897215048e-03 4.7241193897215048e-03 1.9999999999999987e-04 -2.5999999999999999e-03 0.0000000000000000e+00 0.0000000000000000e+00 2.0000000000000009e-04 -3.0000000000000001e-03 4.9441079014990305e-03 2.8632759811688313e-03 2.0000000000000009e-04 -3.4000000000000002e-03 5.3957146642147798e-03 2.7033018099334193e-03 1.9999999999999987e-04 -3.8000000000000000e-03 1.1948517768746966e-02 3.7903477990210636e-03 2.0000000000000009e-04 -4.2000000000000006e-03 1.6302332669940297e-02 3.9723175648453228e-03 2.0000000000000009e-04 -4.5999999999999999e-03 2.2652164871650581e-02 4.5763672802481776e-03 2.0000000000000009e-04 -5.0000000000000001e-03 2.3020814468949415e-02 4.2537271133726200e-03 1.9999999999999966e-04 -5.4000000000000003e-03 2.7305557750665344e-02 4.4287009711273589e-03 2.0000000000000009e-04 -5.7999999999999996e-03 1.9457945835850306e-02 3.7817426451169783e-03 2.0000000000000009e-04 -6.2000000000000006e-03 2.7645506109865266e-02 4.2679939914090732e-03 2.0000000000000009e-04 -6.6000000000000000e-03 2.4223034347324195e-02 3.7655052701117517e-03 2.0000000000000009e-04 -7.0000000000000001e-03 2.8408308819418325e-02 3.7377941755602716e-03 1.9999999999999966e-04 -7.4000000000000003e-03 5.7460495308053604e-02 5.2154049057105455e-03 2.0000000000000009e-04 -7.7999999999999996e-03 1.4898833519509819e-01 7.5478984035617898e-03 2.0000000000000009e-04 -8.1999999999999990e-03 3.5204809294430212e-01 1.1146891694516669e-02 1.9999999999999966e-04 -8.6000000000000000e-03 5.3176577607895481e-01 1.3517251795319620e-02 1.9999999999999966e-04 -8.9999999999999993e-03 7.9145006465015877e-01 1.6276277463585134e-02 2.0000000000000052e-04 -9.3999999999999986e-03 9.6803310478461035e-01 1.7827487993063780e-02 1.9999999999999966e-04 -9.7999999999999997e-03 1.0324643310179094e+00 1.8104900945963596e-02 2.0000000000000052e-04 -1.0204081632653062e-02 6.2876616833212340e-01 1.3873373556929145e-02 2.0408163265306107e-04 -1.0620574760516453e-02 3.5069559151104790e-01 1.0136613757789808e-02 2.1241149521033023e-04 -1.1054067607884473e-02 2.3477751708069897e-01 8.1099626399286761e-03 2.2108135215768900e-04 -1.1505254040859348e-02 1.8964302712880826e-01 7.1805730148316446e-03 2.3010508081718756e-04 -1.1974856246608712e-02 1.4285208497806512e-01 6.0162249267477130e-03 2.3949712493217482e-04 -1.2463625889327434e-02 1.2188457497836602e-01 5.4352795853431970e-03 2.4927251778654805e-04 -1.2972345313381616e-02 1.0530945504618572e-01 5.0275179459601553e-03 2.5944690626763297e-04 -1.3501828795560456e-02 8.0387950876579850e-02 4.1975562768255060e-03 2.7003657591120889e-04 -1.4052923848440476e-02 7.3136722795496253e-02 3.9582003984186967e-03 2.8105847696880976e-04 -1.4626512576948251e-02 6.1298419781514651e-02 3.4783001152817426e-03 2.9253025153896592e-04 -1.5223513090293080e-02 6.2409059365864682e-02 3.4798000624600761e-03 3.0447026180586197e-04 -1.5844880971529533e-02 5.6512800965543043e-02 3.2223775371921573e-03 3.1689761943059103e-04 -1.6491610807102167e-02 5.0440737935525240e-02 2.9021067247837801e-03 3.2983221614204389e-04 -1.7164737778820625e-02 5.0277525044171101e-02 2.8252864493045079e-03 3.4329475557641313e-04 -1.7865339320813300e-02 5.1689705097227867e-02 2.8118143416053952e-03 3.5730678641626538e-04 -1.8594536844111803e-02 5.3007618770583402e-02 2.7685413804410695e-03 3.7189073688223724e-04 -1.9353497531626573e-02 4.9070756677145402e-02 2.5677593751218504e-03 3.8706995063253133e-04 -2.0143436206386842e-02 4.6878831709663782e-02 2.4119133732668076e-03 4.0286872412773761e-04 -2.0965617276035284e-02 4.9199553772144550e-02 2.4276503561561644e-03 4.1931234552070561e-04 -2.1821356756689787e-02 5.2041112703109127e-02 2.4556151556737898e-03 4.3642713513379616e-04 -2.2712024379411822e-02 4.9251781726106690e-02 2.3335505076022252e-03 4.5424048758823873e-04 -2.3639045782653120e-02 4.3172608947743572e-02 2.1138539656044499e-03 4.7278091565306109e-04 -2.4603904794189984e-02 3.8304327635500499e-02 1.9158755178575817e-03 4.9207809588380086e-04 -2.5608145806197739e-02 4.4442200106459967e-02 2.0186419327094269e-03 5.1216291612395451e-04 -2.6653376247267036e-02 3.9587001147536376e-02 1.8488058581743547e-03 5.3306752494534232e-04 -2.7741269155318757e-02 3.6677858215866437e-02 1.7473224966445143e-03 5.5482538310637659e-04 -2.8873565855535847e-02 3.7663512267048754e-02 1.7682821318945074e-03 5.7747131711071743e-04 -3.0052078747598535e-02 3.6755569252809664e-02 1.7350440273063527e-03 6.0104157495196979e-04 -3.1278694206684193e-02 3.8546394417761670e-02 1.7965558626918197e-03 6.2557388413368373e-04 -3.2555375602875386e-02 3.2866785139061716e-02 1.6217721152892931e-03 6.5110751205750897e-04 -3.3884166443809073e-02 3.1513196803753502e-02 1.6061232808323794e-03 6.7768332887618160e-04 -3.5267193645597203e-02 3.0280345918169513e-02 1.5885947028228238e-03 7.0534387291194475e-04 -3.6706670937254229e-02 2.5036982048446406e-02 1.4176844815086535e-03 7.3413341874508514e-04 -3.8204902404080934e-02 2.0831804563285421e-02 1.2803365468167761e-03 7.6409804808161980e-04 -3.9764286175676081e-02 1.9376976329704945e-02 1.2712203272554497e-03 7.9528572351352314e-04 -4.1387318264479181e-02 1.6729675515039004e-02 1.1715497338181137e-03 8.2774636528958404e-04 -4.3076596560988542e-02 1.3996303090353096e-02 1.0654383375290077e-03 8.6153193121977015e-04 -4.4834824992049299e-02 1.0621480384334052e-02 9.2468077823003954e-04 8.9669649984099042e-04 -4.6664817848867640e-02 7.8203324635251256e-03 8.0931024548367521e-04 9.3329635697735405e-04 -4.8569504291678570e-02 6.0428022894521575e-03 7.1838354133842033e-04 9.7139008583356848e-04 -5.0551933038277694e-02 4.0958929714843932e-03 5.8416704469953131e-04 1.0110386607655557e-03 -5.2615277243921690e-02 5.1115251619419473e-03 6.6580030308840434e-04 1.0523055448784409e-03 -5.4762839580408292e-02 2.0207116612746484e-03 4.1438660592314769e-04 1.0952567916081637e-03 -5.6998057522465770e-02 1.7115689314143780e-03 3.8529038925611664e-04 1.1399611504493146e-03 -5.9324508849913360e-02 8.4963058831312487e-04 2.7095330976641694e-04 1.1864901769982721e-03 -6.1745917374399620e-02 8.1421160351772355e-04 2.7251395576638693e-04 1.2349183474879948e-03 -6.4266158899885323e-02 8.9204238262309603e-05 8.9204238263225523e-05 1.2853231779977048e-03 -6.6889267426411256e-02 9.3397363465611626e-05 9.3397363464899779e-05 1.3377853485282282e-03 -6.9619441607081112e-02 4.0599169078880156e-04 2.0303208241886721e-04 1.3923888321416208e-03 -7.2461051468594620e-02 2.1832573520758229e-04 1.5439324988622013e-04 1.4492210293718943e-03 -7.5418645406088280e-02 1.2684339163878999e-04 1.2684339163797725e-04 1.5083729081217731e-03 -7.8496957463479650e-02 0.0000000000000000e+00 0.0000000000000000e+00 1.5699391492695891e-03 -8.1700914910968619e-02 0.0000000000000000e+00 0.0000000000000000e+00 1.6340182982193738e-03 -8.5035646131824488e-02 4.1657483226777538e-04 2.4090333523406435e-04 1.7007129226364950e-03 -8.8506488831082628e-02 0.0000000000000000e+00 0.0000000000000000e+00 1.7701297766216512e-03 -9.2118998579290082e-02 0.0000000000000000e+00 0.0000000000000000e+00 1.8423799715858030e-03 -9.5878957704975398e-02 0.0000000000000000e+00 0.0000000000000000e+00 1.9175791540995135e-03 -9.9792384550076441e-02 0.0000000000000000e+00 0.0000000000000000e+00 1.9958476910015288e-03 -1.0386554310314079e-01 0.0000000000000000e+00 0.0000000000000000e+00 2.0773108620628228e-03 diff --git a/tests/test_enums.py b/tests/test_enums.py deleted file mode 100644 index 3d07c308..00000000 --- a/tests/test_enums.py +++ /dev/null @@ -1,104 +0,0 @@ -"""Tests the enums module.""" - -from collections.abc import Callable - -import pytest - -from ratapi.utils.enums import ( - BackgroundActions, - BoundHandling, - Calculations, - Display, - Geometries, - Hydration, - Languages, - LayerModels, - Parallel, - Priors, - Procedures, - RATEnum, - Strategies, - TypeOptions, -) - - -@pytest.mark.parametrize( - ["test_enum", "test_str", "expected_value"], - [ - (Procedures, "calculate", Procedures.Calculate), - (Procedures, "simplex", Procedures.Simplex), - (Procedures, "ns", Procedures.NS), - (Procedures, "de", Procedures.DE), - (Procedures, "dream", Procedures.DREAM), - (Parallel, "single", Parallel.Single), - (Parallel, "points", Parallel.Points), - (Parallel, "contrasts", Parallel.Contrasts), - (Display, "off", Display.Off), - (Display, "iter", Display.Iter), - (Display, "notify", Display.Notify), - (Display, "final", Display.Final), - (BoundHandling, "off", BoundHandling.Off), - (BoundHandling, "reflect", BoundHandling.Reflect), - (BoundHandling, "bound", BoundHandling.Bound), - (BoundHandling, "fold", BoundHandling.Fold), - (TypeOptions, "constant", TypeOptions.Constant), - (TypeOptions, "data", TypeOptions.Data), - (TypeOptions, "function", TypeOptions.Function), - (BackgroundActions, "add", BackgroundActions.Add), - (BackgroundActions, "subtract", BackgroundActions.Subtract), - (Languages, "cpp", Languages.Cpp), - (Languages, "python", Languages.Python), - (Languages, "matlab", Languages.Matlab), - (Hydration, "bulk in", Hydration.BulkIn), - (Hydration, "bulk out", Hydration.BulkOut), - (Priors, "uniform", Priors.Uniform), - (Priors, "gaussian", Priors.Gaussian), - (Calculations, "normal", Calculations.Normal), - (Calculations, "domains", Calculations.Domains), - (LayerModels, "custom layers", LayerModels.CustomLayers), - (LayerModels, "custom xy", LayerModels.CustomXY), - (LayerModels, "standard layers", LayerModels.StandardLayers), - (Geometries, "air/substrate", Geometries.AirSubstrate), - (Geometries, "substrate/liquid", Geometries.SubstrateLiquid), - ], -) -def test_case_insensitivity(test_enum: Callable, test_str: str, expected_value: RATEnum) -> None: - """RAT Enums should accept string input regardless of case.""" - assert test_enum(test_str) == expected_value - assert test_enum(test_str.upper()) == expected_value - assert test_enum(test_str.title()) == expected_value - - -@pytest.mark.parametrize( - ["test_enum", "test_str", "expected_value"], - [ - (Hydration, "bulk in", Hydration.BulkIn), - (Hydration, "bulk out", Hydration.BulkOut), - (Calculations, "normal", Calculations.Normal), - (LayerModels, "custom layers", LayerModels.CustomLayers), - (LayerModels, "custom xy", LayerModels.CustomXY), - (LayerModels, "standard layers", LayerModels.StandardLayers), - ], -) -def test_dash_underscore(test_enum: Callable, test_str: str, expected_value: RATEnum) -> None: - """RAT Enums should accept dashes or underscores between words with string input.""" - assert test_enum(test_str.replace(" ", "-")) == expected_value - assert test_enum(test_str.replace(" ", "_")) == expected_value - - -@pytest.mark.parametrize( - ["test_enum", "test_str", "expected_value"], - [ - (Languages, "c++", Languages.Cpp), - ], -) -def test_alternative_spellings(test_enum: Callable, test_str: str, expected_value: RATEnum) -> None: - """RAT Enums should accept some alternative spellings.""" - assert test_enum(test_str) == expected_value - assert test_enum(test_str.upper()) == expected_value - assert test_enum(test_str.title()) == expected_value - - -def test_integer_strategies(): - """Test that strategies can be input as integers.""" - assert [Strategies(i) for i in range(1, len(Strategies) + 1)] == list(Strategies) diff --git a/tests/test_events.py b/tests/test_events.py index 06b43c39..b345fe8f 100644 --- a/tests/test_events.py +++ b/tests/test_events.py @@ -1,99 +1,48 @@ -import pickle -from unittest import mock - -import numpy as np +import unittest.mock as mock import pytest - -import ratapi.events +import rat.events -def test_event_register() -> None: +def test_event_register(): first_callback = mock.Mock() second_callback = mock.Mock() with pytest.raises(ValueError): - ratapi.events.register("Message", first_callback) + rat.events.register("Message", first_callback) - ratapi.events.register(ratapi.events.EventTypes.Message, first_callback) - result = ratapi.events.get_event_callback(ratapi.events.EventTypes.Message) + rat.events.register(rat.events.EventTypes.Message, first_callback) + result = rat.events.get_event_callback(rat.events.EventTypes.Message) assert result == [first_callback] - ratapi.events.register(ratapi.events.EventTypes.Plot, second_callback) - assert ratapi.events.get_event_callback(ratapi.events.EventTypes.Plot) == [second_callback] + rat.events.register(rat.events.EventTypes.Plot, second_callback) + assert rat.events.get_event_callback(rat.events.EventTypes.Plot) == [second_callback] - ratapi.events.register(ratapi.events.EventTypes.Message, second_callback) + rat.events.register(rat.events.EventTypes.Message, second_callback) # the list is not guaranteed to be in the same order as inputted hence the set - assert set(ratapi.events.get_event_callback(ratapi.events.EventTypes.Message)) == {first_callback, second_callback} - - ratapi.events.clear(ratapi.events.EventTypes.Message, second_callback) - result = ratapi.events.get_event_callback(ratapi.events.EventTypes.Message) - assert result == [first_callback] - result = ratapi.events.get_event_callback(ratapi.events.EventTypes.Plot) - assert result == [second_callback] - ratapi.events.clear() - assert ratapi.events.get_event_callback(ratapi.events.EventTypes.Plot) == [] - assert ratapi.events.get_event_callback(ratapi.events.EventTypes.Message) == [] + assert set(rat.events.get_event_callback(rat.events.EventTypes.Message)) == set([first_callback, second_callback]) + rat.events.clear() + assert rat.events.get_event_callback(rat.events.EventTypes.Plot) == [] + assert rat.events.get_event_callback(rat.events.EventTypes.Message) == [] -def test_event_notify() -> None: +def test_event_notify(): first_callback = mock.Mock() second_callback = mock.Mock() - third_callback = mock.Mock() - ratapi.events.register(ratapi.events.EventTypes.Message, first_callback) - ratapi.events.register(ratapi.events.EventTypes.Plot, second_callback) - ratapi.events.register(ratapi.events.EventTypes.Progress, third_callback) - - ratapi.events.notify(ratapi.events.EventTypes.Message, "Hello World") + rat.events.register(rat.events.EventTypes.Message, first_callback) + rat.events.register(rat.events.EventTypes.Plot, second_callback) + + rat.events.notify(rat.events.EventTypes.Message, "Hello World") first_callback.assert_called_once_with("Hello World") second_callback.assert_not_called() - data = ratapi.events.PlotEventData() - ratapi.events.notify(ratapi.events.EventTypes.Plot, data) + data = rat.events.PlotEventData() + rat.events.notify(rat.events.EventTypes.Plot, data) first_callback.assert_called_once() second_callback.assert_called_once_with(data) - - data = ratapi.events.ProgressEventData() - ratapi.events.notify(ratapi.events.EventTypes.Progress, data) - first_callback.assert_called_once() - second_callback.assert_called_once() - third_callback.assert_called_once_with(data) - - ratapi.events.clear() - ratapi.events.notify(ratapi.events.EventTypes.Message, "Hello World") - ratapi.events.notify(ratapi.events.EventTypes.Plot, data) + + rat.events.clear() + rat.events.notify(rat.events.EventTypes.Message, "Hello World") + rat.events.notify(rat.events.EventTypes.Plot, data) assert first_callback.call_count == 1 assert second_callback.call_count == 1 - assert third_callback.call_count == 1 - - -def test_event_data_pickle(): - data = ratapi.events.ProgressEventData() - data.message = "Hello" - data.percent = 0.5 - pickled_data = pickle.loads(pickle.dumps(data)) - assert pickled_data.message == data.message - assert pickled_data.percent == data.percent - - data = ratapi.events.PlotEventData() - data.modelType = "custom layers" - data.dataPresent = np.ones(2) - data.subRoughs = np.ones((20, 2)) - data.resample = np.ones(2) - data.resampledLayers = [np.ones((20, 2)), np.ones((20, 2))] - data.reflectivity = [np.ones((20, 2)), np.ones((20, 2))] - data.shiftedData = [np.ones((20, 2)), np.ones((20, 2))] - data.sldProfiles = [np.ones((20, 2)), np.ones((20, 2))] - data.contrastNames = ["D2O", "SMW"] - - pickled_data = pickle.loads(pickle.dumps(data)) - - assert pickled_data.modelType == data.modelType - assert (pickled_data.dataPresent == data.dataPresent).all() - assert (pickled_data.subRoughs == data.subRoughs).all() - assert (pickled_data.resample == data.resample).all() - for i in range(2): - assert (pickled_data.resampledLayers[i] == data.resampledLayers[i]).all() - assert (pickled_data.reflectivity[i] == data.reflectivity[i]).all() - assert (pickled_data.shiftedData[i] == data.shiftedData[i]).all() - assert (pickled_data.sldProfiles[i] == data.sldProfiles[i]).all() - assert pickled_data.contrastNames == data.contrastNames + \ No newline at end of file diff --git a/tests/test_examples.py b/tests/test_examples.py deleted file mode 100644 index 532a5854..00000000 --- a/tests/test_examples.py +++ /dev/null @@ -1,56 +0,0 @@ -"""Test the RAT examples.""" - -import importlib -from pathlib import Path - -import pytest - -import ratapi.examples as examples - - -@pytest.mark.parametrize( - "example_name", - [ - "absorption", - "domains_custom_layers", - "domains_custom_XY", - "domains_standard_layers", - "DSPC_custom_layers", - "DSPC_custom_XY", - "DSPC_standard_layers", - "DSPC_data_background", - ], -) -def test_rat_examples(example_name): - """Test that the RAT example projects run successfully.""" - p, r = getattr(examples, example_name)() - assert p is not None - assert r is not None - - -@pytest.mark.parametrize( - "example_name", - [ - "DSPC_function_background", - ], -) -@pytest.mark.skipif(importlib.util.find_spec("matlab") is None, reason="Matlab not installed") -def test_function_background(example_name): - """Test examples which rely on MATLAB engine being installed.""" - p, r = getattr(examples, example_name)() - assert p is not None - assert r is not None - - -@pytest.mark.parametrize( - "example_name", - [ - "convert_rascal", - ], -) -@pytest.mark.skipif(importlib.util.find_spec("matlab") is None, reason="Matlab not installed") -def test_matlab_examples(example_name, temp_dir): - """Test convert_rascal example, directing the output to a temporary directory.""" - p, r = examples.convert_rascal(Path(temp_dir, "lipid_bilayer.mat")) - assert p is not None - assert r is not None diff --git a/tests/test_inputs.py b/tests/test_inputs.py deleted file mode 100644 index 242d7480..00000000 --- a/tests/test_inputs.py +++ /dev/null @@ -1,814 +0,0 @@ -"""Test the inputs module.""" - -import pathlib -import pickle -import tempfile -from unittest.mock import patch - -import numpy as np -import pytest - -import ratapi -import ratapi.wrappers -from ratapi.inputs import FileHandles, check_indices, make_controls, make_input, make_problem -from ratapi.rat_core import Checks, Control, NameStore, ProblemDefinition -from ratapi.utils.enums import ( - BackgroundActions, - BoundHandling, - Calculations, - Display, - Geometries, - LayerModels, - Parallel, - Procedures, -) -from tests.utils import dummy_function - - -@pytest.fixture -def standard_layers_project(): - """Add parameters to the default project for a normal calculation.""" - test_project = ratapi.Project( - data=ratapi.ClassList([ratapi.models.Data(name="Test Data", data=np.array([[1.0, 1.0, 1.0]]))]), - ) - test_project.parameters.append(name="Test Thickness") - test_project.parameters.append(name="Test SLD") - test_project.parameters.append(name="Test Roughness") - test_project.custom_files.append( - name="Test Custom File", - filename="python_test.py", - function_name="dummy_function", - language="python", - ) - test_project.layers.append( - name="Test Layer", - thickness="Test Thickness", - SLD="Test SLD", - roughness="Test Roughness", - ) - test_project.contrasts.append( - name="Test Contrast", - data="Test Data", - background="Background 1", - bulk_in="SLD Air", - bulk_out="SLD D2O", - scalefactor="Scalefactor 1", - resolution="Resolution 1", - model=["Test Layer"], - ) - return test_project - - -@pytest.fixture -def domains_project(): - """Add parameters to the default project for a domains calculation.""" - test_project = ratapi.Project( - calculation=Calculations.Domains, - data=ratapi.ClassList([ratapi.models.Data(name="Test Data", data=np.array([[1.0, 1.0, 1.0]]))]), - ) - test_project.parameters.append(name="Test Thickness") - test_project.parameters.append(name="Test SLD") - test_project.parameters.append(name="Test Roughness") - test_project.custom_files.append(name="Test Custom File", filename="matlab_test.m", language="matlab") - test_project.layers.append( - name="Test Layer", - thickness="Test Thickness", - SLD="Test SLD", - roughness="Test Roughness", - ) - test_project.domain_contrasts.append(name="up", model=["Test Layer"]) - test_project.domain_contrasts.append(name="down", model=["Test Layer"]) - test_project.contrasts.append( - name="Test Contrast", - data="Test Data", - background="Background 1", - bulk_in="SLD Air", - bulk_out="SLD D2O", - scalefactor="Scalefactor 1", - resolution="Resolution 1", - domain_ratio="Domain Ratio 1", - model=["down", "up"], - ) - return test_project - - -@pytest.fixture -def custom_xy_project(): - """Add parameters to the default project for a normal calculation and use the custom xy model.""" - test_project = ratapi.Project(model=LayerModels.CustomXY) - test_project.parameters.append(name="Test Thickness") - test_project.parameters.append(name="Test SLD") - test_project.parameters.append(name="Test Roughness") - test_project.custom_files.append(name="Test Custom File", filename="cpp_test.dll", language="cpp") - test_project.contrasts.append( - name="Test Contrast", - data="Simulation", - background="Background 1", - bulk_in="SLD Air", - bulk_out="SLD D2O", - scalefactor="Scalefactor 1", - resolution="Resolution 1", - model=["Test Custom File"], - ) - return test_project - - -@pytest.fixture -def test_names(): - """The expected NameStore object from "standard_layers_project", "domains_project" and "custom_xy_project".""" - names = NameStore() - names.params = ["Substrate Roughness", "Test Thickness", "Test SLD", "Test Roughness"] - names.backgroundParams = ["Background Param 1"] - names.scalefactors = ["Scalefactor 1"] - names.bulkIns = ["SLD Air"] - names.bulkOuts = ["SLD D2O"] - names.resolutionParams = ["Resolution Param 1"] - names.domainRatios = [] - names.contrasts = ["Test Contrast"] - - return names - - -@pytest.fixture -def test_checks(): - """The expected checks object from "standard_layers_project", "domains_project" and "custom_xy_project".""" - checks = Checks() - checks.params = np.array([1, 0, 0, 0]) - checks.backgroundParams = np.array([0]) - checks.scalefactors = np.array([0]) - checks.bulkIns = np.array([0]) - checks.bulkOuts = np.array([0]) - checks.resolutionParams = np.array([0]) - checks.domainRatios = np.array([]) - - return checks - - -@pytest.fixture -def standard_layers_problem(test_names, test_checks): - """The expected problem object from "standard_layers_project".""" - problem = ProblemDefinition() - problem.TF = Calculations.Normal - problem.modelType = LayerModels.StandardLayers - problem.geometry = Geometries.AirSubstrate - problem.useImaginary = False - problem.params = [3.0, 0.0, 0.0, 0.0] - problem.bulkIns = [0.0] - problem.bulkOuts = [6.35e-06] - problem.scalefactors = [0.23] - problem.domainRatios = [] - problem.backgroundParams = [1e-06] - problem.resolutionParams = [0.03] - problem.contrastBulkIns = [1] - problem.contrastBulkOuts = [1] - problem.contrastScalefactors = [1] - problem.contrastBackgroundParams = [[1]] - problem.contrastBackgroundActions = [BackgroundActions.Add] - problem.contrastBackgroundTypes = ["constant"] - problem.contrastResolutionParams = [[1]] - problem.contrastResolutionTypes = ["constant"] - problem.contrastCustomFiles = [float("NaN")] - problem.contrastDomainRatios = [0] - problem.resample = [False] - problem.dataPresent = [1] - problem.data = [np.array([[1.0, 1.0, 1.0, 0.0, 0.0, 0.0]])] - problem.dataLimits = [[1.0, 1.0]] - problem.simulationLimits = [[1.0, 1.0]] - problem.numberOfContrasts = 1 - problem.numberOfLayers = 1 - problem.repeatLayers = [1] - problem.layersDetails = [[2, 3, 4, float("NaN"), 1]] - problem.contrastLayers = [[1]] - problem.numberOfDomainContrasts = 0 - problem.domainContrastLayers = [] - problem.fitParams = [3.0] - problem.fitLimits = [[1.0, 5.0]] - problem.priorNames = [ - "Substrate Roughness", - "Test Thickness", - "Test SLD", - "Test Roughness", - "Background Param 1", - "Scalefactor 1", - "SLD Air", - "SLD D2O", - "Resolution Param 1", - ] - problem.priorValues = [ - [1, 0.0, np.inf], - [1, 0.0, np.inf], - [1, 0.0, np.inf], - [1, 0.0, np.inf], - [1, 0.0, np.inf], - [1, 0.0, np.inf], - [1, 0.0, np.inf], - [1, 0.0, np.inf], - [1, 0.0, np.inf], - ] - problem.customFiles = FileHandles([]) - problem.names = test_names - problem.checks = test_checks - - return problem - - -@pytest.fixture -def domains_problem(test_names, test_checks): - """The expected problem object from "domains_project".""" - problem = ProblemDefinition() - problem.TF = Calculations.Domains - problem.modelType = LayerModels.StandardLayers - problem.geometry = Geometries.AirSubstrate - problem.useImaginary = False - problem.params = [3.0, 0.0, 0.0, 0.0] - problem.bulkIns = [0.0] - problem.bulkOuts = [6.35e-06] - problem.scalefactors = [0.23] - problem.domainRatios = [0.5] - problem.backgroundParams = [1e-06] - problem.resolutionParams = [0.03] - problem.contrastBulkIns = [1] - problem.contrastBulkOuts = [1] - problem.contrastScalefactors = [1] - problem.contrastBackgroundParams = [[1]] - problem.contrastBackgroundActions = [BackgroundActions.Add] - problem.contrastBackgroundTypes = ["constant"] - problem.contrastResolutionParams = [[1]] - problem.contrastResolutionTypes = ["constant"] - problem.contrastCustomFiles = [float("NaN")] - problem.contrastDomainRatios = [1] - problem.resample = [False] - problem.dataPresent = [1] - problem.data = [np.array([[1.0, 1.0, 1.0, 0.0, 0.0, 0.0]])] - problem.dataLimits = [[1.0, 1.0]] - problem.simulationLimits = [[1.0, 1.0]] - problem.numberOfContrasts = 1 - problem.numberOfLayers = 1 - problem.repeatLayers = [1] - problem.layersDetails = [[2, 3, 4, float("NaN"), 1]] - problem.contrastLayers = [[2, 1]] - problem.numberOfDomainContrasts = 2 - problem.domainContrastLayers = [[1], [1]] - problem.fitParams = [3.0] - problem.fitLimits = [[1.0, 5.0]] - problem.priorNames = [ - "Substrate Roughness", - "Test Thickness", - "Test SLD", - "Test Roughness", - "Background Param 1", - "Scalefactor 1", - "SLD Air", - "SLD D2O", - "Resolution Param 1", - "Domain Ratio 1", - ] - problem.priorValues = [ - [1, 0.0, np.inf], - [1, 0.0, np.inf], - [1, 0.0, np.inf], - [1, 0.0, np.inf], - [1, 0.0, np.inf], - [1, 0.0, np.inf], - [1, 0.0, np.inf], - [1, 0.0, np.inf], - [1, 0.0, np.inf], - [1, 0.0, np.inf], - ] - problem.customFiles = FileHandles([]) - problem.names = test_names - problem.names.domainRatios = ["Domain Ratio 1"] - problem.checks = test_checks - - return problem - - -@pytest.fixture -def custom_xy_problem(test_names, test_checks): - """The expected problem object from "custom_xy_project".""" - problem = ProblemDefinition() - problem.TF = Calculations.Normal - problem.modelType = LayerModels.CustomXY - problem.geometry = Geometries.AirSubstrate - problem.useImaginary = False - problem.params = [3.0, 0.0, 0.0, 0.0] - problem.bulkIns = [0.0] - problem.bulkOuts = [6.35e-06] - problem.scalefactors = [0.23] - problem.domainRatios = [] - problem.backgroundParams = [1e-06] - problem.resolutionParams = [0.03] - problem.contrastBulkIns = [1] - problem.contrastBulkOuts = [1] - problem.contrastScalefactors = [1] - problem.contrastBackgroundParams = [[1]] - problem.contrastBackgroundActions = [BackgroundActions.Add] - problem.contrastBackgroundTypes = ["constant"] - problem.contrastResolutionParams = [[1]] - problem.contrastResolutionTypes = ["constant"] - problem.contrastCustomFiles = [1] - problem.contrastDomainRatios = [0] - problem.resample = [True] - problem.dataPresent = [0] - problem.data = [np.empty([0, 6])] - problem.dataLimits = [[0.0, 0.0]] - problem.simulationLimits = [[0.005, 0.7]] - problem.repeatLayers = [1] - problem.layersDetails = [] - problem.contrastLayers = [[]] - problem.numberOfContrasts = 1 - problem.numberOfLayers = 0 - problem.numberOfDomainContrasts = 0 - problem.domainContrastLayers = [] - problem.fitParams = [3.0] - problem.fitLimits = [[1.0, 5.0]] - problem.priorNames = [ - "Substrate Roughness", - "Test Thickness", - "Test SLD", - "Test Roughness", - "Background Param 1", - "Scalefactor 1", - "SLD Air", - "SLD D2O", - "Resolution Param 1", - ] - problem.priorValues = [ - [1, 0.0, np.inf], - [1, 0.0, np.inf], - [1, 0.0, np.inf], - [1, 0.0, np.inf], - [1, 0.0, np.inf], - [1, 0.0, np.inf], - [1, 0.0, np.inf], - [1, 0.0, np.inf], - [1, 0.0, np.inf], - ] - problem.customFiles = FileHandles( - [ratapi.models.CustomFile(name="Test Custom File", filename="cpp_test.dll", language="cpp")] - ) - problem.names = test_names - problem.checks = test_checks - - return problem - - -@pytest.fixture -def standard_layers_controls(): - """The expected controls object for input to the compiled RAT code given the default inputs and - "standard_layers_project". - """ - controls = Control() - controls.procedure = Procedures.Calculate - controls.parallel = Parallel.Single - controls.numSimulationPoints = 500 - controls.resampleMinAngle = 0.9 - controls.resampleNPoints = 50 - controls.display = Display.Iter - controls.xTolerance = 1.0e-6 - controls.funcTolerance = 1.0e-6 - controls.maxFuncEvals = 10000 - controls.maxIterations = 1000 - controls.updateFreq = 1 - controls.updatePlotFreq = 20 - controls.populationSize = 20 - controls.fWeight = 0.5 - controls.crossoverProbability = 0.8 - controls.strategy = 4 - controls.targetValue = 1.0 - controls.numGenerations = 500 - controls.nLive = 150 - controls.nMCMC = 0.0 - controls.propScale = 0.1 - controls.nsTolerance = 0.1 - controls.nSamples = 20000 - controls.nChains = 10 - controls.jumpProbability = 0.5 - controls.pUnitGamma = 0.2 - controls.boundHandling = BoundHandling.Reflect - controls.adaptPCR = True - - return controls - - -@pytest.fixture -def custom_xy_controls(): - """The expected controls object for input to the compiled RAT code given the default inputs and - "custom_xy_project". - """ - controls = Control() - controls.procedure = Procedures.Calculate - controls.parallel = Parallel.Single - controls.numSimulationPoints = 500 - controls.resampleMinAngle = 0.9 - controls.resampleNPoints = 50.0 - controls.display = Display.Iter - controls.xTolerance = 1.0e-6 - controls.funcTolerance = 1.0e-6 - controls.maxFuncEvals = 10000 - controls.maxIterations = 1000 - controls.updateFreq = 1 - controls.updatePlotFreq = 20 - controls.populationSize = 20 - controls.fWeight = 0.5 - controls.crossoverProbability = 0.8 - controls.strategy = 4 - controls.targetValue = 1.0 - controls.numGenerations = 500 - controls.nLive = 150 - controls.nMCMC = 0.0 - controls.propScale = 0.1 - controls.nsTolerance = 0.1 - controls.nSamples = 20000 - controls.nChains = 10 - controls.jumpProbability = 0.5 - controls.pUnitGamma = 0.2 - controls.boundHandling = BoundHandling.Reflect - controls.adaptPCR = True - - return controls - - -@pytest.mark.parametrize( - ["test_project", "test_problem", "test_controls"], - [ - ( - "standard_layers_project", - "standard_layers_problem", - "standard_layers_controls", - ), - ( - "custom_xy_project", - "custom_xy_problem", - "custom_xy_controls", - ), - ( - "domains_project", - "domains_problem", - "standard_layers_controls", - ), - ], -) -def test_make_input(test_project, test_problem, test_controls, request) -> None: - """When converting the "project" and "controls", we should obtain the two input objects required for the compiled - RAT code. - """ - test_project = request.getfixturevalue(test_project) - test_problem = request.getfixturevalue(test_problem) - test_controls = request.getfixturevalue(test_controls) - - problem, controls = make_input(test_project, ratapi.Controls()) - - problem = pickle.loads(pickle.dumps(problem)) - check_problem_equal(problem, test_problem) - - controls = pickle.loads(pickle.dumps(controls)) - check_controls_equal(controls, test_controls) - - -@pytest.mark.parametrize( - ["test_project", "test_problem"], - [ - ("standard_layers_project", "standard_layers_problem"), - ("custom_xy_project", "custom_xy_problem"), - ("domains_project", "domains_problem"), - ], -) -def test_make_problem(test_project, test_problem, request) -> None: - """The problem object should contain the relevant parameters defined in the input project object.""" - test_project = request.getfixturevalue(test_project) - test_problem = request.getfixturevalue(test_problem) - - problem = make_problem(test_project) - check_problem_equal(problem, test_problem) - - -@pytest.mark.parametrize("test_problem", ["standard_layers_problem", "custom_xy_problem", "domains_problem"]) -class TestCheckIndices: - """Tests for check_indices over a set of three test problems.""" - - def test_check_indices(self, test_problem, request) -> None: - """The check_indices routine should not raise errors for a properly defined ProblemDefinition object.""" - test_problem = request.getfixturevalue(test_problem) - - check_indices(test_problem) - - @pytest.mark.parametrize( - "index_list", - [ - "contrastBulkIns", - "contrastBulkOuts", - "contrastScalefactors", - "contrastDomainRatios", - ], - ) - @pytest.mark.parametrize("bad_value", ([0.0], [2.0])) - def test_check_indices_error(self, test_problem, index_list, bad_value, request) -> None: - """The check_indices routine should raise an IndexError if a contrast list contains an index that is out of the - range of the corresponding parameter list in a ProblemDefinition object. - """ - param_list = { - "contrastBulkIns": "bulkIns", - "contrastBulkOuts": "bulkOuts", - "contrastScalefactors": "scalefactors", - "contrastDomainRatios": "domainRatios", - } - if (test_problem != "domains_problem") and (index_list == "contrastDomainRatios"): - # we expect this to not raise an error for non-domains problems as domainRatios is empty - pytest.xfail() - - test_problem = request.getfixturevalue(test_problem) - setattr(test_problem, index_list, bad_value) - - with pytest.raises( - IndexError, - match=f'The problem field "{index_list}" contains: {bad_value[0]}, which lies ' - f'outside of the range of "{param_list[index_list]}"', - ): - check_indices(test_problem) - - @pytest.mark.parametrize("background_type", ["constant", "data", "function"]) - @pytest.mark.parametrize("bad_value", ([[0.0]], [[2.0]])) - def test_background_params_source_indices(self, test_problem, background_type, bad_value, request): - """check_indices should raise an IndexError for bad sources in the nested list contrastBackgroundParams.""" - test_problem = request.getfixturevalue(test_problem) - test_problem.contrastBackgroundParams = bad_value - test_problem.contrastBackgroundTypes = [background_type] - - source_param_lists = { - "constant": "backgroundParams", - "data": "data", - "function": "customFiles", - } - - with pytest.raises( - IndexError, - match=f'Entry 0 of contrastBackgroundParams has type "{background_type}" ' - f"and source index {bad_value[0][0]}, " - f'which is outside the range of "{source_param_lists[background_type]}".', - ): - check_indices(test_problem) - - @pytest.mark.parametrize( - "bad_value", - ( - [[1.0, 0.0]], - [[1.0, 2.0]], - [[1.0, 1.0, 2.0]], - [[1.0], [1.0, 0.0]], - ), - ) - def test_background_params_value_indices(self, test_problem, bad_value, request): - """check_indices should raise an IndexError for bad values in the nested list contrastBackgroundParams.""" - test_problem = request.getfixturevalue(test_problem) - test_problem.contrastBackgroundParams = bad_value - - if len(bad_value) > 1: - test_problem.contrastBackgroundTypes.append("constant") - - with pytest.raises( - IndexError, - match=f"Entry {len(bad_value) - 1} of contrastBackgroundParams contains: {bad_value[-1][-1]}" - f', which lies outside of the range of "backgroundParams"', - ): - check_indices(test_problem) - - -@pytest.mark.parametrize("test_project", ["standard_layers_project", "custom_xy_project", "domains_project"]) -@pytest.mark.parametrize("field", ["data", "background", "bulk_in", "bulk_out", "scalefactor", "resolution"]) -def test_undefined_contrast_fields(test_project, field, request): - """If a field in a contrast is empty, we should raise an error.""" - test_project = request.getfixturevalue(test_project) - setattr(test_project.contrasts[0], field, "") - - with pytest.raises( - ValueError, - match=f'In the input project, the "{field}" field of contrast ' - f'"{test_project.contrasts[0].name}" does not have a value defined. ' - f"A value must be supplied before running the project.", - ): - make_problem(test_project) - - -@pytest.mark.parametrize("test_project", ["standard_layers_project", "custom_xy_project", "domains_project"]) -def test_undefined_background(test_project, request): - """If the source field of a background defined in a contrast is empty, we should raise an error.""" - test_project = request.getfixturevalue(test_project) - background = test_project.backgrounds[test_project.contrasts[0].background] - background.source = "" - - with pytest.raises( - ValueError, - match=f"All backgrounds must have a source defined. For a {background.type} type " - f"background, the source must be defined in " - f'"{ratapi.project.values_defined_in[f"backgrounds.{background.type}.source"]}"', - ): - make_problem(test_project) - - -@pytest.mark.parametrize("test_project", ["standard_layers_project", "custom_xy_project", "domains_project"]) -def test_undefined_resolution(test_project, request): - """If the source field of a resolution defined in a contrast is empty, we should raise an error.""" - test_project = request.getfixturevalue(test_project) - resolution = test_project.resolutions[test_project.contrasts[0].resolution] - resolution.source = "" - - with pytest.raises( - ValueError, - match=f"Constant resolutions must have a source defined. The source must be defined in " - f'"{ratapi.project.values_defined_in[f"resolutions.{resolution.type}.source"]}"', - ): - make_problem(test_project) - - -@pytest.mark.parametrize("test_project", ["standard_layers_project", "domains_project"]) -@pytest.mark.parametrize("field", ["thickness", "SLD", "roughness"]) -def test_undefined_layers(test_project, field, request): - """If the thickness, SLD, or roughness fields of a layer defined in the project are empty, we should raise an - error.""" - test_project = request.getfixturevalue(test_project) - setattr(test_project.layers[0], field, "") - - with pytest.raises( - ValueError, - match=f'In the input project, the "{field}" field of layer {test_project.layers[0].name} ' - f"does not have a value defined. A value must be supplied before running the project.", - ): - make_problem(test_project) - - -def test_append_data_background(): - """Test that background data is correctly added to contrast data.""" - data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) - background = np.array([[1, 10, 11], [4, 12, 13], [7, 14, 15]]) - - result = ratapi.inputs.append_data_background(data, background) - np.testing.assert_allclose(result, np.array([[1, 2, 3, 0, 10, 11], [4, 5, 6, 0, 12, 13], [7, 8, 9, 0, 14, 15]])) - - -def test_append_data_background_res(): - """Test that background data is correctly added to contrast data when a resolution is in the data.""" - data = np.array([[1, 2, 3, 4], [4, 5, 6, 6], [7, 8, 9, 72]]) - background = np.array([[1, 10, 11], [4, 12, 13], [7, 14, 15]]) - - result = ratapi.inputs.append_data_background(data, background) - np.testing.assert_allclose(result, np.array([[1, 2, 3, 4, 10, 11], [4, 5, 6, 6, 12, 13], [7, 8, 9, 72, 14, 15]])) - - -def test_append_data_background_error(): - """Test that append_data_background raises an error if the q-values are not equal.""" - data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) - background = np.array([[56, 10, 11], [41, 12, 13], [7, 14, 15]]) - - with pytest.raises(ValueError, match=("The q-values of the data and background must be equal.")): - ratapi.inputs.append_data_background(data, background) - - -def test_get_python_handle(): - path = pathlib.Path(__file__).parent - assert ratapi.inputs.get_python_handle("utils.py", "dummy_function", path).__code__ == dummy_function.__code__ - - -def test_make_controls(standard_layers_controls) -> None: - """The controls object should contain the full set of controls parameters, with the appropriate set defined by the - input controls. - """ - controls = make_controls(ratapi.Controls()) - check_controls_equal(controls, standard_layers_controls) - - -@patch("ratapi.wrappers.MatlabWrapper") -def test_file_handles(wrapper): - handle = FileHandles([ratapi.models.CustomFile(name="Test Custom File", filename="cpp_test.dll", language="cpp")]) - - with pytest.raises(FileNotFoundError, match="The custom file \\(Test Custom File\\) does not have a valid path."): - handle.get_handle(0) - - with tempfile.NamedTemporaryFile("w", suffix=".dll") as f: - tmp_file = pathlib.Path(f.name) - handle.files[0]["path"] = tmp_file.parent - handle.files[0]["filename"] = tmp_file.name - handle.files[0]["function_name"] = "" - # No function name should throw exception - with pytest.raises( - ValueError, match="The custom file \\(Test Custom File\\) does not have a valid function name." - ): - handle.get_handle(0) - - # Matlab does not need function name - handle.files[0]["language"] = "matlab" - handle.get_handle(0) - wrapper.assert_called() - - -def check_problem_equal(actual_problem, expected_problem) -> None: - """Compare two instances of the "problem" object for equality.""" - scalar_fields = [ - "TF", - "modelType", - "geometry", - "useImaginary", - "numberOfContrasts", - "numberOfLayers", - "numberOfDomainContrasts", - "priorNames", - ] - - array_fields = [ - "params", - "backgroundParams", - "scalefactors", - "bulkIns", - "bulkOuts", - "resolutionParams", - "domainRatios", - "contrastBackgroundParams", - "contrastBackgroundActions", - "contrastScalefactors", - "contrastBulkIns", - "contrastBulkOuts", - "contrastResolutionParams", - "contrastDomainRatios", - "resample", - "dataPresent", - "dataLimits", - "simulationLimits", - "repeatLayers", - "contrastLayers", - "domainContrastLayers", - "fitParams", - "fitLimits", - "priorValues", - ] - checks_fields = [ - "params", - "backgroundParams", - "scalefactors", - "bulkIns", - "bulkOuts", - "resolutionParams", - "domainRatios", - ] - names_fields = [*checks_fields, "contrasts"] - - for scalar_field in scalar_fields: - assert getattr(actual_problem, scalar_field) == getattr(expected_problem, scalar_field) - for array_field in array_fields: - assert np.all(getattr(actual_problem, array_field) == getattr(expected_problem, array_field)) - for field in names_fields: - assert getattr(actual_problem.names, field) == getattr(expected_problem.names, field) - for field in checks_fields: - assert (getattr(actual_problem.checks, field) == getattr(expected_problem.checks, field)).all() - - # Data field is a numpy array - assert [ - actual_data == expected_data - for (actual_data, expected_data) in zip(actual_problem.data, expected_problem.data, strict=False) - ] - - # Need to account for "NaN" entries in layersDetails and contrastCustomFiles field - for actual_layer, expected_layer in zip(actual_problem.layersDetails, expected_problem.layersDetails, strict=False): - assert (actual_layer == expected_layer) or ["NaN" if np.isnan(el) else el for el in actual_layer] == [ - "NaN" if np.isnan(el) else el for el in expected_layer - ] - - assert (actual_problem.contrastCustomFiles == expected_problem.contrastCustomFiles).all() or [ - "NaN" if np.isnan(el) else el for el in actual_problem.contrastCustomFiles - ] == ["NaN" if np.isnan(el) else el for el in expected_problem.contrastCustomFiles] - - -def check_controls_equal(actual_controls, expected_controls) -> None: - """Compare two instances of the "controls" object used as input for the compiled RAT code for equality.""" - controls_fields = [ - "procedure", - "parallel", - "numSimulationPoints", - "resampleMinAngle", - "resampleNPoints", - "display", - "xTolerance", - "funcTolerance", - "maxFuncEvals", - "maxIterations", - "updateFreq", - "updatePlotFreq", - "populationSize", - "fWeight", - "crossoverProbability", - "strategy", - "targetValue", - "numGenerations", - "nLive", - "nMCMC", - "propScale", - "nsTolerance", - "nSamples", - "nChains", - "jumpProbability", - "pUnitGamma", - "boundHandling", - "adaptPCR", - ] - - for field in controls_fields: - assert getattr(actual_controls, field) == getattr(expected_controls, field) diff --git a/tests/test_models.py b/tests/test_models.py deleted file mode 100644 index 4343b442..00000000 --- a/tests/test_models.py +++ /dev/null @@ -1,392 +0,0 @@ -"""Test the pydantic models.""" - -import re -from collections.abc import Callable - -import numpy as np -import pydantic -import pytest - -import ratapi.models - - -@pytest.mark.parametrize( - ["model", "model_name", "model_params"], - [ - (ratapi.models.Background, "Background", {}), - (ratapi.models.Contrast, "Contrast", {}), - (ratapi.models.CustomFile, "Custom File", {}), - (ratapi.models.Data, "Data", {}), - (ratapi.models.DomainContrast, "Domain Contrast", {}), - ( - ratapi.models.Layer, - "Layer", - {"thickness": "Test Thickness", "SLD": "Test SLD", "roughness": "Test Roughness"}, - ), - (ratapi.models.Parameter, "Parameter", {}), - (ratapi.models.Resolution, "Resolution", {}), - ], -) -def test_default_names(model: Callable, model_name: str, model_params: dict) -> None: - """When initialising multiple models without specifying a name, they should be given a default name with the - format: "New ". - """ - model_1 = model(**model_params) - prefix = f"New {model_name} " - assert model_1.name.startswith(prefix) - index = int(model_1.name[len(prefix) :]) - - model_2 = model(**model_params) - model_3 = model(name="Given Name", **model_params) - model_4 = model(**model_params) - - assert model_1.name == f"New {model_name} {index}" - assert model_2.name == f"New {model_name} {index + 1}" - assert model_3.name == "Given Name" - assert model_4.name == f"New {model_name} {index + 2}" - - # If user adds name in similar format. The next auto number will take it into account. - model(name=f"{prefix}{index + 20}", **model_params) - model_5 = model(**model_params) - assert model_5.name == f"New {model_name} {index + 21}" - - -@pytest.mark.parametrize( - ["model", "model_params"], - [ - (ratapi.models.Background, {}), - (ratapi.models.Contrast, {}), - (ratapi.models.ContrastWithRatio, {}), - (ratapi.models.CustomFile, {}), - (ratapi.models.Data, {}), - (ratapi.models.DomainContrast, {}), - (ratapi.models.Layer, {"thickness": "Test Thickness", "SLD": "Test SLD", "roughness": "Test Roughness"}), - ( - ratapi.models.AbsorptionLayer, - { - "thickness": "Test Thickness", - "SLD_real": "Test SLD", - "SLD_imaginary": "Test SLD", - "roughness": "Test Roughness", - }, - ), - (ratapi.models.Parameter, {}), - (ratapi.models.Resolution, {}), - ], -) -class TestModels: - def test_initialise_with_wrong_type(self, model: Callable, model_params: dict) -> None: - """When initialising a model with the wrong type for the "name" field, we should raise a ValidationError.""" - with pytest.raises( - pydantic.ValidationError, - match=f"1 validation error for {model.__name__}\nname\n Input should be a valid string", - ): - model(name=1, **model_params) - - def test_assignment_with_wrong_type(self, model: Callable, model_params: dict) -> None: - """When assigning the "name" field of a model with the wrong type, we should raise a ValidationError.""" - test_model = model(**model_params) - with pytest.raises( - pydantic.ValidationError, - match=f"1 validation error for {model.__name__}\nname\n Input should be a valid string", - ): - test_model.name = 1 - - def test_initialise_with_zero_length_name(self, model: Callable, model_params: dict) -> None: - """When initialising a model with a zero length name, we should raise a ValidationError.""" - with pytest.raises( - pydantic.ValidationError, - match=f"1 validation error for {model.__name__}\nname\n String should have at least 1 character", - ): - model(name="", **model_params) - - def test_initialise_with_extra_fields(self, model: Callable, model_params: dict) -> None: - """When initialising a model with unspecified fields, we should raise a ValidationError.""" - with pytest.raises( - pydantic.ValidationError, - match=f"1 validation error for {model.__name__}\nnew_field\n Extra inputs are not permitted", - ): - model(new_field=1, **model_params) - - -def test_data_eq() -> None: - """If we use the Data.__eq__ method with an object that is not a pydantic BaseModel, we should return - "NotImplemented". - """ - assert ratapi.models.Data().__eq__("data") == NotImplemented - - -@pytest.mark.parametrize( - "input_data", - [ - (np.array([[1.0, 1.0, 1.0]])), - ], -) -def test_data_dimension(input_data: np.ndarray[float]) -> None: - """The "data" field of the "Data" model should be a two-dimensional numpy array with at least three values in the - second dimension. - """ - test_data = ratapi.models.Data(data=input_data) - assert (test_data.data == input_data).all() - - -@pytest.mark.parametrize( - "input_data", - [ - (np.array([])), - (np.array([1.0, 1.0])), - ], -) -def test_data_too_few_dimensions(input_data: np.ndarray[float]) -> None: - """If the "data" field of the "Data" model is not a two-dimensional numpy array we should raise a - ValidationError. - """ - with pytest.raises( - pydantic.ValidationError, - match='1 validation error for Data\ndata\n Value error, "data" must have at least two dimensions', - ): - ratapi.models.Data(data=input_data) - - -@pytest.mark.parametrize( - "input_data", - [ - (np.array([[]])), - (np.array([[1.0]])), - (np.array([[1.0, 1.0]])), - ], -) -def test_data_too_few_values(input_data: np.ndarray[float]) -> None: - """If the second dimension of the array in the "data" field of the "Data" model has fewer than three values we - should raise a ValidationError. - """ - with pytest.raises( - pydantic.ValidationError, - match='1 validation error for Data\ndata\n Value error, "data" must have at least three columns', - ): - ratapi.models.Data(data=input_data) - - -@pytest.mark.parametrize( - "input_range", - [ - ([1.0, 2.0]), - ], -) -def test_data_ranges(input_range: list[float]) -> None: - """The "data_range" and "simulation_range" fields of the "Data" model should contain exactly two values.""" - assert ratapi.models.Data(data_range=input_range).data_range == input_range - assert ratapi.models.Data(simulation_range=input_range).simulation_range == input_range - - -@pytest.mark.parametrize( - "input_range", - [ - ([]), - ([1.0]), - ([1.0, 2.0, 3.0]), - ], -) -def test_two_values_in_data_range(input_range: list[float]) -> None: - """If the "data_range" field of the "Data" model contains more or less than two values, we should raise a - ValidationError. - """ - with pytest.raises( - pydantic.ValidationError, - match=f"1 validation error for Data\ndata_range\n List should have " - f"at {'least' if len(input_range) < 2 else 'most'} 2 items " - f"after validation, not {len(input_range)}", - ): - ratapi.models.Data(data_range=input_range) - - -@pytest.mark.parametrize( - "input_range", - [ - ([]), - ([1.0]), - ([1.0, 2.0, 3.0]), - ], -) -def test_two_values_in_simulation_range(input_range: list[float]) -> None: - """If the "simulation_range" field of the "Data" model contains more or less than two values, we should raise a - ValidationError. - """ - with pytest.raises( - pydantic.ValidationError, - match=f"1 validation error for Data\nsimulation_range\n List should " - f"have at {'least' if len(input_range) < 2 else 'most'} 2 items " - f"after validation, not {len(input_range)}", - ): - ratapi.models.Data(simulation_range=input_range) - - -@pytest.mark.parametrize( - "field", - [ - "data_range", - "simulation_range", - ], -) -def test_min_max_in_range(field: str) -> None: - """If the maximum value of the "data_range" or "simulation_range" fields of the "Data" model is greater than the - minimum value, we should raise a ValidationError. - """ - with pytest.raises( - pydantic.ValidationError, - match=f"1 validation error for Data\n{field}\n Value error, {field} " - f'"min" value is greater than the "max" value', - ): - ratapi.models.Data(**{field: [1.0, 0.0]}) - - -def test_default_ranges() -> None: - """If "data" is specified but either the "data_range" or "simulation_range" fields are not, we set the ranges to - the minimum and maximum values of the first column of the data. - """ - test_data = ratapi.models.Data(data=np.array([[1.0, 0.0, 0.0], [3.0, 0.0, 0.0]])) - assert test_data.data_range == [1.0, 3.0] - assert test_data.simulation_range == [1.0, 3.0] - - -@pytest.mark.parametrize( - "test_range", - [ - [0.0, 2.0], - [2.0, 4.0], - [0.0, 4.0], - ], -) -def test_data_range(test_range) -> None: - """If "data" is specified but the "data_range" lies outside of the limits of the data we should raise a - ValidationError. - """ - with pytest.raises( - pydantic.ValidationError, - match=re.escape( - f"1 validation error for Data\n Value error, The " - f"data_range value of: {test_range} must lie within " - f"the min/max values of the data: [1.0, 3.0]", - ), - ): - ratapi.models.Data(data=np.array([[1.0, 0.0, 0.0], [3.0, 0.0, 0.0]]), data_range=test_range) - - -@pytest.mark.parametrize( - "test_range", - [ - [0.0, 2.0], - [2.0, 4.0], - [1.5, 2.5], - ], -) -def test_simulation_range(test_range) -> None: - """If "data" is specified but the "simulation_range" lies within the limits of the data we should raise a - ValidationError. - """ - with pytest.raises( - pydantic.ValidationError, - match=re.escape( - f"1 validation error for Data\n Value error, The " - f"simulation_range value of: {test_range} must lie " - f"outside of the min/max values of the data: " - f"[1.0, 3.0]", - ), - ): - ratapi.models.Data(data=np.array([[1.0, 0.0, 0.0], [3.0, 0.0, 0.0]]), simulation_range=test_range) - - -@pytest.mark.parametrize( - ["minimum", "value", "maximum"], - [ - (0.0, 2.0, 1.0), - (0, 1, 0), - (1, -1, 1), - ], -) -def test_parameter_range(minimum: float, value: float, maximum: float) -> None: - """For the "Parameter" model, if the value of the "value" field does not lie with the values given in the "min" and - "max" fields, we should raise a ValidationError. - """ - with pytest.raises( - pydantic.ValidationError, - match=f"1 validation error for Parameter\n Value error, value " - f"{float(value)} is not within the defined range: " - f"{float(minimum)} <= value <= {float(maximum)}", - ): - ratapi.models.Parameter(min=minimum, value=value, max=maximum) - - -def test_layer_bad_imaginary_SLD(): - """If 'SLD_imaginary' is given to a Layer, it should raise a descriptive ValidationError.""" - with pytest.raises( - pydantic.ValidationError, - match=( - "1 validation error for Layer\n" - " Value error, The Layer class does not support imaginary SLD." - " Use the AbsorptionLayer class instead." - ), - ): - ratapi.models.Layer(name="My Layer", SLD_imaginary="bad sld") - - -def test_contrast_bad_ratio(): - """If 'domain_ratios' is given to a Contrast, it should raise a descriptive ValidationError.""" - with pytest.raises( - pydantic.ValidationError, - match=( - "1 validation error for Contrast\n" - " Value error, The Contrast class does not support domain ratios." - " Use the ContrastWithRatio class instead." - ), - ): - ratapi.models.Contrast(name="My Contrast", domain_ratio="bad ratio") - - -@pytest.mark.parametrize( - ["model", "type", "values"], - [ - (ratapi.models.Background, "function", ["val1", "val2", "val3", "val4", "val5"]), - (ratapi.models.Resolution, "constant", ["", "", "", "", ""]), - ], -) -def test_type_change_clear(model, type, values): - """If the type of a background or resolution is changed, it should wipe the other fields and warn the user.""" - model_instance = model( - name="Test", - type=type, - source="src", - value_1=values[0], - value_2=values[1], - value_3=values[2], - value_4=values[3], - value_5=values[4], - ) - - with pytest.warns(UserWarning, match="Changing the type of Test clears its source and value fields."): - model_instance.type = "data" - for attr in ["source", "value_1", "value_2", "value_3", "value_4", "value_5"]: - assert getattr(model_instance, attr) == "" - - -@pytest.mark.parametrize( - ["model", "signal_type", "values"], - [ - (ratapi.models.Background, "constant", ["value_1", "value_2", "value_3", "value_4", "value_5"]), - (ratapi.models.Background, "data", ["value_2", "value_3", "value_4", "value_5"]), - (ratapi.models.Resolution, "constant", ["value_1", "value_2", "value_3", "value_4", "value_5"]), - (ratapi.models.Resolution, "data", ["value_1", "value_2", "value_3", "value_4", "value_5"]), - ], -) -def test_unsupported_parameters_error(model, signal_type, values): - """If a value is inputted for an unsupported field for a particular type of background or resolution then we should - raise an error.""" - for value in values: - with pytest.raises( - pydantic.ValidationError, - match=( - f"1 validation error for {model.__name__}\n Value error, The following values are not supported" - f' by the "{signal_type}" {model.__name__} type: {value}' - ), - ): - model(**{"type": signal_type, value: "unsupported"}) diff --git a/tests/test_orso_utils.py b/tests/test_orso_utils.py deleted file mode 100644 index 60f04494..00000000 --- a/tests/test_orso_utils.py +++ /dev/null @@ -1,122 +0,0 @@ -"""Tests for the ratapi.utils.orso module.""" - -import os -from io import StringIO -from pathlib import Path - -import numpy as np -import pytest -from orsopy.fileio.model_language import SampleModel - -from ratapi.examples.bayes_benchmark.bayes_benchmark import get_project -from ratapi.project import Project -from ratapi.utils.orso import ORSOProject, orso_model_to_rat - -TEST_DIR_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "test_data") - - -@pytest.fixture -def bare_subs(): - """The bare substrate project from the Bayes Benchmark example.""" - return get_project() - - -@pytest.fixture -def prist(): - """The project from the model data from prist5_10K_m_025.Rqz.ort""" - return Project.load(Path(TEST_DIR_PATH, "prist.json")) - - -@pytest.mark.parametrize( - "model", - [ - "air | FeO2 0.75 | Fe 10 | Si", - "vacuum | 5 (O3 3 | He2 4) | SiO2 0.75 | Si", - "Si | 5 (O2 2 | 3 (D2O 1 | H2O 1)) | air", - ], -) -@pytest.mark.parametrize("absorption", [True, False]) -@pytest.mark.skip(reason="orsopy database website (https://slddb.esss.dk/slddb/) is not available") -def test_orso_model_to_rat(model, absorption): - """Test that orso_model_to_rat gives the expected parameters, layers and model.""" - - expected = SampleModel(model).resolve_to_layers()[1:-1] - expected_layers = [layer.material.formula for layer in expected] - expected_thicknesses = {layer.material.formula: layer.thickness for layer in expected} - expected_roughnesses = {layer.material.formula: layer.roughness for layer in expected} - actual = orso_model_to_rat(model, absorption=absorption) - - assert actual.model == expected_layers - - for layer in actual.layers: - assert layer.name in expected_layers - for layer in expected_layers: - assert layer in [actual_layer.name for actual_layer in actual.layers] - - expected_parameters = [] - # get set of parameters - for layer in set(expected_layers): - expected_parameters.extend([f"{layer} Thickness", f"{layer} Roughness", f"{layer} SLD"]) - if absorption: - expected_parameters.append(f"{layer} SLD imaginary") - - assert actual.parameters[f"{layer} Thickness"].value == expected_thicknesses[layer].as_unit("angstrom") - assert actual.parameters[f"{layer} Roughness"].value == expected_roughnesses[layer].as_unit("angstrom") - - assert set(p.name for p in actual.parameters) == set(expected_parameters) - - -@pytest.mark.parametrize( - "test_data", - [ - "bare_substrate.ort", - "prist5_10K_m_025.Rqz.ort", - ], -) -@pytest.mark.skip(reason="orsopy database website (https://slddb.esss.dk/slddb/) is not available") -def test_load_ort_data(test_data): - """Test that .ort data is loaded correctly.""" - # manually get the test data for comparison - data_strings = [""] - parsing_data = False - with Path(TEST_DIR_PATH, test_data).open() as file: - for line in file: - if line[0] == "#": - if parsing_data: - parsing_data = False - data_strings.append("") - else: - continue - else: - parsing_data = True - data_strings[-1] += line - - expected_data = list(map(lambda s: np.loadtxt(StringIO(s)), data_strings)) - actual_data = ORSOProject(Path(TEST_DIR_PATH, test_data)).data - - assert len(actual_data) == len(expected_data) - for actual_dataset, expected_dataset in zip(actual_data, expected_data, strict=False): - np.testing.assert_array_equal(actual_dataset.data, expected_dataset) - - -@pytest.mark.parametrize( - "test_data, expected_data", - [ - ["bare_substrate.ort", "bare_substrate.json"], - ["prist5_10K_m_025.Rqz.ort", "prist.json"], - ], -) -@pytest.mark.skip(reason="orsopy database website (https://slddb.esss.dk/slddb/) is not available") -def test_load_ort_project(test_data, expected_data): - """Test that a project with model data is loaded correctly.""" - ort_data = ORSOProject(Path(TEST_DIR_PATH, test_data)) - sample = ort_data.samples[0] - exp_project = Project.load(Path(TEST_DIR_PATH, expected_data)) - - for class_list in ["bulk_in", "bulk_out"]: - assert getattr(sample, class_list) == getattr(exp_project, class_list)[0] - assert sample.parameters == exp_project.parameters[1:] - assert sample.layers == exp_project.layers - - for data, exp_data in zip(ort_data.data, exp_project.data[1:], strict=False): - np.testing.assert_array_equal(data.data, exp_data.data) diff --git a/tests/test_orso_validation.py b/tests/test_orso_validation.py deleted file mode 100644 index a7ed22f5..00000000 --- a/tests/test_orso_validation.py +++ /dev/null @@ -1,84 +0,0 @@ -import os -import pathlib -import tempfile - -import numpy as np -import pytest - -import ratapi as RAT - -TEST_FUNC = """import pathlib -import numpy as np - - -def run_func(params, bulk_in, bulk_out, contrast): - layers = np.loadtxt("{layers_file_path}") - - # Change the units to Ã… - layers[:, 1:3] = layers[:, 1:3] * 1e-6 - - # Returns layers only, bulk in and bulk out added to project - return layers[1:-1, :], params[0] -""" - - -@pytest.mark.parametrize( - "layer_index", - [0, 1, 2, 3, 6, 7], -) -def test_orso_validation(layer_index): - data_path = pathlib.Path(__file__).parent / "test_data" / "ORSO" - - problem = RAT.Project(name="test", model="custom layers", absorption=True) - problem.scalefactors.set_fields(0, min=1, value=1, max=1) - problem.background_parameters.set_fields(0, min=0, value=0, max=0) - problem.resolution_parameters.set_fields(0, min=0, value=0, max=0) - - # Write a custom file that reads the ORSO layers. - filename = data_path / f"test{layer_index}.layers" - with tempfile.NamedTemporaryFile("w+", suffix=".py", delete=False) as f: - f.write(TEST_FUNC.format(layers_file_path=filename.as_posix())) - f.flush() - - layers = np.loadtxt(filename) - sub_rough = layers[-1, -1] - - # Change the units to Ã… - bulk_in = layers[0, 1] * 1e-6 - bulk_out = layers[-1, 1] * 1e-6 - - problem.parameters.set_fields(0, min=sub_rough, value=sub_rough, max=sub_rough) - problem.bulk_in.set_fields(0, name="Bulk In", min=bulk_in, value=bulk_in, max=bulk_in, fit=False) - problem.bulk_out.set_fields(0, name="Bulk Out", min=bulk_out, value=bulk_out, max=bulk_out, fit=False) - - data = np.loadtxt(data_path / f"test_{layer_index}.dat") - problem.data.append(name="Data", data=data) - - problem.custom_files.append( - name="Model", - filename=pathlib.Path(f.name).name, - language="python", - path=pathlib.Path(f.name).parent, - function_name="run_func", - ) - - problem.contrasts.append( - name="ORSO Contrast", - background="Background 1", - background_action="add", - resolution="Resolution 1", - scalefactor="Scalefactor 1", - bulk_out="Bulk Out", - bulk_in="Bulk In", - data="Data", - resample=False, - model=["Model"], - ) - - controls = RAT.Controls() - problem, results = RAT.run(problem, controls) - total_error = sum((results.reflectivity[0][:, 1] - results.shiftedData[0][:, 1]) ** 2) - - assert total_error < 1e-10 - f.close() - os.remove(f.name) diff --git a/tests/test_outputs.py b/tests/test_outputs.py deleted file mode 100644 index 7d2afff9..00000000 --- a/tests/test_outputs.py +++ /dev/null @@ -1,236 +0,0 @@ -"""Test the outputs module using the example calculation from "DSPC_standard_layers.py". - -We use the example for both a reflectivity calculation, and Bayesian analysis using the Dream algorithm. -""" - -import tempfile -from pathlib import Path - -import numpy as np -import pytest - -import ratapi -import ratapi.outputs -import ratapi.rat_core -from ratapi.utils.enums import Procedures -from tests.utils import check_results_equal - - -@pytest.fixture -def reflectivity_calculation_str(): - """The string representation of the python results object for a reflectivity calculation of the project set out in - "DSPC_standard_layers.py". - """ - return ( - "reflectivity = [Data array: [21 x 2], Data array: [21 x 2]],\n" - "simulation = [Data array: [21 x 2], Data array: [21 x 2]],\n" - "shiftedData = [Data array: [21 x 3], Data array: [21 x 3]],\n" - "backgrounds = [Data array: [82 x 3], Data array: [82 x 3]],\n" - "resolutions = [Data array: [82 x 2], Data array: [82 x 2]],\n" - "sldProfiles = [[Data array: [25 x 2], Data array: [25 x 2]]],\n" - "layers = [[Data array: [8 x 3]], [Data array: [8 x 3]]],\n" - "resampledLayers = [[Data array: [1 x 3]], [Data array: [1 x 3]]],\n" - "calculationResults = CalculationResults(\n" - "\tchiValues = [ 202.83057377 1641.4024969 ],\n" - "\tsumChi = 1844.2330706690975,\n" - "),\n" - "contrastParams = ContrastParams(\n" - "\tscalefactors = [0.1 0.15],\n" - "\tbulkIn = [2.073e-06 2.073e-06],\n" - "\tbulkOut = [5.98e-06 2.21e-06],\n" - "\tsubRoughs = [3. 3.],\n" - "\tresample = [0. 0.],\n" - "),\n" - "fitParams = [3.000e+00 1.954e+01 2.266e+01 5.252e+00 5.640e+00 1.712e+01 8.560e+00\n" - " 4.545e+01 1.070e+01 6.014e+00 1.782e+01 1.764e+01 3.615e+01 2.361e+01\n" - " 2.230e-06 3.380e-06 5.980e-06 2.210e-06],\n" - "fitNames = ['Substrate Roughness', 'Oxide Thickness', 'SAM Tails Thickness', 'SAM Tails Hydration', " - "'SAM Roughness', 'CW Thickness', 'SAM Heads Thickness', 'SAM Heads Hydration', 'Bilayer Heads Thickness', " - "'Bilayer Roughness', 'Bilayer Tails Thickness', 'Bilayer Tails Hydration', 'Bilayer Heads Hydration', " - "'Oxide Hydration', 'Background parameter D2O', 'Background parameter SMW', 'D2O', 'SMW'],\n" - ) - - -@pytest.fixture -def dream_str(): - """The string representation of the python BayesResults object for a Dream optimisation of the project set out in - "DSPC_standard_layers.py". - """ - return ( - "reflectivity = [Data array: [21 x 2], Data array: [21 x 2]],\n" - "simulation = [Data array: [21 x 2], Data array: [21 x 2]],\n" - "shiftedData = [Data array: [21 x 3], Data array: [21 x 3]],\n" - "backgrounds = [Data array: [82 x 3], Data array: [82 x 3]],\n" - "resolutions = [Data array: [82 x 2], Data array: [82 x 2]],\n" - "sldProfiles = [[Data array: [29 x 2], Data array: [29 x 2]]],\n" - "layers = [[Data array: [8 x 3]], [Data array: [8 x 3]]],\n" - "resampledLayers = [[Data array: [1 x 3]], [Data array: [1 x 3]]],\n" - "calculationResults = CalculationResults(\n" - "\tchiValues = [4.6077885 7.00028098],\n" - "\tsumChi = 11.608069475997699,\n" - "),\n" - "contrastParams = ContrastParams(\n" - "\tscalefactors = [0.1 0.15],\n" - "\tbulkIn = [2.073e-06 2.073e-06],\n" - "\tbulkOut = [6.01489149e-06 1.59371685e-06],\n" - "\tsubRoughs = [6.19503045 6.19503045],\n" - "\tresample = [0. 0.],\n" - "),\n" - "fitParams = [6.19503045e+00 1.84420960e+01 2.11039621e+01 8.75538121e+00\n" - " 3.72292994e+00 1.84624551e+01 1.02316734e+01 2.31156093e+01\n" - " 1.09906265e+01 5.71005361e+00 1.67933822e+01 1.72009856e+01\n" - " 3.00260126e+01 2.94448999e+01 2.37113128e-06 1.99006694e-06\n" - " 6.01489149e-06 1.59371685e-06],\n" - "fitNames = ['Substrate Roughness', 'Oxide Thickness', 'SAM Tails Thickness', 'SAM Tails Hydration', " - "'SAM Roughness', 'CW Thickness', 'SAM Heads Thickness', 'SAM Heads Hydration', " - "'Bilayer Heads Thickness', 'Bilayer Roughness', 'Bilayer Tails Thickness', " - "'Bilayer Tails Hydration', 'Bilayer Heads Hydration', 'Oxide Hydration', " - "'Background parameter D2O', 'Background parameter SMW', 'D2O', 'SMW'],\n" - "predictionIntervals = PredictionIntervals(\n" - "\treflectivity = [Data array: [5 x 21], Data array: [5 x 21]],\n" - "\tsld = [[Data array: [5 x 29], Data array: [5 x 29]]],\n" - "\tsampleChi = Data array: [1000],\n" - "),\n" - "confidenceIntervals = ConfidenceIntervals(\n" - "\tpercentile95 = Data array: [2 x 18],\n" - "\tpercentile65 = Data array: [2 x 18],\n" - "\tmean = Data array: [1 x 18],\n" - "),\n" - "dreamParams = DreamParams(\n" - "\tnParams = 18.0,\n" - "\tnChains = 1.0,\n" - "\tnGenerations = 1.0,\n" - "\tparallel = False,\n" - "\tCPU = 1.0,\n" - "\tjumpProbability = 0.5,\n" - "\tpUnitGamma = 0.2,\n" - "\tnCR = 3.0,\n" - "\tdelta = 3.0,\n" - "\tsteps = 50.0,\n" - "\tzeta = 1e-12,\n" - "\toutlier = iqr,\n" - "\tadaptPCR = False,\n" - "\tthinning = 1.0,\n" - "\tepsilon = 0.025,\n" - "\tABC = False,\n" - "\tIO = False,\n" - "\tstoreOutput = False,\n" - "\tR = Data array: [1 x 1],\n" - "),\n" - "dreamOutput = DreamOutput(\n" - "\tallChains = Data array: [1 x 20 x 1],\n" - "\toutlierChains = Data array: [1 x 2],\n" - "\truntime = 2.6e-06,\n" - "\titeration = 2.0,\n" - "\tAR = Data array: [1 x 2],\n" - "\tR_stat = Data array: [1 x 19],\n" - "\tCR = Data array: [1 x 4],\n" - "),\n" - "nestedSamplerOutput = NestedSamplerOutput(\n" - "\tlogZ = 0.0,\n" - "\tlogZErr = 0.0,\n" - "\tnestSamples = Data array: [1 x 2],\n" - "\tpostSamples = Data array: [1 x 2],\n" - "),\n" - "chain = Data array: [2 x 18],\n" - ) - - -@pytest.mark.parametrize( - ["test_value", "array_limit", "expected_field_string"], - [ - (5, 100, "test_field = 5,\n"), - ([], 100, "test_field = [],\n"), - ([[], [], []], 100, "test_field = [[], [], []],\n"), - ([1, 2, 3], 100, "test_field = [1, 2, 3],\n"), - ([[1], [2], [3]], 100, "test_field = [[1], [2], [3]],\n"), - (np.array([]), 100, "test_field = [],\n"), - (np.array([[], []]), 100, "test_field = Data array: [2 x 0],\n"), - (np.array([1, 2, 3]), 100, "test_field = [1 2 3],\n"), - (np.array([1, 2, 3]), 3, "test_field = Data array: [3],\n"), - (np.array([1, 2, 3]), 2, "test_field = Data array: [3],\n"), - (np.array([[1, 2, 3], [4, 5, 6]]), 100, "test_field = Data array: [2 x 3],\n"), - (np.array([[[1], [2], [3]], [[4], [5], [6]]]), 100, "test_field = Data array: [2 x 3 x 1],\n"), - ([np.array([])], 100, "test_field = [Data array: [0]],\n"), - ([np.array([1, 2, 3])], 100, "test_field = [Data array: [3]],\n"), - ([np.array([[1], [2], [3]])], 100, "test_field = [Data array: [3 x 1]],\n"), - ([[np.array([[1, 2, 3], [4, 5, 6]])]], 100, "test_field = [[Data array: [2 x 3]]],\n"), - ([[np.array([1, 2, 3]), np.array([4, 5, 6])]], 100, "test_field = [[Data array: [3], Data array: [3]]],\n"), - ( - [[np.array([[1, 2], [3, 4]]), np.array([[5, 6], [7, 8]])]], - 100, - "test_field = [[Data array: [2 x 2], Data array: [2 x 2]]],\n", - ), - ], -) -def test_get_field_string(test_value, array_limit, expected_field_string) -> None: - """For the string representation of output classes, we represent multidimensional and large arrays by their shape, - with other variables printed normally. - """ - field_string = ratapi.outputs.get_field_string("test_field", test_value, array_limit) - - assert field_string == expected_field_string - - -@pytest.mark.parametrize( - ["test_procedure", "test_output_results", "test_bayes", "test_results"], - [ - (Procedures.Calculate, "reflectivity_calculation_output_results", None, "reflectivity_calculation_results"), - (Procedures.DREAM, "dream_output_results", "dream_bayes", "dream_results"), - ], -) -def test_make_results(test_procedure, test_output_results, test_bayes, test_results, request) -> None: - """The python results object should contain the relevant parameters defined in the C++ results and bayes objects.""" - test_output_results = request.getfixturevalue(test_output_results) - if test_bayes: - test_bayes = request.getfixturevalue(test_bayes) - - test_results = request.getfixturevalue(test_results) - results = ratapi.outputs.make_results(test_procedure, test_output_results, test_bayes) - - check_results_equal(test_results, results) - - -@pytest.mark.parametrize( - ["test_procedure", "test_results"], - [ - (Procedures.NS, "nested_sampler_results"), - (Procedures.DREAM, "dream_results"), - ], -) -def test_results_procedure(test_procedure, test_results, request) -> None: - """Test that bayes results object return correct procedure.""" - test_output_results = request.getfixturevalue(test_results) - assert test_output_results.from_procedure() == test_procedure - - -@pytest.mark.parametrize( - ["test_output_results", "test_str"], - [ - ("reflectivity_calculation_results", "reflectivity_calculation_str"), - ("dream_results", "dream_str"), - ], -) -def test_results_str(test_output_results, test_str, request) -> None: - """The string representation of the python results object should represent large and multidimensional arrays by - their shape. - """ - test_output_results = request.getfixturevalue(test_output_results) - test_str = request.getfixturevalue(test_str) - - assert test_output_results.__str__() == test_str - - -@pytest.mark.parametrize("result_class", [ratapi.Results, ratapi.BayesResults]) -@pytest.mark.parametrize("test_results", ["reflectivity_calculation_results", "dream_results"]) -def test_save_load(result_class, test_results, request): - """Test that saving and loading an output object returns the same object.""" - test_results = request.getfixturevalue(test_results) - - with tempfile.TemporaryDirectory() as tmp: - # ignore relative path warnings - path = Path(tmp, "results.json") - test_results.save(path) - loaded_results = result_class.load(path) - - check_results_equal(test_results, loaded_results) diff --git a/tests/test_plotting.py b/tests/test_plotting.py deleted file mode 100644 index 31049a28..00000000 --- a/tests/test_plotting.py +++ /dev/null @@ -1,497 +0,0 @@ -import os -import pickle -from math import ceil, sqrt -from unittest.mock import MagicMock, patch - -import matplotlib.pyplot as plt -import numpy as np -import pytest -from matplotlib.collections import PolyCollection, QuadMesh -from matplotlib.patches import Rectangle - -import ratapi.utils.plotting as RATplot -from ratapi.events import notify -from ratapi.rat_core import EventTypes, PlotEventData - -TEST_DIR_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "test_data") - - -def data() -> PlotEventData: - """Creates the data for the tests.""" - data_path = os.path.join(TEST_DIR_PATH, "plotting_data.pickle") - with open(data_path, "rb") as f: - loaded_data = pickle.load(f) - - data = PlotEventData() - data.modelType = loaded_data["modelType"] - data.dataPresent = loaded_data["dataPresent"] - data.subRoughs = loaded_data["subRoughs"] - data.resample = loaded_data["resample"] - data.resampledLayers = loaded_data["resampledLayers"] - data.reflectivity = loaded_data["reflectivity"] - data.shiftedData = loaded_data["shiftedData"] - data.sldProfiles = loaded_data["sldProfiles"] - data.contrastNames = ["D2O", "SMW", "H2O"] - - return data - - -def domains_data() -> PlotEventData: - """Creates the fake domains data for the tests.""" - domains_data = data() - for sld_list in domains_data.sldProfiles: - sld_list.append(sld_list[0]) - - return domains_data - - -@pytest.fixture(params=[False]) -def fig(request) -> plt.figure: - """Creates the fixture for the tests.""" - plt.close("all") - figure = plt.subplots(1, 2)[0] - RATplot.plot_ref_sld_helper(fig=figure, data=domains_data() if request.param else data()) - return figure - - -@pytest.fixture -def bayes_fig(request) -> plt.figure: - plt.close("all") - figure = plt.subplots(1, 2)[0] - dat = data() - - confidence_intervals = { - "reflectivity": [ - (curve[:, 1] - curve[:, 1] * 0.5, curve[:, 1] + curve[:, 1] * 0.5) for curve in dat.reflectivity - ], - "sld": [ - [(curve[:, 1] - curve[:, 1] * 0.1, curve[:, 1] + curve[:, 1] * 0.1) for curve in sld] - for sld in dat.sldProfiles - ], - } - RATplot.plot_ref_sld_helper(data=dat, fig=figure, confidence_intervals=confidence_intervals) - return figure - - -@pytest.mark.parametrize("fig", [False, True], indirect=True) -def test_figure_axis_formatting(fig: plt.figure) -> None: - """Tests the axis formatting of the figure.""" - ref_plot = fig.axes[0] - sld_plot = fig.axes[1] - - assert fig.axes[0].get_subplotspec().get_gridspec().get_geometry() == (1, 2) - assert len(fig.axes) == 2 - - assert ref_plot.get_xlabel() == "$Q_{z} (\u00c5^{-1})$" - assert ref_plot.get_xscale() == "log" - assert ref_plot.get_ylabel() == "Reflectivity" - assert ref_plot.get_yscale() == "log" - assert [label._text for label in ref_plot.get_legend().texts] == ["D2O", "SMW", "H2O"] - - assert sld_plot.get_xlabel() == "$Z (\u00c5)$" - assert sld_plot.get_xscale() == "linear" - assert sld_plot.get_ylabel() == "$SLD (\u00c5^{-2})$" - assert sld_plot.get_yscale() == "linear" - labels = [label._text for label in sld_plot.get_legend().texts] - if len(labels) == 3: - assert labels == ["D2O", "SMW", "H2O"] - else: - assert labels == [ - "D2O Domain 1", - "D2O Domain 2", - "SMW Domain 1", - "SMW Domain 2", - "H2O Domain 1", - "H2O Domain 2", - ] - - -def test_ref_sld_color_formatting(fig: plt.figure) -> None: - """Tests the color formatting of the figure.""" - ref_plot = fig.axes[0] - sld_plot = fig.axes[1] - - assert len(ref_plot.get_lines()) == 6 - assert len(sld_plot.get_lines()) == 6 - - for i in range(0, len(ref_plot.get_lines()), 2): - # Tests whether the color of the line and the errorbars match on the ref_plot - assert ref_plot.containers[i // 2][2][0]._original_edgecolor == ref_plot.get_lines()[i].get_color() - - # Tests whether the color of the sld and resampled_sld match on the sld_plot - assert sld_plot.get_lines()[i].get_color() == sld_plot.get_lines()[i + 1].get_color() - - -def test_ref_sld_bayes(fig, bayes_fig): - """Test that shading is correctly added to the figure when confidence intervals are supplied.""" - # the shading is of type PolyCollection - for axes in fig.axes: - components = axes.get_children() - assert not any(isinstance(comp, PolyCollection) for comp in components) - for axes in bayes_fig.axes: - components = axes.get_children() - assert any(isinstance(comp, PolyCollection) for comp in components) - - -@patch("ratapi.utils.plotting.makeSLDProfile") -def test_sld_profile_function_call(mock: MagicMock) -> None: - """Tests the makeSLDProfile function called with - correct args. - """ - RATplot.plot_ref_sld_helper(data(), plt.subplots(1, 2)[0]) - - assert mock.call_count == 3 - assert mock.call_args_list[0].args[0] == 2.07e-06 - assert mock.call_args_list[0].args[1] == 6.28e-06 - assert mock.call_args_list[0].args[3] == 0.0 - assert mock.call_args_list[0].args[4] == 1 - - assert mock.call_args_list[1].args[0] == 2.07e-06 - assert mock.call_args_list[1].args[1] == 1.83e-06 - assert mock.call_args_list[1].args[3] == 0.0 - assert mock.call_args_list[1].args[4] == 1 - - assert mock.call_args_list[2].args[0] == 2.07e-06 - assert mock.call_args_list[2].args[1] == -5.87e-07 - assert mock.call_args_list[2].args[3] == 0.0 - assert mock.call_args_list[2].args[4] == 1 - - -@patch("ratapi.utils.plotting.makeSLDProfile") -def test_live_plot(mock: MagicMock) -> None: - plot_data = data() - - with RATplot.LivePlot() as figure: - assert len(figure.axes) == 2 - notify(EventTypes.Plot, plot_data) - plt.close(figure) - notify(EventTypes.Plot, plot_data) - - assert mock.call_count == 3 - assert mock.call_args_list[0].args[0] == 2.07e-06 - assert mock.call_args_list[0].args[1] == 6.28e-06 - assert mock.call_args_list[0].args[3] == 0.0 - assert mock.call_args_list[0].args[4] == 1 - - assert mock.call_args_list[1].args[0] == 2.07e-06 - assert mock.call_args_list[1].args[1] == 1.83e-06 - assert mock.call_args_list[1].args[3] == 0.0 - assert mock.call_args_list[1].args[4] == 1 - - assert mock.call_args_list[2].args[0] == 2.07e-06 - assert mock.call_args_list[2].args[1] == -5.87e-07 - assert mock.call_args_list[2].args[3] == 0.0 - assert mock.call_args_list[2].args[4] == 1 - - -@patch("ratapi.utils.plotting.plot_ref_sld_helper") -def test_plot_ref_sld(mock: MagicMock, input_project, reflectivity_calculation_results) -> None: - RATplot.plot_ref_sld(input_project, reflectivity_calculation_results) - mock.assert_called_once() - data = mock.call_args[0][0] - figure = mock.call_args[0][1] - - assert figure.axes[0].get_subplotspec().get_gridspec().get_geometry() == (1, 2) - assert len(figure.axes) == 2 - - for reflectivity, reflectivity_results in zip( - data.reflectivity, reflectivity_calculation_results.reflectivity, strict=False - ): - assert (reflectivity == reflectivity_results).all() - for sldProfile, result_sld_profile in zip( - data.sldProfiles, reflectivity_calculation_results.sldProfiles, strict=False - ): - for sld, sld_results in zip(sldProfile, result_sld_profile, strict=False): - assert (sld == sld_results).all() - - assert data.modelType == input_project.model - assert data.shiftedData == reflectivity_calculation_results.shiftedData - assert data.resampledLayers == reflectivity_calculation_results.resampledLayers - assert data.dataPresent.size == 0 - assert (data.subRoughs == reflectivity_calculation_results.contrastParams.subRoughs).all() - assert data.resample.size == 0 - assert len(data.contrastNames) == 0 - - -def test_ref_sld_subplot_correction(): - """Test that if an incorrect number of subplots is corrected in the figure helper.""" - fig = plt.subplots(1, 3)[0] - RATplot.plot_ref_sld_helper(data=data(), fig=fig) - assert fig.axes[0].get_subplotspec().get_gridspec().get_geometry() == (1, 2) - assert len(fig.axes) == 2 - - -@patch("ratapi.utils.plotting.plot_ref_sld_helper") -def test_plot_ref_sld_bayes_validation(mock, input_project, reflectivity_calculation_results, dream_results): - """Test that plot_ref_sld correctly throws errors for bad Bayesian input.""" - RATplot.plot_ref_sld(input_project, dream_results) - RATplot.plot_ref_sld(input_project, dream_results, bayes=65) - RATplot.plot_ref_sld(input_project, dream_results, bayes=95) - with pytest.raises(ValueError): - RATplot.plot_ref_sld(input_project, reflectivity_calculation_results, bayes=65) - with pytest.raises(ValueError): - RATplot.plot_ref_sld(input_project, dream_results, bayes=15) - - -def test_assert_bayesian(dream_results, reflectivity_calculation_results): - """Test that the `assert_bayesian` decorator validates correctly.""" - - @RATplot.assert_bayesian("test") - def test_plot(results): - pass - - test_plot(dream_results) - with pytest.raises( - ValueError, match=r"test plots are only available for the results of Bayesian analysis \(NS or DREAM\)" - ): - test_plot(reflectivity_calculation_results) - - -@pytest.mark.parametrize("indices", [[0, 1, 2, 3, 4], [2, 5, 11], [8]]) -def test_panel_helper(indices): - """Test that the panel plot helper creates a panel with the expected subplots.""" - - def plot_func(axes, k): - """Plot k lines on an Axes.""" - for i in range(0, k): - axes.plot([i], [i]) - - nplots = len(indices) - - fig = RATplot.panel_plot_helper(plot_func, indices) - # ensure correct number of axes were created - expected_num_axes = ceil(sqrt(nplots)) * round(sqrt(nplots)) - assert len(fig.axes) == expected_num_axes - - # assert all required axes are visible and have the requested number of lines - for i, index in enumerate(indices): - assert len(fig.axes[i].get_lines()) == index - assert fig.axes[i].get_visible() - - # assert remaining axes are not visible - for i in range(nplots, expected_num_axes): - assert fig.axes[i].get_visible() is False - - plt.close(fig) - - -@pytest.mark.parametrize("param", ["CW Thickness", "D2O", 5]) -@pytest.mark.parametrize("hist_settings", [{}, {"bins": 18}, {"density": False, "range": (0, 5)}]) -@pytest.mark.parametrize("est_dens", [None, "normal", "lognor", "kernel"]) -def test_hist(dream_results, param, hist_settings, est_dens): - """Tests the formatting of the histogram plot.""" - fig: plt.Figure = RATplot.plot_one_hist( - dream_results, param, estimated_density=est_dens, **hist_settings, return_fig=True - ) - ax = fig.axes[0] - components = ax.get_children() - - # assert expected number of bins including default - # this ensures default hist_settings are overwritten correctly - # +1 rectangle because the bounds of the plot is a rectangle - expected_bins = hist_settings.get("bins", 25) + 1 - assert len([c for c in components if isinstance(c, Rectangle)]) == expected_bins - - # assert line is only drawn if estimated density given - assert len(ax.get_lines()) == (0 if est_dens is None else 1) - - # assert title is as expected - # also tests string to index conversion - assert ax.get_title(loc="left") == dream_results.fitNames[param] if isinstance(param, int) else param - - # assert range is default, unless given - # this tests non-default hist_settings propagates correctly - try: - expected_range = hist_settings["range"] - except KeyError: # if no range given, compute the automatic range - param_index = dream_results.fitNames.index(param) if isinstance(param, str) else param - param_chain = dream_results.chain[:, param_index] - expected_range = (param_chain.min(), param_chain.max()) - assert ax.get_xbound() == expected_range - - plt.close(fig) - - -@pytest.mark.parametrize(["x_param", "y_param"], [["CW Thickness", "D2O"], ["Bilayer Heads Thickness", 5], [2, 7]]) -@pytest.mark.parametrize("hist2d_settings", [{}, {"bins": 15}, {"range": [(-50.0, 50.0), (-50.0, 200.0)]}]) -def test_contour(dream_results, x_param, y_param, hist2d_settings): - """Test the formatting of the contour plot.""" - fig: plt.Figure = RATplot.plot_contour(dream_results, x_param, y_param, return_fig=True, **hist2d_settings) - ax = fig.axes[0] - components = ax.get_children() - - # assert expected number of bins including default - # this ensures default hist2d_settings are overwritten correctly - # +1 as we are counting edges in this case - expected_bins = hist2d_settings.get("bins", 25) + 1 - quad_mesh = [c for c in components if isinstance(c, QuadMesh)][0] - assert quad_mesh._coordinates.shape == (expected_bins, expected_bins, 2) - - # assert correct axis labels - # this ensures string to index conversion works - assert ax.get_xlabel() == (dream_results.fitNames[x_param] if isinstance(x_param, int) else x_param) - assert ax.get_ylabel() == (dream_results.fitNames[y_param] if isinstance(y_param, int) else y_param) - - # assert range is default, unless given - # this tests non-default hist2d_settings propagates correctly - try: - x_expected_range, y_expected_range = hist2d_settings["range"] - except KeyError: # if no range given, compute the automatic range - x_param_index = dream_results.fitNames.index(x_param) if isinstance(x_param, str) else x_param - y_param_index = dream_results.fitNames.index(y_param) if isinstance(y_param, str) else y_param - x_param_chain = dream_results.chain[:, x_param_index] - y_param_chain = dream_results.chain[:, y_param_index] - x_expected_range = (x_param_chain.min(), x_param_chain.max()) - y_expected_range = (y_param_chain.min(), y_param_chain.max()) - assert ax.get_xbound() == x_expected_range - assert ax.get_ybound() == y_expected_range - - # plt.close(fig) - - -@pytest.mark.parametrize( - "params", - [ - None, - ["Bilayer Heads Thickness", "Bilayer Heads Hydration", "D2O"], - ["Bilayer Heads Thickness", 2, 3, "D2O", 5], - [1, 2, 3, 4, 5], - ], -) -def test_corner(dream_results, params): - """Test that corner plots are formatted correctly.""" - # no use testing hist_settings and hist2d_settings here as they're tested above - fig: plt.Figure = RATplot.plot_corner(dream_results, params, return_fig=True) - axes = fig.axes - if params is None: - params = range(0, len(dream_results.fitNames)) - assert len(axes) == len(params) ** 2 - # annoyingly, fig.axes doesn't preserve the grid shape from plt.subplots... reconstruct grid - axes = np.array([axes[i : i + len(params)] for i in range(0, len(axes), len(params))]) - - for i in range(0, len(params)): - for j in range(0, len(params)): - current_axes = axes[i][j] - # ensure upper triangle is invisible - if i < j: - assert current_axes.get_visible() is False - elif i > j: - # check axes are the same along each row and column for contours - assert current_axes.get_ybound() == axes[i][0].get_ybound() - assert current_axes.get_xbound() == axes[-1][j].get_xbound() - elif i == j: - # check title is correct - assert ( - current_axes.get_title(loc="left") == dream_results.fitNames[params[i]] - if isinstance(params[i], int) - else params[i] - ) - - plt.close(fig) - - -@pytest.mark.parametrize( - "params", [None, [2, 3], [1, 5, "D2O"], ["Bilayer Heads Thickness", "Bilayer Heads Hydration", "D2O"]] -) -@patch("ratapi.plotting.panel_plot_helper") -def test_hist_panel(mock_panel_helper: MagicMock, params, dream_results): - """Test chain panel name-to-index (panel helper has already been tested)""" - fig = RATplot.plot_hists(dream_results, params, return_fig=True) - plt.close(fig) - if params is None: - params = range(0, len(dream_results.fitNames)) - - passed_params = mock_panel_helper.call_args.args[1] - assert len(passed_params) == len(params) - for param in passed_params: - assert param == (dream_results.fitNames.index(param) if isinstance(param, str) else param) - - -@pytest.mark.parametrize( - ["input", "expected_dict"], - [ - (None, "NONEDICT"), - ({"D2O": "kernel"}, "D2O_DICT"), - ({"default": "lognor"}, "DEFAULTDICT"), # workaround as we need to access the fixture attrs - ("lognor", "DEFAULTDICT"), - ({"default": "normal", 1: "kernel"}, "DEFAULT_WITH_1CHANGE_DICT"), - ], -) -@patch("ratapi.plotting.plot_one_hist") -def test_standardise_est_dens(mock_plot_hist: MagicMock, input, expected_dict, dream_results): - """Test estimated density is correctly standardised.""" - _ = RATplot.plot_hists(dream_results, estimated_density=input, return_fig=True) - - expected_dict = { - "NONEDICT": {i: None for i in range(0, len(dream_results.fitNames))}, - "D2O_DICT": {**{i: None for i in range(0, len(dream_results.fitNames))}, **{16: "kernel"}}, - "DEFAULTDICT": {i: "lognor" for i in range(0, len(dream_results.fitNames))}, - "DEFAULT_WITH_1CHANGE_DICT": {**{i: "normal" for i in range(0, len(dream_results.fitNames))}, **{1: "kernel"}}, - }[expected_dict] - - call_args = mock_plot_hist.call_args_list - keys_called = [call[0][1] for call in call_args] - est_density = [call[1]["estimated_density"] for call in call_args] - est_dens_dict = {keys_called[i]: est_density[i] for i in range(0, len(keys_called))} - - assert expected_dict == est_dens_dict - plt.close("all") - - -@pytest.mark.parametrize("input", [{250: "lognor"}, {"Oxide Quickness": "normal"}, {"D2O": "Rattian"}, {-5: "lognor"}]) -def test_est_dens_error(dream_results, input): - """Ensure a bad estimated density input raises an error.""" - # the error message contains the phrase "Parameter {key}" or "Index {key}", so use that - # to ensure we're not getting some random ValueError - with pytest.raises((ValueError, IndexError), match=f"Parameter|Index {(list(input.keys())[0])}"): - RATplot.plot_hists(dream_results, estimated_density=input) - - -@pytest.mark.parametrize( - "params", [None, [2, 3], [1, 5, "D2O"], ["Bilayer Heads Thickness", "Bilayer Heads Hydration", "D2O"]] -) -@patch("ratapi.plotting.panel_plot_helper") -def test_chain_panel(mock_panel_helper: MagicMock, params, dream_results): - """Test chain panel name-to-index (panel helper has already been tested)""" - # return fig just to avoid plt.show() being called - fig = RATplot.plot_chain(dream_results, params, return_fig=True) - plt.close(fig) - if params is None: - params = range(0, len(dream_results.fitNames)) - - for param in mock_panel_helper.call_args()[1]: - assert param == (dream_results.fitNames.index(param) if isinstance(param, str) else param) - - -@patch("ratapi.plotting.plot_ref_sld") -@patch("ratapi.plotting.plot_hists") -@patch("ratapi.plotting.plot_corner") -def test_bayes_calls( - mock_corner: MagicMock, mock_hists: MagicMock, mock_ref_sld: MagicMock, input_project, dream_results -): - """Test that the Bayes plot calls the required plotting subroutines.""" - RATplot.plot_bayes(input_project, dream_results) - assert mock_ref_sld.call_count == 2 - mock_hists.assert_called_once() - mock_corner.assert_called_once() - - -def test_bayes_validation(input_project, reflectivity_calculation_results): - """Ensure that plot_bayes fails if given regular Results.""" - with pytest.raises( - ValueError, match=r"Bayes plots are only available for the results of Bayesian analysis \(NS or DREAM\)" - ): - RATplot.plot_bayes(input_project, reflectivity_calculation_results) - - -@pytest.mark.parametrize("data", [data(), domains_data()]) -def test_extract_plot_data(data) -> None: - plot_data = RATplot._extract_plot_data(data, False, True, 50) - assert len(plot_data["ref"]) == len(data.reflectivity) - assert len(plot_data["sld"]) == len(data.shiftedData) - - with pytest.raises(ValueError, match=r"Parameter `shift_value` must be between 0 and 100"): - RATplot._extract_plot_data(data, False, True, -0.1) - - with pytest.raises(ValueError, match=r"Parameter `shift_value` must be between 0 and 100"): - RATplot._extract_plot_data(data, False, True, 100.5) diff --git a/tests/test_project.py b/tests/test_project.py deleted file mode 100644 index 35d5864e..00000000 --- a/tests/test_project.py +++ /dev/null @@ -1,1662 +0,0 @@ -"""Test the project module.""" - -import copy -import re -import tempfile -import warnings -from collections.abc import Callable -from pathlib import Path -from typing import get_args, get_origin - -import numpy as np -import pydantic -import pytest - -import ratapi -from ratapi.utils.enums import Calculations, LayerModels, TypeOptions - -layer_params = {"thickness": "Test Thickness", "SLD": "Test SLD", "roughness": "Test Roughness"} -absorption_layer_params = { - "thickness": "Test Thickness", - "SLD_real": "Test SLD", - "SLD_imaginary": "Test SLD", - "roughness": "Test Roughness", -} - -model_classes = { - "parameters": ratapi.models.Parameter, - "bulk_in": ratapi.models.Parameter, - "bulk_out": ratapi.models.Parameter, - "scalefactors": ratapi.models.Parameter, - "domain_ratios": ratapi.models.Parameter, - "background_parameters": ratapi.models.Parameter, - "resolution_parameters": ratapi.models.Parameter, - "backgrounds": ratapi.models.Background, - "resolutions": ratapi.models.Resolution, - "custom_files": ratapi.models.CustomFile, - "data": ratapi.models.Data, - "layers": ratapi.models.Layer, - "domain_contrasts": ratapi.models.DomainContrast, - "contrasts": ratapi.models.Contrast, -} - - -@pytest.fixture -def test_project(): - """Add parameters to the default project, so each ClassList can be tested properly.""" - test_project = ratapi.Project( - data=ratapi.ClassList([ratapi.models.Data(name="Simulation", data=np.array([[1.0, 1.0, 1.0]]))]), - ) - test_project.parameters.append(name="Test Thickness") - test_project.parameters.append(name="Test SLD") - test_project.parameters.append(name="Test Roughness") - test_project.custom_files.append(name="Test Custom File") - test_project.layers.append( - name="Test Layer", - thickness="Test Thickness", - SLD="Test SLD", - roughness="Test Roughness", - ) - test_project.contrasts.append( - name="Test Contrast", - data="Simulation", - background="Background 1", - bulk_in="SLD Air", - bulk_out="SLD D2O", - scalefactor="Scalefactor 1", - resolution="Resolution 1", - model=["Test Layer"], - ) - return test_project - - -@pytest.fixture -def default_project_str(): - """A string of the output of str() for a Project model with no parameters specified.""" - return ( - "Calculation: ---------------------------------------------------------------------------------------\n\n" - "normal\n\n" - "Model: ---------------------------------------------------------------------------------------------\n\n" - "standard layers\n\n" - "Geometry: ------------------------------------------------------------------------------------------\n\n" - "air/substrate\n\n" - "Parameters: ----------------------------------------------------------------------------------------\n\n" - "+-------+---------------------+-----+-------+-----+------+\n" - "| index | name | min | value | max | fit |\n" - "+-------+---------------------+-----+-------+-----+------+\n" - "| 0 | Substrate Roughness | 1.0 | 3.0 | 5.0 | True |\n" - "+-------+---------------------+-----+-------+-----+------+\n\n" - "Bulk In: -------------------------------------------------------------------------------------------\n\n" - "+-------+---------+-----+-------+-----+-------+\n" - "| index | name | min | value | max | fit |\n" - "+-------+---------+-----+-------+-----+-------+\n" - "| 0 | SLD Air | 0.0 | 0.0 | 0.0 | False |\n" - "+-------+---------+-----+-------+-----+-------+\n\n" - "Bulk Out: ------------------------------------------------------------------------------------------\n\n" - "+-------+---------+---------+----------+----------+-------+\n" - "| index | name | min | value | max | fit |\n" - "+-------+---------+---------+----------+----------+-------+\n" - "| 0 | SLD D2O | 6.2e-06 | 6.35e-06 | 6.35e-06 | False |\n" - "+-------+---------+---------+----------+----------+-------+\n\n" - "Scalefactors: --------------------------------------------------------------------------------------\n\n" - "+-------+---------------+------+-------+------+-------+\n" - "| index | name | min | value | max | fit |\n" - "+-------+---------------+------+-------+------+-------+\n" - "| 0 | Scalefactor 1 | 0.02 | 0.23 | 0.25 | False |\n" - "+-------+---------------+------+-------+------+-------+\n\n" - "Background Parameters: -----------------------------------------------------------------------------\n\n" - "+-------+--------------------+-------+-------+-------+-------+\n" - "| index | name | min | value | max | fit |\n" - "+-------+--------------------+-------+-------+-------+-------+\n" - "| 0 | Background Param 1 | 1e-07 | 1e-06 | 1e-05 | False |\n" - "+-------+--------------------+-------+-------+-------+-------+\n\n" - "Backgrounds: ---------------------------------------------------------------------------------------\n\n" - "+-------+--------------+----------+--------------------+\n" - "| index | name | type | source |\n" - "+-------+--------------+----------+--------------------+\n" - "| 0 | Background 1 | constant | Background Param 1 |\n" - "+-------+--------------+----------+--------------------+\n\n" - "Resolution Parameters: -----------------------------------------------------------------------------\n\n" - "+-------+--------------------+------+-------+------+-------+\n" - "| index | name | min | value | max | fit |\n" - "+-------+--------------------+------+-------+------+-------+\n" - "| 0 | Resolution Param 1 | 0.01 | 0.03 | 0.05 | False |\n" - "+-------+--------------------+------+-------+------+-------+\n\n" - "Resolutions: ---------------------------------------------------------------------------------------\n\n" - "+-------+--------------+----------+--------------------+\n" - "| index | name | type | source |\n" - "+-------+--------------+----------+--------------------+\n" - "| 0 | Resolution 1 | constant | Resolution Param 1 |\n" - "+-------+--------------+----------+--------------------+\n\n" - "Data: ----------------------------------------------------------------------------------------------\n\n" - "+-------+------------+------+------------+------------------+\n" - "| index | name | data | data range | simulation range |\n" - "+-------+------------+------+------------+------------------+\n" - "| 0 | Simulation | [] | [] | [0.005, 0.7] |\n" - "+-------+------------+------+------------+------------------+\n\n" - ) - - -def test_classlists(test_project) -> None: - """The ClassLists in the "Project" model should contain instances of the models given by the dictionary - "model_in_classlist". - """ - for model in (fields := ratapi.Project.model_fields): - if get_origin(fields[model].annotation) == ratapi.ClassList: - class_list = getattr(test_project, model) - assert class_list._class_handle == get_args(fields[model].annotation)[0] - - -def test_classlists_specific_cases() -> None: - """The ClassLists in the "Project" model should contain instances of specific models given various non-default - options. - """ - project = ratapi.Project(calculation=Calculations.Domains, absorption=True) - assert project.layers._class_handle.__name__ == "AbsorptionLayer" - assert project.contrasts._class_handle.__name__ == "ContrastWithRatio" - - -@pytest.mark.parametrize( - ["input_model", "model_params"], - [ - (ratapi.models.Background, {}), - (ratapi.models.Contrast, {}), - (ratapi.models.ContrastWithRatio, {}), - (ratapi.models.CustomFile, {}), - (ratapi.models.Data, {}), - (ratapi.models.DomainContrast, {}), - (ratapi.models.Layer, layer_params), - (ratapi.models.AbsorptionLayer, absorption_layer_params), - (ratapi.models.Resolution, {}), - ], -) -def test_initialise_wrong_classes(input_model: Callable, model_params: dict) -> None: - """If the "Project" model is initialised with incorrect classes, we should raise a ValidationError.""" - with pytest.raises( - pydantic.ValidationError, - match="1 validation error for Project\nparameters\n " - "Value error, This ClassList only supports elements of type Parameter. In the input list:\n" - f" index 0 is of type {input_model.__name__}", - ): - ratapi.Project(parameters=ratapi.ClassList(input_model(**model_params))) - - -@pytest.mark.parametrize( - ["input_model", "model_params", "absorption", "actual_model_name"], - [ - (ratapi.models.Layer, layer_params, True, "AbsorptionLayer"), - (ratapi.models.AbsorptionLayer, absorption_layer_params, False, "Layer"), - ], -) -def test_initialise_wrong_layers( - input_model: Callable, - model_params: dict, - absorption: bool, - actual_model_name: str, -) -> None: - """If the "Project" model is initialised with the incorrect layer model given the value of absorption, we should - raise a ValidationError. - """ - with pytest.raises( - pydantic.ValidationError, - match=f"1 validation error for Project\nlayers\n Value error, " - f'"The layers attribute contains {input_model.__name__}s, but the absorption parameter is ' - f'{absorption}. The attribute should be a ClassList of {actual_model_name} instead."', - ): - ratapi.Project(absorption=absorption, layers=ratapi.ClassList(input_model(**model_params))) - - -@pytest.mark.parametrize( - ["input_model", "calculation", "actual_model_name"], - [ - (ratapi.models.Contrast, Calculations.Domains, "ContrastWithRatio"), - (ratapi.models.ContrastWithRatio, Calculations.Normal, "Contrast"), - ], -) -def test_initialise_wrong_contrasts( - input_model: ratapi.models.RATModel, calculation: Calculations, actual_model_name: str -) -> None: - """If the "Project" model is initialised with the incorrect contrast model given the value of calculation, we - should raise a ValidationError. - """ - word = "without" if calculation == Calculations.Domains else "with" - with pytest.raises( - pydantic.ValidationError, - match=f"1 validation error for Project\ncontrasts\n" - f' Value error, "The contrasts attribute contains contrasts {word} ratio, ' - f'but the calculation is {calculation}"', - ): - ratapi.Project(calculation=calculation, contrasts=ratapi.ClassList(input_model())) - - -@pytest.mark.parametrize( - "calculation, model", - [(Calculations.Domains, ratapi.models.ContrastWithRatio), (Calculations.Normal, ratapi.models.Contrast)], -) -def test_initialise_ambiguous_contrasts(calculation: Calculations, model: ratapi.models.RATModel): - """If a sequence of dictionaries is passed to 'contrasts', convert them to the correct model for the calculation.""" - proj = ratapi.Project(calculation=calculation, contrasts=ratapi.ClassList([{"name": "Contrast 1"}])) - assert proj.contrasts._class_handle == model - - -def test_initialise_without_substrate_roughness() -> None: - """If the "Project" model is initialised without "Substrate Roughness" as a parameter, add it as a protected - parameter to the front of the "parameters" ClassList. - """ - project = ratapi.Project(parameters=ratapi.ClassList(ratapi.models.Parameter(name="Test Parameter"))) - assert project.parameters[0] == ratapi.models.ProtectedParameter( - name="Substrate Roughness", - min=1.0, - value=3.0, - max=5.0, - fit=True, - prior_type=ratapi.models.Priors.Uniform, - mu=0.0, - sigma=np.inf, - ) - - -@pytest.mark.parametrize( - "input_parameter", - [ - ratapi.models.Parameter(name="Substrate Roughness"), - ratapi.models.Parameter(name="SUBSTRATE ROUGHNESS"), - ratapi.models.Parameter(name="substrate roughness"), - ], -) -def test_initialise_without_protected_substrate_roughness(input_parameter: ratapi.models.Parameter) -> None: - """If the "Project" model is initialised without "Substrate Roughness" as a protected parameter, add it to the - front of the "parameters" ClassList. - """ - project = ratapi.Project(parameters=ratapi.ClassList(input_parameter)) - assert project.parameters[0] == ratapi.models.ProtectedParameter(name=input_parameter.name) - - -def test_initialise_without_simulation() -> None: - """If the "Project" model is initialised without "Simulation" in the "data" ClassList, add it to the front of the - "data" ClassList. - """ - project = ratapi.Project(parameters=ratapi.ClassList(ratapi.models.Parameter(name="Test Parameter"))) - assert project.data[0] == ratapi.models.Data(name="Simulation", simulation_range=[0.005, 0.7]) - - -@pytest.mark.parametrize( - ["field", "model_type", "wrong_input_model", "model_params"], - [ - ("backgrounds", "Background", ratapi.models.Resolution, {}), - ("contrasts", "Contrast", ratapi.models.Layer, layer_params), - ("domain_contrasts", "DomainContrast", ratapi.models.Parameter, {}), - ("custom_files", "CustomFile", ratapi.models.Data, {}), - ("data", "Data", ratapi.models.Contrast, {}), - ("layers", "Layer", ratapi.models.DomainContrast, {}), - ("parameters", "Parameter", ratapi.models.CustomFile, {}), - ("resolutions", "Resolution", ratapi.models.Background, {}), - ], -) -def test_assign_wrong_classes( - test_project, field: str, model_type: str, wrong_input_model: Callable, model_params: dict -) -> None: - """If we assign incorrect classes to the "Project" model, we should raise a ValidationError.""" - if field == "contrasts": - field_name = "contrasts.no_ratio" - elif field == "layers": - field_name = "layers.no_abs" - else: - field_name = field - - with pytest.raises( - pydantic.ValidationError, - match=( - f"1 validation error for Project\n{field_name}\n" - f" Value error, This ClassList only supports elements of type {model_type}. In the input list:\n" - f" index 0 is of type {wrong_input_model.__name__}" - ), - ): - setattr(test_project, field, ratapi.ClassList(wrong_input_model(**model_params))) - - -@pytest.mark.parametrize( - ["wrong_input_model", "model_params", "absorption", "actual_model_name"], - [ - (ratapi.models.Layer, layer_params, True, "AbsorptionLayer"), - (ratapi.models.AbsorptionLayer, absorption_layer_params, False, "Layer"), - ], -) -def test_assign_wrong_layers( - wrong_input_model: Callable, - model_params: dict, - absorption: bool, - actual_model_name: str, -) -> None: - """If we assign incorrect classes to the "Project" model, we should raise a ValidationError.""" - project = ratapi.Project(absorption=absorption) - with pytest.raises( - pydantic.ValidationError, - match=f"1 validation error for Project\nlayers\n Value error, " - f'"The layers attribute contains {wrong_input_model.__name__}s, but the absorption parameter is ' - f'{absorption}. The attribute should be a ClassList of {actual_model_name} instead."', - ): - project.layers = ratapi.ClassList(wrong_input_model(**model_params)) - - -@pytest.mark.parametrize( - ["wrong_input_model", "calculation", "actual_model_name"], - [ - (ratapi.models.Contrast, Calculations.Domains, "ContrastWithRatio"), - (ratapi.models.ContrastWithRatio, Calculations.Normal, "Contrast"), - ], -) -def test_assign_wrong_contrasts(wrong_input_model: Callable, calculation: Calculations, actual_model_name: str) -> None: - """If we assign incorrect classes to the "Project" model, we should raise a ValidationError.""" - project = ratapi.Project(calculation=calculation) - word = "without" if calculation == Calculations.Domains else "with" - with pytest.raises( - pydantic.ValidationError, - match=f"1 validation error for Project\ncontrasts\n" - f' Value error, "The contrasts attribute contains contrasts {word} ratio, but the calculation is ' - f'{calculation}"', - ): - project.contrasts = ratapi.ClassList(wrong_input_model()) - - -@pytest.mark.parametrize( - ["field", "model_params"], - [ - ("backgrounds", {}), - ("contrasts", {}), - ("custom_files", {}), - ("data", {}), - ("layers", layer_params), - ("parameters", {}), - ("resolutions", {}), - ], -) -def test_assign_models(test_project, field: str, model_params: dict) -> None: - """If the "Project" model is initialised with models rather than ClassLists, we should raise a ValidationError.""" - input_model = model_classes[field] - with pytest.raises( - pydantic.ValidationError, - match=f"1 validation error for Project\n{field}\n Input should be an instance of ClassList", - ): - setattr(test_project, field, input_model(**model_params)) - - -def test_wrapped_routines(test_project) -> None: - """When initialising a project, several ClassList routines should be wrapped.""" - wrapped_methods = [ - "_setitem", - "_delitem", - "_iadd", - "append", - "insert", - "pop", - "remove", - "clear", - "extend", - "set_fields", - ] - for class_list in ratapi.project.class_lists: - attribute = getattr(test_project, class_list) - for methodName in wrapped_methods: - assert hasattr(getattr(attribute, methodName), "__wrapped__") - - -def test_set_domain_ratios(test_project) -> None: - """If we are not running a domains calculation, the "domain_ratios" field of the model should always be empty.""" - assert test_project.domain_ratios == [] - test_project.domain_ratios.append(name="New Domain Ratio") - assert test_project.domain_ratios == [] - - -@pytest.mark.parametrize( - "project_parameters", - [ - ({"calculation": Calculations.Normal, "model": LayerModels.StandardLayers}), - ({"calculation": Calculations.Normal, "model": LayerModels.CustomLayers}), - ({"calculation": Calculations.Normal, "model": LayerModels.CustomXY}), - ({"calculation": Calculations.Domains, "model": LayerModels.CustomLayers}), - ({"calculation": Calculations.Domains, "model": LayerModels.CustomXY}), - ], -) -def test_set_domain_contrasts(project_parameters: dict) -> None: - """If we are not running a domains calculation with standard layers, the "domain_contrasts" field of the model - should always be empty. - """ - project = ratapi.Project(**project_parameters) - assert project.domain_contrasts == [] - project.domain_contrasts.append(name="New Domain Contrast") - assert project.domain_contrasts == [] - - -@pytest.mark.parametrize( - "project_parameters", - [ - ({"model": LayerModels.CustomLayers}), - ({"model": LayerModels.CustomXY}), - ], -) -def test_set_layers(project_parameters: dict) -> None: - """If we are not using a standard layers model, the "layers" field of the model should always be empty.""" - project = ratapi.Project(**project_parameters) - assert project.layers == [] - project.layers.append(name="New Layer", thickness="Test Thickness", SLD="Test SLD", roughness="Test Roughness") - assert project.layers == [] - - -@pytest.mark.parametrize( - "project_parameters", - [ - ( - { - "model": LayerModels.CustomLayers, - "contrasts": [ratapi.models.Contrast(name="Test Contrast", repeat_layers=2)], - } - ), - ({"model": LayerModels.CustomXY, "contrasts": [ratapi.models.Contrast(name="Test Contrast", repeat_layers=2)]}), - ], -) -def test_set_repeat_layers(project_parameters: dict) -> None: - """If we are using a custom layers of custom XY model, the "resample" field of all the contrasts should always - be 1.""" - with pytest.warns( - match='For a custom layers or custom XY calculation, the "repeat_layers" setting for each ' - "contrast is not valid - resetting to 1." - ): - project = ratapi.Project(**project_parameters) - assert all(contrast.repeat_layers == 1 for contrast in project.contrasts) - - -@pytest.mark.parametrize( - "project_parameters", - [ - ({"model": LayerModels.CustomXY, "contrasts": [ratapi.models.Contrast(name="Test Contrast")]}), - ], -) -def test_set_resample(project_parameters: dict) -> None: - """If we are using a custom XY model, the "resample" field of all the contrasts should always be True.""" - project = ratapi.Project(**project_parameters) - assert all(contrast.resample for contrast in project.contrasts) - with pytest.warns( - match='For a custom XY calculation, "resample" must be True for each contrast - resetting to True.' - ): - project.contrasts.append(name="New Contrast", resample=False) - assert all(contrast.resample for contrast in project.contrasts) - - -@pytest.mark.parametrize( - ["input_calculation", "input_contrast", "new_calculation", "new_contrast_model", "num_domain_ratios"], - [ - (Calculations.Normal, ratapi.models.Contrast, Calculations.Domains, "ContrastWithRatio", 1), - (Calculations.Domains, ratapi.models.ContrastWithRatio, Calculations.Normal, "Contrast", 0), - ], -) -def test_set_calculation( - input_calculation: Calculations, - input_contrast: Callable, - new_calculation: Calculations, - new_contrast_model: str, - num_domain_ratios: int, -) -> None: - """When changing the value of the calculation option, the "contrasts" ClassList should switch to using the - appropriate Contrast model. - """ - project = ratapi.Project(calculation=input_calculation, contrasts=ratapi.ClassList(input_contrast())) - project.calculation = new_calculation - - assert project.calculation is new_calculation - assert type(project.contrasts[0]).__name__ == new_contrast_model - assert project.contrasts._class_handle.__name__ == new_contrast_model - assert len(project.domain_ratios) == num_domain_ratios - - -@pytest.mark.parametrize( - ["new_calc", "new_model", "expected_contrast_model"], - [ - (Calculations.Normal, LayerModels.StandardLayers, ["Test Layer"]), - (Calculations.Normal, LayerModels.CustomLayers, []), - (Calculations.Normal, LayerModels.CustomXY, []), - (Calculations.Domains, LayerModels.StandardLayers, []), - (Calculations.Domains, LayerModels.CustomLayers, []), - (Calculations.Domains, LayerModels.CustomXY, []), - ], -) -def test_set_contrast_model_field( - test_project, - new_calc: Calculations, - new_model: LayerModels, - expected_contrast_model: list[str], -) -> None: - """If we change the calculation and model such that the values of the "model" field of the "contrasts" model come - from a different field of the project, we should clear the contrast "model" field. - """ - test_project.calculation = new_calc - test_project.model = new_model - assert test_project.contrasts[0].model == expected_contrast_model - - -@pytest.mark.parametrize( - ["input_model", "test_contrast_model", "error_message"], - [ - ( - LayerModels.StandardLayers, - ["Test Domain Ratio"], - 'For a standard layers domains calculation the "model" field of "contrasts" must contain exactly two ' - "values.", - ), - ( - LayerModels.StandardLayers, - ["Test Domain Ratio", "Test Domain Ratio", "Test Domain Ratio"], - 'For a standard layers domains calculation the "model" field of "contrasts" must contain exactly two ' - "values.", - ), - ( - LayerModels.CustomLayers, - ["Test Custom File", "Test Custom File"], - 'For a custom model calculation the "model" field of "contrasts" cannot contain more than one value.', - ), - ], -) -def test_check_contrast_model_length( - test_project, - input_model: LayerModels, - test_contrast_model: list[str], - error_message: str, -) -> None: - """If we are not running a domains calculation with standard layers, the "domain_contrasts" field of the model - should always be empty. - """ - test_domain_ratios = ratapi.ClassList(ratapi.models.Parameter(name="Test Domain Ratio")) - test_contrasts = ratapi.ClassList(ratapi.models.ContrastWithRatio(model=test_contrast_model)) - with pytest.raises( - pydantic.ValidationError, - match=f"1 validation error for Project\n Value error, {error_message}", - ): - ratapi.Project( - calculation=Calculations.Domains, - model=input_model, - domain_ratios=test_domain_ratios, - contrasts=test_contrasts, - ) - - -@pytest.mark.parametrize( - ["input_layer", "model_params", "input_absorption", "new_layer_model"], - [ - (ratapi.models.Layer, layer_params, False, "AbsorptionLayer"), - (ratapi.models.AbsorptionLayer, absorption_layer_params, True, "Layer"), - ], -) -def test_set_absorption( - input_layer: Callable, - model_params: dict, - input_absorption: bool, - new_layer_model: str, -) -> None: - """When changing the value of the absorption option, the "layers" ClassList should switch to using the appropriate - Layer model. - """ - project = ratapi.Project( - absorption=input_absorption, - parameters=ratapi.ClassList( - [ - ratapi.models.Parameter(name="Test Thickness"), - ratapi.models.Parameter(name="Test SLD"), - ratapi.models.Parameter(name="Test Roughness"), - ], - ), - layers=ratapi.ClassList(input_layer(**model_params)), - ) - project.absorption = not input_absorption - - assert project.absorption is not input_absorption - assert type(project.layers[0]).__name__ == new_layer_model - assert project.layers._class_handle.__name__ == new_layer_model - - -@pytest.mark.parametrize( - "delete_operation", - [ - "project.parameters.__delitem__(0)", - "project.parameters.pop()", - 'project.parameters.remove("Substrate Roughness")', - "project.parameters.clear()", - ], -) -def test_check_protected_parameters(delete_operation) -> None: - """If we try to remove a protected parameter, we should raise an error.""" - project = ratapi.Project() - - with pytest.raises( - pydantic.ValidationError, - match="1 validation error for Project\n Value error, " - "Can't delete the protected parameters: Substrate Roughness", - ): - eval(delete_operation) - - # Ensure model was not deleted - assert project.parameters[0].name == "Substrate Roughness" - - -@pytest.mark.parametrize( - ["model", "fields"], - [ - ("background_parameters", ["source"]), - ("resolution_parameters", ["source"]), - ("parameters", ["roughness"]), - ("data", ["data", "source"]), - ("custom_files", ["source", "source"]), - ("backgrounds", ["background"]), - ("bulk_in", ["bulk_in"]), - ("bulk_out", ["bulk_out"]), - ("scalefactors", ["scalefactor"]), - ("resolutions", ["resolution"]), - ], -) -def test_rename_models(test_project, model: str, fields: list[str]) -> None: - """When renaming a model in the project, the new name should be recorded when that model is referred to elsewhere - in the project. - """ - if model == "data": - test_project.backgrounds[0] = ratapi.models.Background(type="data", source="Simulation") - if model == "custom_files": - test_project.backgrounds[0] = ratapi.models.Background(type="function", source="Test Custom File") - # workaround until function resolutions are added - # test_project.resolutions[0] = ratapi.models.Resolution(type="function", source="Test Custom File") - test_project.resolution_parameters.append(ratapi.models.Parameter(name="New Name")) - test_project.resolutions[0] = ratapi.models.Resolution(type="constant", source="New Name") - - getattr(test_project, model).set_fields(-1, name="New Name") - model_name_lists = ratapi.project.model_names_used_in[model] - for model_name_list, field in zip(model_name_lists, fields, strict=False): - attribute = model_name_list.attribute - assert getattr(getattr(test_project, attribute)[-1], field) == "New Name" - - -@pytest.mark.parametrize( - "background_type, expected_field", - [ - [TypeOptions.Constant, "background_parameters"], - [TypeOptions.Data, "data"], - [TypeOptions.Function, "custom_files"], - ], -) -def test_allowed_backgrounds(background_type, expected_field) -> None: - """ - If the source field of the Background model is set to a value that is not specified in the appropriate ClassList, - we should raise a ValidationError. - """ - test_background = ratapi.models.Background(type=background_type, source="undefined") - with pytest.raises( - pydantic.ValidationError, - match=re.escape( - f'1 validation error for Project\n Value error, The value "undefined" used in the "source" field of ' - f'backgrounds[0] must be defined in "{expected_field}". Please add "undefined" to "{expected_field}" ' - f'before including it in "backgrounds".' - ), - ): - ratapi.Project(backgrounds=ratapi.ClassList(test_background)) - - -@pytest.mark.parametrize( - "field", - [ - "thickness", - "SLD", - "roughness", - ], -) -def test_allowed_layers(field: str) -> None: - """If the "thickness", "SLD", or "roughness" fields of the Layer model are set to values that are not specified in - the parameters, we should raise a ValidationError. - """ - test_layer = ratapi.models.Layer(**{**layer_params, field: "undefined"}) - - with pytest.raises( - pydantic.ValidationError, - match=re.escape( - f'1 validation error for Project\n Value error, The value "undefined" used in the "{field}" ' - f'field of layers[0] must be defined in "parameters". Please add "undefined" to "parameters" ' - f'before including it in "layers".' - ), - ): - ratapi.Project( - absorption=False, - parameters=ratapi.ClassList( - [ - ratapi.models.Parameter(name="Test Thickness"), - ratapi.models.Parameter(name="Test SLD"), - ratapi.models.Parameter(name="Test Roughness"), - ], - ), - layers=ratapi.ClassList(test_layer), - ) - - -@pytest.mark.parametrize( - "field", - [ - "thickness", - "SLD_real", - "SLD_imaginary", - "roughness", - ], -) -def test_allowed_absorption_layers(field: str) -> None: - """If the "thickness", "SLD_real", "SLD_imaginary", or "roughness" fields of the AbsorptionLayer model are set to - values that are not specified in the parameters, we should raise a ValidationError. - """ - test_layer = ratapi.models.AbsorptionLayer(**{**absorption_layer_params, field: "undefined"}) - - with pytest.raises( - pydantic.ValidationError, - match=re.escape( - f'1 validation error for Project\n Value error, The value "undefined" used in the "{field}" field of ' - f'layers[0] must be defined in "parameters". Please add "undefined" to "parameters" before including it ' - f'in "layers".' - ), - ): - ratapi.Project( - absorption=True, - parameters=ratapi.ClassList( - [ - ratapi.models.Parameter(name="Test Thickness"), - ratapi.models.Parameter(name="Test SLD"), - ratapi.models.Parameter(name="Test Roughness"), - ], - ), - layers=ratapi.ClassList(test_layer), - ) - - -@pytest.mark.parametrize( - "resolution_type, expected_field", - [ - [TypeOptions.Constant, "resolution_parameters"], - # uncomment when function resolutions are added! - # [TypeOptions.Function, "custom_files"], - ], -) -def test_allowed_resolutions(resolution_type, expected_field) -> None: - """If the "value" fields of the Resolution model are set to values that are not specified in the resolution - parameters, we should raise a ValidationError. - """ - test_resolution = ratapi.models.Resolution(type=resolution_type, source="undefined") - with pytest.raises( - pydantic.ValidationError, - match=re.escape( - f'1 validation error for Project\n Value error, The value "undefined" used in the "source" field of ' - f'resolutions[0] must be defined in "{expected_field}". Please add "undefined" to "{expected_field}" ' - f'before including it in "resolutions".' - ), - ): - ratapi.Project(resolutions=ratapi.ClassList(test_resolution)) - - -@pytest.mark.parametrize( - ["field", "model_name"], - [ - ("data", "data"), - ("background", "backgrounds"), - ("bulk_in", "bulk_in"), - ("bulk_out", "bulk_out"), - ("scalefactor", "scalefactors"), - ("resolution", "resolutions"), - ], -) -def test_allowed_contrasts(field: str, model_name: str) -> None: - """If the fields of the Contrast model are set to values not specified in the other respective models of the - project, we should raise a ValidationError. - """ - test_contrast = ratapi.models.Contrast(**{field: "undefined"}) - with pytest.raises( - pydantic.ValidationError, - match=re.escape( - f'1 validation error for Project\n Value error, The value "undefined" used in the "{field}" field of ' - f'contrasts[0] must be defined in "{model_name}". Please add "undefined" to "{model_name}" before ' - f'including it in "contrasts".' - ), - ): - ratapi.Project(calculation=Calculations.Normal, contrasts=ratapi.ClassList(test_contrast)) - - -@pytest.mark.parametrize( - ["field", "model_name"], - [ - ("data", "data"), - ("background", "backgrounds"), - ("bulk_in", "bulk_in"), - ("bulk_out", "bulk_out"), - ("scalefactor", "scalefactors"), - ("resolution", "resolutions"), - ("domain_ratio", "domain_ratios"), - ], -) -def test_allowed_contrasts_with_ratio(field: str, model_name: str) -> None: - """If the fields of the ContrastWithRatio model are set to values not specified in the other respective models of - the project, we should raise a ValidationError. - """ - test_contrast = ratapi.models.ContrastWithRatio(**{field: "undefined"}) - with pytest.raises( - pydantic.ValidationError, - match=re.escape( - f'1 validation error for Project\n Value error, The value "undefined" used in the "{field}" field of ' - f'contrasts[0] must be defined in "{model_name}". Please add "undefined" to "{model_name}" before ' - f'including it in "contrasts".' - ), - ): - ratapi.Project(calculation=Calculations.Domains, contrasts=ratapi.ClassList(test_contrast)) - - -@pytest.mark.parametrize( - ["input_calc", "input_model", "test_contrast", "field_name"], - [ - ( - Calculations.Domains, - LayerModels.StandardLayers, - ratapi.models.ContrastWithRatio(name="Test Contrast", model=["undefined", "undefined"]), - "domain_contrasts", - ), - ( - Calculations.Domains, - LayerModels.CustomLayers, - ratapi.models.ContrastWithRatio(name="Test Contrast", model=["undefined"]), - "custom_files", - ), - ( - Calculations.Domains, - LayerModels.CustomXY, - ratapi.models.ContrastWithRatio(name="Test Contrast", model=["undefined"]), - "custom_files", - ), - ( - Calculations.Normal, - LayerModels.StandardLayers, - ratapi.models.Contrast(name="Test Contrast", model=["undefined", "undefined", "undefined"]), - "layers", - ), - ( - Calculations.Normal, - LayerModels.CustomLayers, - ratapi.models.Contrast(name="Test Contrast", model=["undefined"]), - "custom_files", - ), - ( - Calculations.Normal, - LayerModels.CustomXY, - ratapi.models.Contrast(name="Test Contrast", model=["undefined"]), - "custom_files", - ), - ], -) -def test_allowed_contrast_models( - input_calc: Calculations, - input_model: LayerModels, - test_contrast: "ratapi.models", - field_name: str, -) -> None: - """If any value in the model field of the contrasts is set to a value not specified in the appropriate part of the - project, we should raise a ValidationError. - """ - missing_values = list(set(test_contrast.model)) - with pytest.raises( - pydantic.ValidationError, - match=re.escape( - f"1 validation error for Project\n Value error, The value{'s' if len(missing_values) > 1 else ''}: " - f'"{", ".join(missing_values)}" used in the "model" field of contrasts[0] must be defined in ' - f'"{field_name}". Please add all required values to "{field_name}" before including them in "contrasts".' - ), - ): - ratapi.Project(calculation=input_calc, model=input_model, contrasts=ratapi.ClassList(test_contrast)) - - -def test_allowed_domain_contrast_models() -> None: - """If any value in the model field of the domain_contrasts is set to a value not specified in the "layers" field of - the project, we should raise a ValidationError. - """ - test_contrast = ratapi.models.DomainContrast(name="Test Domain Contrast", model=["undefined"]) - with pytest.raises( - pydantic.ValidationError, - match=re.escape( - '1 validation error for Project\n Value error, The value: "undefined" used in the "model" field of ' - 'domain_contrasts[0] must be defined in "layers". Please add all required values to "layers" before ' - 'including them in "domain_contrasts".' - ), - ): - ratapi.Project(calculation=Calculations.Domains, domain_contrasts=ratapi.ClassList(test_contrast)) - - -def test_str(default_project_str: str) -> None: - """We should be able to print the "Project" model as a formatted list of the fields.""" - assert str(ratapi.Project()) == default_project_str - - -def test_get_all_names(test_project) -> None: - """We should be able to get the names of all the models defined in the project.""" - assert test_project.get_all_names() == { - "parameters": ["Substrate Roughness", "Test Thickness", "Test SLD", "Test Roughness"], - "bulk_in": ["SLD Air"], - "bulk_out": ["SLD D2O"], - "scalefactors": ["Scalefactor 1"], - "domain_ratios": [], - "background_parameters": ["Background Param 1"], - "backgrounds": ["Background 1"], - "resolution_parameters": ["Resolution Param 1"], - "resolutions": ["Resolution 1"], - "custom_files": ["Test Custom File"], - "data": ["Simulation"], - "layers": ["Test Layer"], - "domain_contrasts": [], - "contrasts": ["Test Contrast"], - } - - -def test_get_all_protected_parameters(test_project) -> None: - """We should be able to get the names of all the protected parameters defined in the project.""" - assert test_project.get_all_protected_parameters() == { - "parameters": ["Substrate Roughness"], - "bulk_in": [], - "bulk_out": [], - "scalefactors": [], - "domain_ratios": [], - "background_parameters": [], - "resolution_parameters": [], - } - - -@pytest.mark.parametrize( - "test_value", - [ - "", - "Substrate Roughness", - ], -) -def test_check_allowed_values(test_value: str) -> None: - """We should not raise an error if string values are defined and on the list of allowed values.""" - allowed_values = ["Substrate Roughness"] - project = ratapi.Project.model_construct( - layers=ratapi.ClassList(ratapi.models.Layer(**dict(layer_params, roughness=test_value))) - ) - assert project.check_allowed_values("layers", ["roughness"], allowed_values, allowed_values) is None - - -@pytest.mark.parametrize( - "test_value", - [ - "Undefined Param", - ], -) -def test_check_allowed_values_not_on_list(test_value: str) -> None: - """If string values are defined and are not included on the list of allowed values we should raise a ValueError.""" - project = ratapi.Project.model_construct( - layers=ratapi.ClassList(ratapi.models.Layer(**dict(layer_params, roughness=test_value))) - ) - allowed_values = ["Substrate Roughness"] - with pytest.raises( - ValueError, - match=re.escape( - f'The value "{test_value}" used in the "roughness" field of layers[0] must be defined in "parameters". ' - f'Please add "{test_value}" to "parameters" before including it in "layers".' - ), - ): - project.check_allowed_values("layers", ["roughness"], allowed_values, allowed_values) - - -@pytest.mark.parametrize( - "test_value", - [ - "", - "Background Param 1", - ], -) -def test_check_allowed_background_resolution_values_constant(test_value: str) -> None: - """We should not raise an error if string values are defined and on the appropriate list of allowed values.""" - project = ratapi.Project.model_construct( - background_parameters=ratapi.ClassList(ratapi.models.Parameter(name="Background Param 1")), - backgrounds=ratapi.ClassList(ratapi.models.Background(type=TypeOptions.Constant, source=test_value)), - ) - assert project.check_allowed_source("backgrounds") is None - - -@pytest.mark.parametrize( - "test_value", - [ - "", - "Simulation", - ], -) -def test_check_allowed_background_resolution_values_data(test_value: str) -> None: - """We should not raise an error if string values are defined and on the appropriate list of allowed values.""" - project = ratapi.Project.model_construct( - backgrounds=ratapi.ClassList(ratapi.models.Background(type=TypeOptions.Data, source=test_value)) - ) - assert project.check_allowed_source("backgrounds") is None - - -@pytest.mark.parametrize( - "test_value", - ["Undefined Param", "Simulation"], -) -def test_check_allowed_background_resolution_values_not_on_constant_list(test_value: str) -> None: - """If string values are defined and are not included on the correct list of allowed values we should raise a - ValueError. - """ - project = ratapi.Project.model_construct( - backgrounds=ratapi.ClassList(ratapi.models.Background(type=TypeOptions.Constant, source=test_value)) - ) - with pytest.raises( - ValueError, - match=re.escape( - f'The value "{test_value}" used in the "source" field of backgrounds[0] must be defined in ' - f'"background_parameters". Please add "{test_value}" to "background_parameters" before including it in ' - f'"backgrounds".' - ), - ): - project.check_allowed_source( - "backgrounds", - ) - - -@pytest.mark.parametrize( - "test_value", - [ - "Undefined Param", - "Background Param 1", - ], -) -def test_check_allowed_background_resolution_values_on_data_list(test_value: str) -> None: - """If string values are defined and are not included on the correct list of allowed values we should raise a - ValueError. - """ - project = ratapi.Project.model_construct( - backgrounds=ratapi.ClassList(ratapi.models.Background(type=TypeOptions.Data, source=test_value)) - ) - with pytest.raises( - ValueError, - match=re.escape( - f'The value "{test_value}" used in the "source" field of backgrounds[0] must be defined in "data". Please ' - f'add "{test_value}" to "data" before including it in "backgrounds".' - ), - ): - project.check_allowed_source("backgrounds") - - -@pytest.mark.parametrize( - "test_values", - [ - [], - ["Test Layer"], - ], -) -def test_check_contrast_model_allowed_values(test_values: list[str]) -> None: - """We should not raise an error if values are defined in a non-empty list and all are on the list of allowed - values. - """ - project = ratapi.Project.model_construct( - contrasts=ratapi.ClassList(ratapi.models.Contrast(name="Test Contrast", model=test_values)), - ) - assert project.check_contrast_model_allowed_values("contrasts", ["Test Layer"], ["Test Layer"], "layers") is None - - -@pytest.mark.parametrize( - "test_values", - [ - ["Undefined Param 1"], - ["Test Layer", "Undefined Param 1"], - ["Undefined Param 1 ", "Test Layer", "Undefined Param 2"], - ], -) -def test_check_allowed_contrast_model_not_on_list(test_values: list[str]) -> None: - """If string values are defined in a non-empty list and any of them are not included on the list of allowed values - we should raise a ValueError. - """ - project = ratapi.Project.model_construct( - contrasts=ratapi.ClassList(ratapi.models.Contrast(name="Test Contrast", model=test_values)), - ) - allowed_values = ["Test Layer"] - missing_values = list(set(test_values) - set(allowed_values)) - with pytest.raises( - ValueError, - match=re.escape( - f'The value{"s" if len(missing_values) > 1 else ""}: "{", ".join(str(i) for i in missing_values)}" used ' - f'in the "model" field of contrasts[0] must be defined in "layers". Please add all required values to ' - f'"layers" before including them in "contrasts".' - ), - ): - project.check_contrast_model_allowed_values("contrasts", allowed_values, allowed_values, "layers") - - -@pytest.mark.parametrize( - "test_values", - [ - ["Undefined Param 1"], - ["Test Layer", "Undefined Param 1"], - ["Undefined Param 1", "Test Layer", "Undefined Param 2"], - ], -) -def test_check_allowed_contrast_model_removed_from_list(test_values: list[str]) -> None: - """If string values are defined in a non-empty list and any of them have been removed from the list of allowed - values we should raise a ValueError. - """ - project = ratapi.Project.model_construct( - contrasts=ratapi.ClassList(ratapi.models.Contrast(name="Test Contrast", model=test_values)), - ) - previous_values = ["Test Layer", "Undefined Param 1", "Undefined Param 2"] - allowed_values = ["Test Layer"] - missing_values = list(set(test_values) - set(allowed_values)) - with pytest.raises( - ValueError, - match=re.escape( - f'The value{"s" if len(missing_values) > 1 else ""}: "{", ".join(str(i) for i in missing_values)}" used ' - f'in the "model" field of contrasts[0] must be defined in "layers". Please remove all unnecessary values ' - f'from "model" before attempting to delete them.' - ), - ): - project.check_contrast_model_allowed_values("contrasts", allowed_values, previous_values, "layers") - - -@pytest.mark.parametrize( - ["input_calc", "input_model", "expected_field_name"], - [ - (Calculations.Domains, LayerModels.StandardLayers, "domain_contrasts"), - (Calculations.Normal, LayerModels.StandardLayers, "layers"), - (Calculations.Domains, LayerModels.CustomLayers, "custom_files"), - (Calculations.Normal, LayerModels.CustomLayers, "custom_files"), - (Calculations.Domains, LayerModels.CustomXY, "custom_files"), - (Calculations.Normal, LayerModels.CustomXY, "custom_files"), - ], -) -def test_get_contrast_model_field(input_calc: Calculations, input_model: LayerModels, expected_field_name: str) -> None: - """Each combination of calculation and model determines the field where the values of "model" field of "contrasts" - are defined. - """ - project = ratapi.Project(calculation=input_calc, model=input_model) - assert project.get_contrast_model_field() == expected_field_name - - -@pytest.mark.parametrize( - "project", - ["r1_default_project", "r1_monolayer", "input_project"], -) -@pytest.mark.parametrize( - "input_filename", - [ - "test_script.py", - "test_script", - ], -) -def test_write_script(project, request, temp_dir, input_filename: str) -> None: - """Test the script we write to regenerate the project is created and runs as expected.""" - test_project = request.getfixturevalue(project) - test_project.write_script("problem", Path(temp_dir, input_filename)) - - # Test the file is written in the correct place - script_path = Path(temp_dir, "test_script.py") - assert script_path.exists() - - # Test we get the project object we expect when running the script - local_dict = {} - exec(script_path.read_text(), globals(), local_dict) - new_project = local_dict["problem"] - - for class_list in ratapi.project.class_lists: - assert getattr(new_project, class_list) == getattr(test_project, class_list) - - -@pytest.mark.parametrize( - "extension", - [ - ".txt", - ".f90", - ".m", - ".pyc", - ], -) -def test_write_script_wrong_extension(test_project, extension: str) -> None: - """If we try to write the script to anything other than a ".py" file, we raise a ValueError.""" - with pytest.raises(ValueError, match='The script name provided to "write_script" must use the ".py" format'): - test_project.write_script("problem", "test" + extension) - - -@pytest.mark.parametrize( - ["class_list", "model_type", "field"], - [ - ("backgrounds", "constant", "source"), - ("resolutions", "constant", "source"), - ("layers", "", "thickness"), - ("layers", "", "SLD"), - ("layers", "", "roughness"), - ("contrasts", "", "data"), - ("contrasts", "", "background"), - ("contrasts", "", "bulk_in"), - ("contrasts", "", "bulk_out"), - ("contrasts", "", "scalefactor"), - ("contrasts", "", "resolution"), - ], -) -@pytest.mark.filterwarnings("ignore:The following values are not recognised by this*:UserWarning") -def test_wrap_set(test_project, class_list: str, model_type: str, field: str) -> None: - """If we set the field values of a model in a ClassList as undefined values, we should raise a ValidationError.""" - test_attribute = getattr(test_project, class_list) - orig_class_list = copy.deepcopy(test_attribute) - class_list_str = f"{class_list}{f'.{model_type}' if model_type else ''}.{field}" - index = 0 - - with pytest.raises( - pydantic.ValidationError, - match=re.escape( - f'1 validation error for Project\n Value error, The value "undefined" used in the "{field}" field of ' - f'{class_list}[{index}] must be defined in "{ratapi.project.values_defined_in[class_list_str]}". Please ' - f'add "undefined" to "{ratapi.project.values_defined_in[class_list_str]}" before including it in ' - f'"{class_list}".' - ), - ): - test_attribute.set_fields(index, **{field: "undefined"}) - - # Ensure invalid model was not changed - assert test_attribute == orig_class_list - - -@pytest.mark.parametrize( - ["class_list", "parameter", "field"], - [ - ("background_parameters", "Background Param 1", "source"), - ("resolution_parameters", "Resolution Param 1", "source"), - ("parameters", "Test SLD", "SLD"), - ("data", "Simulation", "data"), - ("backgrounds", "Background 1", "background"), - ("bulk_in", "SLD Air", "bulk_in"), - ("bulk_out", "SLD D2O", "bulk_out"), - ("scalefactors", "Scalefactor 1", "scalefactor"), - ("resolutions", "Resolution 1", "resolution"), - ], -) -def test_wrap_del(test_project, class_list: str, parameter: str, field: str) -> None: - """If we delete a model in a ClassList containing values defined elsewhere, we should raise a ValidationError.""" - test_attribute = getattr(test_project, class_list) - orig_class_list = copy.deepcopy(test_attribute) - index = test_attribute.index(parameter) - - sub_attribute_name = ratapi.project.model_names_used_in[class_list][0].attribute - sub_attribute = getattr(test_project, sub_attribute_name) - sub_index = [i for i, _ in enumerate(sub_attribute) if getattr(sub_attribute[i], field) == parameter][0] - - with pytest.raises( - pydantic.ValidationError, - match=re.escape( - f'1 validation error for Project\n Value error, The value "{parameter}" used in the "{field}" field of ' - f'{sub_attribute_name}[{sub_index}] must be defined in "{class_list}". Please remove "{parameter}" from ' - f'"{sub_attribute_name}[{sub_index}].{field}" before attempting to delete it.' - ), - ): - del test_attribute[index] - - # Ensure model was not deleted - assert test_attribute == orig_class_list - - -@pytest.mark.parametrize( - ["class_list", "model_type", "field", "model_params"], - [ - ("backgrounds", "constant", "source", {}), - ("resolutions", "constant", "source", {}), - ("layers", "", "thickness", layer_params), - ("layers", "", "SLD", layer_params), - ("layers", "", "roughness", layer_params), - ("contrasts", "", "data", {}), - ("contrasts", "", "background", {}), - ("contrasts", "", "bulk_in", {}), - ("contrasts", "", "bulk_out", {}), - ("contrasts", "", "scalefactor", {}), - ("contrasts", "", "resolution", {}), - ], -) -@pytest.mark.filterwarnings("ignore:The following values are not recognised by this*:UserWarning") -def test_wrap_iadd(test_project, class_list: str, model_type: str, field: str, model_params: dict) -> None: - """If we add a model containing undefined values to a ClassList, we should raise a ValidationError.""" - test_attribute = getattr(test_project, class_list) - orig_class_list = copy.deepcopy(test_attribute) - input_model = model_classes[class_list] - class_list_str = f"{class_list}{f'.{model_type}' if model_type else ''}.{field}" - - with pytest.raises( - pydantic.ValidationError, - match=re.escape( - f'1 validation error for Project\n Value error, The value "undefined" used in the "{field}" ' - f"field of {class_list}[{len(test_attribute)}] must be defined in " - f'"{ratapi.project.values_defined_in[class_list_str]}". Please add "undefined" to ' - f'"{ratapi.project.values_defined_in[class_list_str]}" before including it in "{class_list}".' - ), - ): - test_attribute += [input_model(**{**model_params, field: "undefined"})] - - # Ensure invalid model was not added - assert test_attribute == orig_class_list - - -@pytest.mark.parametrize( - ["class_list", "model_type", "field", "model_params"], - [ - ("backgrounds", "constant", "source", {}), - ("resolutions", "constant", "source", {}), - ("layers", "", "thickness", layer_params), - ("layers", "", "SLD", layer_params), - ("layers", "", "roughness", layer_params), - ("contrasts", "", "data", {}), - ("contrasts", "", "background", {}), - ("contrasts", "", "bulk_in", {}), - ("contrasts", "", "bulk_out", {}), - ("contrasts", "", "scalefactor", {}), - ("contrasts", "", "resolution", {}), - ], -) -@pytest.mark.filterwarnings("ignore:The following values are not recognised by this*:UserWarning") -def test_wrap_append(test_project, class_list: str, model_type: str, field: str, model_params: dict) -> None: - """If we append a model containing undefined values to a ClassList, we should raise a ValidationError.""" - test_attribute = getattr(test_project, class_list) - orig_class_list = copy.deepcopy(test_attribute) - - input_model = model_classes[class_list] - class_list_str = f"{class_list}{f'.{model_type}' if model_type else ''}.{field}" - - with pytest.raises( - pydantic.ValidationError, - match=re.escape( - f'1 validation error for Project\n Value error, The value "undefined" used in the "{field}" ' - f"field of {class_list}[{len(test_attribute)}] must be defined in " - f'"{ratapi.project.values_defined_in[class_list_str]}". Please add "undefined" to ' - f'"{ratapi.project.values_defined_in[class_list_str]}" before including it in "{class_list}".' - ), - ): - test_attribute.append(input_model(**{**model_params, field: "undefined"})) - - # Ensure invalid model was not appended - assert test_attribute == orig_class_list - - -@pytest.mark.parametrize( - ["class_list", "model_type", "field", "model_params"], - [ - ("backgrounds", "constant", "source", {}), - ("resolutions", "constant", "source", {}), - ("layers", "", "thickness", layer_params), - ("layers", "", "SLD", layer_params), - ("layers", "", "roughness", layer_params), - ("contrasts", "", "data", {}), - ("contrasts", "", "background", {}), - ("contrasts", "", "bulk_in", {}), - ("contrasts", "", "bulk_out", {}), - ("contrasts", "", "scalefactor", {}), - ("contrasts", "", "resolution", {}), - ], -) -@pytest.mark.filterwarnings("ignore:The following values are not recognised by this*:UserWarning") -def test_wrap_insert(test_project, class_list: str, model_type: str, field: str, model_params: dict) -> None: - """If we insert a model containing undefined values into a ClassList, we should raise a ValidationError.""" - test_attribute = getattr(test_project, class_list) - orig_class_list = copy.deepcopy(test_attribute) - input_model = model_classes[class_list] - class_list_str = f"{class_list}{f'.{model_type}' if model_type else ''}.{field}" - index = 0 - - with pytest.raises( - pydantic.ValidationError, - match=re.escape( - f'1 validation error for Project\n Value error, The value "undefined" used in the "{field}" ' - f"field of {class_list}[{index}] must be defined in " - f'"{ratapi.project.values_defined_in[class_list_str]}". Please add "undefined" to ' - f'"{ratapi.project.values_defined_in[class_list_str]}" before including it in "{class_list}".' - ), - ): - test_attribute.insert(index, input_model(**{**model_params, field: "undefined"})) - - # Ensure invalid model was not inserted - assert test_attribute == orig_class_list - - -@pytest.mark.parametrize( - ["class_list", "field"], - [ - ("backgrounds", "source"), - ("backgrounds", "value_1"), - ("backgrounds", "value_2"), - ("backgrounds", "value_3"), - ("backgrounds", "value_4"), - ("backgrounds", "value_5"), - ("resolutions", "source"), - ("resolutions", "value_1"), - ("resolutions", "value_2"), - ("resolutions", "value_3"), - ("resolutions", "value_4"), - ("resolutions", "value_5"), - ("contrasts", "data"), - ("contrasts", "background"), - ("contrasts", "bulk_in"), - ("contrasts", "bulk_out"), - ("contrasts", "scalefactor"), - ("contrasts", "resolution"), - ], -) -@pytest.mark.filterwarnings("ignore:The following values are not recognised by this*:UserWarning") -def test_wrap_insert_type_error(test_project, class_list: str, field: str) -> None: - """If we raise a TypeError using the wrapped insert routine, we should re-raise the error.""" - test_attribute = getattr(test_project, class_list) - orig_class_list = copy.deepcopy(test_attribute) - input_model = model_classes[class_list] - - with pytest.raises(TypeError): - test_attribute.insert(input_model) - - # Ensure invalid model was not inserted - assert test_attribute == orig_class_list - - -@pytest.mark.parametrize( - ["class_list", "parameter", "field"], - [ - ("background_parameters", "Background Param 1", "source"), - ("resolution_parameters", "Resolution Param 1", "source"), - ("parameters", "Test SLD", "SLD"), - ("data", "Simulation", "data"), - ("backgrounds", "Background 1", "background"), - ("bulk_in", "SLD Air", "bulk_in"), - ("bulk_out", "SLD D2O", "bulk_out"), - ("scalefactors", "Scalefactor 1", "scalefactor"), - ("resolutions", "Resolution 1", "resolution"), - ], -) -def test_wrap_pop(test_project, class_list: str, parameter: str, field: str) -> None: - """If we pop a model in a ClassList containing values defined elsewhere, we should raise a ValidationError.""" - test_attribute = getattr(test_project, class_list) - orig_class_list = copy.deepcopy(test_attribute) - index = test_attribute.index(parameter) - - sub_attribute_name = ratapi.project.model_names_used_in[class_list][0].attribute - sub_attribute = getattr(test_project, sub_attribute_name) - sub_index = [i for i, _ in enumerate(sub_attribute) if getattr(sub_attribute[i], field) == parameter][0] - - with pytest.raises( - pydantic.ValidationError, - match=re.escape( - f'1 validation error for Project\n Value error, The value "{parameter}" used in the "{field}" field of ' - f'{sub_attribute_name}[{sub_index}] must be defined in "{class_list}". Please remove "{parameter}" from ' - f'"{sub_attribute_name}[{sub_index}].{field}" before attempting to delete it.' - ), - ): - test_attribute.pop(index) - - # Ensure model was not popped - assert test_attribute == orig_class_list - - -@pytest.mark.parametrize( - ["class_list", "parameter", "field"], - [ - ("background_parameters", "Background Param 1", "source"), - ("resolution_parameters", "Resolution Param 1", "source"), - ("parameters", "Test SLD", "SLD"), - ("data", "Simulation", "data"), - ("backgrounds", "Background 1", "background"), - ("bulk_in", "SLD Air", "bulk_in"), - ("bulk_out", "SLD D2O", "bulk_out"), - ("scalefactors", "Scalefactor 1", "scalefactor"), - ("resolutions", "Resolution 1", "resolution"), - ], -) -def test_wrap_remove(test_project, class_list: str, parameter: str, field: str) -> None: - """If we remove a model in a ClassList containing values defined elsewhere, we should raise a ValidationError.""" - test_attribute = getattr(test_project, class_list) - orig_class_list = copy.deepcopy(test_attribute) - - sub_attribute_name = ratapi.project.model_names_used_in[class_list][0].attribute - sub_attribute = getattr(test_project, sub_attribute_name) - sub_index = [i for i, _ in enumerate(sub_attribute) if getattr(sub_attribute[i], field) == parameter][0] - - with pytest.raises( - pydantic.ValidationError, - match=re.escape( - f'1 validation error for Project\n Value error, The value "{parameter}" used in the "{field}" field of ' - f'{sub_attribute_name}[{sub_index}] must be defined in "{class_list}". Please remove "{parameter}" from ' - f'"{sub_attribute_name}[{sub_index}].{field}" before attempting to delete it.' - ), - ): - test_attribute.remove(parameter) - - # Ensure model was not removed - assert test_attribute == orig_class_list - - -@pytest.mark.parametrize( - ["class_list", "parameter", "field"], - [ - ("background_parameters", "Background Param 1", "source"), - ("resolution_parameters", "Resolution Param 1", "source"), - ("parameters", "Test Thickness", "thickness"), - ("data", "Simulation", "data"), - ("backgrounds", "Background 1", "background"), - ("bulk_in", "SLD Air", "bulk_in"), - ("bulk_out", "SLD D2O", "bulk_out"), - ("scalefactors", "Scalefactor 1", "scalefactor"), - ("resolutions", "Resolution 1", "resolution"), - ], -) -def test_wrap_clear(test_project, class_list: str, parameter: str, field: str) -> None: - """If we clear a ClassList containing models with values defined elsewhere, we should raise a ValidationError.""" - test_attribute = getattr(test_project, class_list) - orig_class_list = copy.deepcopy(test_attribute) - - sub_attribute_name = ratapi.project.model_names_used_in[class_list][0].attribute - sub_attribute = getattr(test_project, sub_attribute_name) - sub_index = [i for i, _ in enumerate(sub_attribute) if getattr(sub_attribute[i], field) == parameter][0] - - with pytest.raises( - pydantic.ValidationError, - match=re.escape( - f'1 validation error for Project\n Value error, The value "{parameter}" used in the "{field}" field of ' - f'{sub_attribute_name}[{sub_index}] must be defined in "{class_list}". Please remove "{parameter}" from ' - f'"{sub_attribute_name}[{sub_index}].{field}" before attempting to delete it.' - ), - ): - test_attribute.clear() - - # Ensure list was not cleared - assert test_attribute == orig_class_list - - -@pytest.mark.parametrize( - ["class_list", "model_type", "field", "model_params"], - [ - ("backgrounds", "constant", "source", {}), - ("resolutions", "constant", "source", {}), - ("layers", "", "thickness", layer_params), - ("layers", "", "SLD", layer_params), - ("layers", "", "roughness", layer_params), - ("contrasts", "", "data", {}), - ("contrasts", "", "background", {}), - ("contrasts", "", "bulk_in", {}), - ("contrasts", "", "bulk_out", {}), - ("contrasts", "", "scalefactor", {}), - ("contrasts", "", "resolution", {}), - ], -) -@pytest.mark.filterwarnings("ignore:The following values are not recognised by this*:UserWarning") -def test_wrap_extend(test_project, class_list: str, model_type: str, field: str, model_params: dict) -> None: - """If we extend a ClassList with model containing undefined values, we should raise a ValidationError.""" - test_attribute = getattr(test_project, class_list) - orig_class_list = copy.deepcopy(test_attribute) - input_model = model_classes[class_list] - class_list_str = f"{class_list}{f'.{model_type}' if model_type else ''}.{field}" - - with pytest.raises( - pydantic.ValidationError, - match=re.escape( - f'1 validation error for Project\n Value error, The value "undefined" used in the "{field}" ' - f"field of {class_list}[{len(test_attribute)}] must be defined in " - f'"{ratapi.project.values_defined_in[class_list_str]}". Please add "undefined" to ' - f'"{ratapi.project.values_defined_in[class_list_str]}" before including it in "{class_list}".' - ), - ): - test_attribute.extend([input_model(**{**model_params, field: "undefined"})]) - - # Ensure invalid model was not appended - assert test_attribute == orig_class_list - - -@pytest.mark.parametrize( - "project", - [ - "r1_default_project", - "r1_monolayer", - "r1_monolayer_8_contrasts", - "r1_orso_polymer", - "r1_motofit_bench_mark", - "dspc_standard_layers", - "dspc_custom_layers", - "dspc_custom_xy", - "domains_standard_layers", - "domains_custom_layers", - "domains_custom_xy", - "absorption", - "absorption_different_function", - ], -) -def test_save_load(project, request): - """Test that saving and loading a project returns the same project.""" - original_project = request.getfixturevalue(project) - - with tempfile.TemporaryDirectory() as tmp: - # ignore relative path warnings - path = Path(tmp, "project.json") - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - original_project.save(path) - converted_project = ratapi.Project.load(path) - - for field in ratapi.Project.model_fields: - assert getattr(converted_project, field) == getattr(original_project, field) - - -def test_relative_paths(): - """Test that ``try_relative_to`` correctly creates relative paths to subfolders.""" - - cur_path = Path(".").resolve() - data_path = cur_path / "data/myfile.dat" - assert Path(ratapi.project.try_relative_to(data_path, cur_path)) == Path("data/myfile.dat") - - # relative path will be left relative. - data_path = "data/myfile.dat" - assert Path(ratapi.project.try_relative_to(data_path, cur_path)) == Path("data/myfile.dat") - - -def test_relative_paths_warning(): - """Test that we get a warning for trying to walk up paths.""" - - cur_path = Path(".").resolve() - data_path = cur_path / "tmp/project/data/mydata.dat" - relative_path = cur_path / "tmp/project/project_path/myproj.dat" - - with pytest.warns( - match="Could not write custom file path as relative to the project directory, " - "which means that it may not work on other devices. If you would like to share your project, " - "make sure your custom files are in a subfolder of the project save location.", - ): - assert Path(ratapi.project.try_relative_to(data_path, relative_path)) == data_path diff --git a/tests/test_run.py b/tests/test_run.py deleted file mode 100644 index 3c85fbcd..00000000 --- a/tests/test_run.py +++ /dev/null @@ -1,401 +0,0 @@ -"""Test the run module using the example calculation from "DSPC_standard_layers.py". - -We use the example for both a reflectivity calculation, and Bayesian analysis using the Dream algorithm. -""" - -import io -from contextlib import redirect_stdout -from unittest import mock - -import numpy as np -import pytest - -import ratapi -import ratapi.outputs -import ratapi.rat_core -from ratapi.events import EventTypes, ProgressEventData, notify -from ratapi.run import ProgressBar, TextOutput -from ratapi.utils.enums import Calculations, Geometries, LayerModels, Procedures -from tests.utils import check_results_equal - - -@pytest.fixture -def reflectivity_calculation_problem(): - """The output C++ ProblemDefinition object for a reflectivity calculation of the project set out in - "DSPC_standard_layers.py". - """ - problem = ratapi.rat_core.ProblemDefinition() - problem.TF = Calculations.Normal - problem.modelType = LayerModels.StandardLayers - problem.geometry = Geometries.SubstrateLiquid - problem.useImaginary = False - problem.params = np.array( - [ - 3.000e00, - 1.954e01, - 3.390e-06, - 2.266e01, - -4.010e-07, - 5.252e00, - 5.640e00, - 1.712e01, - 0.000e00, - 8.560e00, - 1.750e-06, - 4.545e01, - 1.070e01, - 1.470e-06, - 6.014e00, - 1.782e01, - -4.610e-07, - 1.764e01, - 3.615e01, - 1.000e02, - 2.361e01, - ], - ) - problem.bulkIns = np.array([2.073e-06]) - problem.bulkOuts = np.array([5.98e-06, 2.21e-06]) - problem.scalefactors = np.array([0.1, 0.15]) - problem.domainRatios = np.array([]) - problem.backgroundParams = np.array([2.23e-06, 3.38e-06]) - problem.resolutionParams = np.array([0.03]) - problem.contrastBulkIns = np.array([1.0, 1.0]) - problem.contrastBulkOuts = np.array([1.0, 2.0]) - problem.contrastScalefactors = np.array([1.0, 2.0]) - problem.contrastBackgroundParams = [[1.0], [2.0]] - problem.contrastBackgroundTypes = ["constant", "constant"] - problem.contrastBackgroundActions = [1.0, 1.0] - problem.contrastResolutionParams = [[1.0], [1.0]] - problem.contrastResolutionTypes = ["constant", "constant"] - problem.contrastCustomFiles = np.array([np.nan, np.nan]) - problem.contrastDomainRatios = np.array([0.0, 0.0]) - problem.resample = np.array([0.0, 0.0]) - problem.dataPresent = np.array([1.0, 1.0]) - problem.dataLimits = [[0.011403, 0.59342], [0.011403, 0.59342]] - problem.simulationLimits = [[0.011403, 0.59342], [0.011403, 0.59342]] - problem.numberOfContrasts = 2.0 - problem.numberOfLayers = 6.0 - problem.repeatLayers = [1.0, 1.0] - problem.layersDetails = [ - np.array([2.0]), - np.array([4.0]), - np.array([10.0]), - np.array([8.0]), - np.array([13.0]), - np.array([16.0]), - ] - problem.contrastLayers = [ - np.array([[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 6.0, 5.0]]), - np.array([[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 6.0, 5.0]]), - ] - problem.numberOfDomainContrasts = 0.0 - problem.domainContrastLayers = [] - problem.fitParams = np.array( - [ - 3.000e00, - 1.954e01, - 2.266e01, - 5.252e00, - 5.640e00, - 1.712e01, - 8.560e00, - 4.545e01, - 1.070e01, - 6.014e00, - 1.782e01, - 1.764e01, - 3.615e01, - 2.361e01, - 2.230e-06, - 3.380e-06, - 5.980e-06, - 2.210e-06, - ], - ) - problem.fitLimits = np.array( - [ - [1.00e00, 1.00e01], - [5.00e00, 6.00e01], - [1.50e01, 3.50e01], - [1.00e00, 5.00e01], - [1.00e00, 1.50e01], - [1.00e01, 2.80e01], - [5.00e00, 1.70e01], - [1.00e01, 5.00e01], - [7.00e00, 1.70e01], - [2.00e00, 1.50e01], - [1.40e01, 2.20e01], - [1.00e01, 5.00e01], - [1.00e01, 5.00e01], - [0.00e00, 6.00e01], - [5.00e-10, 7.00e-06], - [1.00e-10, 4.99e-06], - [5.50e-06, 6.40e-06], - [1.00e-06, 4.99e-06], - ], - ) - problem.names.params = [ - "Substrate Roughness", - "Oxide Thickness", - "Oxide SLD", - "SAM Tails Thickness", - "SAM Tails SLD", - "SAM Tails Hydration", - "SAM Roughness", - "CW Thickness", - "CW SLD", - "SAM Heads Thickness", - "SAM Heads SLD", - "SAM Heads Hydration", - "Bilayer Heads Thickness", - "Bilayer Heads SLD", - "Bilayer Roughness", - "Bilayer Tails Thickness", - "Bilayer Tails SLD", - "Bilayer Tails Hydration", - "Bilayer Heads Hydration", - "CW Hydration", - "Oxide Hydration", - ] - problem.names.backgroundParams = ["Background parameter D2O", "Background parameter SMW"] - problem.names.scalefactors = ["Scalefactor 1", "Scalefactor 2"] - problem.names.bulkIns = ["Silicon"] - problem.names.bulkOuts = ["D2O", "SMW"] - problem.names.resolutionParams = ["Resolution Param 1"] - problem.names.domainRatios = [] - problem.names.contrasts = ["D2O", "SMW"] - problem.checks.params = np.array( - [1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0] - ) - problem.checks.backgroundParams = np.array([1.0, 1.0]) - problem.checks.scalefactors = np.array([0.0, 0.0]) - problem.checks.bulkIns = np.array([0.0]) - problem.checks.bulkOuts = np.array([1.0, 1.0]) - problem.checks.resolutionParams = np.array([0.0]) - problem.checks.domainRatios = np.array([]) - - return problem - - -@pytest.fixture -def dream_problem(): - """The output C++ ProblemDefinition object for a Dream optimisation of the project set out in - "DSPC_standard_layers.py". - - This optimisation used the parameters: nSamples=50000, nChains=10. - """ - problem = ratapi.rat_core.ProblemDefinition() - problem.TF = Calculations.Normal - problem.modelType = LayerModels.StandardLayers - problem.geometry = Geometries.SubstrateLiquid - problem.useImaginary = False - problem.params = np.array( - [ - 6.19503045e00, - 1.84420960e01, - 3.39000000e-06, - 2.11039621e01, - -4.01000000e-07, - 8.75538121e00, - 3.72292994e00, - 1.84624551e01, - 0.00000000e00, - 1.02316734e01, - 1.75000000e-06, - 2.31156093e01, - 1.09906265e01, - 1.47000000e-06, - 5.71005361e00, - 1.67933822e01, - -4.61000000e-07, - 1.72009856e01, - 3.00260126e01, - 1.00000000e02, - 2.94448999e01, - ], - ) - problem.bulkIns = np.array([2.073e-06]) - problem.bulkOuts = np.array([6.01489149e-06, 1.59371685e-06]) - problem.scalefactors = np.array([0.1, 0.15]) - problem.domainRatios = np.array([]) - problem.backgroundParams = np.array([2.37113128e-06, 1.99006694e-06]) - problem.resolutionParams = np.array([0.03]) - problem.contrastBulkIns = np.array([1.0, 1.0]) - problem.contrastBulkOuts = np.array([1.0, 2.0]) - problem.contrastScalefactors = np.array([1.0, 2.0]) - problem.contrastBackgroundParams = [[1.0], [2.0]] - problem.contrastBackgroundTypes = ["constant", "constant"] - problem.contrastBackgroundActions = [1.0, 1.0] - problem.contrastResolutionParams = [[1.0], [1.0]] - problem.contrastResolutionTypes = ["constant", "constant"] - problem.contrastCustomFiles = np.array([np.nan, np.nan]) - problem.contrastDomainRatios = np.array([0.0, 0.0]) - problem.resample = np.array([0.0, 0.0]) - problem.dataPresent = np.array([1.0, 1.0]) - problem.dataLimits = [[0.011403, 0.59342], [0.011403, 0.59342]] - problem.simulationLimits = [[0.011403, 0.59342], [0.011403, 0.59342]] - problem.numberOfContrasts = 2.0 - problem.numberOfLayers = 6.0 - problem.repeatLayers = [1.0, 1.0] - problem.layersDetails = [ - np.array([2.0]), - np.array([4.0]), - np.array([10.0]), - np.array([8.0]), - np.array([13.0]), - np.array([16.0]), - ] - problem.contrastLayers = [ - np.array([[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 6.0, 5.0]]), - np.array([[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 6.0, 5.0]]), - ] - problem.numberOfDomainContrasts = 0.0 - problem.domainContrastLayers = [] - problem.fitParams = np.array( - [ - 6.19503045e00, - 1.84420960e01, - 2.11039621e01, - 8.75538121e00, - 3.72292994e00, - 1.84624551e01, - 1.02316734e01, - 2.31156093e01, - 1.09906265e01, - 5.71005361e00, - 1.67933822e01, - 1.72009856e01, - 3.00260126e01, - 2.94448999e01, - 2.37113128e-06, - 1.99006694e-06, - 6.01489149e-06, - 1.59371685e-06, - ], - ) - problem.fitLimits = np.array( - [ - [1.00e00, 1.00e01], - [5.00e00, 6.00e01], - [1.50e01, 3.50e01], - [1.00e00, 5.00e01], - [1.00e00, 1.50e01], - [1.00e01, 2.80e01], - [5.00e00, 1.70e01], - [1.00e01, 5.00e01], - [7.00e00, 1.70e01], - [2.00e00, 1.50e01], - [1.40e01, 2.20e01], - [1.00e01, 5.00e01], - [1.00e01, 5.00e01], - [0.00e00, 6.00e01], - [5.00e-10, 7.00e-06], - [1.00e-10, 4.99e-06], - [5.50e-06, 6.40e-06], - [1.00e-06, 4.99e-06], - ], - ) - problem.names.params = [ - "Substrate Roughness", - "Oxide Thickness", - "Oxide SLD", - "SAM Tails Thickness", - "SAM Tails SLD", - "SAM Tails Hydration", - "SAM Roughness", - "CW Thickness", - "CW SLD", - "SAM Heads Thickness", - "SAM Heads SLD", - "SAM Heads Hydration", - "Bilayer Heads Thickness", - "Bilayer Heads SLD", - "Bilayer Roughness", - "Bilayer Tails Thickness", - "Bilayer Tails SLD", - "Bilayer Tails Hydration", - "Bilayer Heads Hydration", - "CW Hydration", - "Oxide Hydration", - ] - problem.names.backgroundParams = ["Background parameter D2O", "Background parameter SMW"] - problem.names.scalefactors = ["Scalefactor 1", "Scalefactor 2"] - problem.names.bulkIns = ["Silicon"] - problem.names.bulkOuts = ["D2O", "SMW"] - problem.names.resolutionParams = ["Resolution Param 1"] - problem.names.domainRatios = [] - problem.names.contrasts = ["D2O", "SMW"] - problem.checks.params = np.array( - [1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0] - ) - problem.checks.backgroundParams = np.array([1.0, 1.0]) - problem.checks.scalefactors = np.array([0.0, 0.0]) - problem.checks.bulkIns = np.array([0.0]) - problem.checks.bulkOuts = np.array([1.0, 1.0]) - problem.checks.resolutionParams = np.array([0.0]) - problem.checks.domainRatios = np.array([]) - - return problem - - -@pytest.mark.parametrize( - ["test_procedure", "test_output_problem", "test_output_results", "test_bayes", "test_results"], - [ - ( - Procedures.Calculate, - "reflectivity_calculation_problem", - "reflectivity_calculation_output_results", - None, - "reflectivity_calculation_results", - ), - (Procedures.DREAM, "dream_problem", "dream_output_results", "dream_bayes", "dream_results"), - ], -) -def test_run(test_procedure, test_output_problem, test_output_results, test_bayes, test_results, request) -> None: - input_project = request.getfixturevalue("input_project") - test_output_problem = request.getfixturevalue(test_output_problem) - test_output_results = request.getfixturevalue(test_output_results) - if test_bayes: - test_bayes = request.getfixturevalue(test_bayes) - - test_results = request.getfixturevalue(test_results) - - with mock.patch.object( - ratapi.rat_core, - "RATMain", - mock.MagicMock(return_value=(test_output_problem, test_output_results, test_bayes)), - ): - # Use default project as we patch RATMain to give the desired outputs - project, results = ratapi.run(input_project, ratapi.Controls(procedure=test_procedure)) - - check_results_equal(test_results, results) - - -def test_progress_bar() -> None: - event = ProgressEventData() - event.message = "TESTING" - event.percent = 0.2 - with ProgressBar() as bar: - assert bar.pbar is None - notify(EventTypes.Progress, event) - assert bar.pbar.desc == "TESTING" - assert bar.pbar.n == 20 - - event.message = "AGAIN" - event.percent = 0.6 - notify(EventTypes.Progress, event) - assert bar.pbar.desc == "AGAIN" - assert bar.pbar.n == 60 - - -def test_text_output() -> None: - with io.StringIO() as buf, redirect_stdout(buf), TextOutput(): - assert buf.getvalue() == "" - notify(EventTypes.Message, "Hello World") - assert buf.getvalue() == "Hello World" - - with io.StringIO() as buf, redirect_stdout(buf), TextOutput(display=False): - assert buf.getvalue() == "" - notify(EventTypes.Message, "Hello World") - assert buf.getvalue() == "" diff --git a/tests/test_wrappers.py b/tests/test_wrappers.py index 782e833c..05ae995a 100644 --- a/tests/test_wrappers.py +++ b/tests/test_wrappers.py @@ -1,58 +1,51 @@ import pathlib -from unittest import mock - +import sys +import unittest.mock as mock import pytest - -import ratapi.wrappers +import rat.misc -def test_matlab_wrapper() -> None: - with ( - mock.patch.object(ratapi.wrappers.MatlabWrapper, "loader", None), - pytest.raises(ImportError), - ): - ratapi.wrappers.MatlabWrapper("demo.m") - - mocked_matlab_future = mock.MagicMock() +def test_matlab_wrapper(): + with pytest.raises(ImportError): + rat.misc.MatlabWrapper('demo.m') + mocked_matlab_module = mock.MagicMock() mocked_engine = mock.MagicMock() - mocked_matlab_future.result.return_value = mocked_engine - with mock.patch.object(ratapi.wrappers.MatlabWrapper, "loader", mocked_matlab_future): - wrapper = ratapi.wrappers.MatlabWrapper("demo.m") - assert wrapper.function_name == "demo" + mocked_matlab_module.engine.start_matlab.return_value = mocked_engine + + # mocked_matlab_module.engine = mock.MagicMock() + + with mock.patch.dict('sys.modules', {'matlab': mocked_matlab_module, + 'matlab.engine': mocked_matlab_module.engine}): + wrapper = rat.misc.MatlabWrapper('demo.m') + assert wrapper.function_name == 'demo' mocked_engine.cd.assert_called_once() - assert pathlib.Path(mocked_engine.cd.call_args[0][0]).samefile(".") + assert pathlib.Path(mocked_engine.cd.call_args[0][0]).samefile('.') handle = wrapper.getHandle() - + mocked_engine.demo.return_value = ([2], 5) - result = handle([1], [2], [3], 1) - assert result == ([2], 5) + result = handle([1], [2], [3], 0) + assert result == ([2], 5) assert wrapper.engine.demo.call_args[0] == ([1], [2], [3], 1) mocked_engine.demo.assert_called_once() mocked_engine.demo.return_value = ([3, 1], 7) - result = handle([4], [5], [6], 2, 2) + result = handle([4], [5], [6], 1, 1) assert result == ([3, 1], 7) assert wrapper.engine.demo.call_args[0] == ([4], [5], [6], 2, 2) assert mocked_engine.demo.call_count == 2 + - mocked_engine.demo.return_value = [4, 7] - result = handle([3], [9]) - assert result == [4, 7] - assert wrapper.engine.demo.call_args[0] == ([3], [9]) - assert mocked_engine.demo.call_count == 3 - - -def test_dylib_wrapper() -> None: +def test_dylib_wrapper(): mocked_engine = mock.MagicMock() - with mock.patch("ratapi.wrappers.ratapi.rat_core.DylibEngine", mocked_engine): - wrapper = ratapi.wrappers.DylibWrapper("demo.dylib", "demo") - mocked_engine.assert_called_once_with("demo.dylib", "demo") + with mock.patch('rat.misc.rat_core.DylibEngine', mocked_engine): + wrapper = rat.misc.DylibWrapper('demo.dylib', 'demo') + mocked_engine.assert_called_once_with('demo.dylib', 'demo') wrapper.engine.invoke.return_value = ([2], 5) handle = wrapper.getHandle() result = handle([1], [2], [3], 0) - assert result == ([2], 5) + assert result == ([2], 5) assert wrapper.engine.invoke.call_args[0] == ([1], [2], [3], 0) wrapper.engine.invoke.assert_called_once() diff --git a/tests/utils.py b/tests/utils.py deleted file mode 100644 index 5387b30a..00000000 --- a/tests/utils.py +++ /dev/null @@ -1,114 +0,0 @@ -import numpy as np - -import ratapi.outputs - - -class InputAttributes: - """Set input arguments as class attributes.""" - - def __init__(self, **kwargs) -> None: - for key, value in kwargs.items(): - setattr(self, key, value) - - def __eq__(self, other: object): - if isinstance(other, InputAttributes): - return self.__dict__ == other.__dict__ - return False - - -class SubInputAttributes(InputAttributes): - """Trivial subclass of InputAttributes.""" - - -def dummy_function() -> None: - """Trivial function for function handle tests.""" - - -def check_results_equal(actual_results, expected_results) -> None: - """Compare two instances of "Results" or "BayesResults" objects for equality. - - We focus here on the fields common to both results objects, and also check the equality of the subclasses - "CalculationResults" and "ContrastParams". - """ - contrast_param_fields = [ - "scalefactors", - "bulkIn", - "bulkOut", - "subRoughs", - "resample", - ] - - assert ( - isinstance(actual_results, ratapi.outputs.Results) and isinstance(expected_results, ratapi.outputs.Results) - ) or ( - isinstance(actual_results, ratapi.outputs.BayesResults) - and isinstance(expected_results, ratapi.outputs.BayesResults) - ) - - # The first set of fields are either 1D or 2D python lists containing numpy arrays. - # Hence, we need to compare them element-wise. - for list_field in ratapi.outputs.results_fields["list_fields"]: - for a, b in zip(getattr(actual_results, list_field), getattr(expected_results, list_field), strict=False): - assert (a == b).all() - - for list_field in ratapi.outputs.results_fields["double_list_fields"]: - actual_list = getattr(actual_results, list_field) - expected_list = getattr(expected_results, list_field) - assert len(actual_list) == len(expected_list) - for i in range(len(actual_list)): - for a, b in zip(actual_list[i], expected_list[i], strict=False): - assert (a == b).all() - - # Compare the final fields - assert (actual_results.fitParams == expected_results.fitParams).all() - assert actual_results.fitNames == expected_results.fitNames - - # Compare the two subclasses defined within the class - assert actual_results.calculationResults.sumChi == expected_results.calculationResults.sumChi - assert (actual_results.calculationResults.chiValues == expected_results.calculationResults.chiValues).all() - - for field in contrast_param_fields: - assert (getattr(actual_results.contrastParams, field) == getattr(expected_results.contrastParams, field)).all() - - if isinstance(actual_results, ratapi.outputs.BayesResults) and isinstance( - expected_results, ratapi.outputs.BayesResults - ): - check_bayes_fields_equal(actual_results, expected_results) - - -def check_bayes_fields_equal(actual_results, expected_results) -> None: - """Compare two instances of the "BayesResults" object for equality. - - We focus here on the fields and subclasses specific to the Bayesian optimisation. - """ - # The BayesResults object consists of a number of subclasses, each containing fields of differing formats. - for subclass in ratapi.outputs.bayes_results_subclasses: - actual_subclass = getattr(actual_results, subclass) - expected_subclass = getattr(expected_results, subclass) - - for field in ratapi.outputs.bayes_results_fields["param_fields"][subclass]: - assert getattr(actual_subclass, field) == getattr(expected_subclass, field) - - for field in ratapi.outputs.bayes_results_fields["list_fields"][subclass]: - for a, b in zip(getattr(actual_subclass, field), getattr(expected_subclass, field), strict=False): - assert (a == b).all() - - for field in ratapi.outputs.bayes_results_fields["double_list_fields"][subclass]: - actual_list = getattr(actual_subclass, field) - expected_list = getattr(expected_subclass, field) - assert len(actual_list) == len(expected_list) - for i in range(len(actual_list)): - for a, b in zip(actual_list[i], expected_list[i], strict=False): - assert (a == b).all() - - # Need to account for the arrays that are initialised as "NaN" in the compiled code - for array in ratapi.outputs.bayes_results_fields["array_fields"][subclass]: - actual_array = getattr(actual_subclass, array) - expected_array = getattr(expected_subclass, array) - for i in range(len(actual_array)): - assert (actual_array == expected_array).all() or ( - ["NaN" if np.isnan(el) else el for el in actual_array[i]] - == ["NaN" if np.isnan(el) else el for el in expected_array[i]] - ) - - assert (actual_results.chain == expected_results.chain).all()