From f03f8b4ad8d8382bc8eda8fb9e16212285295d6a Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 17 May 2026 09:26:59 +0200 Subject: [PATCH 01/14] build: migrate to pyproject.toml with scikit-build-core and uv --- .github/workflows/test-cpp.yml | 2 +- .github/workflows/test-python.yml | 54 +++++------- .github/workflows/wheels.yml | 133 ++++++++++++++-------------- .gitignore | 133 +++++++++++++++++++++++++--- .lgtm.yml | 23 ----- pyproject.toml | 51 +++++++++++ pytest.ini | 2 - python/CMakeLists.txt | 9 +- requirements.txt | 3 - setup.py | 139 ------------------------------ 10 files changed, 268 insertions(+), 281 deletions(-) delete mode 100644 .lgtm.yml create mode 100644 pyproject.toml delete mode 100644 pytest.ini delete mode 100644 requirements.txt delete mode 100644 setup.py diff --git a/.github/workflows/test-cpp.yml b/.github/workflows/test-cpp.yml index 5ad865bf..a77127a7 100644 --- a/.github/workflows/test-cpp.yml +++ b/.github/workflows/test-cpp.yml @@ -21,7 +21,7 @@ jobs: fail-fast: false max-parallel: 4 matrix: - os: [ubuntu-latest, windows-latest, macOS-latest] + os: [ubuntu-latest, windows-latest, macos-latest] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index 6f3b5783..68b3eb42 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -2,48 +2,38 @@ name: Test Python on: push: - branches: [ main ] + branches: [main] pull_request: - branches: [ main ] - -env: - CMAKE_POLICY_VERSION_MINIMUM: "3.5" + branches: [main] jobs: test_python: name: build (${{ matrix.os }}) - + runs-on: ${{ matrix.os }} strategy: fail-fast: false max-parallel: 4 matrix: - os: [ubuntu-latest, windows-latest, macOS-latest] + os: [ubuntu-latest, windows-latest, macos-latest] steps: - - uses: actions/checkout@v4 - - - uses: actions/cache@v4 - with: - path: "**/cpm_modules" - key: ${{ github.workflow }}-cpm-modules-${{ matrix.os }}-${{ hashFiles('**/CMakeLists.txt', '**/*.cmake') }} - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.10' - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - - - name: Install package - run: | - pip install . - - - name: Test with pytest - run: | - pip install pytest - pytest + - uses: actions/checkout@v4 + + - uses: actions/cache@v4 + with: + path: "**/cpm_modules" + key: ${{ github.workflow }}-cpm-modules-${{ matrix.os }}-${{ hashFiles('**/CMakeLists.txt', '**/*.cmake') }} + + - name: Install uv + uses: astral-sh/setup-uv@v6 + + - name: Set up Python + run: uv python install 3.12 + + - name: Install package + run: uv sync + + - name: Test with pytest + run: uv run pytest diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index a9cd06ab..b88bb7a8 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: push: branches: - - main + - main release: types: - published @@ -13,40 +13,43 @@ env: CIBW_TEST_COMMAND: pytest {project} CIBW_TEST_EXTRAS: test HYPERJET_VERSION: ${{ github.event.release.tag_name }} - CMAKE_POLICY_VERSION_MINIMUM: "3.5" - jobs: build_sdist: name: Build SDist runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - with: - submodules: true - - - name: Patch version - run: | - import os - with open('setup.py', 'r') as f: - content = f.read() - version = os.getenv('HYPERJET_VERSION', 'v0.0.0')[1:] - print(version) - content = content.replace('0.0.0', version) - with open('setup.py', 'w') as f: - f.write(content) - shell: python - - - name: Build SDist - run: pipx run build --sdist - - - name: Check metadata - run: pipx run twine check dist/* - - - uses: actions/upload-artifact@v4 - with: - path: dist/*.tar.gz - + - uses: actions/checkout@v4 + with: + submodules: true + + - name: Install uv + uses: astral-sh/setup-uv@v6 + + - name: Set up Python + run: uv python install 3.12 + + - name: Patch version + run: | + import os, re + version = os.getenv('HYPERJET_VERSION', 'v0.0.0').lstrip('v') + print(f"Setting version to {version}") + with open('pyproject.toml', 'r') as f: + content = f.read() + content = re.sub(r'^version = ".*"', f'version = "{version}"', content, flags=re.MULTILINE) + with open('pyproject.toml', 'w') as f: + f.write(content) + shell: python + + - name: Build SDist + run: uv build --sdist + + - name: Check metadata + run: uvx twine check dist/* + + - uses: actions/upload-artifact@v4 + with: + path: dist/*.tar.gz build_wheels: name: Wheels on ${{ matrix.os }} @@ -57,50 +60,46 @@ jobs: os: [ubuntu-latest, windows-latest, macos-latest] steps: - - uses: actions/checkout@v4 - with: - submodules: true - - - name: Patch version - run: | - import os - with open('setup.py', 'r') as f: - content = f.read() - version = os.getenv('HYPERJET_VERSION', 'v0.0.0')[1:] - print(version) - content = content.replace('0.0.0', version) - with open('setup.py', 'w') as f: - f.write(content) - shell: python - - - uses: pypa/cibuildwheel@v2.22.0 - env: - CIBW_ARCHS_MACOS: auto universal2 - CIBW_TEST_EXTRAS: test - CIBW_TEST_COMMAND: pytest {project} - CIBW_SKIP: pp* - - - name: Upload wheels - uses: actions/upload-artifact@v4 - with: - path: wheelhouse/*.whl - + - uses: actions/checkout@v4 + with: + submodules: true + + - name: Patch version + run: | + import os, re + version = os.getenv('HYPERJET_VERSION', 'v0.0.0').lstrip('v') + print(f"Setting version to {version}") + with open('pyproject.toml', 'r') as f: + content = f.read() + content = re.sub(r'^version = ".*"', f'version = "{version}"', content, flags=re.MULTILINE) + with open('pyproject.toml', 'w') as f: + f.write(content) + shell: python + + - uses: pypa/cibuildwheel@v2.22.0 + env: + CIBW_ARCHS_MACOS: auto universal2 + CIBW_TEST_EXTRAS: test + CIBW_TEST_COMMAND: pytest {project} + CIBW_SKIP: pp* + + - name: Upload wheels + uses: actions/upload-artifact@v4 + with: + path: wheelhouse/*.whl upload_all: name: Upload if release needs: [build_wheels, build_sdist] runs-on: ubuntu-latest if: github.event_name == 'release' && github.event.action == 'published' + permissions: + id-token: write steps: - - uses: actions/setup-python@v5 - - - uses: actions/download-artifact@v4 - with: - name: artifact - path: dist + - uses: actions/download-artifact@v4 + with: + name: artifact + path: dist - - uses: pypa/gh-action-pypi-publish@release/v1 - with: - user: ${{ secrets.PYPI_USERNAME }} - password: ${{ secrets.PYPI_PASSWORD }} + - uses: pypa/gh-action-pypi-publish@v1.12.4 diff --git a/.gitignore b/.gitignore index 2288f643..b85f2b72 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ # Byte-compiled / optimized / DLL files __pycache__/ -*.py[cod] +*.py[codz] *$py.class # C extensions @@ -20,14 +20,15 @@ parts/ sdist/ var/ wheels/ +share/python-wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec @@ -38,14 +39,18 @@ pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ +.nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover +*.py.cover +*.lcov .hypothesis/ .pytest_cache/ +cover/ # Translations *.mo @@ -55,6 +60,7 @@ coverage.xml *.log local_settings.py db.sqlite3 +db.sqlite3-journal # Flask stuff: instance/ @@ -67,22 +73,85 @@ instance/ docs/_build/ # PyBuilder +.pybuilder/ target/ # Jupyter Notebook .ipynb_checkpoints -# pyenv -.python-version +# IPython +profile_default/ +ipython_config.py -# celery beat schedule file -celerybeat-schedule +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +# Pipfile.lock + +# UV +# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# uv.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +# poetry.lock +# poetry.toml + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python. +# https://pdm-project.org/en/latest/usage/project/#working-with-version-control +# pdm.lock +# pdm.toml +.pdm-python +.pdm-build/ + +# pixi +# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control. +# pixi.lock +# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one +# in the .venv directory. It is recommended not to include this directory in version control. +.pixi/* +!.pixi/config.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule* +celerybeat.pid + +# Redis +*.rdb +*.aof +*.pid + +# RabbitMQ +mnesia/ +rabbitmq/ +rabbitmq-data/ + +# ActiveMQ +activemq-data/ # SageMath parsed files *.sage.py # Environments .env +.envrc .venv env/ venv/ @@ -102,6 +171,50 @@ venv.bak/ # mypy .mypy_cache/ - -# executables -/bin/*.exe +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +# .idea/ + +# Abstra +# Abstra is an AI-powered process automation framework. +# Ignore directories containing user credentials, local state, and settings. +# Learn more at https://abstra.io/docs +.abstra/ + +# Visual Studio Code +# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore +# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore +# and can be added to the global gitignore or merged into this file. However, if you prefer, +# you could uncomment the following to ignore the entire vscode folder +# .vscode/ +# Temporary file for partial code execution +tempCodeRunnerFile.py + +# Ruff stuff: +.ruff_cache/ + +# PyPI configuration file +.pypirc + +# Marimo +marimo/_static/ +marimo/_lsp/ +__marimo__/ + +# Streamlit +.streamlit/secrets.toml \ No newline at end of file diff --git a/.lgtm.yml b/.lgtm.yml deleted file mode 100644 index c1074537..00000000 --- a/.lgtm.yml +++ /dev/null @@ -1,23 +0,0 @@ -path_classifiers: - docs: - - exclude: / # ignore default classification - - docs - library: - - exclude: / # ignore default classification - - pybind11 - - external_libraries - test: - - exclude: / # ignore default classification - - tests - -extraction: - cpp: - after_prepare: - - mkdir custom_cmake - - wget --quiet -O - "http://www.cmake.org/files/v3.17/cmake-3.17.5-Linux-x86_64.tar.gz" | tar --strip-components=1 -xz -C custom_cmake - - export PATH=$(pwd)/custom_cmake/bin:${PATH} - index: - build_command: - - cmake --version - - cmake -S python -B build - - cmake --build build diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..8bfffcfa --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,51 @@ +[build-system] +requires = ["scikit-build-core>=0.10", "pybind11>=2.13"] +build-backend = "scikit_build_core.build" + +[project] +name = "hyperjet" +version = "0.0.0" +description = "Automatic differentiation with dual numbers" +readme = "README.md" +license = "MIT" +requires-python = ">=3.11" +authors = [ + { name = "Thomas Oberbichler", email = "thomas.oberbichler@gmail.com" }, +] +classifiers = [ + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", +] +dependencies = [ + "numpy>=2.0", + "msvc-runtime; platform_system == 'Windows'", +] + +[project.optional-dependencies] +test = ["pytest>=8.0"] + +[project.urls] +Homepage = "https://github.com/oberbichler/HyperJet" +Repository = "https://github.com/oberbichler/HyperJet" + +[dependency-groups] +test = ["pytest>=8.0"] + +[tool.scikit-build] +minimum-version = "0.10" +cmake.source-dir = "python" +cmake.build-type = "Release" +cmake.minimum-version = "3.14" + +[tool.scikit-build.cmake.define] +HYPERJET_VERSION = {env = "HYPERJET_VERSION", default = "0.0.0"} + +[tool.pytest.ini_options] +testpaths = ["python/tests"] + +[tool.uv] +default-groups = ["test"] diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index c1dbf677..00000000 --- a/pytest.ini +++ /dev/null @@ -1,2 +0,0 @@ -[pytest] -testpaths = python/tests diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 63335bcc..8c20ef64 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -18,7 +18,8 @@ if(Eigen_ADDED) target_include_directories(Eigen INTERFACE ${Eigen_SOURCE_DIR}) endif() -CPMAddPackage("gh:/pybind/pybind11@2.13.6") +# pybind11 is provided by scikit-build-core build requirements +find_package(pybind11 CONFIG REQUIRED) if(TEST_INSTALLED_VERSION) find_package(HyperJet REQUIRED) @@ -28,18 +29,18 @@ endif() # --- Create binary -include_directories("external_libraries") - file(GLOB sources CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) pybind11_add_module(HyperJetPython ${sources}) target_link_libraries(HyperJetPython PRIVATE hyperjet::hyperjet Eigen) target_compile_definitions(HyperJetPython PRIVATE - -DHYPERJET_VERSION="${PROJECT_VERSION}" + -DHYPERJET_VERSION="${HYPERJET_VERSION}" -DHYPERJET_EXCEPTIONS ) set_target_properties(HyperJetPython PROPERTIES CXX_STANDARD 17) set_target_properties(HyperJetPython PROPERTIES OUTPUT_NAME hyperjet) + +install(TARGETS HyperJetPython DESTINATION .) diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 582e5d46..00000000 --- a/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -numpy -pumpit -wheel diff --git a/setup.py b/setup.py deleted file mode 100644 index 70e4b915..00000000 --- a/setup.py +++ /dev/null @@ -1,139 +0,0 @@ -# -*- coding: utf-8 -*- -import os -import re -import subprocess -import sys - -from setuptools import setup, Extension -from setuptools.command.build_ext import build_ext - - -HYPERJET_VERSION = '0.0.0' - -# Convert distutils Windows platform specifiers to CMake -A arguments -PLAT_TO_CMAKE = { - "win32": "Win32", - "win-amd64": "x64", - "win-arm32": "ARM", - "win-arm64": "ARM64", -} - -# A CMakeExtension needs a sourcedir instead of a file list. -# The name must be the _single_ output extension from the CMake build. -# If you need multiple extensions, see scikit-build. -class CMakeExtension(Extension): - def __init__(self, name, sourcedir=""): - Extension.__init__(self, name, sources=[]) - self.sourcedir = os.path.abspath(sourcedir) - - -class CMakeBuild(build_ext): - def build_extension(self, ext): - extdir = os.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name))) - - # required for auto-detection of auxiliary "native" libs - if not extdir.endswith(os.path.sep): - extdir += os.path.sep - - cfg = "Debug" if self.debug else "Release" - - # CMake lets you override the generator - we need to check this. - # Can be set with Conda-Build, for example. - cmake_generator = os.environ.get("CMAKE_GENERATOR", "") - - # Set Python_EXECUTABLE instead if you use PYBIND11_FINDPYTHON - # EXAMPLE_VERSION_INFO shows you how to pass a value into the C++ code - # from Python. - cmake_args = [ - "-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={}".format(extdir), - "-DPYTHON_EXECUTABLE={}".format(sys.executable), - "-DHYPERJET_VERSION={}".format(self.distribution.get_version()), - "-DCMAKE_BUILD_TYPE={}".format(cfg), # not used on MSVC, but no harm - "-DCMAKE_POLICY_VERSION_MINIMUM=3.5", - ] - build_args = [] - - if self.compiler.compiler_type != "msvc": - # Using Ninja-build since it a) is available as a wheel and b) - # multithreads automatically. MSVC would require all variables be - # exported for Ninja to pick it up, which is a little tricky to do. - # Users can override the generator with CMAKE_GENERATOR in CMake - # 3.15+. - if not cmake_generator: - try: - import ninja # noqa: F401 - - cmake_args += ["-GNinja"] - except ImportError: - pass - - else: - - # Single config generators are handled "normally" - single_config = any(x in cmake_generator for x in {"NMake", "Ninja"}) - - # CMake allows an arch-in-generator style for backward compatibility - contains_arch = any(x in cmake_generator for x in {"ARM", "Win64"}) - - # Specify the arch if using MSVC generator, but only if it doesn't - # contain a backward-compatibility arch spec already in the - # generator name. - if not single_config and not contains_arch: - cmake_args += ["-A", PLAT_TO_CMAKE[self.plat_name]] - - # Multi-config generators have a different way to specify configs - if not single_config: - cmake_args += [ - "-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}".format(cfg.upper(), extdir), - "-DHYPERJET_VERSION={}".format(self.distribution.get_version()), - ] - build_args += ["--config", cfg] - - if sys.platform.startswith("darwin"): - # Cross-compile support for macOS - respect ARCHFLAGS if set - archs = re.findall(r"-arch (\S+)", os.environ.get("ARCHFLAGS", "")) - if archs: - cmake_args += ["-DCMAKE_OSX_ARCHITECTURES={}".format(";".join(archs))] - - # Set CMAKE_BUILD_PARALLEL_LEVEL to control the parallel build level - # across all generators. - if "CMAKE_BUILD_PARALLEL_LEVEL" not in os.environ: - # self.parallel is a Python 3 only way to set parallel jobs by hand - # using -j in the build_ext call, not supported by pip or PyPA-build. - if hasattr(self, "parallel") and self.parallel: - # CMake 3.12+ only. - build_args += ["-j{}".format(self.parallel)] - - if not os.path.exists(self.build_temp): - os.makedirs(self.build_temp) - - subprocess.check_call( - ["cmake", ext.sourcedir] + cmake_args, cwd=self.build_temp - ) - subprocess.check_call( - ["cmake", "--build", "."] + build_args, cwd=self.build_temp - ) - -setup( - name='hyperjet', - description='Automatic differentiation with dual numbers', - long_description=open('README.md', 'r').read(), - long_description_content_type='text/markdown', - version=HYPERJET_VERSION, - url='https://github.com/oberbichler/HyperJet', - author='Thomas Oberbichler', - author_email='thomas.oberbichler@gmail.com', - classifiers=[ - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "License :: OSI Approved :: MIT License", - ], - python_requires='>=3.6', - ext_modules=[CMakeExtension('hyperjet', sourcedir='python')], - cmdclass=dict(build_ext=CMakeBuild), - install_requires=['msvc-runtime ; platform_system=="Windows"', 'numpy'], - zip_safe=False, - extras_require={"test": ["pytest"]}, -) From ec9360fe4f0f8d709e763bd4e18aabcc6d5a7339 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 17 May 2026 09:29:19 +0200 Subject: [PATCH 02/14] fix: cmake version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8bfffcfa..09721632 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,7 +39,7 @@ test = ["pytest>=8.0"] minimum-version = "0.10" cmake.source-dir = "python" cmake.build-type = "Release" -cmake.minimum-version = "3.14" +cmake.version = ">=3.14" [tool.scikit-build.cmake.define] HYPERJET_VERSION = {env = "HYPERJET_VERSION", default = "0.0.0"} From 919b07d3ba652448494c4ced3cf4e7d0cdefa3e0 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 17 May 2026 09:34:01 +0200 Subject: [PATCH 03/14] fix: classifiers --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 09721632..99dddcbe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,6 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", - "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", ] dependencies = [ From a691d030b1825cd47695da12fb08f1fccf320afa Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 17 May 2026 09:38:41 +0200 Subject: [PATCH 04/14] fix: artefact naming collision --- .github/workflows/wheels.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index b88bb7a8..630709d9 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -49,6 +49,7 @@ jobs: - uses: actions/upload-artifact@v4 with: + name: sdist path: dist/*.tar.gz build_wheels: @@ -86,6 +87,7 @@ jobs: - name: Upload wheels uses: actions/upload-artifact@v4 with: + name: wheels-${{ matrix.os }} path: wheelhouse/*.whl upload_all: @@ -99,7 +101,7 @@ jobs: steps: - uses: actions/download-artifact@v4 with: - name: artifact path: dist + merge-multiple: true - uses: pypa/gh-action-pypi-publish@v1.12.4 From 68976c85c4bee8a9ff986a89a1d00311e90e0319 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 17 May 2026 09:39:50 +0200 Subject: [PATCH 05/14] fix: test all python versions --- .github/workflows/test-python.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index 68b3eb42..8bcb9151 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -8,15 +8,15 @@ on: jobs: test_python: - name: build (${{ matrix.os }}) + name: build (${{ matrix.os }}, py${{ matrix.python-version }}) runs-on: ${{ matrix.os }} strategy: fail-fast: false - max-parallel: 4 matrix: os: [ubuntu-latest, windows-latest, macos-latest] + python-version: ['3.11', '3.12', '3.13'] steps: - uses: actions/checkout@v4 @@ -30,7 +30,7 @@ jobs: uses: astral-sh/setup-uv@v6 - name: Set up Python - run: uv python install 3.12 + run: uv python install ${{ matrix.python-version }} - name: Install package run: uv sync From fe11f0932b3527cd835334d76984cb9cbe984ea8 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 17 May 2026 09:40:28 +0200 Subject: [PATCH 06/14] fix: test release build --- .github/workflows/test-cpp.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test-cpp.yml b/.github/workflows/test-cpp.yml index a77127a7..18c2dac7 100644 --- a/.github/workflows/test-cpp.yml +++ b/.github/workflows/test-cpp.yml @@ -13,15 +13,15 @@ env: jobs: test_cpp: - name: build (${{ matrix.os }}, C++) + name: build (${{ matrix.os }}, ${{ matrix.build-type }}) runs-on: ${{ matrix.os }} strategy: fail-fast: false - max-parallel: 4 matrix: os: [ubuntu-latest, windows-latest, macos-latest] + build-type: [Debug, Release] steps: - uses: actions/checkout@v4 @@ -32,12 +32,12 @@ jobs: key: ${{ github.workflow }}-cpm-modules-${{ matrix.os }}-${{ hashFiles('**/CMakeLists.txt', '**/*.cmake') }} - name: Configure - run: cmake -Stest -Bbuild + run: cmake -Stest -Bbuild -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} - name: Build - run: cmake --build build --config Debug -j4 + run: cmake --build build --config ${{ matrix.build-type }} -j4 - name: Test run: | cd build - ctest --build-config Debug + ctest --build-config ${{ matrix.build-type }} From 0973a34dc72a865ec354c045876e0a5d3e4970f5 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 17 May 2026 09:41:14 +0200 Subject: [PATCH 07/14] fix: redundant env variables --- .github/workflows/wheels.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 630709d9..7fb7f012 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -10,8 +10,6 @@ on: - published env: - CIBW_TEST_COMMAND: pytest {project} - CIBW_TEST_EXTRAS: test HYPERJET_VERSION: ${{ github.event.release.tag_name }} jobs: From 8137c6dde6e2b5eb77604367795db7455b121e01 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 17 May 2026 09:42:09 +0200 Subject: [PATCH 08/14] fix: add concurrency-groups --- .github/workflows/test-cpp.yml | 4 ++++ .github/workflows/test-python.yml | 4 ++++ .github/workflows/wheels.yml | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/.github/workflows/test-cpp.yml b/.github/workflows/test-cpp.yml index 18c2dac7..6f7e7cee 100644 --- a/.github/workflows/test-cpp.yml +++ b/.github/workflows/test-cpp.yml @@ -6,6 +6,10 @@ on: pull_request: branches: [ main ] +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + env: CTEST_OUTPUT_ON_FAILURE: 1 CPM_SOURCE_CACHE: ${{ github.workspace }}/cpm_modules diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index 8bcb9151..45e216d6 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -6,6 +6,10 @@ on: pull_request: branches: [main] +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: test_python: name: build (${{ matrix.os }}, py${{ matrix.python-version }}) diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 7fb7f012..a2f525b4 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -9,6 +9,10 @@ on: types: - published +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + env: HYPERJET_VERSION: ${{ github.event.release.tag_name }} From 54ac1906dd408e9ca5dcf69b6f700dccaf0da237 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 17 May 2026 09:42:56 +0200 Subject: [PATCH 09/14] fix: remove push-trigger from wheels --- .github/workflows/wheels.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index a2f525b4..d28f1394 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -2,9 +2,6 @@ name: Wheels on: workflow_dispatch: - push: - branches: - - main release: types: - published From ac6a8e1cd6a9e881b454f697f889eee14c7928dc Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 17 May 2026 09:47:46 +0200 Subject: [PATCH 10/14] fix: Wheels-CI --- .github/workflows/wheels.yml | 11 ++++++----- pyproject.toml | 11 +++++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index d28f1394..0e5fd7f3 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -78,10 +78,7 @@ jobs: - uses: pypa/cibuildwheel@v2.22.0 env: - CIBW_ARCHS_MACOS: auto universal2 - CIBW_TEST_EXTRAS: test - CIBW_TEST_COMMAND: pytest {project} - CIBW_SKIP: pp* + CIBW_ENVIRONMENT_PASS_LINUX: HYPERJET_VERSION - name: Upload wheels uses: actions/upload-artifact@v4 @@ -94,8 +91,10 @@ jobs: needs: [build_wheels, build_sdist] runs-on: ubuntu-latest if: github.event_name == 'release' && github.event.action == 'published' + environment: pypi permissions: id-token: write + attestations: write steps: - uses: actions/download-artifact@v4 @@ -103,4 +102,6 @@ jobs: path: dist merge-multiple: true - - uses: pypa/gh-action-pypi-publish@v1.12.4 + - uses: pypa/gh-action-pypi-publish@release/v1 + with: + attestations: true diff --git a/pyproject.toml b/pyproject.toml index 99dddcbe..8e063632 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,3 +48,14 @@ testpaths = ["python/tests"] [tool.uv] default-groups = ["test"] + +[tool.cibuildwheel] +skip = "pp*" +test-extras = "test" +test-command = "pytest {project}" + +[tool.cibuildwheel.macos] +archs = ["auto", "universal2"] + +[tool.cibuildwheel.macos.test] +skip = ["*universal2:arm64"] From 5baa60f389614b6da48b47d53e79ada6f1afeca5 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 17 May 2026 09:50:00 +0200 Subject: [PATCH 11/14] fix: include arm --- pyproject.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 8e063632..a6dfd9a3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,6 +56,3 @@ test-command = "pytest {project}" [tool.cibuildwheel.macos] archs = ["auto", "universal2"] - -[tool.cibuildwheel.macos.test] -skip = ["*universal2:arm64"] From ea738f0510282c84b7513b2bf1d5f72b3b08863b Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 17 May 2026 10:14:43 +0200 Subject: [PATCH 12/14] add clang format --- .clang-format | 99 ++++++++++++++++ .editorconfig | 59 --------- .github/workflows/format.yml | 24 ++++ include/hyperjet/hyperjet.h | 2 +- pyproject.toml | 1 + python/src/main.cpp | 3 +- uv.lock | 224 +++++++++++++++++++++++++++++++++++ 7 files changed, 350 insertions(+), 62 deletions(-) create mode 100644 .clang-format delete mode 100644 .editorconfig create mode 100644 .github/workflows/format.yml create mode 100644 uv.lock diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..de091bed --- /dev/null +++ b/.clang-format @@ -0,0 +1,99 @@ +--- +Language: Cpp +BasedOnStyle: Microsoft + +# Indentation +IndentWidth: 4 +TabWidth: 4 +UseTab: Never +IndentCaseLabels: false +IndentCaseBlocks: false +IndentPPDirectives: None +NamespaceIndentation: All +IndentWrappedFunctionNames: false +ContinuationIndentWidth: 4 +AccessModifierOffset: -4 +IndentAccessModifiers: false + +# Braces +BreakBeforeBraces: Allman +Cpp11BracedListStyle: true + +# Line breaks +ColumnLimit: 0 +KeepEmptyLinesAtTheStartOfBlocks: false +MaxEmptyLinesToKeep: 2 + +# Alignment +PointerAlignment: Right +ReferenceAlignment: Right +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignConsecutiveMacros: false +AlignEscapedNewlines: Left +AlignOperands: Align +AlignTrailingComments: true + +# Spaces +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInParentheses: false +SpacesInSquareBrackets: false + +# Includes +SortIncludes: false +IncludeBlocks: Preserve + +# Short forms +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: Always +AllowShortCaseLabelsOnASingleLine: false +AllowShortEnumsOnASingleLine: true +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: false + +# Other +BinPackArguments: true +BinPackParameters: true +BreakBeforeBinaryOperators: None +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +BreakStringLiterals: false +CompactNamespaces: false +DerivePointerAlignment: false +FixNamespaceComments: false +ReflowComments: false +SortUsingDeclarations: false + +# Penalties +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 1000 + +# Lambda +LambdaBodyIndentation: Signature +... diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 16398870..00000000 --- a/.editorconfig +++ /dev/null @@ -1,59 +0,0 @@ -[*] -cpp_indent_braces=false -cpp_indent_multi_line_relative_to=innermost_parenthesis -cpp_indent_within_parentheses=indent -cpp_indent_preserve_within_parentheses=false -cpp_indent_case_labels=false -cpp_indent_case_contents=true -cpp_indent_case_contents_when_block=false -cpp_indent_lambda_braces_when_parameter=true -cpp_indent_goto_labels=one_left -cpp_indent_preprocessor=leftmost_column -cpp_indent_access_specifiers=false -cpp_indent_namespace_contents=true -cpp_indent_preserve_comments=false -cpp_new_line_before_open_brace_namespace=ignore -cpp_new_line_before_open_brace_type=ignore -cpp_new_line_before_open_brace_function=ignore -cpp_new_line_before_open_brace_block=ignore -cpp_new_line_before_open_brace_lambda=ignore -cpp_new_line_scope_braces_on_separate_lines=false -cpp_new_line_close_brace_same_line_empty_type=false -cpp_new_line_close_brace_same_line_empty_function=false -cpp_new_line_before_catch=true -cpp_new_line_before_else=true -cpp_new_line_before_while_in_do_while=false -cpp_space_before_function_open_parenthesis=remove -cpp_space_within_parameter_list_parentheses=false -cpp_space_between_empty_parameter_list_parentheses=false -cpp_space_after_keywords_in_control_flow_statements=true -cpp_space_within_control_flow_statement_parentheses=false -cpp_space_before_lambda_open_parenthesis=false -cpp_space_within_cast_parentheses=false -cpp_space_after_cast_close_parenthesis=false -cpp_space_within_expression_parentheses=false -cpp_space_before_block_open_brace=true -cpp_space_between_empty_braces=false -cpp_space_before_initializer_list_open_brace=false -cpp_space_within_initializer_list_braces=true -cpp_space_preserve_in_initializer_list=true -cpp_space_before_open_square_bracket=false -cpp_space_within_square_brackets=false -cpp_space_before_empty_square_brackets=false -cpp_space_between_empty_square_brackets=false -cpp_space_group_square_brackets=true -cpp_space_within_lambda_brackets=false -cpp_space_between_empty_lambda_brackets=false -cpp_space_before_comma=false -cpp_space_after_comma=true -cpp_space_remove_around_member_operators=true -cpp_space_before_inheritance_colon=true -cpp_space_before_constructor_colon=true -cpp_space_remove_before_semicolon=true -cpp_space_after_semicolon=false -cpp_space_remove_around_unary_operator=true -cpp_space_around_binary_operator=insert -cpp_space_around_assignment_operator=insert -cpp_space_pointer_reference_alignment=left -cpp_space_around_ternary_operator=insert -cpp_wrap_preserve_blocks=one_liners diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml new file mode 100644 index 00000000..5dfffd0a --- /dev/null +++ b/.github/workflows/format.yml @@ -0,0 +1,24 @@ +name: Format + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + clang-format: + name: clang-format + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: astral-sh/setup-uv@v6 + + - name: Check formatting + run: uv run --group dev clang-format --dry-run --Werror include/hyperjet/*.h python/src/*.h python/src/*.cpp test/src/*.cpp benchmark/src/*.cpp diff --git a/include/hyperjet/hyperjet.h b/include/hyperjet/hyperjet.h index 52412e83..15b6b109 100644 --- a/include/hyperjet/hyperjet.h +++ b/include/hyperjet/hyperjet.h @@ -2083,7 +2083,7 @@ namespace hyperjet return it->second; } - Scalar eval(const Data& d) const + Scalar eval(const Data &d) const { Scalar r(m_f); diff --git a/pyproject.toml b/pyproject.toml index a6dfd9a3..ffd9f1cd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,6 +32,7 @@ Homepage = "https://github.com/oberbichler/HyperJet" Repository = "https://github.com/oberbichler/HyperJet" [dependency-groups] +dev = ["clang-format>=19.0"] test = ["pytest>=8.0"] [tool.scikit-build] diff --git a/python/src/main.cpp b/python/src/main.cpp index 9eb058d9..fc79b5ac 100644 --- a/python/src/main.cpp +++ b/python/src/main.cpp @@ -194,8 +194,7 @@ PYBIND11_MODULE(hyperjet, m) } break; } - return results; - }, + return results; }, "values"_a, "order"_a = 2); } } diff --git a/uv.lock b/uv.lock new file mode 100644 index 00000000..ca227483 --- /dev/null +++ b/uv.lock @@ -0,0 +1,224 @@ +version = 1 +revision = 3 +requires-python = ">=3.11" + +[[package]] +name = "clang-format" +version = "22.1.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/12/67/4195b7bf2204e77a1c6305ea976f8e5dc63e70bcb59702912adb266a102e/clang_format-22.1.5.tar.gz", hash = "sha256:94401741d1db878ee1e002e3c33305a7c8e50ff1a9b0a4b8c713690f404d535c", size = 11508, upload-time = "2026-05-06T13:12:22.996Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6f/f4/eef03a87fe65a666bf8a1d9cf804addd5cd26eb225d4e270f22c20d832b0/clang_format-22.1.5-py2.py3-none-macosx_10_9_x86_64.whl", hash = "sha256:a73a500dcabdac1ebc993b99f77fe61de967c7ab9c26d12d664f02def31f0464", size = 1492641, upload-time = "2026-05-06T13:11:49.939Z" }, + { url = "https://files.pythonhosted.org/packages/0f/d8/e5cfbfd7f0d29c167dda2d014bd76ee3c4169000958948c73dd270c995c4/clang_format-22.1.5-py2.py3-none-macosx_11_0_arm64.whl", hash = "sha256:47e73563e6c55b47d6800bcc52e53e66c73b1d801f775b118dcc7aab8410c36f", size = 1478953, upload-time = "2026-05-06T13:11:52.282Z" }, + { url = "https://files.pythonhosted.org/packages/d9/d5/077d5bbea3d07c494705dc0960e58150651eeb024d9f837ea3350505b1a9/clang_format-22.1.5-py2.py3-none-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2db8b07d54f2b9583327715267b8ae5e9852e8da23b49c1bf8dde19067ce6fbc", size = 1757816, upload-time = "2026-05-06T13:11:54.468Z" }, + { url = "https://files.pythonhosted.org/packages/ca/95/25636844c2255fa40d1e6a691c483a9c8804f0ce6903eb790f8e4d95dfa6/clang_format-22.1.5-py2.py3-none-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:7a93aad78b03f190d8a73e5e81d6942bc0e4f449add21e62c7fad1be2cdfec03", size = 1888629, upload-time = "2026-05-06T13:11:56.31Z" }, + { url = "https://files.pythonhosted.org/packages/6f/59/8b9a1f6f4197292577dae8ff9f94c5900622c0e0a395a46cb2278e4d813a/clang_format-22.1.5-py2.py3-none-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b40d0d264003c831cda317d09db31f0ebbcddd5dc13f04af52be5664d2b8aa89", size = 2070260, upload-time = "2026-05-06T13:11:58.243Z" }, + { url = "https://files.pythonhosted.org/packages/f1/a8/f33290829eb73e1baece6d46a55d19a3d286ddee559a1955add639ceb731/clang_format-22.1.5-py2.py3-none-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a89ec86dd33f367b4e10dc1f243508709deed8576bb75a7b01c1412de47504df", size = 2101891, upload-time = "2026-05-06T13:12:00.131Z" }, + { url = "https://files.pythonhosted.org/packages/39/5e/bf1ea7a20ec3ffecda7eff98ad0f1621255e244e0f888d011a2106a04318/clang_format-22.1.5-py2.py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:451efcd0738908b2bd4d76409b52920ef381e045eb6728f9286d2ae5f02f3ef2", size = 1841172, upload-time = "2026-05-06T13:12:02.03Z" }, + { url = "https://files.pythonhosted.org/packages/b5/5f/853664a3d7599a682b2c89cc76606b818c5c56c7741251a42004e3e76104/clang_format-22.1.5-py2.py3-none-manylinux_2_31_armv7l.whl", hash = "sha256:39af8c0b77fb05d1dc7073ee9e348d81a965a0b96c0307d07cd92bbd74c611c7", size = 1684799, upload-time = "2026-05-06T13:12:03.6Z" }, + { url = "https://files.pythonhosted.org/packages/81/0b/7eb88226eed4c6cb529878d578f888c96ad3778df30e64d3223860327a08/clang_format-22.1.5-py2.py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:cbafc220a1ad3da603f0e4a469f52cf31be60da384d213727b62af0684cfd96b", size = 2735300, upload-time = "2026-05-06T13:12:05.329Z" }, + { url = "https://files.pythonhosted.org/packages/7e/82/38a8271f80861e75012c5ef63955f42ddd90cfff6a4ac09c84c055c1f4b3/clang_format-22.1.5-py2.py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:4f43424bc0944402f2166337cc330f92d31d102b5a3ee31714814823ac647a67", size = 2514975, upload-time = "2026-05-06T13:12:07.458Z" }, + { url = "https://files.pythonhosted.org/packages/98/7a/2fb4e48fb9205e0b4380fe44d27d1e29141211f0fa53887e75224bf4fbe7/clang_format-22.1.5-py2.py3-none-musllinux_1_2_i686.whl", hash = "sha256:a6f700f948a0eeccdc74966a773d3f2f348ffedab4b49b10b71439f26d1b8ad2", size = 2985901, upload-time = "2026-05-06T13:12:09.317Z" }, + { url = "https://files.pythonhosted.org/packages/8c/0a/1f6cd7f0ebb8083db3098d648af3d363c35f6864159fa508d213279294b0/clang_format-22.1.5-py2.py3-none-musllinux_1_2_ppc64le.whl", hash = "sha256:f0fb5226525c846a8770b8adaba3a323261b6031a13d065d4d4c4aa0bf6dbbc4", size = 3119111, upload-time = "2026-05-06T13:12:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/e3/7e/89cdc4216d8d49eeff98043bb5836eec5da805fd31aeb8f480bf4b8fa8ca/clang_format-22.1.5-py2.py3-none-musllinux_1_2_s390x.whl", hash = "sha256:86838932bcbfebdb4c900ea9e7c4dc4356a56aa75990c38065863c82c0d5e39f", size = 3217256, upload-time = "2026-05-06T13:12:13.252Z" }, + { url = "https://files.pythonhosted.org/packages/f7/eb/a1fa659d85d9b40eee594bfd2be7ddaf05e0296788ee2955473ef1e7bb38/clang_format-22.1.5-py2.py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5028f730a1acd0a2ff5fde309c3a064b2f8375caa664e57ff99c69a524d6cfd2", size = 2848433, upload-time = "2026-05-06T13:12:15.421Z" }, + { url = "https://files.pythonhosted.org/packages/c0/f7/f6c94ec536b6ada3dd23e0b49e691c80991dc5de89a5152b1ea2ed14c20b/clang_format-22.1.5-py2.py3-none-win32.whl", hash = "sha256:c1c2c4b9c9b7fba124c1b60647706ac6d4950e52830303951e7004403bb07006", size = 1299262, upload-time = "2026-05-06T13:12:17.449Z" }, + { url = "https://files.pythonhosted.org/packages/79/62/96fb942f00a39f93aeedf8ab5a16b2b42688bdc7ca7ec94714502b787c0e/clang_format-22.1.5-py2.py3-none-win_amd64.whl", hash = "sha256:0393ce061bf7bd7e7ce349fc758a05f9ce604d8653e23b47f24322fb4843074c", size = 1460369, upload-time = "2026-05-06T13:12:19.016Z" }, + { url = "https://files.pythonhosted.org/packages/ce/2d/35c5301c6d04f4babf218ad9716c061abebb8a56a1bbad167a86dfe966d3/clang_format-22.1.5-py2.py3-none-win_arm64.whl", hash = "sha256:4f5ac3b91bb5700c43cb96beb32e360a5aa6a7f94105d7900054f6496554d9b9", size = 1344987, upload-time = "2026-05-06T13:12:20.88Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "hyperjet" +version = "0.0.0" +source = { editable = "." } +dependencies = [ + { name = "msvc-runtime", marker = "sys_platform == 'win32'" }, + { name = "numpy" }, +] + +[package.optional-dependencies] +test = [ + { name = "pytest" }, +] + +[package.dev-dependencies] +dev = [ + { name = "clang-format" }, +] +test = [ + { name = "pytest" }, +] + +[package.metadata] +requires-dist = [ + { name = "msvc-runtime", marker = "sys_platform == 'win32'" }, + { name = "numpy", specifier = ">=2.0" }, + { name = "pytest", marker = "extra == 'test'", specifier = ">=8.0" }, +] +provides-extras = ["test"] + +[package.metadata.requires-dev] +dev = [{ name = "clang-format", specifier = ">=19.0" }] +test = [{ name = "pytest", specifier = ">=8.0" }] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "msvc-runtime" +version = "14.44.35112" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/6d/db7a1f232aaaab3fb639db8d5c5d846af32ebed9dcb2373335de8767169b/msvc_runtime-14.44.35112-cp311-cp311-win32.whl", hash = "sha256:438a584930820238141162ef9b92bd8099ccca62a67fa0ddef63ed88b8eb4e0d", size = 1921504, upload-time = "2025-08-08T03:57:50.173Z" }, + { url = "https://files.pythonhosted.org/packages/ce/92/5a10262c2a489d5854f96d69e287923d6f720c4935dd26634deb7a5426e9/msvc_runtime-14.44.35112-cp311-cp311-win_amd64.whl", hash = "sha256:aba7fbe71897d25ed53fbb7f391e9f50289378a8a9ae218ba18530c663448391", size = 1921911, upload-time = "2025-08-08T03:57:51.814Z" }, + { url = "https://files.pythonhosted.org/packages/cc/33/88002539f2f5f2cc1fe978bf44cc5d140044473326da3baf52d99a6d8128/msvc_runtime-14.44.35112-cp311-cp311-win_arm64.whl", hash = "sha256:3a9c137951944fdc121377947bb4787dcd1007b505d7cf26f62d308d2b8df280", size = 3208236, upload-time = "2025-08-08T03:57:53.338Z" }, + { url = "https://files.pythonhosted.org/packages/1f/7d/f86050e24fd78e76e56145b326bfd3e7ae2c028e87e0732802a0c5144223/msvc_runtime-14.44.35112-cp312-cp312-win32.whl", hash = "sha256:7c5af6756056dbf6f3593f69b0f4575dbbd9e8ec10d3108ff00437da811a7b67", size = 1921505, upload-time = "2025-08-08T03:57:54.509Z" }, + { url = "https://files.pythonhosted.org/packages/21/3b/134d04268ab8e35853cd007582076429b45d60d6abb1036d159be9c50342/msvc_runtime-14.44.35112-cp312-cp312-win_amd64.whl", hash = "sha256:32f9c706009e16ccc319d6947ce3bffe20e5192bee52b18cf48313f9e7bedfbe", size = 1921899, upload-time = "2025-08-08T03:57:55.648Z" }, + { url = "https://files.pythonhosted.org/packages/a0/38/f245d6d30a76655293575683aaa5f72a7a70fc8efa1637bf6fd9e5e7e665/msvc_runtime-14.44.35112-cp312-cp312-win_arm64.whl", hash = "sha256:62f272c51f30ce0de1b7a796e50af4d3911b76cbc9bc909917435d094f68d5fe", size = 3208186, upload-time = "2025-08-08T03:57:57.401Z" }, + { url = "https://files.pythonhosted.org/packages/b0/3b/590fcbf92fee8f0d3ac46cd8b32069b058d6ce7bfb8be6c07a35d9c9188b/msvc_runtime-14.44.35112-cp313-cp313-win32.whl", hash = "sha256:e60781114472891c34fe14cc45a19ac28d80e0084dfbce882b7475c40c743152", size = 1921506, upload-time = "2025-08-08T03:57:58.888Z" }, + { url = "https://files.pythonhosted.org/packages/fe/17/7a1eace5a7c6083bd99db861625c08bb37010dfbe90ed7a0194ae0281689/msvc_runtime-14.44.35112-cp313-cp313-win_amd64.whl", hash = "sha256:d4f6cf106aaf235f2a90952f9ec7de49e9946323880d051abf9745a6d4bf60bf", size = 1921893, upload-time = "2025-08-08T03:58:00.234Z" }, + { url = "https://files.pythonhosted.org/packages/33/0d/88d6183846ad33b4a8fcb82fc86f26f9b7e21d776a925b6c8ab89618234a/msvc_runtime-14.44.35112-cp313-cp313-win_arm64.whl", hash = "sha256:359152dc9769559fee4ffdaa19f1fc2b72ab1535631a6105116776b263a235ac", size = 3208191, upload-time = "2025-08-08T03:58:02.35Z" }, + { url = "https://files.pythonhosted.org/packages/d7/9c/b9ee5402fe9daf6f4dba458f11238289c606df05e0cc9f0750d5ada4ff3b/msvc_runtime-14.44.35112-cp314-cp314-win32.whl", hash = "sha256:99c22caa2755c76cfa34b741e96bee99c461480d709fb9c582492ccc0f03c7ae", size = 1976509, upload-time = "2025-08-08T03:58:03.698Z" }, + { url = "https://files.pythonhosted.org/packages/d2/48/7fb574a4bfa697574a7dc7105bc15ef6882125e7c77c794c5e73429de832/msvc_runtime-14.44.35112-cp314-cp314-win_amd64.whl", hash = "sha256:af179a6c552070e660493765efd5856283af3fed971ddc3577203a7d3f1ee8e7", size = 1976906, upload-time = "2025-08-08T03:58:05.079Z" }, + { url = "https://files.pythonhosted.org/packages/93/b3/bdb7c215d1080ea08deb5e151dc261f74f5b1d25544947e31e902eb1253f/msvc_runtime-14.44.35112-cp314-cp314-win_arm64.whl", hash = "sha256:81eb9346ab2a269ea934bf13492fe5c1cd50af871a2fbb973f0a514031e81b6a", size = 3300540, upload-time = "2025-08-08T03:58:06.52Z" }, + { url = "https://files.pythonhosted.org/packages/95/99/271ff26cf07d875766efa4a376fe9415c033f07fe85a1371a071aaa37aca/msvc_runtime-14.44.35112-cp314-cp314t-win32.whl", hash = "sha256:38d64f2db707be465a79c87f0bec347249af89614550d10ed0345f6a7f80cf73", size = 1976674, upload-time = "2025-08-08T03:58:07.902Z" }, + { url = "https://files.pythonhosted.org/packages/47/eb/76fd58fd64209e7f3dbfe59237e2c49ee6bdd4c21eba9efe5a2354dacd3e/msvc_runtime-14.44.35112-cp314-cp314t-win_amd64.whl", hash = "sha256:1105f8f8117ee210b85bd8c771dbefff8f8d35771ee7ce3291ddd91d2a03eff1", size = 1977068, upload-time = "2025-08-08T03:58:09.376Z" }, + { url = "https://files.pythonhosted.org/packages/e2/38/b1ff1734e257c99a6450c60a1632d0c9ddbdb049ee4095439a591a0949a5/msvc_runtime-14.44.35112-cp314-cp314t-win_arm64.whl", hash = "sha256:a2ab094e35fa04172f6fd5cfc7d2a2017755ea9c3ff39cad5c2a4456e0bff689", size = 3300780, upload-time = "2025-08-08T03:58:11.061Z" }, +] + +[[package]] +name = "numpy" +version = "2.4.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/50/8e/b8041bc719f056afd864478029d52214789341ac6583437b0ee5031e9530/numpy-2.4.5.tar.gz", hash = "sha256:ca670567a5683b7c1670ec03e0ddd5862e10934e92a70751d68d7b7b74ca7f9f", size = 20735669, upload-time = "2026-05-15T20:25:19.492Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/44/1383ee4d1e916a9e610e46c876b5c83ea023526117d23cd911983929ec34/numpy-2.4.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3176dc8ff71dbb593606f91a69ad0c3cd3303c7eb546af477370ab9edf760288", size = 16969261, upload-time = "2026-05-15T20:22:23.036Z" }, + { url = "https://files.pythonhosted.org/packages/3d/61/54bacfbec7550bc398e6b6d9a861db35d64f75844e1d7920f5722c3cd5e7/numpy-2.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1811150e5148f5a01a7cc282cb2f489b4a3050a773e173adb480e507bad3a3d7", size = 14964009, upload-time = "2026-05-15T20:22:25.819Z" }, + { url = "https://files.pythonhosted.org/packages/7a/55/fe86c64561761f185339c26001164a2687bd4787af681e961431abd2d534/numpy-2.4.5-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:0d63a780070871210853ba01e90b88f9b85cf2abf63a7f143d5127189265ddf6", size = 5469106, upload-time = "2026-05-15T20:22:28.13Z" }, + { url = "https://files.pythonhosted.org/packages/2f/74/cf29b8317627f0e3aa2c9fb332d386bd734308cecd9e07da9f407d9ce0c3/numpy-2.4.5-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:0c6919cefafb3b76cd46a89dbb203bf1dd95529d2a6d09fef2d325d95d6a79d8", size = 6798945, upload-time = "2026-05-15T20:22:30.061Z" }, + { url = "https://files.pythonhosted.org/packages/80/a9/b61730a17fa87d5abb13ce560a1b4ce3485d37a13e03eb7b414e598e72f8/numpy-2.4.5-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d51efede1e58e8b11877536a5518f60e318d8ff69b89ad7b38ee5e431b24d772", size = 15967025, upload-time = "2026-05-15T20:22:32.328Z" }, + { url = "https://files.pythonhosted.org/packages/03/39/70bcd187eb4d223c21fde02c2bdfbffbffef3288cbb3947c04c74ae39a08/numpy-2.4.5-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:07ce7e74da92d7c71b5df157b9758bcdd53d7fea10602154de3afd2b3ddc34dd", size = 16918685, upload-time = "2026-05-15T20:22:34.759Z" }, + { url = "https://files.pythonhosted.org/packages/ab/31/400fd1315bbe228af3937cf8a74e32023df6217af36077919d00adc382e4/numpy-2.4.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d7828234a13185effb34979e146f9921f2a65dfbbe215e6dbb57d6478fc8e059", size = 17322963, upload-time = "2026-05-15T20:22:37.557Z" }, + { url = "https://files.pythonhosted.org/packages/18/6a/bbbafb657e6f6ee826b4ecdb8722a2e0aae4a981888eaf59eae6a535cc13/numpy-2.4.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f96083adc3dfc1bbf778f2c79654d88115fa07074c97cb724fe9508f12d91c55", size = 18651594, upload-time = "2026-05-15T20:22:40.449Z" }, + { url = "https://files.pythonhosted.org/packages/de/0c/857a515154a2a18b0dfae04089600d166d352d473ec17a0680d879582d06/numpy-2.4.5-cp311-cp311-win32.whl", hash = "sha256:4ed78c904a638b6e5d7cd4db90c06fca5fc6ec2f28d258305368f454a50e79cf", size = 6233849, upload-time = "2026-05-15T20:22:43.139Z" }, + { url = "https://files.pythonhosted.org/packages/f0/66/d215f3fb93541617adb5d58b3b9508e8a6413e499711e0adc0b80bcb445d/numpy-2.4.5-cp311-cp311-win_amd64.whl", hash = "sha256:079b0fad6f2899b23c5da89792b5409d2d83fc83e8bd5c2299cc9c397a264864", size = 12608238, upload-time = "2026-05-15T20:22:45.229Z" }, + { url = "https://files.pythonhosted.org/packages/cb/c4/611d66d3fcfa931954d37a19ce5575f3283d023e89ff0df6ad43b334ae9c/numpy-2.4.5-cp311-cp311-win_arm64.whl", hash = "sha256:d6c78e260b53affe9b395a9d54fc61f101f9521c4d9452c7e9e3718b19e2215b", size = 10479452, upload-time = "2026-05-15T20:22:47.962Z" }, + { url = "https://files.pythonhosted.org/packages/6c/18/3275231e98620002681c922e792db04d72c356e9d8073c387344fc0e4ff1/numpy-2.4.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:654fb8674b61b1c4bd568f944d13a908566fdcb0d797303521d4149d16da05ef", size = 16689166, upload-time = "2026-05-15T20:22:50.761Z" }, + { url = "https://files.pythonhosted.org/packages/db/23/000aab6a16bdec53307f0f72546b57a3ac9266a62d8c257bee97d85fd078/numpy-2.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4cd9f6fa7ce10dc4627f2bb81dd9075dab67e94632e04c2b638e12575ddaa862", size = 14699514, upload-time = "2026-05-15T20:22:53.678Z" }, + { url = "https://files.pythonhosted.org/packages/47/cc/ddaf3af9c46966fef5be879256f213d85a0c56c75d07a3b7defec7cf6b4c/numpy-2.4.5-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:4f5bc96d35d94e4ceab8b38a92241b4611e95dc44e63b9f1fa2a331858ee3507", size = 5204601, upload-time = "2026-05-15T20:22:56.257Z" }, + { url = "https://files.pythonhosted.org/packages/07/ea/627fadd11959b3c7759008f34c92a35af8ff942dd8284a66ced648bbe516/numpy-2.4.5-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:4bb33e900ee81730ad77a258965134aa8ceac805124f7e5229347beda4b8d0aa", size = 6551360, upload-time = "2026-05-15T20:22:58.334Z" }, + { url = "https://files.pythonhosted.org/packages/a1/47/0728b986b8682d742ff68c16baa5af9d185484abfc635c5cc700f44e62be/numpy-2.4.5-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:32f8f852273ef32b291201ac2a2c97629c4a1ee8632bb670e3443eaa09fc2e72", size = 15671157, upload-time = "2026-05-15T20:23:01.081Z" }, + { url = "https://files.pythonhosted.org/packages/d1/0b/b905ae82d9419dc38123523862db64978ca2954b69609c3ae8fdaca1084c/numpy-2.4.5-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:685681e956fc8dcb75adc6ff26694e1dfd738b24bd8d4696c51ca0110157f912", size = 16645703, upload-time = "2026-05-15T20:23:04.358Z" }, + { url = "https://files.pythonhosted.org/packages/5f/24/e27fc3f5236b4118ed9eed67111675f5c61a07ea333acec87c869c3b359d/numpy-2.4.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6f64dd84b277a737eb59513f6b9bb6195bf41ab11941ef15b2562dbab43fa8ef", size = 17021018, upload-time = "2026-05-15T20:23:07.021Z" }, + { url = "https://files.pythonhosted.org/packages/d3/a7/9041af38d527ab80a06a93570a77e29425b41507ad41f6acf5da78cfb4a4/numpy-2.4.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b42d9496f79e3a728192f05a42d86e36163217b7cdecb3813d0028a0aa6b72d7", size = 18368768, upload-time = "2026-05-15T20:23:09.44Z" }, + { url = "https://files.pythonhosted.org/packages/49/82/326a014442f32c2663434fd424d9298791f47f8a0f17585ad60519a5606e/numpy-2.4.5-cp312-cp312-win32.whl", hash = "sha256:86d980970f5110595ca14855768073b08585fc1acc36895de303e039e7dee4a5", size = 5962819, upload-time = "2026-05-15T20:23:11.631Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/cbf5d391b0b3a5e8cad264603e2fae256b0bde8ce43566b13b78faedc659/numpy-2.4.5-cp312-cp312-win_amd64.whl", hash = "sha256:3333dba6a4e611d666f69e177ba8fe4140366ff681a5feb2374d3fd4fff3acb6", size = 12321621, upload-time = "2026-05-15T20:23:14.305Z" }, + { url = "https://files.pythonhosted.org/packages/3c/d0/0f18909d9bc37a5f3f969fc737d2bb5df9f2ff295f71b467e6f52a0d6c4e/numpy-2.4.5-cp312-cp312-win_arm64.whl", hash = "sha256:4593d197270b894efeb538dcbe227e4bcf1c77f88c4c6bf933ead812cfaa4453", size = 10221430, upload-time = "2026-05-15T20:23:16.887Z" }, + { url = "https://files.pythonhosted.org/packages/e3/a4/fb50657c7cab297bf34edcd60a074cb0647f61771430d6363575274160fe/numpy-2.4.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1ef248460b645c102026b82337cc4e88231909c66dd77b59ec6d6cac7e44f277", size = 16684760, upload-time = "2026-05-15T20:23:19.436Z" }, + { url = "https://files.pythonhosted.org/packages/3e/43/87e731299b9408eda705b3b9cb31c7bceb9347d2af9cbb16b2b1e4b5bc0f/numpy-2.4.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4603622bdcdbf8dccb1d9d5b21d16a7aa4e473ae6c8e14048d846fd4ca2907a0", size = 14694117, upload-time = "2026-05-15T20:23:21.832Z" }, + { url = "https://files.pythonhosted.org/packages/a9/c7/0b2bb8acea222e9dd6e582afc2bc553b89b8833cbdccc68e68f050fb31f8/numpy-2.4.5-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:6c18d49c67689c562854b53fdc433b93e47c12952aa6fa6d59f185e1a5992419", size = 5199141, upload-time = "2026-05-15T20:23:24.066Z" }, + { url = "https://files.pythonhosted.org/packages/39/60/b6972b5d47033d90000f0097c81a98b9486589a2d7003bf725bff275cb0d/numpy-2.4.5-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:b1c663ddc641f4192e90511bec61a09bc231e3bbdb996cdc6edbcaa0e528d685", size = 6546954, upload-time = "2026-05-15T20:23:26.099Z" }, + { url = "https://files.pythonhosted.org/packages/c1/e9/ed667cb12c11ca0adde431f685d3a5dd78e6f78b27228c581c8415198e9e/numpy-2.4.5-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:93793222b524f692f12b2f8752ce8b1d9d9125b2bfd5dbf0fb69c92c5e1ce86c", size = 15669430, upload-time = "2026-05-15T20:23:28.147Z" }, + { url = "https://files.pythonhosted.org/packages/44/e5/679f6ffeb01294b0008e5ada4a113cb47617bc0e1819a529fd7973c6d7f4/numpy-2.4.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1616bde34b2bcba2fa9bde06217ce00da4f3d1bdfb264d54525a99e8fe170d83", size = 16633390, upload-time = "2026-05-15T20:23:31.622Z" }, + { url = "https://files.pythonhosted.org/packages/36/46/42bfffc9a780ec902ccd7470d3219192ee82b7b442710307dd85b4d121b0/numpy-2.4.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:09d7d97da1c2c62f4818b3e150a57572ff8dcf1cf5ac501aac832ffd4ebd9566", size = 17020709, upload-time = "2026-05-15T20:23:34.08Z" }, + { url = "https://files.pythonhosted.org/packages/44/00/3e840bfee0cc6cec22209f2c97057f26eeb30de031e4933b4dfc0395416c/numpy-2.4.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2d68d0b355ab2e39fe0de59001d7151dfdbbb880ef67baeed806661e03df5097", size = 18357818, upload-time = "2026-05-15T20:23:36.965Z" }, + { url = "https://files.pythonhosted.org/packages/72/cb/3447b400b9da84134575486f0f656541559b00d4b262477bce9b678bbca8/numpy-2.4.5-cp313-cp313-win32.whl", hash = "sha256:fe28b64777ddfa0eca9b5f51474034ebe3dcb8324f48f27b28f479085673ae33", size = 5961114, upload-time = "2026-05-15T20:23:39.586Z" }, + { url = "https://files.pythonhosted.org/packages/28/f9/a90d2220ffcdc0798f5d55bb5d5463cd6254ec9ef43f384dae80217d7a2f/numpy-2.4.5-cp313-cp313-win_amd64.whl", hash = "sha256:fb4a6c9c537d6ccec9cc4aeae4261bd3cc79b070c67ddc0646f5b1c07fddde42", size = 12318553, upload-time = "2026-05-15T20:23:41.436Z" }, + { url = "https://files.pythonhosted.org/packages/b8/c9/96f531fb3234545315152d34efdf3de7daee81254448447eb619e8d16967/numpy-2.4.5-cp313-cp313-win_arm64.whl", hash = "sha256:6d7df2da2e7ea0624a43aa368104b3a3ce14aae98ad4bb2c9a93fecef76f1c97", size = 10222200, upload-time = "2026-05-15T20:23:43.681Z" }, + { url = "https://files.pythonhosted.org/packages/e1/f4/a291caab5a3c520babf93ff77c54fd5fdb1ebbc3296cee2eb2146ce773b1/numpy-2.4.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:2a235607a18df941760a695927051af4b1cd5d3ee85840d0e2af816785771feb", size = 14821438, upload-time = "2026-05-15T20:23:45.911Z" }, + { url = "https://files.pythonhosted.org/packages/85/26/13dbb1159b864370568e7309063fd72667984df89db74e9caeb175d067c7/numpy-2.4.5-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:58dcf64969d870f36bc7fbd557d2617e997db7dc06261b6e3327148ea460d0a4", size = 5326663, upload-time = "2026-05-15T20:23:48.18Z" }, + { url = "https://files.pythonhosted.org/packages/7c/99/d233408072a0e019e2288e27edd23f7d572ccd4a73d1539baa3270ede85d/numpy-2.4.5-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:235f54b0156274d8fa3155db3ed6d2f401c7e8f3367c90db0a12f02a58fde6ed", size = 6646874, upload-time = "2026-05-15T20:23:49.856Z" }, + { url = "https://files.pythonhosted.org/packages/c5/00/eeb6f193dfe767725e952e0464f3e51f44145c5dd261cd7389aa36ac0713/numpy-2.4.5-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ef3b5bb65437a3555c648e706475db01c645559ca80dc8b03e4f202ea757e0d6", size = 15728147, upload-time = "2026-05-15T20:23:51.655Z" }, + { url = "https://files.pythonhosted.org/packages/e5/c9/b8ed039f1fde1b13a8807c893e7e2f9432a379f4d6401edecf0028da5b2c/numpy-2.4.5-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7f09a7e5f017d7098c66522097c96257411c9620c0926212200d66bc8cee3976", size = 16681770, upload-time = "2026-05-15T20:23:53.933Z" }, + { url = "https://files.pythonhosted.org/packages/11/5b/0198ef6cb7016eca6d895d392106012138127fab23f46637e76d5e25c9f5/numpy-2.4.5-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:993a88d8fdd8554466a8765cd8bacd97ba56b70ca6b0a04bcdca77f5afed4222", size = 17086218, upload-time = "2026-05-15T20:23:56.646Z" }, + { url = "https://files.pythonhosted.org/packages/f0/fe/8821f3cfc660ae84c92ee158505941874b62c56a42e035a41425228cd8cf/numpy-2.4.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:84f58bed609b5669f5ad3d597901a4f1f86ee5b3c3708aaa55f05b4fe6e0f656", size = 18403542, upload-time = "2026-05-15T20:23:59.173Z" }, + { url = "https://files.pythonhosted.org/packages/0e/00/e64ecaf498865e7b091f57658b2c522503e5d1b70e43b807f5f8247e1d88/numpy-2.4.5-cp313-cp313t-win32.whl", hash = "sha256:7200c58f3f933ca61e66346667dcc8510bb111995e9ce15398a731e6a4afa4bb", size = 6084903, upload-time = "2026-05-15T20:24:01.506Z" }, + { url = "https://files.pythonhosted.org/packages/20/c0/354997dedaf74e8311c2cf9a6027b476fd8d424cb92189cc0ae2b25f501c/numpy-2.4.5-cp313-cp313t-win_amd64.whl", hash = "sha256:c26c71080d35db5002102f5d9ff614d45de02aa1f7802943e691e063e5ee93bc", size = 12458420, upload-time = "2026-05-15T20:24:03.735Z" }, + { url = "https://files.pythonhosted.org/packages/66/dc/917ee5ea4a31ca1a6e4c9a85386477efa318dcc60db257c5ef4adda096c1/numpy-2.4.5-cp313-cp313t-win_arm64.whl", hash = "sha256:2caa576d1707b275cba1aeb60a5c50daa6fa2a3f28ecb08123bc05fd439005db", size = 10291826, upload-time = "2026-05-15T20:24:06.535Z" }, + { url = "https://files.pythonhosted.org/packages/ca/c1/3be0bf102fc17cff5bd142e3be0bfffabec6fa46da0a462396c76b0765d0/numpy-2.4.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:889ca2c072315de638a5194a772aa1fa2df92bdd6175f6a222d4784040424b61", size = 16683455, upload-time = "2026-05-15T20:24:08.988Z" }, + { url = "https://files.pythonhosted.org/packages/e8/3e/0742d724901fa36bc54b338c6e62e463a7601180da896aa44978f0adf004/numpy-2.4.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:89e89304fb1f8c3f0ecfa4a7d48f311dd79771336a940e920159d643d1307e77", size = 14704577, upload-time = "2026-05-15T20:24:11.542Z" }, + { url = "https://files.pythonhosted.org/packages/25/1c/196c610ff4c6782d697ba780ebdc1616be143213701bf22c1a270f3bf7dd/numpy-2.4.5-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:144fcc5a3a17679b2b82543b4a2d8dd29937230a7af13232b5f753872feb6361", size = 5209756, upload-time = "2026-05-15T20:24:14.091Z" }, + { url = "https://files.pythonhosted.org/packages/52/c0/23fb1bc506f774e03db66219a2830e720f4d3dbcaaddf855a7ff7bb6d96f/numpy-2.4.5-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:398bb16772b265b9fa5c07b07072646ea97137c10ffb62a9a087b277fc825c29", size = 6543937, upload-time = "2026-05-15T20:24:16.223Z" }, + { url = "https://files.pythonhosted.org/packages/9f/49/db4662c26e68520afcc84d672a6f9f5294063dee0e57a46d61afdaa7f9ed/numpy-2.4.5-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fb352e7b8876da1249e72254736d6c58c505fa4e58a3d7e30efca241ca9ca9ce", size = 15685292, upload-time = "2026-05-15T20:24:17.978Z" }, + { url = "https://files.pythonhosted.org/packages/43/80/1315439acedd8398319bac177d6de3d48ab39c62cc0c810f74f0a9a73996/numpy-2.4.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7341b08ff8124d7353939778e2707b8732d03c78c1c30e0815aba2dacbe1245a", size = 16638528, upload-time = "2026-05-15T20:24:20.478Z" }, + { url = "https://files.pythonhosted.org/packages/56/81/364388600932618fe735d97fdd2437cb8dd87a23377ac11d8b9d5db098b7/numpy-2.4.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:deb01226f012539f3945261ffe1c10aec081a0fa0a5c925419933c70f3ae2d23", size = 17036709, upload-time = "2026-05-15T20:24:22.949Z" }, + { url = "https://files.pythonhosted.org/packages/32/4a/a1185b18a94a6d9587e54b437e7d0ba36ecf6e614f1bea03f5249912c64e/numpy-2.4.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d888bdf7335f76878c3c7b264ac1ff089863e211ec81249f9fb5795c2183dc25", size = 18363254, upload-time = "2026-05-15T20:24:25.402Z" }, + { url = "https://files.pythonhosted.org/packages/b9/8e/95c1d2ed15ae97750ede8c8a0ac487c9c01207afff430f47078b1d9d7dc5/numpy-2.4.5-cp314-cp314-win32.whl", hash = "sha256:15f90d1256e9b2320aff24fde44815b787ab6d7c49a1a11bfd8138b321c5f080", size = 6010184, upload-time = "2026-05-15T20:24:27.852Z" }, + { url = "https://files.pythonhosted.org/packages/aa/92/d063df4d63d988b20d881856c74df76c0c1786229bb870f3a52af0981d4d/numpy-2.4.5-cp314-cp314-win_amd64.whl", hash = "sha256:4bd2cd4ef9c0afa87de73723c0a33c0edff62143e1432917458e26d3d195d87f", size = 12450344, upload-time = "2026-05-15T20:24:29.856Z" }, + { url = "https://files.pythonhosted.org/packages/3d/64/c0ae481f7c3b2f85869bcd8fc5d30aa7c96b394162eef9c9315957f115c5/numpy-2.4.5-cp314-cp314-win_arm64.whl", hash = "sha256:db304568c650e9d7039744d3575d0d287754debb2057d7c7b8cdfdc2c487a957", size = 10495674, upload-time = "2026-05-15T20:24:32.352Z" }, + { url = "https://files.pythonhosted.org/packages/57/89/c5a4c677acf17aa50ba09a15e61812f90baac42bb6ca38d112e005858351/numpy-2.4.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6de2883e0d2c63eae1bab1a84b390dca74aabb3d20ea1f5d58f360853c83abf3", size = 14824078, upload-time = "2026-05-15T20:24:34.669Z" }, + { url = "https://files.pythonhosted.org/packages/e7/52/57e7144284f6b51ba93523e495ff239260b1ecd5257e3700a436332e5688/numpy-2.4.5-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:06760fe73ae5005008748d182de612c733542af3cde063d532cd2127561b27be", size = 5329246, upload-time = "2026-05-15T20:24:36.957Z" }, + { url = "https://files.pythonhosted.org/packages/b9/b3/09dbce80fd4a7db4318f2fc01eec0ae76f29306442b5a32d4b811d082cdf/numpy-2.4.5-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:4b51a01745cb04cc19278482207444b4d30728ce91c28d27a3bfae5fc6ff24c7", size = 6649877, upload-time = "2026-05-15T20:24:38.861Z" }, + { url = "https://files.pythonhosted.org/packages/30/c2/dbdb23e82d540b757690ef13f011c386fca6a63848eec6136baf8ce7cbed/numpy-2.4.5-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9a05636d7937d0936f271e5ba957fa8d746b5be3c2025caa1a2508f4fe521d40", size = 15730534, upload-time = "2026-05-15T20:24:41.168Z" }, + { url = "https://files.pythonhosted.org/packages/c4/bd/68f6e9b3c20decf40ac06708a7b506757e3a8588efed32988d1b747316be/numpy-2.4.5-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14b86f56048ed09c3bbe48962a7dff077c2fd3274f8cf981800f3b38eac49cc3", size = 16679741, upload-time = "2026-05-15T20:24:44.874Z" }, + { url = "https://files.pythonhosted.org/packages/39/1d/0fcac0b6b4ea1b50ca8fca05a34bed5c8d56e34c1cb5ffb04cf76109ac3c/numpy-2.4.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:130d58151c4db23e9fa860b84784e219a3aa3e030acc88a493ea37006c4dfd4c", size = 17085598, upload-time = "2026-05-15T20:24:47.603Z" }, + { url = "https://files.pythonhosted.org/packages/0b/e8/a472b2564cf6cc498ad7aa9741d9832648221b8ab8cc0dbef41faa248ede/numpy-2.4.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d475afc8cbe935ff5944f753d863bba774d7f4e1feaaa4102901e3e053ca5963", size = 18403855, upload-time = "2026-05-15T20:24:50.474Z" }, + { url = "https://files.pythonhosted.org/packages/b9/a4/da82196f8cc4bd28ecf17bd57008c84f3d4696caf06753d9bad45e4ad749/numpy-2.4.5-cp314-cp314t-win32.whl", hash = "sha256:27f4a6dc26353a860b348961b9aa9e009835688b435cfa105e873b8dc2c726f5", size = 6156900, upload-time = "2026-05-15T20:24:53.134Z" }, + { url = "https://files.pythonhosted.org/packages/98/31/860959b91a73d9a085006554fa3850da51a7ffab64599bac5097243438ab/numpy-2.4.5-cp314-cp314t-win_amd64.whl", hash = "sha256:76ac6e90f5e226011c88f9b7040a4bcae612518bc7e9adc127e697a13b28ad1a", size = 12638906, upload-time = "2026-05-15T20:24:55.009Z" }, + { url = "https://files.pythonhosted.org/packages/9e/2a/bbd3097913083ad07c0f28fc9629666221fc18923e17ce97ae22a5dccdd6/numpy-2.4.5-cp314-cp314t-win_arm64.whl", hash = "sha256:7c392e2c1bf596701d3c6832be7567eab5d5b0a13865036c33365ee097d37f8b", size = 10565875, upload-time = "2026-05-15T20:24:57.425Z" }, + { url = "https://files.pythonhosted.org/packages/fc/5d/9a644cfb841bc76b584afc3af1708b3bf6c5cb51fc84a7008246cd93b7b7/numpy-2.4.5-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:6bf0bfc1c2e1db972e30b6cd3d4861f477f3af908b27799b239dc3cbe3eb4b95", size = 16847544, upload-time = "2026-05-15T20:24:59.746Z" }, + { url = "https://files.pythonhosted.org/packages/56/8f/4fe5e3ba76d858dae1fe79078818c0520447335be0082c0dedf82719cc08/numpy-2.4.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:73d664413fb97229149c4711ef56531a6fe8c15c1c2626b0bbe497b84c287e70", size = 14889039, upload-time = "2026-05-15T20:25:03.179Z" }, + { url = "https://files.pythonhosted.org/packages/8e/6f/79f195abf922ecc43e7d0eb6cc969462a71b524a35bcd1fa26b4a1d7406a/numpy-2.4.5-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:b35bee5ef99e8d227a07829bee2e864fcb65f7c157646fcd8ec8b4b45dd8b88f", size = 5394106, upload-time = "2026-05-15T20:25:05.659Z" }, + { url = "https://files.pythonhosted.org/packages/58/6f/79cd6247205802bcbd10b40ea087e20ded526e10e9be224d34de832b216e/numpy-2.4.5-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:02981d0fc9f9ce147643d552966d47f329a02f7ecb3b113e84207242f20dfa83", size = 6708718, upload-time = "2026-05-15T20:25:08.071Z" }, + { url = "https://files.pythonhosted.org/packages/d7/22/5f378a9d4633c98f28c4709d4144b1a4630c5c09e109d2e781e2d26c8fe1/numpy-2.4.5-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0e63caf31a1df06338ae63d999f7a33a675ced62eea9c9b02db4b1c1f45cff38", size = 15798292, upload-time = "2026-05-15T20:25:10.689Z" }, + { url = "https://files.pythonhosted.org/packages/63/1c/cec582febef798c99888892d92dc1d28dfe29cb427c41f44d13d0dec208f/numpy-2.4.5-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d8fc52b85a7b45e474be53eddf08e006d22e381a4e41bcde8e4aa08da0e7d198", size = 16747406, upload-time = "2026-05-15T20:25:13.879Z" }, + { url = "https://files.pythonhosted.org/packages/b1/dc/d358a16a6fec86cf736b8fbe67386044b3fa2aded1a80cff90e836799301/numpy-2.4.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:40c71d50a4da1a7c317af419461052d3911a5770bfc5fd55baf52cc45e7a2c20", size = 12504085, upload-time = "2026-05-15T20:25:16.667Z" }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pytest" +version = "9.0.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc8cf64563a117c0f3765662e2e668477624baeec44d5/pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c", size = 1572165, upload-time = "2026-04-07T17:16:18.027Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" }, +] From 7151556919f060d4d9070c444900efd02e68889c Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 17 May 2026 10:19:38 +0200 Subject: [PATCH 13/14] switch to LLVM standard --- .clang-format | 100 +- benchmark/src/benchmarks.cpp | 806 +++--- include/hyperjet/hyperjet.h | 4027 +++++++++++++----------------- python/src/bind_ddscalar_0d.cpp | 19 +- python/src/bind_ddscalar_10d.cpp | 19 +- python/src/bind_ddscalar_11d.cpp | 19 +- python/src/bind_ddscalar_12d.cpp | 19 +- python/src/bind_ddscalar_13d.cpp | 19 +- python/src/bind_ddscalar_14d.cpp | 19 +- python/src/bind_ddscalar_15d.cpp | 19 +- python/src/bind_ddscalar_16d.cpp | 19 +- python/src/bind_ddscalar_1d.cpp | 19 +- python/src/bind_ddscalar_2d.cpp | 19 +- python/src/bind_ddscalar_3d.cpp | 19 +- python/src/bind_ddscalar_4d.cpp | 19 +- python/src/bind_ddscalar_5d.cpp | 19 +- python/src/bind_ddscalar_6d.cpp | 19 +- python/src/bind_ddscalar_7d.cpp | 19 +- python/src/bind_ddscalar_8d.cpp | 19 +- python/src/bind_ddscalar_9d.cpp | 19 +- python/src/bind_ddscalar_xd.cpp | 19 +- python/src/bind_sscalar.cpp | 194 +- python/src/common.h | 397 ++- python/src/main.cpp | 333 +-- test/src/test.cpp | 1242 +++++---- 25 files changed, 3340 insertions(+), 4101 deletions(-) diff --git a/.clang-format b/.clang-format index de091bed..941486e2 100644 --- a/.clang-format +++ b/.clang-format @@ -1,99 +1,3 @@ --- -Language: Cpp -BasedOnStyle: Microsoft - -# Indentation -IndentWidth: 4 -TabWidth: 4 -UseTab: Never -IndentCaseLabels: false -IndentCaseBlocks: false -IndentPPDirectives: None -NamespaceIndentation: All -IndentWrappedFunctionNames: false -ContinuationIndentWidth: 4 -AccessModifierOffset: -4 -IndentAccessModifiers: false - -# Braces -BreakBeforeBraces: Allman -Cpp11BracedListStyle: true - -# Line breaks -ColumnLimit: 0 -KeepEmptyLinesAtTheStartOfBlocks: false -MaxEmptyLinesToKeep: 2 - -# Alignment -PointerAlignment: Right -ReferenceAlignment: Right -AlignAfterOpenBracket: Align -AlignConsecutiveAssignments: false -AlignConsecutiveDeclarations: false -AlignConsecutiveMacros: false -AlignEscapedNewlines: Left -AlignOperands: Align -AlignTrailingComments: true - -# Spaces -SpaceAfterCStyleCast: false -SpaceAfterLogicalNot: false -SpaceAfterTemplateKeyword: true -SpaceBeforeAssignmentOperators: true -SpaceBeforeCaseColon: false -SpaceBeforeCpp11BracedList: false -SpaceBeforeCtorInitializerColon: true -SpaceBeforeInheritanceColon: true -SpaceBeforeParens: ControlStatements -SpaceBeforeRangeBasedForLoopColon: true -SpaceBeforeSquareBrackets: false -SpaceInEmptyBlock: false -SpaceInEmptyParentheses: false -SpacesBeforeTrailingComments: 1 -SpacesInAngles: false -SpacesInCStyleCastParentheses: false -SpacesInConditionalStatement: false -SpacesInContainerLiterals: true -SpacesInParentheses: false -SpacesInSquareBrackets: false - -# Includes -SortIncludes: false -IncludeBlocks: Preserve - -# Short forms -AllowAllArgumentsOnNextLine: true -AllowAllParametersOfDeclarationOnNextLine: true -AllowShortBlocksOnASingleLine: Always -AllowShortCaseLabelsOnASingleLine: false -AllowShortEnumsOnASingleLine: true -AllowShortFunctionsOnASingleLine: All -AllowShortIfStatementsOnASingleLine: Never -AllowShortLambdasOnASingleLine: All -AllowShortLoopsOnASingleLine: false - -# Other -BinPackArguments: true -BinPackParameters: true -BreakBeforeBinaryOperators: None -BreakBeforeTernaryOperators: true -BreakConstructorInitializers: BeforeColon -BreakStringLiterals: false -CompactNamespaces: false -DerivePointerAlignment: false -FixNamespaceComments: false -ReflowComments: false -SortUsingDeclarations: false - -# Penalties -PenaltyBreakAssignment: 2 -PenaltyBreakBeforeFirstCallParameter: 19 -PenaltyBreakComment: 300 -PenaltyBreakFirstLessLess: 120 -PenaltyBreakString: 1000 -PenaltyExcessCharacter: 1000000 -PenaltyReturnTypeOnItsOwnLine: 1000 - -# Lambda -LambdaBodyIndentation: Signature -... +BasedOnStyle: LLVM +--- diff --git a/benchmark/src/benchmarks.cpp b/benchmark/src/benchmarks.cpp index e8733fa4..286e4db3 100644 --- a/benchmark/src/benchmarks.cpp +++ b/benchmark/src/benchmarks.cpp @@ -4,649 +4,533 @@ namespace hj = hyperjet; -// f g0 g1 g2 h00 h01 h02 h11 h12 h22 -const hj::DDScalar<2, double, 3> dd1{3.0, 1.0, 6.0, 4.0, 0.0, 5.0, 9.0, 2.0, 7.0, 8.0}; -const hj::DDScalar<2, double, 3> dd2{4.0, 7.0, 1.0, 0.0, 6.0, 8.0, 2.0, 9.0, 5.0, 3.0}; -const hj::DDScalar<2, double, 3> dd3{0.3, 0.1, 0.8, 0.2, 0.5, 0.7, 0.9, 0.4, 0.6, 0.0}; - -#define HJ_BENCHMARK(method) \ - BENCHMARK_TEMPLATE(method, 1); \ - BENCHMARK_TEMPLATE(method, 2); \ - BENCHMARK_TEMPLATE(method, 4); \ - BENCHMARK_TEMPLATE(method, 8); \ - BENCHMARK_TEMPLATE(method, 16); \ - BENCHMARK_TEMPLATE(method, -1)->RangeMultiplier(2)->Range(1, 64); +// f g0 g1 g2 h00 h01 h02 h11 h12 +// h22 +const hj::DDScalar<2, double, 3> dd1{3.0, 1.0, 6.0, 4.0, 0.0, + 5.0, 9.0, 2.0, 7.0, 8.0}; +const hj::DDScalar<2, double, 3> dd2{4.0, 7.0, 1.0, 0.0, 6.0, + 8.0, 2.0, 9.0, 5.0, 3.0}; +const hj::DDScalar<2, double, 3> dd3{0.3, 0.1, 0.8, 0.2, 0.5, + 0.7, 0.9, 0.4, 0.6, 0.0}; + +#define HJ_BENCHMARK(method) \ + BENCHMARK_TEMPLATE(method, 1); \ + BENCHMARK_TEMPLATE(method, 2); \ + BENCHMARK_TEMPLATE(method, 4); \ + BENCHMARK_TEMPLATE(method, 8); \ + BENCHMARK_TEMPLATE(method, 16); \ + BENCHMARK_TEMPLATE(method, -1)->RangeMultiplier(2)->Range(1, 64); // add -template -static void add_dd_s(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - for (auto _ : state) - { - const auto r = dd1 + 3.5; - benchmark::DoNotOptimize(r); - } +template static void add_dd_s(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + for (auto _ : state) { + const auto r = dd1 + 3.5; + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(add_dd_s); -template -static void add_s_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - for (auto _ : state) - { - const auto r = 3.5 + dd1; - benchmark::DoNotOptimize(r); - } +template static void add_s_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + for (auto _ : state) { + const auto r = 3.5 + dd1; + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(add_s_dd); -template -static void add_dd_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - const auto dd2 = hj::DDScalar<2, double, TSize>::empty(s); - for (auto _ : state) - { - const auto r = dd1 + dd2; - benchmark::DoNotOptimize(r); - } +template static void add_dd_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + const auto dd2 = hj::DDScalar<2, double, TSize>::empty(s); + for (auto _ : state) { + const auto r = dd1 + dd2; + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(add_dd_dd); // sub -template -static void sub_dd_s(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - for (auto _ : state) - { - const auto r = dd1 - 3.5; - benchmark::DoNotOptimize(r); - } +template static void sub_dd_s(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + for (auto _ : state) { + const auto r = dd1 - 3.5; + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(sub_dd_s); -template -static void sub_s_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - for (auto _ : state) - { - const auto r = 3.5 - dd1; - benchmark::DoNotOptimize(r); - } +template static void sub_s_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + for (auto _ : state) { + const auto r = 3.5 - dd1; + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(sub_s_dd); -template -static void sub_dd_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - const auto dd2 = hj::DDScalar<2, double, TSize>::empty(s); - for (auto _ : state) - { - const auto r = dd1 - dd2; - benchmark::DoNotOptimize(r); - } +template static void sub_dd_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + const auto dd2 = hj::DDScalar<2, double, TSize>::empty(s); + for (auto _ : state) { + const auto r = dd1 - dd2; + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(sub_dd_dd); // mul -template -static void mul_dd_s(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - for (auto _ : state) - { - const auto r = dd1 * 3.5; - benchmark::DoNotOptimize(r); - } +template static void mul_dd_s(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + for (auto _ : state) { + const auto r = dd1 * 3.5; + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(mul_dd_s); -template -static void mul_s_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - for (auto _ : state) - { - const auto r = 3.5 * dd1; - benchmark::DoNotOptimize(r); - } +template static void mul_s_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + for (auto _ : state) { + const auto r = 3.5 * dd1; + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(mul_s_dd); -template -static void mul_dd_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - const auto dd2 = hj::DDScalar<2, double, TSize>::empty(s); - for (auto _ : state) - { - const auto r = dd1 * dd2; - benchmark::DoNotOptimize(r); - } +template static void mul_dd_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + const auto dd2 = hj::DDScalar<2, double, TSize>::empty(s); + for (auto _ : state) { + const auto r = dd1 * dd2; + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(mul_dd_dd); // div -template -static void div_dd_s(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - for (auto _ : state) - { - const auto r = dd1 / 3.5; - benchmark::DoNotOptimize(r); - } +template static void div_dd_s(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + for (auto _ : state) { + const auto r = dd1 / 3.5; + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(div_dd_s); -template -static void div_s_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - for (auto _ : state) - { - const auto r = 3.5 / dd1; - benchmark::DoNotOptimize(r); - } +template static void div_s_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + for (auto _ : state) { + const auto r = 3.5 / dd1; + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(div_s_dd); -template -static void div_dd_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - const auto dd2 = hj::DDScalar<2, double, TSize>::empty(s); - for (auto _ : state) - { - const auto r = dd1 / dd2; - benchmark::DoNotOptimize(r); - } +template static void div_dd_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + const auto dd2 = hj::DDScalar<2, double, TSize>::empty(s); + for (auto _ : state) { + const auto r = dd1 / dd2; + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(div_dd_dd); // iadd -template -static void iadd_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - const auto dd2 = hj::DDScalar<2, double, TSize>::empty(s); - auto r = dd1; - for (auto _ : state) - { - r += dd2; - benchmark::DoNotOptimize(r); - } +template static void iadd_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + const auto dd2 = hj::DDScalar<2, double, TSize>::empty(s); + auto r = dd1; + for (auto _ : state) { + r += dd2; + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(iadd_dd); // isub -template -static void isub_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - const auto dd2 = hj::DDScalar<2, double, TSize>::empty(s); - auto r = dd1; - for (auto _ : state) - { - r -= dd2; - benchmark::DoNotOptimize(r); - } +template static void isub_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + const auto dd2 = hj::DDScalar<2, double, TSize>::empty(s); + auto r = dd1; + for (auto _ : state) { + r -= dd2; + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(isub_dd); // imul -template -static void imul_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - const auto dd2 = hj::DDScalar<2, double, TSize>::empty(s); - auto r = dd1; - for (auto _ : state) - { - r *= dd2; - benchmark::DoNotOptimize(r); - } +template static void imul_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + const auto dd2 = hj::DDScalar<2, double, TSize>::empty(s); + auto r = dd1; + for (auto _ : state) { + r *= dd2; + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(imul_dd); // idiv -template -static void idiv_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - const auto dd2 = hj::DDScalar<2, double, TSize>::empty(s); - auto r = dd1; - for (auto _ : state) - { - r /= dd2; - benchmark::DoNotOptimize(r); - } +template static void idiv_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + const auto dd2 = hj::DDScalar<2, double, TSize>::empty(s); + auto r = dd1; + for (auto _ : state) { + r /= dd2; + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(idiv_dd); // abs -template -static void abs_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - using std::abs; - for (auto _ : state) - { - const auto r = abs(dd1); - benchmark::DoNotOptimize(r); - } +template static void abs_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + using std::abs; + for (auto _ : state) { + const auto r = abs(dd1); + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(abs_dd); // neg -template -static void neg_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - for (auto _ : state) - { - const auto r = -dd1; - benchmark::DoNotOptimize(r); - } +template static void neg_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + for (auto _ : state) { + const auto r = -dd1; + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(neg_dd); // pow -template -static void pow_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - using std::pow; - for (auto _ : state) - { - const auto r = pow(dd1, 3.5); - benchmark::DoNotOptimize(r); - } +template static void pow_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + using std::pow; + for (auto _ : state) { + const auto r = pow(dd1, 3.5); + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(pow_dd); // sqrt -template -static void sqrt_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - using std::sqrt; - for (auto _ : state) - { - const auto r = sqrt(dd1); - benchmark::DoNotOptimize(r); - } +template static void sqrt_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + using std::sqrt; + for (auto _ : state) { + const auto r = sqrt(dd1); + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(sqrt_dd); // cbrt -template -static void cbrt_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - using std::cbrt; - for (auto _ : state) - { - const auto r = cbrt(dd1); - benchmark::DoNotOptimize(r); - } +template static void cbrt_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + using std::cbrt; + for (auto _ : state) { + const auto r = cbrt(dd1); + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(cbrt_dd); // reciprocal -template -static void reciprocal_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - for (auto _ : state) - { - const auto r = dd1.reciprocal(); - benchmark::DoNotOptimize(r); - } +template static void reciprocal_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + for (auto _ : state) { + const auto r = dd1.reciprocal(); + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(reciprocal_dd); // cos -template -static void cos_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - using std::cos; - for (auto _ : state) - { - const auto r = cos(dd1); - benchmark::DoNotOptimize(r); - } +template static void cos_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + using std::cos; + for (auto _ : state) { + const auto r = cos(dd1); + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(cos_dd); // sin -template -static void sin_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - using std::sin; - for (auto _ : state) - { - const auto r = sin(dd1); - benchmark::DoNotOptimize(r); - } +template static void sin_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + using std::sin; + for (auto _ : state) { + const auto r = sin(dd1); + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(sin_dd); // tan -template -static void tan_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - using std::tan; - for (auto _ : state) - { - const auto r = tan(dd1); - benchmark::DoNotOptimize(r); - } +template static void tan_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + using std::tan; + for (auto _ : state) { + const auto r = tan(dd1); + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(tan_dd); // acos -template -static void acos_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - using std::acos; - using std::tan; - const auto a = acos(dd1); - for (auto _ : state) - { - const auto r = acos(a); - benchmark::DoNotOptimize(r); - } +template static void acos_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + using std::acos; + using std::tan; + const auto a = acos(dd1); + for (auto _ : state) { + const auto r = acos(a); + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(acos_dd); // asin -template -static void asin_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - using std::asin; - using std::tan; - const auto a = asin(dd1); - for (auto _ : state) - { - const auto r = asin(a); - benchmark::DoNotOptimize(r); - } +template static void asin_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + using std::asin; + using std::tan; + const auto a = asin(dd1); + for (auto _ : state) { + const auto r = asin(a); + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(asin_dd); // atan -template -static void atan_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - using std::atan; - using std::tan; - const auto a = atan(dd1); - for (auto _ : state) - { - const auto r = atan(a); - benchmark::DoNotOptimize(r); - } +template static void atan_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + using std::atan; + using std::tan; + const auto a = atan(dd1); + for (auto _ : state) { + const auto r = atan(a); + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(atan_dd); // atan2 -template -static void atan2_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - using std::atan2; - using std::cos; - using std::sin; - const auto a = cos(dd1); - const auto b = sin(dd1); - for (auto _ : state) - { - const auto r = atan2(b, a); - benchmark::DoNotOptimize(r); - } +template static void atan2_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + using std::atan2; + using std::cos; + using std::sin; + const auto a = cos(dd1); + const auto b = sin(dd1); + for (auto _ : state) { + const auto r = atan2(b, a); + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(atan2_dd); // cosh -template -static void cosh_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - using std::cosh; - for (auto _ : state) - { - const auto r = cosh(dd1); - benchmark::DoNotOptimize(r); - } +template static void cosh_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + using std::cosh; + for (auto _ : state) { + const auto r = cosh(dd1); + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(cosh_dd); // sinh -template -static void sinh_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - using std::sinh; - for (auto _ : state) - { - const auto r = sinh(dd1); - benchmark::DoNotOptimize(r); - } +template static void sinh_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + using std::sinh; + for (auto _ : state) { + const auto r = sinh(dd1); + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(sinh_dd); // tanh -template -static void tanh_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - using std::tanh; - for (auto _ : state) - { - const auto r = tanh(dd1); - benchmark::DoNotOptimize(r); - } +template static void tanh_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + using std::tanh; + for (auto _ : state) { + const auto r = tanh(dd1); + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(tanh_dd); // cosh -template -static void acosh_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - using std::acosh; - using std::cosh; - const auto a = cosh(dd1); - for (auto _ : state) - { - const auto r = acosh(a); - benchmark::DoNotOptimize(r); - } +template static void acosh_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + using std::acosh; + using std::cosh; + const auto a = cosh(dd1); + for (auto _ : state) { + const auto r = acosh(a); + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(acosh_dd); // sinh -template -static void asinh_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - using std::asinh; - using std::sinh; - const auto a = sinh(dd1); - for (auto _ : state) - { - const auto r = asinh(a); - benchmark::DoNotOptimize(r); - } +template static void asinh_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + using std::asinh; + using std::sinh; + const auto a = sinh(dd1); + for (auto _ : state) { + const auto r = asinh(a); + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(asinh_dd); // tanh -template -static void atanh_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - using std::atanh; - using std::tanh; - const auto a = tanh(dd1); - for (auto _ : state) - { - const auto r = atanh(a); - benchmark::DoNotOptimize(r); - } +template static void atanh_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + using std::atanh; + using std::tanh; + const auto a = tanh(dd1); + for (auto _ : state) { + const auto r = atanh(a); + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(atanh_dd); // exp -template -static void exp_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - using std::exp; - for (auto _ : state) - { - const auto r = exp(dd1); - benchmark::DoNotOptimize(r); - } +template static void exp_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + using std::exp; + for (auto _ : state) { + const auto r = exp(dd1); + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(exp_dd); // log -template -static void log_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - using std::log; - for (auto _ : state) - { - const auto r = log(dd1); - benchmark::DoNotOptimize(r); - } +template static void log_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + using std::log; + for (auto _ : state) { + const auto r = log(dd1); + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(log_dd); // log2 -template -static void log2_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - using std::log2; - for (auto _ : state) - { - const auto r = log2(dd1); - benchmark::DoNotOptimize(r); - } +template static void log2_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + using std::log2; + for (auto _ : state) { + const auto r = log2(dd1); + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(log2_dd); // log10 -template -static void log10_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - using std::log10; - for (auto _ : state) - { - const auto r = log10(dd1); - benchmark::DoNotOptimize(r); - } +template static void log10_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + using std::log10; + for (auto _ : state) { + const auto r = log10(dd1); + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(log10_dd); // logn -template -static void logn_dd(benchmark::State &state) -{ - const hj::index s = TSize < 0 ? state.range(0) : TSize; - const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); - for (auto _ : state) - { - const auto r = dd1.log(3.5); - benchmark::DoNotOptimize(r); - } +template static void logn_dd(benchmark::State &state) { + const hj::index s = TSize < 0 ? state.range(0) : TSize; + const auto dd1 = hj::DDScalar<2, double, TSize>::empty(s); + for (auto _ : state) { + const auto r = dd1.log(3.5); + benchmark::DoNotOptimize(r); + } } HJ_BENCHMARK(logn_dd); diff --git a/include/hyperjet/hyperjet.h b/include/hyperjet/hyperjet.h index 15b6b109..9c71916a 100644 --- a/include/hyperjet/hyperjet.h +++ b/include/hyperjet/hyperjet.h @@ -1,19 +1,18 @@ #pragma once -#include // array -#include // assert -#include // acos, acosh, asin, asinh, atan, atanh, atan2, cbrt, cos, cosh, exp, hypot, log, log2, log10, pow, sin, sinh, sqrt, tan, tanh +#include // array +#include // assert +#include // acos, acosh, asin, asinh, atan, atanh, atan2, cbrt, cos, cosh, exp, hypot, log, log2, log10, pow, sin, sinh, sqrt, tan, tanh #include // ptrdiff_t #include // initializer_list #include // ostream #include // stringstream #include // string #include // conditional -#include // vector #include // unordered_map +#include // vector -namespace hyperjet -{ +namespace hyperjet { #if defined(_MSC_VER) #define HYPERJET_INLINE __forceinline @@ -21,2918 +20,2442 @@ namespace hyperjet #define HYPERJET_INLINE __attribute__((always_inline)) inline #endif - using index = std::ptrdiff_t; +using index = std::ptrdiff_t; - const index Dynamic = -1; +const index Dynamic = -1; - template - HYPERJET_INLINE index length(const T &container) - { - return static_cast(container.size()); - } +template HYPERJET_INLINE index length(const T &container) { + return static_cast(container.size()); +} - HYPERJET_INLINE constexpr bool throw_exceptions() - { +HYPERJET_INLINE constexpr bool throw_exceptions() { #if defined(HYPERJET_NO_EXCEPTIONS) - return false; + return false; #else - return true; + return true; #endif +} + +template +class DDScalar { + static constexpr index StaticDataSize = + TOrder == 1 ? 1 + TSize : (TSize + 1) * (TSize + 2) / 2; + static constexpr index DataSize = TSize < 0 ? Dynamic : StaticDataSize; + + using DynamicStorage = std::vector; + using StaticStorage = std::array; + +public: + using Type = DDScalar; + using Scalar = TScalar; + using Data = typename std::conditional::type; + + index m_size; + Data m_data; + +public: + HYPERJET_INLINE static index data_length_from_size(const index size) { + return TOrder == 1 ? 1 + size : (size + 1) * (size + 2) / 2; + } + + HYPERJET_INLINE static index size_from_data_length(const index n) { + const index s = + TOrder == 1 ? n - 1 : static_cast(std::sqrt(1 + 8 * n) - 3) / 2; + + if constexpr (throw_exceptions()) { + if (s < 0 || data_length_from_size(s) != n) { + throw std::runtime_error("Invalid length"); + } + } else { + assert(s >= 0 && data_length_from_size(s) == n && "Invalid length"); } - template - class DDScalar - { - static constexpr index StaticDataSize = TOrder == 1 ? 1 + TSize : (TSize + 1) * (TSize + 2) / 2; - static constexpr index DataSize = TSize < 0 ? Dynamic : StaticDataSize; + return s; + } + +private: + HYPERJET_INLINE static void check_valid_size(const index size) { + if constexpr (TSize == Dynamic) { + if constexpr (throw_exceptions()) { + if (size < 0) { + throw std::runtime_error("Negative size"); + } + } else { + assert(size >= 0 && "Negative size"); + } + } else { + if constexpr (throw_exceptions()) { + if (size != TSize) { + throw std::runtime_error("Invalid size"); + } + } else { + assert(size == TSize && "Invalid size"); + } + } + } + + HYPERJET_INLINE static void check_equal_size(const index size_a, + const index size_b) { + if constexpr (TSize == Dynamic) { + if constexpr (throw_exceptions()) { + if (size_a != size_b) { + throw std::runtime_error("Incompatible size"); + } + } else { + assert(size_a == size_b && "Incompatible size"); + } + } + } - using DynamicStorage = std::vector; - using StaticStorage = std::array; + struct Zero { + HYPERJET_INLINE Zero operator*(const Scalar) const { return Zero(); } - public: - using Type = DDScalar; - using Scalar = TScalar; - using Data = typename std::conditional::type; + template HYPERJET_INLINE T operator+(const T b) const { + return b; + } - index m_size; - Data m_data; + template + HYPERJET_INLINE friend T operator+(const T a, const Zero) { + return a; + } + }; - public: - HYPERJET_INLINE static index data_length_from_size(const index size) - { - return TOrder == 1 ? 1 + size : (size + 1) * (size + 2) / 2; - } + struct MinusOne { + HYPERJET_INLINE Scalar operator*(const Scalar b) const { return -b; } + }; - HYPERJET_INLINE static index size_from_data_length(const index n) - { - const index s = TOrder == 1 ? n - 1 : static_cast(std::sqrt(1 + 8 * n) - 3) / 2; - - if constexpr (throw_exceptions()) - { - if (s < 0 || data_length_from_size(s) != n) - { - throw std::runtime_error("Invalid length"); - } - } - else - { - assert(s >= 0 && data_length_from_size(s) == n && "Invalid length"); - } - - return s; - } + struct One { + HYPERJET_INLINE MinusOne operator-() const { return MinusOne(); } - private: - HYPERJET_INLINE static void check_valid_size(const index size) - { - if constexpr (TSize == Dynamic) - { - if constexpr (throw_exceptions()) - { - if (size < 0) - { - throw std::runtime_error("Negative size"); - } - } - else - { - assert(size >= 0 && "Negative size"); - } - } - else - { - if constexpr (throw_exceptions()) - { - if (size != TSize) - { - throw std::runtime_error("Invalid size"); - } - } - else - { - assert(size == TSize && "Invalid size"); - } - } - } + HYPERJET_INLINE Scalar operator*(const Scalar b) const { return b; } + }; - HYPERJET_INLINE static void check_equal_size(const index size_a, const index size_b) - { - if constexpr (TSize == Dynamic) - { - if constexpr (throw_exceptions()) - { - if (size_a != size_b) - { - throw std::runtime_error("Incompatible size"); - } - } - else - { - assert(size_a == size_b && "Incompatible size"); - } - } - } + template + HYPERJET_INLINE void unary(const Data &a, const Scalar f, const TDa da, + const TDaa daa, Data &r) const noexcept { + const index n = data_length(); - struct Zero - { - HYPERJET_INLINE Zero operator*(const Scalar) const - { - return Zero(); - } - - template - HYPERJET_INLINE T operator+(const T b) const - { - return b; - } - - template - HYPERJET_INLINE friend T operator+(const T a, const Zero) - { - return a; - } - }; - - struct MinusOne - { - HYPERJET_INLINE Scalar operator*(const Scalar b) const - { - return -b; - } - }; - - struct One - { - HYPERJET_INLINE MinusOne operator-() const - { - return MinusOne(); - } - - HYPERJET_INLINE Scalar operator*(const Scalar b) const - { - return b; - } - }; - - template - HYPERJET_INLINE void unary(const Data &a, const Scalar f, const TDa da, const TDaa daa, Data &r) const noexcept - { - const index n = data_length(); - - r[0] = f; - - if constexpr (TOrder < 1 || std::is_same()) - { - return; - } - - for (index i = 1; i < n; i++) - { - if constexpr (TIncrement) - { - r[i] += da * a[i]; - } - else - { - r[i] = da * a[i]; - } - } - - if constexpr (TOrder < 2 || std::is_same()) - { - return; - } - - index k = 1 + size(); - - for (index i = 0; i < size(); i++) - { - const auto ca = daa * a[1 + i]; - - for (index j = i; j < size(); j++) - { - r[k++] += ca * a[1 + j]; - } - } - } + r[0] = f; - template - HYPERJET_INLINE void binary(const Data &a, const Data &b, const Scalar f, const TDa da, const TDb db, const TDaa daa, const TDab dab, const TDbb dbb, Data &r) const noexcept - { - const index n = data_length(); - - r[0] = f; - - if constexpr (TOrder < 1 || (std::is_same_v && std::is_same_v)) - { - return; - } - else - { - for (index i = 1; i < n; i++) - { - if constexpr (TIncrement) - { - r[i] += da * a[i] + db * b[i]; - } - else - { - r[i] = da * a[i] + db * b[i]; - } - } - } - - if constexpr (TOrder < 2 || (std::is_same_v && std::is_same_v && std::is_same_v)) - { - return; - } - else - { - index k = 1 + size(); - - for (index i = 0; i < size(); i++) - { - const auto ca = daa * a[1 + i] + dab * b[1 + i]; - const auto cb = dab * a[1 + i] + dbb * b[1 + i]; - - for (index j = i; j < size(); j++) - { - r[k++] += ca * a[1 + j] + cb * b[1 + j]; - } - } - } - } + if constexpr (TOrder < 1 || std::is_same()) { + return; + } - template - HYPERJET_INLINE void ternary(const Data &a, const Data &b, const Data &c, const Scalar f, const TDa da, const TDb db, const TDc dc, const TDaa daa, const TDab dab, const TDac dac, const TDbb dbb, const TDbc dbc, const TDcc dcc, Data &r) const noexcept - { - const index n = data_length(); - - r[0] = f; - - if constexpr (TOrder < 1 || (std::is_same_v && std::is_same_v && std::is_same_v)) - { - return; - } - else - { - for (index i = 1; i < n; i++) - { - if constexpr (TIncrement) - { - r[i] += da * a[i] + db * b[i] + dc * c[i]; - } - else - { - r[i] = da * a[i] + db * b[i] + dc * c[i]; - } - } - } - - if constexpr (TOrder < 2 || (std::is_same_v && std::is_same_v && std::is_same_v && std::is_same_v && std::is_same_v && std::is_same_v)) - { - return; - } - else - { - index k = 1 + size(); - - for (index i = 0; i < size(); i++) - { - const auto ca = daa * a[1 + i] + dab * b[1 + i] + dac * c[1 + i]; - const auto cb = dab * a[1 + i] + dbb * b[1 + i] + dbc * c[1 + i]; - const auto cc = dac * a[1 + i] + dbc * b[1 + i] + dcc * c[1 + i]; - - for (index j = i; j < size(); j++) - { - r[k++] += ca * a[1 + j] + cb * b[1 + j] + cc * c[1 + j]; - } - } - } - } + for (index i = 1; i < n; i++) { + if constexpr (TIncrement) { + r[i] += da * a[i]; + } else { + r[i] = da * a[i]; + } + } - public: - DDScalar() - { - static_assert(0 < order() && order() <= 2); - - if constexpr (is_dynamic()) - { - m_size = 1; - m_data = Data(1); - } - else - { - static_assert(TSize >= 0); - } - } + if constexpr (TOrder < 2 || std::is_same()) { + return; + } - DDScalar(const TScalar f) - { - static_assert(0 < order() && order() <= 2); - - if constexpr (is_dynamic()) - { - m_size = 1; - m_data = Data(1); - } - else - { - static_assert(TSize >= 0); - } - this->f() = f; - std::fill(m_data.begin() + 1, m_data.end(), 0); - } + index k = 1 + size(); - DDScalar(const Data &data) : m_data(data) - { - static_assert(0 < order() && order() <= 2); + for (index i = 0; i < size(); i++) { + const auto ca = daa * a[1 + i]; - static_assert(!is_dynamic()); - } + for (index j = i; j < size(); j++) { + r[k++] += ca * a[1 + j]; + } + } + } + + template + HYPERJET_INLINE void binary(const Data &a, const Data &b, const Scalar f, + const TDa da, const TDb db, const TDaa daa, + const TDab dab, const TDbb dbb, + Data &r) const noexcept { + const index n = data_length(); + + r[0] = f; + + if constexpr (TOrder < 1 || + (std::is_same_v && std::is_same_v)) { + return; + } else { + for (index i = 1; i < n; i++) { + if constexpr (TIncrement) { + r[i] += da * a[i] + db * b[i]; + } else { + r[i] = da * a[i] + db * b[i]; + } + } + } - DDScalar(const Data &data, const index size) : m_data(data), m_size(size) - { - static_assert(0 < order() && order() <= 2); + if constexpr (TOrder < 2 || + (std::is_same_v && std::is_same_v && + std::is_same_v)) { + return; + } else { + index k = 1 + size(); - static_assert(is_dynamic()); + for (index i = 0; i < size(); i++) { + const auto ca = daa * a[1 + i] + dab * b[1 + i]; + const auto cb = dab * a[1 + i] + dbb * b[1 + i]; + + for (index j = i; j < size(); j++) { + r[k++] += ca * a[1 + j] + cb * b[1 + j]; } + } + } + } + + template + HYPERJET_INLINE void ternary(const Data &a, const Data &b, const Data &c, + const Scalar f, const TDa da, const TDb db, + const TDc dc, const TDaa daa, const TDab dab, + const TDac dac, const TDbb dbb, const TDbc dbc, + const TDcc dcc, Data &r) const noexcept { + const index n = data_length(); + + r[0] = f; + + if constexpr (TOrder < 1 || + (std::is_same_v && std::is_same_v && + std::is_same_v)) { + return; + } else { + for (index i = 1; i < n; i++) { + if constexpr (TIncrement) { + r[i] += da * a[i] + db * b[i] + dc * c[i]; + } else { + r[i] = da * a[i] + db * b[i] + dc * c[i]; + } + } + } - DDScalar(std::initializer_list data) : m_size(size_from_data_length(length(data))) - { - static_assert(0 < order() && order() <= 2); + if constexpr (TOrder < 2 || + (std::is_same_v && std::is_same_v && + std::is_same_v && std::is_same_v && + std::is_same_v && std::is_same_v)) { + return; + } else { + index k = 1 + size(); - std::copy(data.begin(), data.end(), m_data.begin()); - } + for (index i = 0; i < size(); i++) { + const auto ca = daa * a[1 + i] + dab * b[1 + i] + dac * c[1 + i]; + const auto cb = dab * a[1 + i] + dbb * b[1 + i] + dbc * c[1 + i]; + const auto cc = dac * a[1 + i] + dbc * b[1 + i] + dcc * c[1 + i]; - static constexpr index order() - { - return TOrder; + for (index j = i; j < size(); j++) { + r[k++] += ca * a[1 + j] + cb * b[1 + j] + cc * c[1 + j]; } + } + } + } - Data &data() - { - return m_data; - } +public: + DDScalar() { + static_assert(0 < order() && order() <= 2); - Scalar const *ptr() const - { - return m_data.data(); - } + if constexpr (is_dynamic()) { + m_size = 1; + m_data = Data(1); + } else { + static_assert(TSize >= 0); + } + } - Scalar *ptr() - { - return m_data.data(); - } + DDScalar(const TScalar f) { + static_assert(0 < order() && order() <= 2); - const Data &data() const - { - return m_data; - } + if constexpr (is_dynamic()) { + m_size = 1; + m_data = Data(1); + } else { + static_assert(TSize >= 0); + } + this->f() = f; + std::fill(m_data.begin() + 1, m_data.end(), 0); + } - static constexpr index static_size() - { - return TSize; - } + DDScalar(const Data &data) : m_data(data) { + static_assert(0 < order() && order() <= 2); - constexpr index size() const - { - if constexpr (is_dynamic()) - { - return m_size; - } - else - { - return TSize; - } - } + static_assert(!is_dynamic()); + } - constexpr index data_length() const - { - if constexpr (is_dynamic()) - { - return length(m_data); - } - else - { - return StaticDataSize; - } - } + DDScalar(const Data &data, const index size) : m_data(data), m_size(size) { + static_assert(0 < order() && order() <= 2); - void resize(const index size) - { - static_assert(is_dynamic()); - m_size = size; - const index n = data_length_from_size(size); - m_data.resize(n); - } + static_assert(is_dynamic()); + } - Type pad_left(const index new_size) const - { - static_assert(is_dynamic()); + DDScalar(std::initializer_list data) + : m_size(size_from_data_length(length(data))) { + static_assert(0 < order() && order() <= 2); - Type result = empty(new_size); + std::copy(data.begin(), data.end(), m_data.begin()); + } - const index head = new_size - size(); + static constexpr index order() { return TOrder; } - auto source = m_data.cbegin(); - auto target = result.m_data.begin(); + Data &data() { return m_data; } - *target++ = *source++; + Scalar const *ptr() const { return m_data.data(); } - for (index i = 0; i < head; i++) - { - *target++ = Scalar(0); - } + Scalar *ptr() { return m_data.data(); } - for (index i = 0; i < size(); i++) - { - *target++ = *source++; - } + const Data &data() const { return m_data; } - if constexpr (order() == 1) - { - return result; - } + static constexpr index static_size() { return TSize; } - for (index i = 0; i < head; i++) - { - for (index j = i; j < new_size; j++) - { - *target++ = Scalar(0); - } - } + constexpr index size() const { + if constexpr (is_dynamic()) { + return m_size; + } else { + return TSize; + } + } - for (index i = 0; i < size(); i++) - { - for (index j = i; j < size(); j++) - { - *target++ = *source++; - } - } + constexpr index data_length() const { + if constexpr (is_dynamic()) { + return length(m_data); + } else { + return StaticDataSize; + } + } - return result; - } + void resize(const index size) { + static_assert(is_dynamic()); + m_size = size; + const index n = data_length_from_size(size); + m_data.resize(n); + } - Type pad_right(const index new_size) const - { - static_assert(is_dynamic()); - - Type result = empty(new_size); - - const index tail = new_size - size(); - - auto source = m_data.cbegin(); - auto target = result.m_data.begin(); - - for (index i = 0; i < size() + 1; i++) - { - *target++ = *source++; - } - - for (index i = 0; i < tail; i++) - { - *target++ = Scalar(0); - } - - if (order() == 1) - { - return result; - } - - for (index i = 0; i < size(); i++) - { - for (index j = i; j < size(); j++) - { - *target++ = *source++; - } - - for (index j = 0; j < tail; j++) - { - *target++ = Scalar(0); - } - } - - for (index i = 0; i < tail; i++) - { - for (index j = i; j < tail; j++) - { - *target++ = Scalar(0); - } - } - - return result; - } + Type pad_left(const index new_size) const { + static_assert(is_dynamic()); - static constexpr bool is_dynamic() - { - return TSize == Dynamic; - } + Type result = empty(new_size); - static Type create(const Data &data) - { - if constexpr (is_dynamic()) - { - const auto s = size_from_data_length(length(data)); - Type result(data, s); - return result; - } - else - { - const auto s = size_from_data_length(length(data)); - check_valid_size(s); - Type result(data); - return result; - } - } + const index head = new_size - size(); - static Type empty() - { - if constexpr (is_dynamic()) - { - Data data(1); - Type result(data, 0); - return result; - } - else - { - Data data; - Type result(data); - return result; - } - } + auto source = m_data.cbegin(); + auto target = result.m_data.begin(); - static Type empty(const index size) - { - if constexpr (is_dynamic()) - { - const index n = data_length_from_size(size); - const Data data(n); - Type result(data, size); - return result; - } - else - { - check_valid_size(size); - return empty(); - } - } + *target++ = *source++; - static Type zero() - { - if constexpr (is_dynamic()) - { - Data data(1); - Type result(data, 0); - return result; - } - else - { - Data data; - data.fill(0); - Type result(data); - return result; - } - } + for (index i = 0; i < head; i++) { + *target++ = Scalar(0); + } - static Type zero(const index size) - { - if constexpr (is_dynamic()) - { - const Data data(data_length_from_size(size), 0); - Type result(data, size); - return result; - } - else - { - check_valid_size(size); - return zero(); - } - } + for (index i = 0; i < size(); i++) { + *target++ = *source++; + } - static Type constant(const Scalar f) - { - Type result = zero(); - result.f() = f; - return result; - } + if constexpr (order() == 1) { + return result; + } - static Type constant(const Scalar f, const index size) - { - if constexpr (is_dynamic()) - { - Type result = zero(size); - result.f() = f; - return result; - } - else - { - check_valid_size(size); - return constant(f); - } - } + for (index i = 0; i < head; i++) { + for (index j = i; j < new_size; j++) { + *target++ = Scalar(0); + } + } - static Type variable(const index i, const Scalar f) - { - static_assert(!is_dynamic()); - Type result = zero(); - result.f() = f; - result.g(i) = 1; - return result; - } + for (index i = 0; i < size(); i++) { + for (index j = i; j < size(); j++) { + *target++ = *source++; + } + } - static Type variable(const index i, const Scalar f, const index size) - { - if constexpr (is_dynamic()) - { - Type result = zero(size); - result.f() = f; - result.g(i) = 1; - return result; - } - else - { - check_valid_size(size); - return variable(i, f); - } - } + return result; + } - static std::vector variables(const std::vector &values) - { - const index s = length(values); - - if constexpr (!is_dynamic()) - { - assert(s == TSize); - } - - std::vector vars(s); - for (index i = 0; i < s; i++) - { - vars[i] = variable(i, values[i], s); - } - return vars; - } + Type pad_right(const index new_size) const { + static_assert(is_dynamic()); - template - static std::conditional_t, std::array> variables(const std::array &values) - { - if constexpr (!is_dynamic()) - { - static_assert(T == TSize); - } - - const index s = length(values); - - if constexpr (is_dynamic()) - { - std::vector vars(s); - for (index i = 0; i < s; i++) - { - vars[i] = variable(i, values[i], s); - } - return vars; - } - else - { - std::array vars; - for (index i = 0; i < s; i++) - { - vars[i] = variable(i, values[i], s); - } - return vars; - } - } + Type result = empty(new_size); - Scalar &f() - { - return m_data[0]; - } + const index tail = new_size - size(); - Scalar f() const - { - return m_data[0]; - } + auto source = m_data.cbegin(); + auto target = result.m_data.begin(); - void set_f(const Scalar value) - { - m_data[0] = value; - } + for (index i = 0; i < size() + 1; i++) { + *target++ = *source++; + } - Scalar &g(const index i) - { - assert(i < size()); + for (index i = 0; i < tail; i++) { + *target++ = Scalar(0); + } - return m_data[1 + i]; - } + if (order() == 1) { + return result; + } - Scalar g(const index i) const - { - assert(0 <= i && i < size()); + for (index i = 0; i < size(); i++) { + for (index j = i; j < size(); j++) { + *target++ = *source++; + } - return m_data[1 + i]; - } + for (index j = 0; j < tail; j++) { + *target++ = Scalar(0); + } + } - void set_g(const index i, const Scalar value) - { - g(i) = value; - } + for (index i = 0; i < tail; i++) { + for (index j = i; j < tail; j++) { + *target++ = Scalar(0); + } + } - Scalar &h(const index i) - { - assert(0 <= i && i < size() * (size() + 1) / 2); + return result; + } + + static constexpr bool is_dynamic() { return TSize == Dynamic; } + + static Type create(const Data &data) { + if constexpr (is_dynamic()) { + const auto s = size_from_data_length(length(data)); + Type result(data, s); + return result; + } else { + const auto s = size_from_data_length(length(data)); + check_valid_size(s); + Type result(data); + return result; + } + } + + static Type empty() { + if constexpr (is_dynamic()) { + Data data(1); + Type result(data, 0); + return result; + } else { + Data data; + Type result(data); + return result; + } + } + + static Type empty(const index size) { + if constexpr (is_dynamic()) { + const index n = data_length_from_size(size); + const Data data(n); + Type result(data, size); + return result; + } else { + check_valid_size(size); + return empty(); + } + } + + static Type zero() { + if constexpr (is_dynamic()) { + Data data(1); + Type result(data, 0); + return result; + } else { + Data data; + data.fill(0); + Type result(data); + return result; + } + } + + static Type zero(const index size) { + if constexpr (is_dynamic()) { + const Data data(data_length_from_size(size), 0); + Type result(data, size); + return result; + } else { + check_valid_size(size); + return zero(); + } + } + + static Type constant(const Scalar f) { + Type result = zero(); + result.f() = f; + return result; + } + + static Type constant(const Scalar f, const index size) { + if constexpr (is_dynamic()) { + Type result = zero(size); + result.f() = f; + return result; + } else { + check_valid_size(size); + return constant(f); + } + } + + static Type variable(const index i, const Scalar f) { + static_assert(!is_dynamic()); + Type result = zero(); + result.f() = f; + result.g(i) = 1; + return result; + } + + static Type variable(const index i, const Scalar f, const index size) { + if constexpr (is_dynamic()) { + Type result = zero(size); + result.f() = f; + result.g(i) = 1; + return result; + } else { + check_valid_size(size); + return variable(i, f); + } + } - return m_data[1 + size() + i]; - } + static std::vector variables(const std::vector &values) { + const index s = length(values); - Scalar h(const index i) const - { - assert(0 <= i && i < size() * (size() + 1) / 2); + if constexpr (!is_dynamic()) { + assert(s == TSize); + } - return m_data[1 + size() + i]; - } + std::vector vars(s); + for (index i = 0; i < s; i++) { + vars[i] = variable(i, values[i], s); + } + return vars; + } + + template + static std::conditional_t, + std::array> + variables(const std::array &values) { + if constexpr (!is_dynamic()) { + static_assert(T == TSize); + } - void set_h(const index i, const Scalar value) - { - h(i) = value; - } + const index s = length(values); + + if constexpr (is_dynamic()) { + std::vector vars(s); + for (index i = 0; i < s; i++) { + vars[i] = variable(i, values[i], s); + } + return vars; + } else { + std::array vars; + for (index i = 0; i < s; i++) { + vars[i] = variable(i, values[i], s); + } + return vars; + } + } - Scalar &h(const index i, const index j) - { - assert(0 <= i && i < size()); - assert(0 <= j && j < size()); - - if (i < j) - { - return m_data[1 + size() + (2 * size() - 1 - i) * i / 2 + j]; - } - else - { - return m_data[1 + size() + (2 * size() - 1 - j) * j / 2 + i]; - } - } + Scalar &f() { return m_data[0]; } - Scalar h(const index i, const index j) const - { - assert(0 <= i && i < size()); - assert(0 <= j && j < size()); - - if (i < j) - { - return m_data[1 + size() + (2 * size() - 1 - i) * i / 2 + j]; - } - else - { - return m_data[1 + size() + (2 * size() - 1 - j) * j / 2 + i]; - } - } + Scalar f() const { return m_data[0]; } - void set_h(const index i, const index j, const Scalar value) - { - h(i, j) = value; - } + void set_f(const Scalar value) { m_data[0] = value; } + + Scalar &g(const index i) { + assert(i < size()); + + return m_data[1 + i]; + } + + Scalar g(const index i) const { + assert(0 <= i && i < size()); + + return m_data[1 + i]; + } + + void set_g(const index i, const Scalar value) { g(i) = value; } + + Scalar &h(const index i) { + assert(0 <= i && i < size() * (size() + 1) / 2); + + return m_data[1 + size() + i]; + } + + Scalar h(const index i) const { + assert(0 <= i && i < size() * (size() + 1) / 2); + + return m_data[1 + size() + i]; + } + + void set_h(const index i, const Scalar value) { h(i) = value; } + + Scalar &h(const index i, const index j) { + assert(0 <= i && i < size()); + assert(0 <= j && j < size()); + + if (i < j) { + return m_data[1 + size() + (2 * size() - 1 - i) * i / 2 + j]; + } else { + return m_data[1 + size() + (2 * size() - 1 - j) * j / 2 + i]; + } + } + + Scalar h(const index i, const index j) const { + assert(0 <= i && i < size()); + assert(0 <= j && j < size()); + + if (i < j) { + return m_data[1 + size() + (2 * size() - 1 - i) * i / 2 + j]; + } else { + return m_data[1 + size() + (2 * size() - 1 - j) * j / 2 + i]; + } + } + + void set_h(const index i, const index j, const Scalar value) { + h(i, j) = value; + } #if defined EIGEN_WORLD_VERSION - using Vector = Eigen::Matrix; - using Matrix = Eigen::Matrix; - using DataVector = Eigen::Matrix; + using Vector = Eigen::Matrix; + using Matrix = Eigen::Matrix; + using DataVector = Eigen::Matrix; - Eigen::Ref ag() const - { - return Eigen::Map(ptr() + 1, size()); - } + Eigen::Ref ag() const { + return Eigen::Map(ptr() + 1, size()); + } - Eigen::Ref ag() - { - return Eigen::Map(ptr() + 1, size()); - } + Eigen::Ref ag() { return Eigen::Map(ptr() + 1, size()); } - Matrix hm(const std::string mode) const - { - Matrix result(size(), size()); + Matrix hm(const std::string mode) const { + Matrix result(size(), size()); - hm(mode, result); + hm(mode, result); - return result; - } + return result; + } - void hm(const std::string mode, Eigen::Ref out) const - { - index it = 0; - - for (index i = 0; i < size(); i++) - { - for (index j = i; j < size(); j++) - { - out(i, j) = h(it++); - } - } - - if (mode == "zeros") - { - for (index i = 0; i < size(); i++) - { - for (index j = 0; j < i; j++) - { - out(i, j) = 0; - } - } - } - else if (mode == "full") - { - for (index i = 0; i < size(); i++) - { - for (index j = 0; j < i; j++) - { - out(i, j) = out(j, i); - } - } - } - else - { - throw std::runtime_error("Invalid value for 'mode'"); - } - } + void hm(const std::string mode, Eigen::Ref out) const { + index it = 0; - void set_hm(const Eigen::Ref &value) - { - index it = 0; - - for (index i = 0; i < size(); i++) - { - for (index j = i; j < size(); j++) - { - h(it++) = value(i, j); - } - } - } + for (index i = 0; i < size(); i++) { + for (index j = i; j < size(); j++) { + out(i, j) = h(it++); + } + } - Eigen::Ref adata() - { - return Eigen::Map(ptr(), length(m_data)); + if (mode == "zeros") { + for (index i = 0; i < size(); i++) { + for (index j = 0; j < i; j++) { + out(i, j) = 0; } - - void set_adata(const Eigen::Ref value) - { - Eigen::Map(ptr(), length(m_data)) = value; + } + } else if (mode == "full") { + for (index i = 0; i < size(); i++) { + for (index j = 0; j < i; j++) { + out(i, j) = out(j, i); } + } + } else { + throw std::runtime_error("Invalid value for 'mode'"); + } + } - static Type from_gradient(const TScalar f, const Eigen::Ref &g) - { - static_assert(order() == 1); + void set_hm(const Eigen::Ref &value) { + index it = 0; - Type result = empty(length(g)); + for (index i = 0; i < size(); i++) { + for (index j = i; j < size(); j++) { + h(it++) = value(i, j); + } + } + } - result.f() = f; - result.ag() = g; + Eigen::Ref adata() { + return Eigen::Map(ptr(), length(m_data)); + } - return result; - } + void set_adata(const Eigen::Ref value) { + Eigen::Map(ptr(), length(m_data)) = value; + } - static Type from_arrays(const TScalar f, const Eigen::Ref &g, const Eigen::Ref &hm) - { - static_assert(order() == 2); + static Type from_gradient(const TScalar f, + const Eigen::Ref &g) { + static_assert(order() == 1); - assert(g.size() == hm.rows() && g.size() == hm.cols()); + Type result = empty(length(g)); - Type result = empty(length(g)); + result.f() = f; + result.ag() = g; - result.f() = f; - result.ag() = g; - result.set_hm(hm); + return result; + } - return result; - } + static Type from_arrays(const TScalar f, const Eigen::Ref &g, + const Eigen::Ref &hm) { + static_assert(order() == 2); - Scalar eval(typename std::conditional < TSize == Dynamic, std::vector, std::array>::type d) const - { - Scalar result = f(); + assert(g.size() == hm.rows() && g.size() == hm.cols()); - for (index i = 0; i < size(); i++) - { - result += d[i] * g(i); - } + Type result = empty(length(g)); - if constexpr (order() == 1) - { - return result; - } + result.f() = f; + result.ag() = g; + result.set_hm(hm); - Scalar t(0); + return result; + } - for (index i = 0; i < size(); i++) - { - Scalar s(0); + Scalar eval(typename std::conditional < TSize == Dynamic, std::vector, + std::array>::type d) const { + Scalar result = f(); - index k = 1 + size() + i; + for (index i = 0; i < size(); i++) { + result += d[i] * g(i); + } - for (index j = 0; j < i; j++) - { - s += d[j] * m_data[k]; - k += size() - j - 1; - } + if constexpr (order() == 1) { + return result; + } - for (index j = i; j < size(); j++) - { - s += d[j] * m_data[k++]; - } + Scalar t(0); - t += d[i] * s; - } + for (index i = 0; i < size(); i++) { + Scalar s(0); - result += 0.5 * t; + index k = 1 + size() + i; - return result; - } + for (index j = 0; j < i; j++) { + s += d[j] * m_data[k]; + k += size() - j - 1; + } + + for (index j = i; j < size(); j++) { + s += d[j] * m_data[k++]; + } + + t += d[i] * s; + } + + result += 0.5 * t; + + return result; + } #endif - void set_zero() - { - std::fill(m_data.begin(), m_data.end(), 0); - } + void set_zero() { std::fill(m_data.begin(), m_data.end(), 0); } - friend std::ostream &operator<<(std::ostream &out, const Type &value) - { - out << value.f() << "hj"; - return out; - } + friend std::ostream &operator<<(std::ostream &out, const Type &value) { + out << value.f() << "hj"; + return out; + } - std::string to_string() - { - std::stringstream output; + std::string to_string() { + std::stringstream output; - output << *this; + output << *this; - return output.str(); - } + return output.str(); + } - // --- neg + // --- neg - Type operator-() const - { - Type result = Type::empty(size()); + Type operator-() const { + Type result = Type::empty(size()); - for (index i = 0; i < data_length(); i++) - { - result.m_data[i] = -m_data[i]; - } + for (index i = 0; i < data_length(); i++) { + result.m_data[i] = -m_data[i]; + } - return result; - } + return result; + } - // --- add + // --- add - Type operator+(const Type &b) const - { - check_equal_size(size(), b.size()); + Type operator+(const Type &b) const { + check_equal_size(size(), b.size()); - Type result = Type::empty(size()); + Type result = Type::empty(size()); - const auto f = this->f() + b.f(); + const auto f = this->f() + b.f(); - const auto da = One(); - const auto db = One(); + const auto da = One(); + const auto db = One(); - const auto daa = Zero(); - const auto dab = Zero(); - const auto dbb = Zero(); + const auto daa = Zero(); + const auto dab = Zero(); + const auto dbb = Zero(); - binary(m_data, b.m_data, f, da, db, daa, dab, dbb, result.m_data); + binary(m_data, b.m_data, f, da, db, daa, dab, dbb, result.m_data); - return result; - } + return result; + } - Type operator+(const Scalar b) const - { - Type result = *this; + Type operator+(const Scalar b) const { + Type result = *this; - result.f() += b; + result.f() += b; - return result; - } + return result; + } - friend Type operator+(const Scalar a, const Type &b) - { - return b + a; - } + friend Type operator+(const Scalar a, const Type &b) { return b + a; } - Type &operator+=(const Type &b) - { - check_equal_size(size(), b.size()); + Type &operator+=(const Type &b) { + check_equal_size(size(), b.size()); - for (index i = 0; i < length(m_data); i++) - { - m_data[i] += b.m_data[i]; - } + for (index i = 0; i < length(m_data); i++) { + m_data[i] += b.m_data[i]; + } - return *this; - } + return *this; + } - Type &operator+=(const Scalar &b) - { - f() += b; + Type &operator+=(const Scalar &b) { + f() += b; - return *this; - } + return *this; + } - // --- sub + // --- sub - Type operator-(const Type &b) const - { - check_equal_size(size(), b.size()); + Type operator-(const Type &b) const { + check_equal_size(size(), b.size()); - Type result = Type::empty(size()); + Type result = Type::empty(size()); - const auto f = this->f() - b.f(); + const auto f = this->f() - b.f(); - const auto da = One(); - const auto db = -One(); + const auto da = One(); + const auto db = -One(); - const auto daa = Zero(); - const auto dab = Zero(); - const auto dbb = Zero(); + const auto daa = Zero(); + const auto dab = Zero(); + const auto dbb = Zero(); - binary(m_data, b.m_data, f, da, db, daa, dab, dbb, result.m_data); + binary(m_data, b.m_data, f, da, db, daa, dab, dbb, result.m_data); - return result; - } + return result; + } - Type operator-(const Scalar b) const - { - return -b + *this; - } + Type operator-(const Scalar b) const { return -b + *this; } - friend Type operator-(const Scalar a, const Type &b) - { - Type result = Type::empty(b.size()); + friend Type operator-(const Scalar a, const Type &b) { + Type result = Type::empty(b.size()); - for (index i = 0; i < result.data_length(); i++) - { - result.m_data[i] = -b.m_data[i]; - } + for (index i = 0; i < result.data_length(); i++) { + result.m_data[i] = -b.m_data[i]; + } - result.f() += a; + result.f() += a; - return result; - } + return result; + } - Type &operator-=(const Type &b) - { - check_equal_size(size(), b.size()); + Type &operator-=(const Type &b) { + check_equal_size(size(), b.size()); - for (index i = 0; i < length(m_data); i++) - { - m_data[i] -= b.m_data[i]; - } + for (index i = 0; i < length(m_data); i++) { + m_data[i] -= b.m_data[i]; + } - return *this; - } + return *this; + } - Type &operator-=(const Scalar &b) - { - f() -= b; + Type &operator-=(const Scalar &b) { + f() -= b; - return *this; - } + return *this; + } - // --- mul + // --- mul - Type operator*(const Type &b) const - { - check_equal_size(size(), b.size()); + Type operator*(const Type &b) const { + check_equal_size(size(), b.size()); - Type result = Type::empty(size()); + Type result = Type::empty(size()); - const auto f = this->f() * b.f(); + const auto f = this->f() * b.f(); - const auto da = b.f(); - const auto db = this->f(); + const auto da = b.f(); + const auto db = this->f(); - const auto daa = Zero(); - const auto dab = One(); - const auto dbb = Zero(); + const auto daa = Zero(); + const auto dab = One(); + const auto dbb = Zero(); - binary(m_data, b.m_data, f, da, db, daa, dab, dbb, result.m_data); + binary(m_data, b.m_data, f, da, db, daa, dab, dbb, result.m_data); - return result; - } + return result; + } - Type operator*(const Scalar b) const - { - Type result = Type::empty(size()); + Type operator*(const Scalar b) const { + Type result = Type::empty(size()); - for (index i = 0; i < data_length(); i++) - { - result.m_data[i] = m_data[i] * b; - } + for (index i = 0; i < data_length(); i++) { + result.m_data[i] = m_data[i] * b; + } - return result; - } + return result; + } - friend Type operator*(const Scalar a, const Type &b) - { - return b * a; - } + friend Type operator*(const Scalar a, const Type &b) { return b * a; } - Type &operator*=(const Type &b) - { - check_equal_size(size(), b.size()); + Type &operator*=(const Type &b) { + check_equal_size(size(), b.size()); - const Data a_m_data = m_data; + const Data a_m_data = m_data; - const Scalar da = b.f(); - const Scalar db = this->f(); + const Scalar da = b.f(); + const Scalar db = this->f(); - f() *= b.f(); + f() *= b.f(); - for (index i = 1; i < length(m_data); i++) - { - m_data[i] = da * m_data[i] + db * b.m_data[i]; - } + for (index i = 1; i < length(m_data); i++) { + m_data[i] = da * m_data[i] + db * b.m_data[i]; + } - if constexpr (order() == 1) - return *this; + if constexpr (order() == 1) + return *this; - auto *it = &m_data[1 + size()]; + auto *it = &m_data[1 + size()]; - for (index i = 0; i < size(); i++) - { - for (index j = i; j < size(); j++) - { - *it++ += a_m_data[1 + i] * b.m_data[1 + j] + a_m_data[1 + j] * b.m_data[1 + i]; - } - } + for (index i = 0; i < size(); i++) { + for (index j = i; j < size(); j++) { + *it++ += a_m_data[1 + i] * b.m_data[1 + j] + + a_m_data[1 + j] * b.m_data[1 + i]; + } + } - return *this; - } + return *this; + } - Type &operator*=(const Scalar &b) - { - for (index i = 0; i < length(m_data); i++) - { - m_data[i] = m_data[i] * b; - } + Type &operator*=(const Scalar &b) { + for (index i = 0; i < length(m_data); i++) { + m_data[i] = m_data[i] * b; + } - return *this; - } + return *this; + } - // --- div + // --- div - Type operator/(const Type &b) const - { - using std::pow; + Type operator/(const Type &b) const { + using std::pow; - check_equal_size(size(), b.size()); + check_equal_size(size(), b.size()); - const Scalar tmp = 1 / b.f(); + const Scalar tmp = 1 / b.f(); - const auto f = this->f() * tmp; - const auto da = tmp; - const auto db = -this->f() / pow(b.f(), 2); - const auto daa = Zero(); - const auto dab = -1 / pow(b.f(), 2); - const auto dbb = 2 * this->f() / pow(b.f(), 3); + const auto f = this->f() * tmp; + const auto da = tmp; + const auto db = -this->f() / pow(b.f(), 2); + const auto daa = Zero(); + const auto dab = -1 / pow(b.f(), 2); + const auto dbb = 2 * this->f() / pow(b.f(), 3); - Type result = Type::empty(size()); + Type result = Type::empty(size()); - binary(m_data, b.m_data, f, da, db, daa, dab, dbb, result.m_data); + binary(m_data, b.m_data, f, da, db, daa, dab, dbb, result.m_data); - return result; - } + return result; + } - Type operator/(const Scalar b) const - { - return Scalar(1) / b * (*this); - } + Type operator/(const Scalar b) const { return Scalar(1) / b * (*this); } - friend Type operator/(const Scalar a, const Type &b) - { - using std::pow; + friend Type operator/(const Scalar a, const Type &b) { + using std::pow; - Type result = Type::empty(b.size()); + Type result = Type::empty(b.size()); - const auto f = a / b.f(); - const auto db = -a / pow(b.f(), 2); - const auto dbb = 2 * a / pow(b.f(), 3); + const auto f = a / b.f(); + const auto db = -a / pow(b.f(), 2); + const auto dbb = 2 * a / pow(b.f(), 3); - b.unary(b.m_data, f, db, dbb, result.m_data); + b.unary(b.m_data, f, db, dbb, result.m_data); - return result; - } + return result; + } - Type &operator/=(const Type &b) - { - using std::pow; + Type &operator/=(const Type &b) { + using std::pow; - check_equal_size(size(), b.size()); + check_equal_size(size(), b.size()); - const Data a_m_data = m_data; + const Data a_m_data = m_data; - const auto f = a_m_data[0] / b.f(); - const auto da = 1 / b.f(); - const auto db = -a_m_data[0] / pow(b.f(), 2); - const auto daa = Zero(); - const auto dab = -1 / pow(b.f(), 2); - const auto dbb = 2 * a_m_data[0] / pow(b.f(), 3); + const auto f = a_m_data[0] / b.f(); + const auto da = 1 / b.f(); + const auto db = -a_m_data[0] / pow(b.f(), 2); + const auto daa = Zero(); + const auto dab = -1 / pow(b.f(), 2); + const auto dbb = 2 * a_m_data[0] / pow(b.f(), 3); - binary(a_m_data, b.m_data, f, da, db, daa, dab, dbb, m_data); + binary(a_m_data, b.m_data, f, da, db, daa, dab, dbb, m_data); - return *this; - } + return *this; + } - Type &operator/=(const Scalar &b) - { - operator*=(1 / b); + Type &operator/=(const Scalar &b) { + operator*=(1 / b); - return *this; - } + return *this; + } - // --- arithmetic operations + // --- arithmetic operations - Type pow(const double b) const - { - using std::pow; + Type pow(const double b) const { + using std::pow; - Type result = Type::empty(size()); + Type result = Type::empty(size()); - const auto f = pow(this->f(), b); - const auto da = b * pow(this->f(), b - 1); - const auto daa = (b - 1) * b * pow(this->f(), b - 2); + const auto f = pow(this->f(), b); + const auto da = b * pow(this->f(), b - 1); + const auto daa = (b - 1) * b * pow(this->f(), b - 2); - unary(m_data, f, da, daa, result.m_data); + unary(m_data, f, da, daa, result.m_data); - return result; - } + return result; + } - Type sqrt() const - { - using std::pow; - using std::sqrt; + Type sqrt() const { + using std::pow; + using std::sqrt; - Type result = Type::empty(size()); + Type result = Type::empty(size()); - const auto f = sqrt(this->f()); - const auto da = 1 / (2 * f); - const auto daa = -da / (2 * this->f()); + const auto f = sqrt(this->f()); + const auto da = 1 / (2 * f); + const auto daa = -da / (2 * this->f()); - unary(m_data, f, da, daa, result.m_data); + unary(m_data, f, da, daa, result.m_data); - return result; - } + return result; + } - Type cbrt() const - { - using std::cbrt; + Type cbrt() const { + using std::cbrt; - Type result = Type::empty(size()); + Type result = Type::empty(size()); - const auto f = cbrt(this->f()); - const auto da = 1 / (3 * f * f); - const auto daa = -da * 2 / (3 * this->f()); + const auto f = cbrt(this->f()); + const auto da = 1 / (3 * f * f); + const auto daa = -da * 2 / (3 * this->f()); - unary(m_data, f, da, daa, result.m_data); + unary(m_data, f, da, daa, result.m_data); - return result; - } + return result; + } - Type reciprocal() const - { - Type result = Type::empty(size()); + Type reciprocal() const { + Type result = Type::empty(size()); - const auto f = 1 / this->f(); - const auto da = -f * f; - const auto daa = -2 * f * da; + const auto f = 1 / this->f(); + const auto da = -f * f; + const auto daa = -2 * f * da; - unary(m_data, f, da, daa, result.m_data); + unary(m_data, f, da, daa, result.m_data); - return result; - } + return result; + } - // --- trigonometric functions + // --- trigonometric functions - Type cos() const - { - using std::cos; - using std::sin; + Type cos() const { + using std::cos; + using std::sin; - Type result = Type::empty(size()); + Type result = Type::empty(size()); - const auto f = cos(this->f()); - const auto da = -sin(this->f()); - const auto daa = -cos(this->f()); + const auto f = cos(this->f()); + const auto da = -sin(this->f()); + const auto daa = -cos(this->f()); - unary(m_data, f, da, daa, result.m_data); + unary(m_data, f, da, daa, result.m_data); - return result; - } + return result; + } - Type sin() const - { - using std::cos; - using std::sin; + Type sin() const { + using std::cos; + using std::sin; - Type result = Type::empty(size()); + Type result = Type::empty(size()); - const auto f = sin(this->f()); - const auto da = cos(this->f()); - const auto daa = -sin(this->f()); + const auto f = sin(this->f()); + const auto da = cos(this->f()); + const auto daa = -sin(this->f()); - unary(m_data, f, da, daa, result.m_data); + unary(m_data, f, da, daa, result.m_data); - return result; - } + return result; + } - Type tan() const - { - using std::tan; + Type tan() const { + using std::tan; - Type result = Type::empty(size()); + Type result = Type::empty(size()); - const auto f = tan(this->f()); - const auto da = f * f + 1; - const auto daa = da * 2 * f; + const auto f = tan(this->f()); + const auto da = f * f + 1; + const auto daa = da * 2 * f; - unary(m_data, f, da, daa, result.m_data); + unary(m_data, f, da, daa, result.m_data); - return result; - } + return result; + } - Type acos() const - { - using std::acos; - using std::sqrt; + Type acos() const { + using std::acos; + using std::sqrt; - Type result = Type::empty(size()); + Type result = Type::empty(size()); - const Scalar tmp = 1 - this->f() * this->f(); + const Scalar tmp = 1 - this->f() * this->f(); - const auto f = acos(this->f()); - const auto da = -1 / sqrt(tmp); - const auto daa = da * this->f() / tmp; + const auto f = acos(this->f()); + const auto da = -1 / sqrt(tmp); + const auto daa = da * this->f() / tmp; - unary(m_data, f, da, daa, result.m_data); + unary(m_data, f, da, daa, result.m_data); - return result; - } + return result; + } - Type asin() const - { - using std::asin; - using std::sqrt; + Type asin() const { + using std::asin; + using std::sqrt; - Type result = Type::empty(size()); + Type result = Type::empty(size()); - const Scalar tmp = 1 - this->f() * this->f(); + const Scalar tmp = 1 - this->f() * this->f(); - const auto f = asin(this->f()); - const auto da = 1 / sqrt(tmp); - const auto daa = da * this->f() / tmp; + const auto f = asin(this->f()); + const auto da = 1 / sqrt(tmp); + const auto daa = da * this->f() / tmp; - unary(m_data, f, da, daa, result.m_data); + unary(m_data, f, da, daa, result.m_data); - return result; - } + return result; + } - Type atan() const - { - using std::atan; + Type atan() const { + using std::atan; - Type result = Type::empty(size()); + Type result = Type::empty(size()); - const auto f = atan(this->f()); - const auto da = 1 / (this->f() * this->f() + 1); - const auto daa = -da * da * 2 * this->f(); + const auto f = atan(this->f()); + const auto da = 1 / (this->f() * this->f() + 1); + const auto daa = -da * da * 2 * this->f(); - unary(m_data, f, da, daa, result.m_data); + unary(m_data, f, da, daa, result.m_data); - return result; - } + return result; + } - Type atan2(const Type &b) const - { - using std::atan2; + Type atan2(const Type &b) const { + using std::atan2; - Type result = Type::empty(size()); + Type result = Type::empty(size()); - const Scalar tmp = this->f() * this->f() + b.f() * b.f(); + const Scalar tmp = this->f() * this->f() + b.f() * b.f(); - const auto f = atan2(this->f(), b.f()); - const auto da = b.f() / tmp; - const auto db = -this->f() / tmp; - const auto daa = db * da * 2; - const auto dab = db * db - da * da; - const auto dbb = -daa; + const auto f = atan2(this->f(), b.f()); + const auto da = b.f() / tmp; + const auto db = -this->f() / tmp; + const auto daa = db * da * 2; + const auto dab = db * db - da * da; + const auto dbb = -daa; - binary(m_data, b.m_data, f, da, db, daa, dab, dbb, result.m_data); + binary(m_data, b.m_data, f, da, db, daa, dab, dbb, result.m_data); - return result; - } + return result; + } - static Type hypot(const Type &a, const Type &b) - { - using std::hypot; + static Type hypot(const Type &a, const Type &b) { + using std::hypot; - check_equal_size(a.size(), b.size()); + check_equal_size(a.size(), b.size()); - Type result = Type::empty(a.size()); + Type result = Type::empty(a.size()); - const auto f = hypot(a.f(), b.f()); - const auto f3 = f * f * f; - const auto da = a.f() / f; - const auto db = b.f() / f; - const auto daa = b.f() * b.f() / f3; - const auto dab = -a.f() * b.f() / f3; - const auto dbb = a.f() * a.f() / f3; + const auto f = hypot(a.f(), b.f()); + const auto f3 = f * f * f; + const auto da = a.f() / f; + const auto db = b.f() / f; + const auto daa = b.f() * b.f() / f3; + const auto dab = -a.f() * b.f() / f3; + const auto dbb = a.f() * a.f() / f3; - a.binary(a.m_data, b.m_data, f, da, db, daa, dab, dbb, result.m_data); + a.binary(a.m_data, b.m_data, f, da, db, daa, dab, dbb, + result.m_data); - return result; - } + return result; + } - static Type hypot(const Type &a, const Type &b, const Type &c) - { - using std::hypot; + static Type hypot(const Type &a, const Type &b, const Type &c) { + using std::hypot; - check_equal_size(a.size(), b.size()); + check_equal_size(a.size(), b.size()); - Type result = Type::empty(a.size()); + Type result = Type::empty(a.size()); - const auto f = hypot(a.f(), b.f(), c.f()); - const auto f3 = f * f * f; - const auto a2 = a.f() * a.f(); - const auto b2 = b.f() * b.f(); - const auto c2 = c.f() * c.f(); - const auto da = a.f() / f; - const auto db = b.f() / f; - const auto dc = c.f() / f; - const auto daa = (b2 + c2) / f3; - const auto dab = -(a.f() * b.f()) / f3; - const auto dac = -(a.f() * c.f()) / f3; - const auto dbb = (a2 + c2) / f3; - const auto dbc = -(b.f() * c.f()) / f3; - const auto dcc = (a2 + b2) / f3; + const auto f = hypot(a.f(), b.f(), c.f()); + const auto f3 = f * f * f; + const auto a2 = a.f() * a.f(); + const auto b2 = b.f() * b.f(); + const auto c2 = c.f() * c.f(); + const auto da = a.f() / f; + const auto db = b.f() / f; + const auto dc = c.f() / f; + const auto daa = (b2 + c2) / f3; + const auto dab = -(a.f() * b.f()) / f3; + const auto dac = -(a.f() * c.f()) / f3; + const auto dbb = (a2 + c2) / f3; + const auto dbc = -(b.f() * c.f()) / f3; + const auto dcc = (a2 + b2) / f3; - a.ternary(a.m_data, b.m_data, c.m_data, f, da, db, dc, daa, dab, dac, dbb, dbc, dcc, result.m_data); + a.ternary(a.m_data, b.m_data, c.m_data, f, da, db, dc, daa, dab, dac, + dbb, dbc, dcc, result.m_data); - return result; - } + return result; + } - // --- hyperbolic functions + // --- hyperbolic functions - Type cosh() const - { - using std::cosh; - using std::sinh; + Type cosh() const { + using std::cosh; + using std::sinh; - Type result = Type::empty(size()); + Type result = Type::empty(size()); - const auto f = cosh(this->f()); - const auto da = sinh(this->f()); - const auto daa = f; + const auto f = cosh(this->f()); + const auto da = sinh(this->f()); + const auto daa = f; - unary(m_data, f, da, daa, result.m_data); + unary(m_data, f, da, daa, result.m_data); - return result; - } + return result; + } - Type sinh() const - { - using std::cosh; - using std::sinh; + Type sinh() const { + using std::cosh; + using std::sinh; - Type result = Type::empty(size()); + Type result = Type::empty(size()); - const auto f = sinh(this->f()); - const auto da = cosh(this->f()); - const auto daa = f; + const auto f = sinh(this->f()); + const auto da = cosh(this->f()); + const auto daa = f; - unary(m_data, f, da, daa, result.m_data); + unary(m_data, f, da, daa, result.m_data); - return result; - } + return result; + } - Type tanh() const - { - using std::tanh; + Type tanh() const { + using std::tanh; - Type result = Type::empty(size()); + Type result = Type::empty(size()); - const auto f = tanh(this->f()); - const auto da = 1 - f * f; - const auto daa = -2 * f * da; + const auto f = tanh(this->f()); + const auto da = 1 - f * f; + const auto daa = -2 * f * da; - unary(m_data, f, da, daa, result.m_data); + unary(m_data, f, da, daa, result.m_data); - return result; - } + return result; + } - Type acosh() const - { - using std::acosh; - using std::sqrt; + Type acosh() const { + using std::acosh; + using std::sqrt; - Type result = Type::empty(size()); + Type result = Type::empty(size()); - const auto f = acosh(this->f()); - const auto da = 1 / (sqrt(this->f() - 1) * sqrt(this->f() + 1)); - const auto daa = -da * this->f() / ((this->f() - 1) * (this->f() + 1)); + const auto f = acosh(this->f()); + const auto da = 1 / (sqrt(this->f() - 1) * sqrt(this->f() + 1)); + const auto daa = -da * this->f() / ((this->f() - 1) * (this->f() + 1)); - unary(m_data, f, da, daa, result.m_data); + unary(m_data, f, da, daa, result.m_data); - return result; - } + return result; + } - Type asinh() const - { - using std::asinh; - using std::sqrt; + Type asinh() const { + using std::asinh; + using std::sqrt; - Type result = Type::empty(size()); + Type result = Type::empty(size()); - const auto f = asinh(this->f()); - const auto da = 1 / sqrt(1 + this->f() * this->f()); - const auto daa = -da * this->f() / (1 + this->f() * this->f()); + const auto f = asinh(this->f()); + const auto da = 1 / sqrt(1 + this->f() * this->f()); + const auto daa = -da * this->f() / (1 + this->f() * this->f()); - unary(m_data, f, da, daa, result.m_data); + unary(m_data, f, da, daa, result.m_data); - return result; - } + return result; + } - Type atanh() const - { - using std::atanh; - using std::pow; + Type atanh() const { + using std::atanh; + using std::pow; - Type result = Type::empty(size()); + Type result = Type::empty(size()); - const auto f = atanh(this->f()); - const auto da = 1 / (1 - this->f() * this->f()); - const auto daa = 2 * this->f() / pow(this->f() * this->f() - 1, 2); + const auto f = atanh(this->f()); + const auto da = 1 / (1 - this->f() * this->f()); + const auto daa = 2 * this->f() / pow(this->f() * this->f() - 1, 2); - unary(m_data, f, da, daa, result.m_data); + unary(m_data, f, da, daa, result.m_data); - return result; - } + return result; + } - // exponents and logarithms + // exponents and logarithms - Type exp() const - { - using std::exp; + Type exp() const { + using std::exp; - Type result = Type::empty(size()); + Type result = Type::empty(size()); - const auto f = exp(this->f()); - const auto da = f; - const auto daa = f; + const auto f = exp(this->f()); + const auto da = f; + const auto daa = f; - unary(m_data, f, da, daa, result.m_data); + unary(m_data, f, da, daa, result.m_data); - return result; - } + return result; + } - Type log() const - { - using std::log; + Type log() const { + using std::log; - Type result = Type::empty(size()); + Type result = Type::empty(size()); - const auto f = log(this->f()); - const auto da = 1 / this->f(); - const auto daa = -da * da; + const auto f = log(this->f()); + const auto da = 1 / this->f(); + const auto daa = -da * da; - unary(m_data, f, da, daa, result.m_data); + unary(m_data, f, da, daa, result.m_data); - return result; - } + return result; + } - Type log(const TScalar base) const - { - using std::log; + Type log(const TScalar base) const { + using std::log; - Type result = Type::empty(size()); + Type result = Type::empty(size()); - const auto f = log(this->f()) / log(base); - const auto da = 1 / (this->f() * log(base)); - const auto daa = -da / this->f(); + const auto f = log(this->f()) / log(base); + const auto da = 1 / (this->f() * log(base)); + const auto daa = -da / this->f(); - unary(m_data, f, da, daa, result.m_data); + unary(m_data, f, da, daa, result.m_data); - return result; - } + return result; + } - Type log2() const - { - using std::log; - using std::log2; + Type log2() const { + using std::log; + using std::log2; - Type result = Type::empty(size()); + Type result = Type::empty(size()); - const auto f = log2(this->f()); - const auto da = 1 / (this->f() * log(2)); - const auto daa = -da / this->f(); + const auto f = log2(this->f()); + const auto da = 1 / (this->f() * log(2)); + const auto daa = -da / this->f(); - unary(m_data, f, da, daa, result.m_data); + unary(m_data, f, da, daa, result.m_data); - return result; - } + return result; + } - Type log10() const - { - using std::log; - using std::log10; + Type log10() const { + using std::log; + using std::log10; - Type result = Type::empty(size()); + Type result = Type::empty(size()); - const auto f = log10(this->f()); - const auto da = 1 / (this->f() * log(10)); - const auto daa = -da / this->f(); + const auto f = log10(this->f()); + const auto da = 1 / (this->f() * log(10)); + const auto daa = -da / this->f(); - unary(m_data, f, da, daa, result.m_data); + unary(m_data, f, da, daa, result.m_data); - return result; - } + return result; + } - // abs + // abs - Type abs() const - { - return f() < 0 ? -(*this) : *this; - } + Type abs() const { return f() < 0 ? -(*this) : *this; } - // comparison + // comparison - bool operator==(const Type &b) const - { - return f() == b.f(); - } + bool operator==(const Type &b) const { return f() == b.f(); } - bool operator!=(const Type &b) const - { - return f() != b.f(); - } + bool operator!=(const Type &b) const { return f() != b.f(); } - bool operator<(const Type &b) const - { - return f() < b.f(); - } + bool operator<(const Type &b) const { return f() < b.f(); } - bool operator>(const Type &b) const - { - return f() > b.f(); - } + bool operator>(const Type &b) const { return f() > b.f(); } - bool operator<=(const Type &b) const - { - return f() <= b.f(); - } + bool operator<=(const Type &b) const { return f() <= b.f(); } - bool operator>=(const Type &b) const - { - return f() >= b.f(); - } + bool operator>=(const Type &b) const { return f() >= b.f(); } - bool operator==(const Scalar b) const - { - return f() == b; - } + bool operator==(const Scalar b) const { return f() == b; } - bool operator!=(const Scalar b) const - { - return f() != b; - } + bool operator!=(const Scalar b) const { return f() != b; } - bool operator<(const Scalar b) const - { - return f() < b; - } + bool operator<(const Scalar b) const { return f() < b; } - bool operator>(const Scalar b) const - { - return f() > b; - } + bool operator>(const Scalar b) const { return f() > b; } - bool operator<=(const Scalar b) const - { - return f() <= b; - } + bool operator<=(const Scalar b) const { return f() <= b; } - bool operator>=(const Scalar b) const - { - return f() >= b; - } + bool operator>=(const Scalar b) const { return f() >= b; } - friend bool operator==(const Scalar a, const Type &b) - { - return b.operator==(a); - } + friend bool operator==(const Scalar a, const Type &b) { + return b.operator==(a); + } - friend bool operator!=(const Scalar a, const Type &b) - { - return b.operator!=(a); - } + friend bool operator!=(const Scalar a, const Type &b) { + return b.operator!=(a); + } - friend bool operator<(const Scalar a, const Type &b) - { - return b.operator>(a); - } + friend bool operator<(const Scalar a, const Type &b) { + return b.operator>(a); + } - friend bool operator>(const Scalar a, const Type &b) - { - return b.operator<(a); - } + friend bool operator>(const Scalar a, const Type &b) { + return b.operator<(a); + } - friend bool operator<=(const Scalar a, const Type &b) - { - return b.operator>=(a); - } + friend bool operator<=(const Scalar a, const Type &b) { + return b.operator>=(a); + } - friend bool operator>=(const Scalar a, const Type &b) - { - return b.operator<=(a); - } - }; + friend bool operator>=(const Scalar a, const Type &b) { + return b.operator<=(a); + } +}; - // std::abs +// std::abs - using std::abs; +using std::abs; - template - DDScalar abs(const DDScalar &a) - { - return a.abs(); - } +template +DDScalar +abs(const DDScalar &a) { + return a.abs(); +} - // std::pow +// std::pow - using std::pow; +using std::pow; - template - DDScalar pow(const DDScalar &a, const index b) - { - return a.pow(b); - } +template +DDScalar pow(const DDScalar &a, + const index b) { + return a.pow(b); +} - template - DDScalar pow(const DDScalar &a, const double b) - { - return a.pow(b); - } +template +DDScalar pow(const DDScalar &a, + const double b) { + return a.pow(b); +} - // std::sqrt +// std::sqrt - using std::sqrt; +using std::sqrt; - template - DDScalar sqrt(const DDScalar &a) - { - return a.sqrt(); - } +template +DDScalar +sqrt(const DDScalar &a) { + return a.sqrt(); +} - // std::cbrt +// std::cbrt - using std::cbrt; +using std::cbrt; - template - DDScalar cbrt(const DDScalar &a) - { - return a.cbrt(); - } +template +DDScalar +cbrt(const DDScalar &a) { + return a.cbrt(); +} - // std::cos +// std::cos - using std::cos; +using std::cos; - template - DDScalar cos(const DDScalar &a) - { - return a.cos(); - } +template +DDScalar +cos(const DDScalar &a) { + return a.cos(); +} - // std::sin +// std::sin - using std::sin; +using std::sin; - template - DDScalar sin(const DDScalar &a) - { - return a.sin(); - } +template +DDScalar +sin(const DDScalar &a) { + return a.sin(); +} - // std::tan +// std::tan - using std::tan; +using std::tan; - template - DDScalar tan(const DDScalar &a) - { - return a.tan(); - } +template +DDScalar +tan(const DDScalar &a) { + return a.tan(); +} - // std::acos +// std::acos - using std::acos; +using std::acos; - template - DDScalar acos(const DDScalar &a) - { - return a.acos(); - } +template +DDScalar +acos(const DDScalar &a) { + return a.acos(); +} - // std::asin +// std::asin - using std::asin; +using std::asin; - template - DDScalar asin(const DDScalar &a) - { - return a.asin(); - } +template +DDScalar +asin(const DDScalar &a) { + return a.asin(); +} - // std::atan +// std::atan - using std::atan; +using std::atan; - template - DDScalar atan(const DDScalar &a) - { - return a.atan(); - } +template +DDScalar +atan(const DDScalar &a) { + return a.atan(); +} - // std::atan2 +// std::atan2 - using std::atan2; +using std::atan2; - template - DDScalar atan2(const DDScalar &a, const DDScalar &b) - { - return a.atan2(b); - } +template +DDScalar +atan2(const DDScalar &a, + const DDScalar &b) { + return a.atan2(b); +} - // std::hypot +// std::hypot - using std::hypot; +using std::hypot; - template - DDScalar hypot(const DDScalar &a, const DDScalar &b) - { - return DDScalar::hypot(a, b); - } +template +DDScalar +hypot(const DDScalar &a, + const DDScalar &b) { + return DDScalar::hypot(a, b); +} - template - DDScalar hypot(const DDScalar &a, const DDScalar &b, const DDScalar &c) - { - return DDScalar::hypot(a, b, c); - } +template +DDScalar +hypot(const DDScalar &a, + const DDScalar &b, + const DDScalar &c) { + return DDScalar::hypot(a, b, c); +} - // std::cosh +// std::cosh - using std::cosh; +using std::cosh; - template - DDScalar cosh(const DDScalar &a) - { - return a.cosh(); - } +template +DDScalar +cosh(const DDScalar &a) { + return a.cosh(); +} - // std::sinh +// std::sinh - using std::sinh; +using std::sinh; - template - DDScalar sinh(const DDScalar &a) - { - return a.sinh(); - } +template +DDScalar +sinh(const DDScalar &a) { + return a.sinh(); +} - // std::tanh +// std::tanh - using std::tanh; +using std::tanh; - template - DDScalar tanh(const DDScalar &a) - { - return a.tanh(); - } +template +DDScalar +tanh(const DDScalar &a) { + return a.tanh(); +} - // std::acosh +// std::acosh - using std::acosh; +using std::acosh; - template - DDScalar acosh(const DDScalar &a) - { - return a.acosh(); - } +template +DDScalar +acosh(const DDScalar &a) { + return a.acosh(); +} - // std::asin +// std::asin - using std::asinh; +using std::asinh; - template - DDScalar asinh(const DDScalar &a) - { - return a.asinh(); - } +template +DDScalar +asinh(const DDScalar &a) { + return a.asinh(); +} - // std::atan +// std::atan - using std::atanh; +using std::atanh; - template - DDScalar atanh(const DDScalar &a) - { - return a.atanh(); - } +template +DDScalar +atanh(const DDScalar &a) { + return a.atanh(); +} - // std::exp +// std::exp - using std::exp; +using std::exp; - template - DDScalar exp(const DDScalar &a) - { - return a.exp(); - } +template +DDScalar +exp(const DDScalar &a) { + return a.exp(); +} - // std::log +// std::log - using std::log; +using std::log; - template - DDScalar log(const DDScalar &a) - { - return a.log(); - } +template +DDScalar +log(const DDScalar &a) { + return a.log(); +} - // std::log2 +// std::log2 - using std::log2; +using std::log2; - template - DDScalar log2(const DDScalar &a) - { - return a.log2(); - } +template +DDScalar +log2(const DDScalar &a) { + return a.log2(); +} - // std::log10 +// std::log10 - using std::log10; +using std::log10; - template - DDScalar log10(const DDScalar &a) - { - return a.log10(); - } +template +DDScalar +log10(const DDScalar &a) { + return a.log10(); +} - template - class SScalar - { - public: // types - using Type = SScalar; - using Scalar = TScalar; - using Data = std::unordered_map; +template class SScalar { +public: // types + using Type = SScalar; + using Scalar = TScalar; + using Data = std::unordered_map; - private: // variables - Scalar m_f; - Data m_d; +private: // variables + Scalar m_f; + Data m_d; - private: // methods - template - HYPERJET_INLINE static Data unary(const Data &a, const TDa &da) - { - Data r{a}; +private: // methods + template + HYPERJET_INLINE static Data unary(const Data &a, const TDa &da) { + Data r{a}; - for (auto &d : r) - d.second *= da; + for (auto &d : r) + d.second *= da; - return r; - } + return r; + } - template - HYPERJET_INLINE static Data binary(const Data &a, const Data &b, const TDa &da, const TDb &db) - { - Data r{a}; + template + HYPERJET_INLINE static Data binary(const Data &a, const Data &b, + const TDa &da, const TDb &db) { + Data r{a}; - for (auto &d : r) - d.second *= da; + for (auto &d : r) + d.second *= da; - for (auto &d : b) - r[d.first] += db * d.second; + for (auto &d : b) + r[d.first] += db * d.second; - return r; - } + return r; + } - template - HYPERJET_INLINE static Data ternary(const Data &a, const Data &b, const Data &c, const TDa &da, const TDb &db, const TDc &dc) - { - Data r{a}; + template + HYPERJET_INLINE static Data ternary(const Data &a, const Data &b, + const Data &c, const TDa &da, + const TDb &db, const TDc &dc) { + Data r{a}; - for (auto &d : r) - d.second *= da; + for (auto &d : r) + d.second *= da; - for (auto &d : b) - r[d.first] += db * d.second; + for (auto &d : b) + r[d.first] += db * d.second; - for (auto &d : c) - r[d.first] += dc * d.second; + for (auto &d : c) + r[d.first] += dc * d.second; - return r; - } + return r; + } - public: // constructors - SScalar() = default; +public: // constructors + SScalar() = default; - SScalar(const Scalar f) : m_f(f), m_d() - { - } + SScalar(const Scalar f) : m_f(f), m_d() {} - SScalar(const Scalar f, const Data &d) : m_f(f), m_d(d) - { - } + SScalar(const Scalar f, const Data &d) : m_f(f), m_d(d) {} - static SScalar constant(const Scalar value) - { - return SScalar(value, Data()); - } + static SScalar constant(const Scalar value) { return SScalar(value, Data()); } - static SScalar variable(const std::string &name, const Scalar value) - { - return SScalar(value, {{name, Scalar(1)}}); - } + static SScalar variable(const std::string &name, const Scalar value) { + return SScalar(value, {{name, Scalar(1)}}); + } - public: // methods - index size() const - { - return m_d.size(); - } +public: // methods + index size() const { return m_d.size(); } - Scalar f() const - { - return m_f; - } + Scalar f() const { return m_f; } - Scalar d(const std::string &variable) const - { - const auto it = m_d.find(variable); + Scalar d(const std::string &variable) const { + const auto it = m_d.find(variable); - if (it == m_d.end()) - return Scalar(0); + if (it == m_d.end()) + return Scalar(0); - return it->second; - } + return it->second; + } - Scalar eval(const Data &d) const - { - Scalar r(m_f); + Scalar eval(const Data &d) const { + Scalar r(m_f); - for (const auto coef : m_d) - { - const auto it = d.find(coef.first); + for (const auto coef : m_d) { + const auto it = d.find(coef.first); - if (it == d.end()) - continue; + if (it == d.end()) + continue; - r += coef.second * it->second; - } + r += coef.second * it->second; + } - return r; - } + return r; + } - friend std::ostream &operator<<(std::ostream &out, const Type &value) - { - out << value.m_f; + friend std::ostream &operator<<(std::ostream &out, const Type &value) { + out << value.m_f; - for (const auto &d : value.m_d) - { - if (d.second < 0) - out << " " << d.second << "*d" << d.first; - else - out << " +" << d.second << "*d" << d.first; - } + for (const auto &d : value.m_d) { + if (d.second < 0) + out << " " << d.second << "*d" << d.first; + else + out << " +" << d.second << "*d" << d.first; + } - return out; - } + return out; + } - std::string to_string() - { - std::stringstream output; + std::string to_string() { + std::stringstream output; - output << *this; + output << *this; - return output.str(); - } + return output.str(); + } - // operators: negate + // operators: negate - Type operator-() const - { - Type result = *this; + Type operator-() const { + Type result = *this; - result.m_f = -m_f; + result.m_f = -m_f; - for (auto &d : result.m_d) - d.second = -d.second; + for (auto &d : result.m_d) + d.second = -d.second; - return result; - } + return result; + } - // operators: add + // operators: add - Type operator+(const Type &b) const - { - const auto f = m_f + b.f(); - const auto da = 1; - const auto db = 1; + Type operator+(const Type &b) const { + const auto f = m_f + b.f(); + const auto da = 1; + const auto db = 1; - return Type(f, binary(m_d, b.m_d, da, db)); - } + return Type(f, binary(m_d, b.m_d, da, db)); + } - Type operator+(const Scalar b) const - { - Type result = *this; + Type operator+(const Scalar b) const { + Type result = *this; - result.m_f += b; + result.m_f += b; - return result; - } + return result; + } - friend Type operator+(const Scalar a, const Type &b) - { - return b + a; - } + friend Type operator+(const Scalar a, const Type &b) { return b + a; } - Type &operator+=(const Type &b) - { - m_f += b.m_f; + Type &operator+=(const Type &b) { + m_f += b.m_f; - for (const auto &d : b.m_d) - m_d[d.first] += d.second; + for (const auto &d : b.m_d) + m_d[d.first] += d.second; - return *this; - } + return *this; + } - Type &operator+=(const Scalar &b) - { - m_f += b; + Type &operator+=(const Scalar &b) { + m_f += b; - return *this; - } + return *this; + } - // operators: sub + // operators: sub - Type operator-(const Type &b) const - { - const auto f = m_f - b.f(); - const auto da = 1; - const auto db = -1; + Type operator-(const Type &b) const { + const auto f = m_f - b.f(); + const auto da = 1; + const auto db = -1; - return Type(f, binary(m_d, b.m_d, da, db)); - } + return Type(f, binary(m_d, b.m_d, da, db)); + } - Type operator-(const Scalar b) const - { - return -b + *this; - } + Type operator-(const Scalar b) const { return -b + *this; } - friend Type operator-(const Scalar a, const Type &b) - { - Type result = -b; + friend Type operator-(const Scalar a, const Type &b) { + Type result = -b; - result.m_f += a; + result.m_f += a; - return result; - } + return result; + } - Type &operator-=(const Type &b) - { - m_f -= b.m_f; + Type &operator-=(const Type &b) { + m_f -= b.m_f; - for (const auto &d : b.m_d) - m_d[d.first] -= d.second; + for (const auto &d : b.m_d) + m_d[d.first] -= d.second; - return *this; - } + return *this; + } - Type &operator-=(const Scalar &b) - { - m_f -= b; + Type &operator-=(const Scalar &b) { + m_f -= b; - return *this; - } + return *this; + } - // operators: mul + // operators: mul - Type operator*(const Type &b) const - { - const auto f = m_f * b.f(); - const auto da = b.f(); - const auto db = m_f; + Type operator*(const Type &b) const { + const auto f = m_f * b.f(); + const auto da = b.f(); + const auto db = m_f; - return Type(f, binary(m_d, b.m_d, da, db)); - } + return Type(f, binary(m_d, b.m_d, da, db)); + } - Type operator*(const Scalar b) const - { - Type result = *this; + Type operator*(const Scalar b) const { + Type result = *this; - result.m_f *= b; + result.m_f *= b; - for (auto &d : result.m_d) - d.second *= b; + for (auto &d : result.m_d) + d.second *= b; - return result; - } + return result; + } - friend Type operator*(const Scalar a, const Type &b) - { - return b * a; - } + friend Type operator*(const Scalar a, const Type &b) { return b * a; } - Type &operator*=(const Type &b) - { - const Scalar da = b.m_f; - const Scalar db = m_f; + Type &operator*=(const Type &b) { + const Scalar da = b.m_f; + const Scalar db = m_f; - m_f *= b.m_f; + m_f *= b.m_f; - for (auto &d : m_d) - d.second *= da; + for (auto &d : m_d) + d.second *= da; - for (auto &d : b.m_d) - m_d[d.first] += db * d.second; + for (auto &d : b.m_d) + m_d[d.first] += db * d.second; - return *this; - } + return *this; + } - Type &operator*=(const Scalar &b) - { - m_f *= b; + Type &operator*=(const Scalar &b) { + m_f *= b; - for (auto &d : m_d) - d.second *= b; + for (auto &d : m_d) + d.second *= b; - return *this; - } + return *this; + } - // operators: div + // operators: div - Type operator/(const Type &b) const - { - using std::pow; + Type operator/(const Type &b) const { + using std::pow; - const auto tmp = 1 / b.f(); + const auto tmp = 1 / b.f(); - const auto f = m_f * tmp; - const auto da = tmp; - const auto db = -m_f / pow(b.f(), 2); + const auto f = m_f * tmp; + const auto da = tmp; + const auto db = -m_f / pow(b.f(), 2); - return Type(f, binary(m_d, b.m_d, da, db)); - } + return Type(f, binary(m_d, b.m_d, da, db)); + } - Type operator/(const Scalar b) const - { - return Scalar(1) / b * (*this); - } + Type operator/(const Scalar b) const { return Scalar(1) / b * (*this); } - friend Type operator/(const Scalar a, const Type &b) - { - using std::pow; + friend Type operator/(const Scalar a, const Type &b) { + using std::pow; - const auto f = a / b.f(); - const auto db = -a / pow(b.f(), 2); + const auto f = a / b.f(); + const auto db = -a / pow(b.f(), 2); - return Type(f, unary(b.m_d, db)); - } + return Type(f, unary(b.m_d, db)); + } - Type &operator/=(const Type &b) - { - using std::pow; + Type &operator/=(const Type &b) { + using std::pow; - const auto da = 1 / b.m_f; - const auto db = -m_f / pow(b.m_f, 2); + const auto da = 1 / b.m_f; + const auto db = -m_f / pow(b.m_f, 2); - m_f /= b.m_f; + m_f /= b.m_f; - for (auto &d : m_d) - d.second *= da; + for (auto &d : m_d) + d.second *= da; - for (auto &d : b.m_d) - m_d[d.first] += db * d.second; + for (auto &d : b.m_d) + m_d[d.first] += db * d.second; - return *this; - } + return *this; + } - Type &operator/=(const Scalar &b) - { - operator*=(1 / b); + Type &operator/=(const Scalar &b) { + operator*=(1 / b); - return *this; - } + return *this; + } - // arithmetic + // arithmetic - Type pow(const Scalar b) const - { - using std::pow; + Type pow(const Scalar b) const { + using std::pow; - const auto f = pow(m_f, b); - const auto da = b * pow(m_f, b - Scalar(1)); + const auto f = pow(m_f, b); + const auto da = b * pow(m_f, b - Scalar(1)); - return Type(f, unary(m_d, da)); - } + return Type(f, unary(m_d, da)); + } - Type sqrt() const - { - using std::sqrt; + Type sqrt() const { + using std::sqrt; - const auto f = sqrt(m_f); - const auto da = Scalar(1) / (Scalar(2) * f); + const auto f = sqrt(m_f); + const auto da = Scalar(1) / (Scalar(2) * f); - return Type(f, unary(m_d, da)); - } + return Type(f, unary(m_d, da)); + } - Type cbrt() const - { - using std::cbrt; + Type cbrt() const { + using std::cbrt; - const auto f = cbrt(m_f); - const auto da = Scalar(1) / (Scalar(3) * f * f); + const auto f = cbrt(m_f); + const auto da = Scalar(1) / (Scalar(3) * f * f); - return Type(f, unary(m_d, da)); - } + return Type(f, unary(m_d, da)); + } - Type reciprocal() const - { - const auto f = Scalar(1) / m_f; - const auto da = -f * f; + Type reciprocal() const { + const auto f = Scalar(1) / m_f; + const auto da = -f * f; - return Type(f, unary(m_d, da)); - } + return Type(f, unary(m_d, da)); + } - // trigonometric + // trigonometric - Type cos() const - { - using std::cos; - using std::sin; + Type cos() const { + using std::cos; + using std::sin; - const auto f = cos(m_f); - const auto da = -sin(m_f); + const auto f = cos(m_f); + const auto da = -sin(m_f); - return Type(f, unary(m_d, da)); - } + return Type(f, unary(m_d, da)); + } - Type sin() const - { - using std::cos; - using std::sin; + Type sin() const { + using std::cos; + using std::sin; - const auto f = sin(m_f); - const auto da = cos(m_f); + const auto f = sin(m_f); + const auto da = cos(m_f); - return Type(f, unary(m_d, da)); - } + return Type(f, unary(m_d, da)); + } - Type tan() const - { - using std::tan; + Type tan() const { + using std::tan; - const auto f = tan(m_f); - const auto da = f * f + Scalar(1); + const auto f = tan(m_f); + const auto da = f * f + Scalar(1); - return Type(f, unary(m_d, da)); - } + return Type(f, unary(m_d, da)); + } - Type acos() const - { - using std::acos; - using std::sqrt; + Type acos() const { + using std::acos; + using std::sqrt; - const auto tmp = Scalar(1) - m_f * m_f; + const auto tmp = Scalar(1) - m_f * m_f; - const auto f = acos(m_f); - const auto da = -Scalar(1) / sqrt(tmp); + const auto f = acos(m_f); + const auto da = -Scalar(1) / sqrt(tmp); - return Type(f, unary(m_d, da)); - } + return Type(f, unary(m_d, da)); + } - Type asin() const - { - using std::asin; - using std::sqrt; + Type asin() const { + using std::asin; + using std::sqrt; - const auto tmp = Scalar(1) - m_f * m_f; + const auto tmp = Scalar(1) - m_f * m_f; - const auto f = asin(m_f); - const auto da = Scalar(1) / sqrt(tmp); + const auto f = asin(m_f); + const auto da = Scalar(1) / sqrt(tmp); - return Type(f, unary(m_d, da)); - } + return Type(f, unary(m_d, da)); + } - Type atan() const - { - using std::atan; + Type atan() const { + using std::atan; - const auto f = atan(m_f); - const auto da = Scalar(1) / (m_f * m_f + Scalar(1)); + const auto f = atan(m_f); + const auto da = Scalar(1) / (m_f * m_f + Scalar(1)); - return Type(f, unary(m_d, da)); - } + return Type(f, unary(m_d, da)); + } - Type atan2(const Type &b) const - { - using std::atan2; + Type atan2(const Type &b) const { + using std::atan2; - const auto tmp = m_f * m_f + b.m_f * b.m_f; + const auto tmp = m_f * m_f + b.m_f * b.m_f; - const auto f = atan2(m_f, b.m_f); - const auto da = b.m_f / tmp; - const auto db = -m_f / tmp; + const auto f = atan2(m_f, b.m_f); + const auto da = b.m_f / tmp; + const auto db = -m_f / tmp; - return Type(f, binary(m_d, b.m_d, da, db)); - } + return Type(f, binary(m_d, b.m_d, da, db)); + } - static Type hypot(const Type &a, const Type &b) - { - using std::hypot; + static Type hypot(const Type &a, const Type &b) { + using std::hypot; - const auto f = hypot(a.m_f, b.m_f); - const auto f3 = f * f * f; - const auto da = a.m_f / f; - const auto db = b.m_f / f; + const auto f = hypot(a.m_f, b.m_f); + const auto f3 = f * f * f; + const auto da = a.m_f / f; + const auto db = b.m_f / f; - return Type(f, binary(a.m_d, b.m_d, da, db)); - } + return Type(f, binary(a.m_d, b.m_d, da, db)); + } - static Type hypot(const Type &a, const Type &b, const Type &c) - { - using std::hypot; + static Type hypot(const Type &a, const Type &b, const Type &c) { + using std::hypot; - const auto f = hypot(a.m_f, b.m_f, c.m_f); + const auto f = hypot(a.m_f, b.m_f, c.m_f); - const auto f3 = f * f * f; - const auto a2 = a.m_f * a.m_f; - const auto b2 = b.m_f * b.m_f; - const auto c2 = c.m_f * c.m_f; + const auto f3 = f * f * f; + const auto a2 = a.m_f * a.m_f; + const auto b2 = b.m_f * b.m_f; + const auto c2 = c.m_f * c.m_f; - const auto da = a.m_f / f; - const auto db = b.m_f / f; - const auto dc = c.m_f / f; + const auto da = a.m_f / f; + const auto db = b.m_f / f; + const auto dc = c.m_f / f; - return Type(f, ternary(a.m_d, b.m_d, c.m_d, da, db, dc)); - } + return Type(f, ternary(a.m_d, b.m_d, c.m_d, da, db, dc)); + } - // hyperbolic + // hyperbolic - Type cosh() const - { - using std::cosh; - using std::sinh; + Type cosh() const { + using std::cosh; + using std::sinh; - const auto f = cosh(m_f); - const auto da = sinh(m_f); + const auto f = cosh(m_f); + const auto da = sinh(m_f); - return Type(f, unary(m_d, da)); - } + return Type(f, unary(m_d, da)); + } - Type sinh() const - { - using std::cosh; - using std::sinh; + Type sinh() const { + using std::cosh; + using std::sinh; - const auto f = sinh(m_f); - const auto da = cosh(m_f); + const auto f = sinh(m_f); + const auto da = cosh(m_f); - return Type(f, unary(m_d, da)); - } + return Type(f, unary(m_d, da)); + } - Type tanh() const - { - using std::tanh; + Type tanh() const { + using std::tanh; - const auto f = tanh(m_f); - const auto da = 1 - f * f; + const auto f = tanh(m_f); + const auto da = 1 - f * f; - return Type(f, unary(m_d, da)); - } + return Type(f, unary(m_d, da)); + } - Type acosh() const - { - using std::acosh; - using std::sqrt; + Type acosh() const { + using std::acosh; + using std::sqrt; - const auto f = acosh(m_f); - const auto da = 1 / (sqrt(m_f - 1) * sqrt(m_f + 1)); + const auto f = acosh(m_f); + const auto da = 1 / (sqrt(m_f - 1) * sqrt(m_f + 1)); - return Type(f, unary(m_d, da)); - } + return Type(f, unary(m_d, da)); + } - Type asinh() const - { - using std::asinh; - using std::sqrt; + Type asinh() const { + using std::asinh; + using std::sqrt; - const auto f = asinh(m_f); - const auto da = 1 / sqrt(1 + m_f * m_f); + const auto f = asinh(m_f); + const auto da = 1 / sqrt(1 + m_f * m_f); - return Type(f, unary(m_d, da)); - } + return Type(f, unary(m_d, da)); + } - Type atanh() const - { - using std::atanh; - using std::pow; + Type atanh() const { + using std::atanh; + using std::pow; - const auto f = atanh(m_f); - const auto da = 1 / (1 - m_f * m_f); + const auto f = atanh(m_f); + const auto da = 1 / (1 - m_f * m_f); - return Type(f, unary(m_d, da)); - } + return Type(f, unary(m_d, da)); + } - // exponents and logarithms + // exponents and logarithms - Type exp() const - { - using std::exp; + Type exp() const { + using std::exp; - const auto f = exp(m_f); - const auto da = f; + const auto f = exp(m_f); + const auto da = f; - return Type(f, unary(m_d, da)); - } + return Type(f, unary(m_d, da)); + } - Type log() const - { - using std::log; + Type log() const { + using std::log; - const auto f = log(m_f); - const auto da = 1 / m_f; + const auto f = log(m_f); + const auto da = 1 / m_f; - return Type(f, unary(m_d, da)); - } + return Type(f, unary(m_d, da)); + } - Type log(const TScalar base) const - { - using std::log; + Type log(const TScalar base) const { + using std::log; - const auto f = log(m_f) / log(base); - const auto da = 1 / (m_f * log(base)); + const auto f = log(m_f) / log(base); + const auto da = 1 / (m_f * log(base)); - return Type(f, unary(m_d, da)); - } + return Type(f, unary(m_d, da)); + } - Type log2() const - { - using std::log; - using std::log2; + Type log2() const { + using std::log; + using std::log2; - const auto f = log2(m_f); - const auto da = 1 / (m_f * log(2)); + const auto f = log2(m_f); + const auto da = 1 / (m_f * log(2)); - return Type(f, unary(m_d, da)); - } + return Type(f, unary(m_d, da)); + } - Type log10() const - { - using std::log; - using std::log10; + Type log10() const { + using std::log; + using std::log10; - const auto f = log10(m_f); - const auto da = 1 / (m_f * log(10)); + const auto f = log10(m_f); + const auto da = 1 / (m_f * log(10)); - return Type(f, unary(m_d, da)); - } + return Type(f, unary(m_d, da)); + } - // abs + // abs - Type abs() const - { - return m_f < 0 ? -(*this) : *this; - } + Type abs() const { return m_f < 0 ? -(*this) : *this; } - // comparison + // comparison - bool operator==(const Type &b) const - { - return m_f == b.m_f; - } + bool operator==(const Type &b) const { return m_f == b.m_f; } - bool operator!=(const Type &b) const - { - return m_f != b.m_f; - } + bool operator!=(const Type &b) const { return m_f != b.m_f; } - bool operator<(const Type &b) const - { - return m_f < b.m_f; - } + bool operator<(const Type &b) const { return m_f < b.m_f; } - bool operator>(const Type &b) const - { - return m_f > b.m_f; - } + bool operator>(const Type &b) const { return m_f > b.m_f; } - bool operator<=(const Type &b) const - { - return m_f <= b.m_f; - } + bool operator<=(const Type &b) const { return m_f <= b.m_f; } - bool operator>=(const Type &b) const - { - return m_f >= b.m_f; - } + bool operator>=(const Type &b) const { return m_f >= b.m_f; } - bool operator==(const Scalar b) const - { - return m_f == b; - } + bool operator==(const Scalar b) const { return m_f == b; } - bool operator!=(const Scalar b) const - { - return m_f != b; - } + bool operator!=(const Scalar b) const { return m_f != b; } - bool operator<(const Scalar b) const - { - return m_f < b; - } + bool operator<(const Scalar b) const { return m_f < b; } - bool operator>(const Scalar b) const - { - return m_f > b; - } + bool operator>(const Scalar b) const { return m_f > b; } - bool operator<=(const Scalar b) const - { - return m_f <= b; - } + bool operator<=(const Scalar b) const { return m_f <= b; } - bool operator>=(const Scalar b) const - { - return m_f >= b; - } + bool operator>=(const Scalar b) const { return m_f >= b; } - friend bool operator==(const Scalar a, const Type &b) - { - return b.operator==(a); - } + friend bool operator==(const Scalar a, const Type &b) { + return b.operator==(a); + } - friend bool operator!=(const Scalar a, const Type &b) - { - return b.operator!=(a); - } + friend bool operator!=(const Scalar a, const Type &b) { + return b.operator!=(a); + } - friend bool operator<(const Scalar a, const Type &b) - { - return b.operator>(a); - } + friend bool operator<(const Scalar a, const Type &b) { + return b.operator>(a); + } - friend bool operator>(const Scalar a, const Type &b) - { - return b.operator<(a); - } + friend bool operator>(const Scalar a, const Type &b) { + return b.operator<(a); + } - friend bool operator<=(const Scalar a, const Type &b) - { - return b.operator>=(a); - } + friend bool operator<=(const Scalar a, const Type &b) { + return b.operator>=(a); + } - friend bool operator>=(const Scalar a, const Type &b) - { - return b.operator<=(a); - } - }; + friend bool operator>=(const Scalar a, const Type &b) { + return b.operator<=(a); + } +}; - // std::abs +// std::abs - template - SScalar abs(const SScalar &a) - { - return a.abs(); - } +template SScalar abs(const SScalar &a) { + return a.abs(); +} - // std::pow +// std::pow - template - SScalar pow(const SScalar &a, const index b) - { - return a.pow(b); - } +template +SScalar pow(const SScalar &a, const index b) { + return a.pow(b); +} - template - SScalar pow(const SScalar &a, const TScalar b) - { - return a.pow(b); - } +template +SScalar pow(const SScalar &a, const TScalar b) { + return a.pow(b); +} - // std::sqrt +// std::sqrt - template - SScalar sqrt(const SScalar &a) - { - return a.sqrt(); - } +template SScalar sqrt(const SScalar &a) { + return a.sqrt(); +} - // std::cbrt +// std::cbrt - template - SScalar cbrt(const SScalar &a) - { - return a.cbrt(); - } +template SScalar cbrt(const SScalar &a) { + return a.cbrt(); +} - // std::cos +// std::cos - template - SScalar cos(const SScalar &a) - { - return a.cos(); - } +template SScalar cos(const SScalar &a) { + return a.cos(); +} - // std::sin +// std::sin - template - SScalar sin(const SScalar &a) - { - return a.sin(); - } +template SScalar sin(const SScalar &a) { + return a.sin(); +} - // std::tan +// std::tan - template - SScalar tan(const SScalar &a) - { - return a.tan(); - } +template SScalar tan(const SScalar &a) { + return a.tan(); +} - // std::acos +// std::acos - template - SScalar acos(const SScalar &a) - { - return a.acos(); - } +template SScalar acos(const SScalar &a) { + return a.acos(); +} - // std::asin +// std::asin - template - SScalar asin(const SScalar &a) - { - return a.asin(); - } +template SScalar asin(const SScalar &a) { + return a.asin(); +} - // std::atan +// std::atan - template - SScalar atan(const SScalar &a) - { - return a.atan(); - } +template SScalar atan(const SScalar &a) { + return a.atan(); +} - // std::atan2 +// std::atan2 - template - SScalar atan2(const SScalar &a, const SScalar &b) - { - return a.atan2(b); - } +template +SScalar atan2(const SScalar &a, const SScalar &b) { + return a.atan2(b); +} - // std::hypot +// std::hypot - template - SScalar hypot(const SScalar &a, const SScalar &b) - { - return SScalar::hypot(a, b); - } +template +SScalar hypot(const SScalar &a, const SScalar &b) { + return SScalar::hypot(a, b); +} - template - SScalar hypot(const SScalar &a, const SScalar &b, const SScalar &c) - { - return SScalar::hypot(a, b, c); - } +template +SScalar hypot(const SScalar &a, const SScalar &b, + const SScalar &c) { + return SScalar::hypot(a, b, c); +} - // std::cosh +// std::cosh - template - SScalar cosh(const SScalar &a) - { - return a.cosh(); - } +template SScalar cosh(const SScalar &a) { + return a.cosh(); +} - // std::sinh +// std::sinh - template - SScalar sinh(const SScalar &a) - { - return a.sinh(); - } +template SScalar sinh(const SScalar &a) { + return a.sinh(); +} - // std::tanh +// std::tanh - template - SScalar tanh(const SScalar &a) - { - return a.tanh(); - } +template SScalar tanh(const SScalar &a) { + return a.tanh(); +} - // std::acosh +// std::acosh - template - SScalar acosh(const SScalar &a) - { - return a.acosh(); - } +template SScalar acosh(const SScalar &a) { + return a.acosh(); +} - // std::asin +// std::asin - template - SScalar asinh(const SScalar &a) - { - return a.asinh(); - } +template SScalar asinh(const SScalar &a) { + return a.asinh(); +} - // std::atan +// std::atan - template - SScalar atanh(const SScalar &a) - { - return a.atanh(); - } +template SScalar atanh(const SScalar &a) { + return a.atanh(); +} - // std::exp +// std::exp - template - SScalar exp(const SScalar &a) - { - return a.exp(); - } +template SScalar exp(const SScalar &a) { + return a.exp(); +} - // std::log +// std::log - template - SScalar log(const SScalar &a) - { - return a.log(); - } +template SScalar log(const SScalar &a) { + return a.log(); +} - // std::log2 +// std::log2 - template - SScalar log2(const SScalar &a) - { - return a.log2(); - } +template SScalar log2(const SScalar &a) { + return a.log2(); +} - // std::log10 +// std::log10 - template - SScalar log10(const SScalar &a) - { - return a.log10(); - } +template SScalar log10(const SScalar &a) { + return a.log10(); +} } // namespace hyperjet #if defined EIGEN_WORLD_VERSION -namespace Eigen -{ - - template - struct NumTraits; - - template - struct NumTraits> : NumTraits - { - using Real = hyperjet::DDScalar; - using NonInteger = hyperjet::DDScalar; - using Nested = hyperjet::DDScalar; - - enum - { - IsComplex = 0, - IsInteger = 0, - IsSigned = 1, - RequireInitialization = 1, - ReadCost = 1, - AddCost = 1, - MulCost = 3 - }; - }; - - template - struct ScalarBinaryOpTraits, TScalar, BinOp> - { - using ReturnType = hyperjet::DDScalar; - }; - - template - struct ScalarBinaryOpTraits, BinOp> - { - using ReturnType = hyperjet::DDScalar; - }; +namespace Eigen { + +template struct NumTraits; + +template +struct NumTraits> + : NumTraits { + using Real = hyperjet::DDScalar; + using NonInteger = hyperjet::DDScalar; + using Nested = hyperjet::DDScalar; + + enum { + IsComplex = 0, + IsInteger = 0, + IsSigned = 1, + RequireInitialization = 1, + ReadCost = 1, + AddCost = 1, + MulCost = 3 + }; +}; + +template +struct ScalarBinaryOpTraits, TScalar, + BinOp> { + using ReturnType = hyperjet::DDScalar; +}; + +template +struct ScalarBinaryOpTraits, + BinOp> { + using ReturnType = hyperjet::DDScalar; +}; } // namespace Eigen diff --git a/python/src/bind_ddscalar_0d.cpp b/python/src/bind_ddscalar_0d.cpp index c02b4b87..4d9e89da 100644 --- a/python/src/bind_ddscalar_0d.cpp +++ b/python/src/bind_ddscalar_0d.cpp @@ -1,14 +1,13 @@ #include "common.h" -void bind_ddscalar_0d(pybind11::module &m) -{ - using DType = hj::DDScalar<1, double, 0>; - using DDType = hj::DDScalar<2, double, 0>; - // using DSType = hj::DDScalar<1, hj::SScalar, 0>; - // using DDSType = hj::DDScalar<2, hj::SScalar, 0>; +void bind_ddscalar_0d(pybind11::module &m) { + using DType = hj::DDScalar<1, double, 0>; + using DDType = hj::DDScalar<2, double, 0>; + // using DSType = hj::DDScalar<1, hj::SScalar, 0>; + // using DDSType = hj::DDScalar<2, hj::SScalar, 0>; - auto d_cls = bind(m, "D0Scalar"); - auto dd_cls = bind(m, "DD0Scalar"); - // auto ds_cls = bind(m, "D0SScalar"); - // auto dds_cls = bind(m, "DD0SScalar"); + auto d_cls = bind(m, "D0Scalar"); + auto dd_cls = bind(m, "DD0Scalar"); + // auto ds_cls = bind(m, "D0SScalar"); + // auto dds_cls = bind(m, "DD0SScalar"); } \ No newline at end of file diff --git a/python/src/bind_ddscalar_10d.cpp b/python/src/bind_ddscalar_10d.cpp index 6801eb0a..648cd989 100644 --- a/python/src/bind_ddscalar_10d.cpp +++ b/python/src/bind_ddscalar_10d.cpp @@ -1,14 +1,13 @@ #include "common.h" -void bind_ddscalar_10d(pybind11::module &m) -{ - using DType = hj::DDScalar<1, double, 10>; - using DDType = hj::DDScalar<2, double, 10>; - // using DSType = hj::DDScalar<1, hj::SScalar, 10>; - // using DDSType = hj::DDScalar<2, hj::SScalar, 10>; +void bind_ddscalar_10d(pybind11::module &m) { + using DType = hj::DDScalar<1, double, 10>; + using DDType = hj::DDScalar<2, double, 10>; + // using DSType = hj::DDScalar<1, hj::SScalar, 10>; + // using DDSType = hj::DDScalar<2, hj::SScalar, 10>; - auto d_cls = bind(m, "D10Scalar"); - auto dd_cls = bind(m, "DD10Scalar"); - // auto ds_cls = bind(m, "D10SScalar"); - // auto dds_cls = bind(m, "DD10SScalar"); + auto d_cls = bind(m, "D10Scalar"); + auto dd_cls = bind(m, "DD10Scalar"); + // auto ds_cls = bind(m, "D10SScalar"); + // auto dds_cls = bind(m, "DD10SScalar"); } \ No newline at end of file diff --git a/python/src/bind_ddscalar_11d.cpp b/python/src/bind_ddscalar_11d.cpp index 66d28f23..a2de1bd1 100644 --- a/python/src/bind_ddscalar_11d.cpp +++ b/python/src/bind_ddscalar_11d.cpp @@ -1,14 +1,13 @@ #include "common.h" -void bind_ddscalar_11d(pybind11::module &m) -{ - using DType = hj::DDScalar<1, double, 11>; - using DDType = hj::DDScalar<2, double, 11>; - // using DSType = hj::DDScalar<1, hj::SScalar, 11>; - // using DDSType = hj::DDScalar<2, hj::SScalar, 11>; +void bind_ddscalar_11d(pybind11::module &m) { + using DType = hj::DDScalar<1, double, 11>; + using DDType = hj::DDScalar<2, double, 11>; + // using DSType = hj::DDScalar<1, hj::SScalar, 11>; + // using DDSType = hj::DDScalar<2, hj::SScalar, 11>; - auto d_cls = bind(m, "D11Scalar"); - auto dd_cls = bind(m, "DD11Scalar"); - // auto ds_cls = bind(m, "D11SScalar"); - // auto dds_cls = bind(m, "DD11SScalar"); + auto d_cls = bind(m, "D11Scalar"); + auto dd_cls = bind(m, "DD11Scalar"); + // auto ds_cls = bind(m, "D11SScalar"); + // auto dds_cls = bind(m, "DD11SScalar"); } \ No newline at end of file diff --git a/python/src/bind_ddscalar_12d.cpp b/python/src/bind_ddscalar_12d.cpp index ddb784e2..4c32d19e 100644 --- a/python/src/bind_ddscalar_12d.cpp +++ b/python/src/bind_ddscalar_12d.cpp @@ -1,14 +1,13 @@ #include "common.h" -void bind_ddscalar_12d(pybind11::module &m) -{ - using DType = hj::DDScalar<1, double, 12>; - using DDType = hj::DDScalar<2, double, 12>; - // using DSType = hj::DDScalar<1, hj::SScalar, 12>; - // using DDSType = hj::DDScalar<2, hj::SScalar, 12>; +void bind_ddscalar_12d(pybind11::module &m) { + using DType = hj::DDScalar<1, double, 12>; + using DDType = hj::DDScalar<2, double, 12>; + // using DSType = hj::DDScalar<1, hj::SScalar, 12>; + // using DDSType = hj::DDScalar<2, hj::SScalar, 12>; - auto d_cls = bind(m, "D12Scalar"); - auto dd_cls = bind(m, "DD12Scalar"); - // auto ds_cls = bind(m, "D12SScalar"); - // auto dds_cls = bind(m, "DD12SScalar"); + auto d_cls = bind(m, "D12Scalar"); + auto dd_cls = bind(m, "DD12Scalar"); + // auto ds_cls = bind(m, "D12SScalar"); + // auto dds_cls = bind(m, "DD12SScalar"); } \ No newline at end of file diff --git a/python/src/bind_ddscalar_13d.cpp b/python/src/bind_ddscalar_13d.cpp index 1e484d4f..4d0b0a50 100644 --- a/python/src/bind_ddscalar_13d.cpp +++ b/python/src/bind_ddscalar_13d.cpp @@ -1,14 +1,13 @@ #include "common.h" -void bind_ddscalar_13d(pybind11::module &m) -{ - using DType = hj::DDScalar<1, double, 13>; - using DDType = hj::DDScalar<2, double, 13>; - // using DSType = hj::DDScalar<1, hj::SScalar, 13>; - // using DDSType = hj::DDScalar<2, hj::SScalar, 13>; +void bind_ddscalar_13d(pybind11::module &m) { + using DType = hj::DDScalar<1, double, 13>; + using DDType = hj::DDScalar<2, double, 13>; + // using DSType = hj::DDScalar<1, hj::SScalar, 13>; + // using DDSType = hj::DDScalar<2, hj::SScalar, 13>; - auto d_cls = bind(m, "D13Scalar"); - auto dd_cls = bind(m, "DD13Scalar"); - // auto ds_cls = bind(m, "D13SScalar"); - // auto dds_cls = bind(m, "DD13SScalar"); + auto d_cls = bind(m, "D13Scalar"); + auto dd_cls = bind(m, "DD13Scalar"); + // auto ds_cls = bind(m, "D13SScalar"); + // auto dds_cls = bind(m, "DD13SScalar"); } \ No newline at end of file diff --git a/python/src/bind_ddscalar_14d.cpp b/python/src/bind_ddscalar_14d.cpp index b3187a30..e4e9a056 100644 --- a/python/src/bind_ddscalar_14d.cpp +++ b/python/src/bind_ddscalar_14d.cpp @@ -1,14 +1,13 @@ #include "common.h" -void bind_ddscalar_14d(pybind11::module &m) -{ - using DType = hj::DDScalar<1, double, 14>; - using DDType = hj::DDScalar<2, double, 14>; - // using DSType = hj::DDScalar<1, hj::SScalar, 14>; - // using DDSType = hj::DDScalar<2, hj::SScalar, 14>; +void bind_ddscalar_14d(pybind11::module &m) { + using DType = hj::DDScalar<1, double, 14>; + using DDType = hj::DDScalar<2, double, 14>; + // using DSType = hj::DDScalar<1, hj::SScalar, 14>; + // using DDSType = hj::DDScalar<2, hj::SScalar, 14>; - auto d_cls = bind(m, "D14Scalar"); - auto dd_cls = bind(m, "DD14Scalar"); - // auto ds_cls = bind(m, "D14SScalar"); - // auto dds_cls = bind(m, "DD14SScalar"); + auto d_cls = bind(m, "D14Scalar"); + auto dd_cls = bind(m, "DD14Scalar"); + // auto ds_cls = bind(m, "D14SScalar"); + // auto dds_cls = bind(m, "DD14SScalar"); } \ No newline at end of file diff --git a/python/src/bind_ddscalar_15d.cpp b/python/src/bind_ddscalar_15d.cpp index 2f3220a8..f7313de9 100644 --- a/python/src/bind_ddscalar_15d.cpp +++ b/python/src/bind_ddscalar_15d.cpp @@ -1,14 +1,13 @@ #include "common.h" -void bind_ddscalar_15d(pybind11::module &m) -{ - using DType = hj::DDScalar<1, double, 15>; - using DDType = hj::DDScalar<2, double, 15>; - // using DSType = hj::DDScalar<1, hj::SScalar, 15>; - // using DDSType = hj::DDScalar<2, hj::SScalar, 15>; +void bind_ddscalar_15d(pybind11::module &m) { + using DType = hj::DDScalar<1, double, 15>; + using DDType = hj::DDScalar<2, double, 15>; + // using DSType = hj::DDScalar<1, hj::SScalar, 15>; + // using DDSType = hj::DDScalar<2, hj::SScalar, 15>; - auto d_cls = bind(m, "D15Scalar"); - auto dd_cls = bind(m, "DD15Scalar"); - // auto ds_cls = bind(m, "D15SScalar"); - // auto dds_cls = bind(m, "DD15SScalar"); + auto d_cls = bind(m, "D15Scalar"); + auto dd_cls = bind(m, "DD15Scalar"); + // auto ds_cls = bind(m, "D15SScalar"); + // auto dds_cls = bind(m, "DD15SScalar"); } \ No newline at end of file diff --git a/python/src/bind_ddscalar_16d.cpp b/python/src/bind_ddscalar_16d.cpp index 949d802a..9f91394b 100644 --- a/python/src/bind_ddscalar_16d.cpp +++ b/python/src/bind_ddscalar_16d.cpp @@ -1,14 +1,13 @@ #include "common.h" -void bind_ddscalar_16d(pybind11::module &m) -{ - using DType = hj::DDScalar<1, double, 16>; - using DDType = hj::DDScalar<2, double, 16>; - // using DSType = hj::DDScalar<1, hj::SScalar, 16>; - // using DDSType = hj::DDScalar<2, hj::SScalar, 16>; +void bind_ddscalar_16d(pybind11::module &m) { + using DType = hj::DDScalar<1, double, 16>; + using DDType = hj::DDScalar<2, double, 16>; + // using DSType = hj::DDScalar<1, hj::SScalar, 16>; + // using DDSType = hj::DDScalar<2, hj::SScalar, 16>; - auto d_cls = bind(m, "D16Scalar"); - auto dd_cls = bind(m, "DD16Scalar"); - // auto ds_cls = bind(m, "D16SScalar"); - // auto dds_cls = bind(m, "DD16SScalar"); + auto d_cls = bind(m, "D16Scalar"); + auto dd_cls = bind(m, "DD16Scalar"); + // auto ds_cls = bind(m, "D16SScalar"); + // auto dds_cls = bind(m, "DD16SScalar"); } \ No newline at end of file diff --git a/python/src/bind_ddscalar_1d.cpp b/python/src/bind_ddscalar_1d.cpp index 1c665d6d..d3ecbf53 100644 --- a/python/src/bind_ddscalar_1d.cpp +++ b/python/src/bind_ddscalar_1d.cpp @@ -1,14 +1,13 @@ #include "common.h" -void bind_ddscalar_1d(pybind11::module &m) -{ - using DType = hj::DDScalar<1, double, 1>; - using DDType = hj::DDScalar<2, double, 1>; - // using DSType = hj::DDScalar<1, hj::SScalar, 1>; - // using DDSType = hj::DDScalar<2, hj::SScalar, 1>; +void bind_ddscalar_1d(pybind11::module &m) { + using DType = hj::DDScalar<1, double, 1>; + using DDType = hj::DDScalar<2, double, 1>; + // using DSType = hj::DDScalar<1, hj::SScalar, 1>; + // using DDSType = hj::DDScalar<2, hj::SScalar, 1>; - auto d_cls = bind(m, "D1Scalar"); - auto dd_cls = bind(m, "DD1Scalar"); - // auto ds_cls = bind(m, "D1SScalar"); - // auto dds_cls = bind(m, "DD1SScalar"); + auto d_cls = bind(m, "D1Scalar"); + auto dd_cls = bind(m, "DD1Scalar"); + // auto ds_cls = bind(m, "D1SScalar"); + // auto dds_cls = bind(m, "DD1SScalar"); } \ No newline at end of file diff --git a/python/src/bind_ddscalar_2d.cpp b/python/src/bind_ddscalar_2d.cpp index 39ed9e5f..78ef9f61 100644 --- a/python/src/bind_ddscalar_2d.cpp +++ b/python/src/bind_ddscalar_2d.cpp @@ -1,14 +1,13 @@ #include "common.h" -void bind_ddscalar_2d(pybind11::module &m) -{ - using DType = hj::DDScalar<1, double, 2>; - using DDType = hj::DDScalar<2, double, 2>; - // using DSType = hj::DDScalar<1, hj::SScalar, 2>; - // using DDSType = hj::DDScalar<2, hj::SScalar, 2>; +void bind_ddscalar_2d(pybind11::module &m) { + using DType = hj::DDScalar<1, double, 2>; + using DDType = hj::DDScalar<2, double, 2>; + // using DSType = hj::DDScalar<1, hj::SScalar, 2>; + // using DDSType = hj::DDScalar<2, hj::SScalar, 2>; - auto d_cls = bind(m, "D2Scalar"); - auto dd_cls = bind(m, "DD2Scalar"); - // auto ds_cls = bind(m, "D2SScalar"); - // auto dds_cls = bind(m, "DD2SScalar"); + auto d_cls = bind(m, "D2Scalar"); + auto dd_cls = bind(m, "DD2Scalar"); + // auto ds_cls = bind(m, "D2SScalar"); + // auto dds_cls = bind(m, "DD2SScalar"); } \ No newline at end of file diff --git a/python/src/bind_ddscalar_3d.cpp b/python/src/bind_ddscalar_3d.cpp index eae9bef6..052b0664 100644 --- a/python/src/bind_ddscalar_3d.cpp +++ b/python/src/bind_ddscalar_3d.cpp @@ -1,14 +1,13 @@ #include "common.h" -void bind_ddscalar_3d(pybind11::module &m) -{ - using DType = hj::DDScalar<1, double, 3>; - using DDType = hj::DDScalar<2, double, 3>; - // using DSType = hj::DDScalar<1, hj::SScalar, 3>; - // using DDSType = hj::DDScalar<2, hj::SScalar, 3>; +void bind_ddscalar_3d(pybind11::module &m) { + using DType = hj::DDScalar<1, double, 3>; + using DDType = hj::DDScalar<2, double, 3>; + // using DSType = hj::DDScalar<1, hj::SScalar, 3>; + // using DDSType = hj::DDScalar<2, hj::SScalar, 3>; - auto d_cls = bind(m, "D3Scalar"); - auto dd_cls = bind(m, "DD3Scalar"); - // auto ds_cls = bind(m, "D3SScalar"); - // auto dds_cls = bind(m, "DD3SScalar"); + auto d_cls = bind(m, "D3Scalar"); + auto dd_cls = bind(m, "DD3Scalar"); + // auto ds_cls = bind(m, "D3SScalar"); + // auto dds_cls = bind(m, "DD3SScalar"); } \ No newline at end of file diff --git a/python/src/bind_ddscalar_4d.cpp b/python/src/bind_ddscalar_4d.cpp index dd636c95..34e7a59c 100644 --- a/python/src/bind_ddscalar_4d.cpp +++ b/python/src/bind_ddscalar_4d.cpp @@ -1,14 +1,13 @@ #include "common.h" -void bind_ddscalar_4d(pybind11::module &m) -{ - using DType = hj::DDScalar<1, double, 4>; - using DDType = hj::DDScalar<2, double, 4>; - // using DSType = hj::DDScalar<1, hj::SScalar, 4>; - // using DDSType = hj::DDScalar<2, hj::SScalar, 4>; +void bind_ddscalar_4d(pybind11::module &m) { + using DType = hj::DDScalar<1, double, 4>; + using DDType = hj::DDScalar<2, double, 4>; + // using DSType = hj::DDScalar<1, hj::SScalar, 4>; + // using DDSType = hj::DDScalar<2, hj::SScalar, 4>; - auto d_cls = bind(m, "D4Scalar"); - auto dd_cls = bind(m, "DD4Scalar"); - // auto ds_cls = bind(m, "D4SScalar"); - // auto dds_cls = bind(m, "DD4SScalar"); + auto d_cls = bind(m, "D4Scalar"); + auto dd_cls = bind(m, "DD4Scalar"); + // auto ds_cls = bind(m, "D4SScalar"); + // auto dds_cls = bind(m, "DD4SScalar"); } \ No newline at end of file diff --git a/python/src/bind_ddscalar_5d.cpp b/python/src/bind_ddscalar_5d.cpp index 38ca5eed..6f3a7c0e 100644 --- a/python/src/bind_ddscalar_5d.cpp +++ b/python/src/bind_ddscalar_5d.cpp @@ -1,14 +1,13 @@ #include "common.h" -void bind_ddscalar_5d(pybind11::module &m) -{ - using DType = hj::DDScalar<1, double, 5>; - using DDType = hj::DDScalar<2, double, 5>; - // using DSType = hj::DDScalar<1, hj::SScalar, 5>; - // using DDSType = hj::DDScalar<2, hj::SScalar, 5>; +void bind_ddscalar_5d(pybind11::module &m) { + using DType = hj::DDScalar<1, double, 5>; + using DDType = hj::DDScalar<2, double, 5>; + // using DSType = hj::DDScalar<1, hj::SScalar, 5>; + // using DDSType = hj::DDScalar<2, hj::SScalar, 5>; - auto d_cls = bind(m, "D5Scalar"); - auto dd_cls = bind(m, "DD5Scalar"); - // auto ds_cls = bind(m, "D5SScalar"); - // auto dds_cls = bind(m, "DD5SScalar"); + auto d_cls = bind(m, "D5Scalar"); + auto dd_cls = bind(m, "DD5Scalar"); + // auto ds_cls = bind(m, "D5SScalar"); + // auto dds_cls = bind(m, "DD5SScalar"); } \ No newline at end of file diff --git a/python/src/bind_ddscalar_6d.cpp b/python/src/bind_ddscalar_6d.cpp index c5505d30..d1cda358 100644 --- a/python/src/bind_ddscalar_6d.cpp +++ b/python/src/bind_ddscalar_6d.cpp @@ -1,14 +1,13 @@ #include "common.h" -void bind_ddscalar_6d(pybind11::module &m) -{ - using DType = hj::DDScalar<1, double, 6>; - using DDType = hj::DDScalar<2, double, 6>; - // using DSType = hj::DDScalar<1, hj::SScalar, 6>; - // using DDSType = hj::DDScalar<2, hj::SScalar, 6>; +void bind_ddscalar_6d(pybind11::module &m) { + using DType = hj::DDScalar<1, double, 6>; + using DDType = hj::DDScalar<2, double, 6>; + // using DSType = hj::DDScalar<1, hj::SScalar, 6>; + // using DDSType = hj::DDScalar<2, hj::SScalar, 6>; - auto d_cls = bind(m, "D6Scalar"); - auto dd_cls = bind(m, "DD6Scalar"); - // auto ds_cls = bind(m, "D6SScalar"); - // auto dds_cls = bind(m, "DD6SScalar"); + auto d_cls = bind(m, "D6Scalar"); + auto dd_cls = bind(m, "DD6Scalar"); + // auto ds_cls = bind(m, "D6SScalar"); + // auto dds_cls = bind(m, "DD6SScalar"); } \ No newline at end of file diff --git a/python/src/bind_ddscalar_7d.cpp b/python/src/bind_ddscalar_7d.cpp index 29572561..21498673 100644 --- a/python/src/bind_ddscalar_7d.cpp +++ b/python/src/bind_ddscalar_7d.cpp @@ -1,14 +1,13 @@ #include "common.h" -void bind_ddscalar_7d(pybind11::module &m) -{ - using DType = hj::DDScalar<1, double, 7>; - using DDType = hj::DDScalar<2, double, 7>; - // using DSType = hj::DDScalar<1, hj::SScalar, 7>; - // using DDSType = hj::DDScalar<2, hj::SScalar, 7>; +void bind_ddscalar_7d(pybind11::module &m) { + using DType = hj::DDScalar<1, double, 7>; + using DDType = hj::DDScalar<2, double, 7>; + // using DSType = hj::DDScalar<1, hj::SScalar, 7>; + // using DDSType = hj::DDScalar<2, hj::SScalar, 7>; - auto d_cls = bind(m, "D7Scalar"); - auto dd_cls = bind(m, "DD7Scalar"); - // auto ds_cls = bind(m, "D7SScalar"); - // auto dds_cls = bind(m, "DD7SScalar"); + auto d_cls = bind(m, "D7Scalar"); + auto dd_cls = bind(m, "DD7Scalar"); + // auto ds_cls = bind(m, "D7SScalar"); + // auto dds_cls = bind(m, "DD7SScalar"); } \ No newline at end of file diff --git a/python/src/bind_ddscalar_8d.cpp b/python/src/bind_ddscalar_8d.cpp index 692c20b8..3b712530 100644 --- a/python/src/bind_ddscalar_8d.cpp +++ b/python/src/bind_ddscalar_8d.cpp @@ -1,14 +1,13 @@ #include "common.h" -void bind_ddscalar_8d(pybind11::module &m) -{ - using DType = hj::DDScalar<1, double, 8>; - using DDType = hj::DDScalar<2, double, 8>; - // using DSType = hj::DDScalar<1, hj::SScalar, 8>; - // using DDSType = hj::DDScalar<2, hj::SScalar, 8>; +void bind_ddscalar_8d(pybind11::module &m) { + using DType = hj::DDScalar<1, double, 8>; + using DDType = hj::DDScalar<2, double, 8>; + // using DSType = hj::DDScalar<1, hj::SScalar, 8>; + // using DDSType = hj::DDScalar<2, hj::SScalar, 8>; - auto d_cls = bind(m, "D8Scalar"); - auto dd_cls = bind(m, "DD8Scalar"); - // auto ds_cls = bind(m, "D8SScalar"); - // auto dds_cls = bind(m, "DD8SScalar"); + auto d_cls = bind(m, "D8Scalar"); + auto dd_cls = bind(m, "DD8Scalar"); + // auto ds_cls = bind(m, "D8SScalar"); + // auto dds_cls = bind(m, "DD8SScalar"); } \ No newline at end of file diff --git a/python/src/bind_ddscalar_9d.cpp b/python/src/bind_ddscalar_9d.cpp index 23de3c67..2ca6cb6c 100644 --- a/python/src/bind_ddscalar_9d.cpp +++ b/python/src/bind_ddscalar_9d.cpp @@ -1,14 +1,13 @@ #include "common.h" -void bind_ddscalar_9d(pybind11::module &m) -{ - using DType = hj::DDScalar<1, double, 9>; - using DDType = hj::DDScalar<2, double, 9>; - // using DSType = hj::DDScalar<1, hj::SScalar, 9>; - // using DDSType = hj::DDScalar<2, hj::SScalar, 9>; +void bind_ddscalar_9d(pybind11::module &m) { + using DType = hj::DDScalar<1, double, 9>; + using DDType = hj::DDScalar<2, double, 9>; + // using DSType = hj::DDScalar<1, hj::SScalar, 9>; + // using DDSType = hj::DDScalar<2, hj::SScalar, 9>; - auto d_cls = bind(m, "D9Scalar"); - auto dd_cls = bind(m, "DD9Scalar"); - // auto ds_cls = bind(m, "D9SScalar"); - // auto dds_cls = bind(m, "DD9SScalar"); + auto d_cls = bind(m, "D9Scalar"); + auto dd_cls = bind(m, "DD9Scalar"); + // auto ds_cls = bind(m, "D9SScalar"); + // auto dds_cls = bind(m, "DD9SScalar"); } \ No newline at end of file diff --git a/python/src/bind_ddscalar_xd.cpp b/python/src/bind_ddscalar_xd.cpp index a38c8be7..48689caa 100644 --- a/python/src/bind_ddscalar_xd.cpp +++ b/python/src/bind_ddscalar_xd.cpp @@ -1,14 +1,13 @@ #include "common.h" -void bind_ddscalar_xd(pybind11::module &m) -{ - using DType = hj::DDScalar<1, double>; - using DDType = hj::DDScalar<2, double>; - // using DSType = hj::DDScalar<1, hj::SScalar>; - // using DDSType = hj::DDScalar<2, hj::SScalar>; +void bind_ddscalar_xd(pybind11::module &m) { + using DType = hj::DDScalar<1, double>; + using DDType = hj::DDScalar<2, double>; + // using DSType = hj::DDScalar<1, hj::SScalar>; + // using DDSType = hj::DDScalar<2, hj::SScalar>; - auto d_cls = bind(m, "DScalar"); - auto dd_cls = bind(m, "DDScalar"); - // auto ds_cls = bind(m, "DSScalar"); - // auto dds_cls = bind(m, "DDSScalar"); + auto d_cls = bind(m, "DScalar"); + auto dd_cls = bind(m, "DDScalar"); + // auto ds_cls = bind(m, "DSScalar"); + // auto dds_cls = bind(m, "DDSScalar"); } \ No newline at end of file diff --git a/python/src/bind_sscalar.cpp b/python/src/bind_sscalar.cpp index 1094099d..6498c420 100644 --- a/python/src/bind_sscalar.cpp +++ b/python/src/bind_sscalar.cpp @@ -1,113 +1,105 @@ #include "common.h" -void bind_sscalar(pybind11::module &m) -{ - using T = hj::SScalar; +void bind_sscalar(pybind11::module &m) { + using T = hj::SScalar; - auto cls = py::class_(m, "SScalar"); + auto cls = py::class_(m, "SScalar"); - // constructor - cls - .def(py::init<>()) - .def(py::init(), "f"_a = 0) - .def(py::init(), "f"_a = 0, "d"_a); + // constructor + cls.def(py::init<>()) + .def(py::init(), "f"_a = 0) + .def(py::init(), "f"_a = 0, "d"_a); - // static methods - cls - .def_static("constant", &T::constant, "value"_a) - .def_static("variable", &T::variable, "name"_a, "value"_a); + // static methods + cls.def_static("constant", &T::constant, "value"_a) + .def_static("variable", &T::variable, "name"_a, "value"_a); - // properties - cls - .def_property_readonly("f", &T::f) - .def_property_readonly("size", &T::size); + // properties + cls.def_property_readonly("f", &T::f).def_property_readonly("size", &T::size); - // methods - cls - .def("__abs__", &T::abs) - .def("__len__", &T::size) - .def("__pow__", &T::pow) - .def("__repr__", &T::to_string) - .def("abs", &T::abs) - .def("d", &T::d, "variable"_a) - .def("eval", &T::eval, "d"_a); + // methods + cls.def("__abs__", &T::abs) + .def("__len__", &T::size) + .def("__pow__", &T::pow) + .def("__repr__", &T::to_string) + .def("abs", &T::abs) + .def("d", &T::d, "variable"_a) + .def("eval", &T::eval, "d"_a); - // methods: arithmetic operations - cls - .def("reciprocal", &T::reciprocal) - .def("sqrt", &T::sqrt) - .def("cbrt", &T::cbrt) - .def("cos", &T::cos) - .def("sin", &T::sin) - .def("tan", &T::tan) - .def("acos", &T::acos) - .def("asin", &T::asin) - .def("atan", &T::atan) - .def("atan2", &T::atan2) - .def("arccos", &T::acos) - .def("arcsin", &T::asin) - .def("arctan", &T::atan) - .def("arctan2", &T::atan2) - .def("hypot", py::overload_cast(&T::hypot)) - .def("hypot", py::overload_cast(&T::hypot)); + // methods: arithmetic operations + cls.def("reciprocal", &T::reciprocal) + .def("sqrt", &T::sqrt) + .def("cbrt", &T::cbrt) + .def("cos", &T::cos) + .def("sin", &T::sin) + .def("tan", &T::tan) + .def("acos", &T::acos) + .def("asin", &T::asin) + .def("atan", &T::atan) + .def("atan2", &T::atan2) + .def("arccos", &T::acos) + .def("arcsin", &T::asin) + .def("arctan", &T::atan) + .def("arctan2", &T::atan2) + .def("hypot", py::overload_cast(&T::hypot)) + .def("hypot", + py::overload_cast(&T::hypot)); - // methods: hyperbolic functions - cls - .def("cosh", &T::cosh) - .def("sinh", &T::sinh) - .def("tanh", &T::tanh) - .def("acosh", &T::acosh) - .def("arccosh", &T::acosh) - .def("asinh", &T::asinh) - .def("arcsinh", &T::asinh) - .def("atanh", &T::atanh) - .def("arctanh", &T::atanh); + // methods: hyperbolic functions + cls.def("cosh", &T::cosh) + .def("sinh", &T::sinh) + .def("tanh", &T::tanh) + .def("acosh", &T::acosh) + .def("arccosh", &T::acosh) + .def("asinh", &T::asinh) + .def("arcsinh", &T::asinh) + .def("atanh", &T::atanh) + .def("arctanh", &T::atanh); - // methods: exponents and logarithms - cls - .def("exp", &T::exp) - .def("log", py::overload_cast<>(&T::log, py::const_)) - .def("log", py::overload_cast(&T::log, py::const_), "base"_a) - .def("log2", &T::log2) - .def("log10", &T::log10); + // methods: exponents and logarithms + cls.def("exp", &T::exp) + .def("log", py::overload_cast<>(&T::log, py::const_)) + .def("log", py::overload_cast(&T::log, py::const_), + "base"_a) + .def("log2", &T::log2) + .def("log10", &T::log10); - // operators - cls - .def(-py::self) - .def(py::self == py::self) - .def(py::self != py::self) - .def(py::self < py::self) - .def(py::self > py::self) - .def(py::self <= py::self) - .def(py::self >= py::self) - .def(py::self == double()) - .def(py::self != double()) - .def(py::self < double()) - .def(py::self > double()) - .def(py::self <= double()) - .def(py::self >= double()) - .def(double() == py::self) - .def(double() != py::self) - .def(double() < py::self) - .def(double() > py::self) - .def(double() <= py::self) - .def(double() >= py::self) - .def(py::self + py::self) - .def(py::self + double()) - .def(py::self - py::self) - .def(py::self - double()) - .def(py::self * py::self) - .def(py::self * double()) - .def(py::self / py::self) - .def(py::self / double()) - .def(py::self += py::self) - .def(py::self -= py::self) - .def(py::self *= py::self) - .def(py::self *= double()) - .def(py::self /= py::self) - .def(py::self /= double()) - .def(double() + py::self) - .def(double() - py::self) - .def(double() * py::self) - .def(double() / py::self); + // operators + cls.def(-py::self) + .def(py::self == py::self) + .def(py::self != py::self) + .def(py::self < py::self) + .def(py::self > py::self) + .def(py::self <= py::self) + .def(py::self >= py::self) + .def(py::self == double()) + .def(py::self != double()) + .def(py::self < double()) + .def(py::self > double()) + .def(py::self <= double()) + .def(py::self >= double()) + .def(double() == py::self) + .def(double() != py::self) + .def(double() < py::self) + .def(double() > py::self) + .def(double() <= py::self) + .def(double() >= py::self) + .def(py::self + py::self) + .def(py::self + double()) + .def(py::self - py::self) + .def(py::self - double()) + .def(py::self * py::self) + .def(py::self * double()) + .def(py::self / py::self) + .def(py::self / double()) + .def(py::self += py::self) + .def(py::self -= py::self) + .def(py::self *= py::self) + .def(py::self *= double()) + .def(py::self /= py::self) + .def(py::self /= double()) + .def(double() + py::self) + .def(double() - py::self) + .def(double() * py::self) + .def(double() / py::self); } \ No newline at end of file diff --git a/python/src/common.h b/python/src/common.h index 81b1193d..af875233 100644 --- a/python/src/common.h +++ b/python/src/common.h @@ -4,220 +4,209 @@ #include -#include #include #include #include #include -#include +#include #include +#include namespace hj = hyperjet; namespace py = pybind11; using namespace py::literals; -template -auto bind(py::module &m, const std::string &name) -{ - py::class_ cls(m, name.c_str()); - - // constructor - cls - .def(py::init(py::overload_cast(&T::constant)), "f"_a = 0, "size"_a) - .def(py::init(py::overload_cast(&T::create)), "data"_a) - .def(py::init(py::overload_cast(&T::constant)), "f"_a = 0); - - if constexpr (T::order() == 1) - { - cls - .def(py::init(&T::from_gradient), "f"_a, "g"_a); - } - else - { - cls - .def(py::init(&T::from_arrays), "f"_a, "g"_a, "hm"_a); - } - - // properties - cls - .def_property("f", py::overload_cast<>(&T::f, py::const_), &T::set_f); - - // static read-only properties - cls - .def_property_readonly_static("is_dynamic", [](py::object) - { return T::is_dynamic(); }) - .def_property_readonly_static("order", [](py::object) - { return T::order(); }); - - // read-only properties - cls - .def_property_readonly("data", py::overload_cast<>(&T::adata)) - .def_property_readonly("g", py::overload_cast<>(&T::ag)) - .def_property_readonly("size", &T::size); - - // static methods - cls - .def_static("constant", py::overload_cast(&T::constant), "f"_a, "size"_a) - .def_static("constant", py::overload_cast(&T::constant), "f"_a) - .def_static("empty", py::overload_cast<>(&T::empty)) - .def_static("empty", py::overload_cast(&T::empty), "size"_a) - .def_static("variable", py::overload_cast(&T::variable), "i"_a, "f"_a, "size"_a) - .def_static("zero", py::overload_cast<>(&T::zero)) - .def_static("zero", py::overload_cast(&T::zero), "size"_a); - - if constexpr (T::is_dynamic()) - { - cls - .def_static( - "variables", [](const std::vector &values) - { return T::variables(values); }, - "values"_a); - } - else - { - cls - .def_static("variable", py::overload_cast(&T::variable), "i"_a, "f"_a) - .def_static( - "variables", [](const std::array &values) - { return T::template variables(values); }, - "values"_a); - } - - // methods - cls - .def("__abs__", &T::abs) - .def("__len__", &T::size) - .def("__pow__", &T::pow) - .def("__repr__", &T::to_string) - .def("abs", &T::abs) - .def("eval", &T::eval, "d"_a) - .def("h", py::overload_cast(&T::h), "row"_a, "col"_a) - .def("set_h", py::overload_cast(&T::set_h), "row"_a, "col"_a, "value"_a) - .def("hm", py::overload_cast(&T::hm, py::const_), "mode"_a = "full") - .def("set_hm", &T::set_hm, "value"_a); - - if constexpr (T::is_dynamic()) - { - cls - .def("resize", &T::resize, "size"_a) - .def("pad_right", &T::pad_right, "new_size"_a) - .def("pad_left", &T::pad_left, "new_size"_a); - } - - // methods: arithmetic operations - cls - .def("reciprocal", &T::reciprocal) - .def("sqrt", &T::sqrt) - .def("cbrt", &T::cbrt) - .def("cos", &T::cos) - .def("sin", &T::sin) - .def("tan", &T::tan) - .def("acos", &T::acos) - .def("asin", &T::asin) - .def("atan", &T::atan) - .def("atan2", &T::atan2) - .def("arccos", &T::acos) - .def("arcsin", &T::asin) - .def("arctan", &T::atan) - .def("arctan2", &T::atan2) - .def("hypot", py::overload_cast(&T::hypot)) - .def("hypot", py::overload_cast(&T::hypot)); - - // methods: hyperbolic functions - cls - .def("cosh", &T::cosh) - .def("sinh", &T::sinh) - .def("tanh", &T::tanh) - .def("acosh", &T::acosh) - .def("arccosh", &T::acosh) - .def("asinh", &T::asinh) - .def("arcsinh", &T::asinh) - .def("atanh", &T::atanh) - .def("arctanh", &T::atanh); - - // methods: exponents and logarithms - cls - .def("exp", &T::exp) - .def("log", py::overload_cast<>(&T::log, py::const_)) - .def("log", py::overload_cast(&T::log, py::const_), "base"_a) - .def("log2", &T::log2) - .def("log10", &T::log10); - - // operators - cls - .def(-py::self) - .def(py::self == py::self) - .def(py::self != py::self) - .def(py::self < py::self) - .def(py::self > py::self) - .def(py::self <= py::self) - .def(py::self >= py::self) - .def(py::self == double()) - .def(py::self != double()) - .def(py::self < double()) - .def(py::self > double()) - .def(py::self <= double()) - .def(py::self >= double()) - .def(double() == py::self) - .def(double() != py::self) - .def(double() < py::self) - .def(double() > py::self) - .def(double() <= py::self) - .def(double() >= py::self) - .def(py::self + py::self) - .def(py::self + double()) - .def(py::self - py::self) - .def(py::self - double()) - .def(py::self * py::self) - .def(py::self * double()) - .def(py::self / py::self) - .def(py::self / double()) - .def(py::self += py::self) - .def(py::self -= py::self) - .def(py::self *= py::self) - .def(py::self *= double()) - .def(py::self /= py::self) - .def(py::self /= double()) - .def(double() + py::self) - .def(double() - py::self) - .def(double() * py::self) - .def(double() / py::self); - - // serialization - cls - .def(py::pickle( - [](const T &self) - { - return py::make_tuple(self.m_data); +template auto bind(py::module &m, const std::string &name) { + py::class_ cls(m, name.c_str()); + + // constructor + cls.def(py::init( + py::overload_cast(&T::constant)), + "f"_a = 0, "size"_a) + .def(py::init(py::overload_cast(&T::create)), + "data"_a) + .def(py::init(py::overload_cast(&T::constant)), + "f"_a = 0); + + if constexpr (T::order() == 1) { + cls.def(py::init(&T::from_gradient), "f"_a, "g"_a); + } else { + cls.def(py::init(&T::from_arrays), "f"_a, "g"_a, "hm"_a); + } + + // properties + cls.def_property("f", py::overload_cast<>(&T::f, py::const_), &T::set_f); + + // static read-only properties + cls.def_property_readonly_static("is_dynamic", + [](py::object) { return T::is_dynamic(); }) + .def_property_readonly_static("order", + [](py::object) { return T::order(); }); + + // read-only properties + cls.def_property_readonly("data", py::overload_cast<>(&T::adata)) + .def_property_readonly("g", py::overload_cast<>(&T::ag)) + .def_property_readonly("size", &T::size); + + // static methods + cls.def_static("constant", + py::overload_cast(&T::constant), + "f"_a, "size"_a) + .def_static("constant", + py::overload_cast(&T::constant), "f"_a) + .def_static("empty", py::overload_cast<>(&T::empty)) + .def_static("empty", py::overload_cast(&T::empty), "size"_a) + .def_static("variable", + py::overload_cast( + &T::variable), + "i"_a, "f"_a, "size"_a) + .def_static("zero", py::overload_cast<>(&T::zero)) + .def_static("zero", py::overload_cast(&T::zero), "size"_a); + + if constexpr (T::is_dynamic()) { + cls.def_static( + "variables", + [](const std::vector &values) { + return T::variables(values); + }, + "values"_a); + } else { + cls.def_static( + "variable", + py::overload_cast(&T::variable), + "i"_a, "f"_a) + .def_static( + "variables", + [](const std::array &values) { + return T::template variables(values); }, - [](py::tuple tuple) - { - if (hyperjet::length(tuple) != 1) - { - throw std::runtime_error("Invalid state!"); - } - - const auto data = tuple[0].cast(); - - if constexpr (T::is_dynamic()) - { - return T(data, T::size_from_data_length(hj::length(data))); - } - else - { - return T(data); - } - })) - .def("__copy__", [](const T &self) - { return self; }) - .def( - "__deepcopy__", [](const T &self, py::dict &memo) - { return self; }, - "memodict"_a); - - m.def("hypot", py::overload_cast(&T::hypot)); - m.def("hypot", py::overload_cast(&T::hypot)); - - return cls; + "values"_a); + } + + // methods + cls.def("__abs__", &T::abs) + .def("__len__", &T::size) + .def("__pow__", &T::pow) + .def("__repr__", &T::to_string) + .def("abs", &T::abs) + .def("eval", &T::eval, "d"_a) + .def("h", py::overload_cast(&T::h), "row"_a, + "col"_a) + .def("set_h", + py::overload_cast( + &T::set_h), + "row"_a, "col"_a, "value"_a) + .def("hm", py::overload_cast(&T::hm, py::const_), + "mode"_a = "full") + .def("set_hm", &T::set_hm, "value"_a); + + if constexpr (T::is_dynamic()) { + cls.def("resize", &T::resize, "size"_a) + .def("pad_right", &T::pad_right, "new_size"_a) + .def("pad_left", &T::pad_left, "new_size"_a); + } + + // methods: arithmetic operations + cls.def("reciprocal", &T::reciprocal) + .def("sqrt", &T::sqrt) + .def("cbrt", &T::cbrt) + .def("cos", &T::cos) + .def("sin", &T::sin) + .def("tan", &T::tan) + .def("acos", &T::acos) + .def("asin", &T::asin) + .def("atan", &T::atan) + .def("atan2", &T::atan2) + .def("arccos", &T::acos) + .def("arcsin", &T::asin) + .def("arctan", &T::atan) + .def("arctan2", &T::atan2) + .def("hypot", py::overload_cast(&T::hypot)) + .def("hypot", + py::overload_cast(&T::hypot)); + + // methods: hyperbolic functions + cls.def("cosh", &T::cosh) + .def("sinh", &T::sinh) + .def("tanh", &T::tanh) + .def("acosh", &T::acosh) + .def("arccosh", &T::acosh) + .def("asinh", &T::asinh) + .def("arcsinh", &T::asinh) + .def("atanh", &T::atanh) + .def("arctanh", &T::atanh); + + // methods: exponents and logarithms + cls.def("exp", &T::exp) + .def("log", py::overload_cast<>(&T::log, py::const_)) + .def("log", py::overload_cast(&T::log, py::const_), + "base"_a) + .def("log2", &T::log2) + .def("log10", &T::log10); + + // operators + cls.def(-py::self) + .def(py::self == py::self) + .def(py::self != py::self) + .def(py::self < py::self) + .def(py::self > py::self) + .def(py::self <= py::self) + .def(py::self >= py::self) + .def(py::self == double()) + .def(py::self != double()) + .def(py::self < double()) + .def(py::self > double()) + .def(py::self <= double()) + .def(py::self >= double()) + .def(double() == py::self) + .def(double() != py::self) + .def(double() < py::self) + .def(double() > py::self) + .def(double() <= py::self) + .def(double() >= py::self) + .def(py::self + py::self) + .def(py::self + double()) + .def(py::self - py::self) + .def(py::self - double()) + .def(py::self * py::self) + .def(py::self * double()) + .def(py::self / py::self) + .def(py::self / double()) + .def(py::self += py::self) + .def(py::self -= py::self) + .def(py::self *= py::self) + .def(py::self *= double()) + .def(py::self /= py::self) + .def(py::self /= double()) + .def(double() + py::self) + .def(double() - py::self) + .def(double() * py::self) + .def(double() / py::self); + + // serialization + cls.def(py::pickle([](const T &self) { return py::make_tuple(self.m_data); }, + [](py::tuple tuple) { + if (hyperjet::length(tuple) != 1) { + throw std::runtime_error("Invalid state!"); + } + + const auto data = tuple[0].cast(); + + if constexpr (T::is_dynamic()) { + return T(data, + T::size_from_data_length(hj::length(data))); + } else { + return T(data); + } + })) + .def("__copy__", [](const T &self) { return self; }) + .def( + "__deepcopy__", [](const T &self, py::dict &memo) { return self; }, + "memodict"_a); + + m.def("hypot", py::overload_cast(&T::hypot)); + m.def("hypot", py::overload_cast(&T::hypot)); + + return cls; } \ No newline at end of file diff --git a/python/src/main.cpp b/python/src/main.cpp index fc79b5ac..1a42a159 100644 --- a/python/src/main.cpp +++ b/python/src/main.cpp @@ -21,180 +21,181 @@ void bind_ddscalar_16d(pybind11::module &); void bind_sscalar(pybind11::module &); -PYBIND11_MODULE(hyperjet, m) -{ - using namespace pybind11::literals; +PYBIND11_MODULE(hyperjet, m) { + using namespace pybind11::literals; - namespace py = pybind11; - namespace hj = hyperjet; + namespace py = pybind11; + namespace hj = hyperjet; - m.doc() = "HyperJet by Thomas Oberbichler"; - m.attr("__author__") = "Thomas Oberbichler"; - m.attr("__copyright__") = "Copyright (c) 2019-2021, Thomas Oberbichler"; - m.attr("__version__") = HYPERJET_VERSION; - m.attr("__email__") = "thomas.oberbichler@gmail.com"; - m.attr("__status__") = "Development"; + m.doc() = "HyperJet by Thomas Oberbichler"; + m.attr("__author__") = "Thomas Oberbichler"; + m.attr("__copyright__") = "Copyright (c) 2019-2021, Thomas Oberbichler"; + m.attr("__version__") = HYPERJET_VERSION; + m.attr("__email__") = "thomas.oberbichler@gmail.com"; + m.attr("__status__") = "Development"; - bind_ddscalar_xd(m); - bind_ddscalar_0d(m); - bind_ddscalar_1d(m); - bind_ddscalar_2d(m); - bind_ddscalar_3d(m); - bind_ddscalar_4d(m); - bind_ddscalar_5d(m); - bind_ddscalar_6d(m); - bind_ddscalar_7d(m); - bind_ddscalar_8d(m); - bind_ddscalar_9d(m); - bind_ddscalar_10d(m); - bind_ddscalar_11d(m); - bind_ddscalar_12d(m); - bind_ddscalar_13d(m); - bind_ddscalar_14d(m); - bind_ddscalar_15d(m); - bind_ddscalar_16d(m); + bind_ddscalar_xd(m); + bind_ddscalar_0d(m); + bind_ddscalar_1d(m); + bind_ddscalar_2d(m); + bind_ddscalar_3d(m); + bind_ddscalar_4d(m); + bind_ddscalar_5d(m); + bind_ddscalar_6d(m); + bind_ddscalar_7d(m); + bind_ddscalar_8d(m); + bind_ddscalar_9d(m); + bind_ddscalar_10d(m); + bind_ddscalar_11d(m); + bind_ddscalar_12d(m); + bind_ddscalar_13d(m); + bind_ddscalar_14d(m); + bind_ddscalar_15d(m); + bind_ddscalar_16d(m); - bind_sscalar(m); + bind_sscalar(m); - // utilities - { - py::object numpy = py::module::import("numpy"); - auto global = py::dict(); - global["np"] = numpy; + // utilities + { + py::object numpy = py::module::import("numpy"); + auto global = py::dict(); + global["np"] = numpy; - m.attr("f") = py::eval("np.vectorize(lambda v: v.f if hasattr(v, 'f') else v)", global); - m.attr("d") = py::eval("np.vectorize(lambda v: v.g if hasattr(v, 'g') else np.zeros((0)), signature='()->(n)')", global); - m.attr("dd") = py::eval("np.vectorize(lambda v: v.hm() if hasattr(v, 'hm') else np.zeros((0, 0)), signature='()->(n,m)')", global); + m.attr("f") = py::eval( + "np.vectorize(lambda v: v.f if hasattr(v, 'f') else v)", global); + m.attr("d") = py::eval("np.vectorize(lambda v: v.g if hasattr(v, 'g') else " + "np.zeros((0)), signature='()->(n)')", + global); + m.attr("dd") = py::eval("np.vectorize(lambda v: v.hm() if hasattr(v, 'hm') " + "else np.zeros((0, 0)), signature='()->(n,m)')", + global); - m.def( - "variables", [](const std::vector &values, const hj::index order) - { - if (order < 0 || 2 < order) - { - throw std::runtime_error("Invalid order"); - } + m.def( + "variables", + [](const std::vector &values, const hj::index order) { + if (order < 0 || 2 < order) { + throw std::runtime_error("Invalid order"); + } - py::list results; + py::list results; - const auto extend = results.attr("extend"); + const auto extend = results.attr("extend"); - switch (order) - { - case 0: - extend(values); - break; - case 1: - switch (hj::length(values)) - { - case 0: - break; - case 1: - extend(hj::DDScalar<1, double, 1>::variables(values)); - break; - case 2: - extend(hj::DDScalar<1, double, 2>::variables(values)); - break; - case 3: - extend(hj::DDScalar<1, double, 3>::variables(values)); - break; - case 4: - extend(hj::DDScalar<1, double, 4>::variables(values)); - break; - case 5: - extend(hj::DDScalar<1, double, 5>::variables(values)); - break; - case 6: - extend(hj::DDScalar<1, double, 6>::variables(values)); - break; - case 7: - extend(hj::DDScalar<1, double, 7>::variables(values)); - break; - case 8: - extend(hj::DDScalar<1, double, 8>::variables(values)); - break; - case 9: - extend(hj::DDScalar<1, double, 9>::variables(values)); - break; - case 10: - extend(hj::DDScalar<1, double, 10>::variables(values)); - break; - case 11: - extend(hj::DDScalar<1, double, 11>::variables(values)); - break; - case 12: - extend(hj::DDScalar<1, double, 12>::variables(values)); - break; - case 13: - extend(hj::DDScalar<1, double, 13>::variables(values)); - break; - case 14: - extend(hj::DDScalar<1, double, 14>::variables(values)); - break; - case 15: - extend(hj::DDScalar<1, double, 15>::variables(values)); - break; - default: - extend(hj::DDScalar<1, double, -1>::variables(values)); - break; - } - break; - case 2: - switch (hj::length(values)) - { - case 0: - break; - case 1: - extend(hj::DDScalar<2, double, 1>::variables(values)); - break; - case 2: - extend(hj::DDScalar<2, double, 2>::variables(values)); - break; - case 3: - extend(hj::DDScalar<2, double, 3>::variables(values)); - break; - case 4: - extend(hj::DDScalar<2, double, 4>::variables(values)); - break; - case 5: - extend(hj::DDScalar<2, double, 5>::variables(values)); - break; - case 6: - extend(hj::DDScalar<2, double, 6>::variables(values)); - break; - case 7: - extend(hj::DDScalar<2, double, 7>::variables(values)); - break; - case 8: - extend(hj::DDScalar<2, double, 8>::variables(values)); - break; - case 9: - extend(hj::DDScalar<2, double, 9>::variables(values)); - break; - case 10: - extend(hj::DDScalar<2, double, 10>::variables(values)); - break; - case 11: - extend(hj::DDScalar<2, double, 11>::variables(values)); - break; - case 12: - extend(hj::DDScalar<2, double, 12>::variables(values)); - break; - case 13: - extend(hj::DDScalar<2, double, 13>::variables(values)); - break; - case 14: - extend(hj::DDScalar<2, double, 14>::variables(values)); - break; - case 15: - extend(hj::DDScalar<2, double, 15>::variables(values)); - break; - default: - extend(hj::DDScalar<2, double, -1>::variables(values)); - break; - } - break; - } - return results; }, - "values"_a, "order"_a = 2); - } + switch (order) { + case 0: + extend(values); + break; + case 1: + switch (hj::length(values)) { + case 0: + break; + case 1: + extend(hj::DDScalar<1, double, 1>::variables(values)); + break; + case 2: + extend(hj::DDScalar<1, double, 2>::variables(values)); + break; + case 3: + extend(hj::DDScalar<1, double, 3>::variables(values)); + break; + case 4: + extend(hj::DDScalar<1, double, 4>::variables(values)); + break; + case 5: + extend(hj::DDScalar<1, double, 5>::variables(values)); + break; + case 6: + extend(hj::DDScalar<1, double, 6>::variables(values)); + break; + case 7: + extend(hj::DDScalar<1, double, 7>::variables(values)); + break; + case 8: + extend(hj::DDScalar<1, double, 8>::variables(values)); + break; + case 9: + extend(hj::DDScalar<1, double, 9>::variables(values)); + break; + case 10: + extend(hj::DDScalar<1, double, 10>::variables(values)); + break; + case 11: + extend(hj::DDScalar<1, double, 11>::variables(values)); + break; + case 12: + extend(hj::DDScalar<1, double, 12>::variables(values)); + break; + case 13: + extend(hj::DDScalar<1, double, 13>::variables(values)); + break; + case 14: + extend(hj::DDScalar<1, double, 14>::variables(values)); + break; + case 15: + extend(hj::DDScalar<1, double, 15>::variables(values)); + break; + default: + extend(hj::DDScalar<1, double, -1>::variables(values)); + break; + } + break; + case 2: + switch (hj::length(values)) { + case 0: + break; + case 1: + extend(hj::DDScalar<2, double, 1>::variables(values)); + break; + case 2: + extend(hj::DDScalar<2, double, 2>::variables(values)); + break; + case 3: + extend(hj::DDScalar<2, double, 3>::variables(values)); + break; + case 4: + extend(hj::DDScalar<2, double, 4>::variables(values)); + break; + case 5: + extend(hj::DDScalar<2, double, 5>::variables(values)); + break; + case 6: + extend(hj::DDScalar<2, double, 6>::variables(values)); + break; + case 7: + extend(hj::DDScalar<2, double, 7>::variables(values)); + break; + case 8: + extend(hj::DDScalar<2, double, 8>::variables(values)); + break; + case 9: + extend(hj::DDScalar<2, double, 9>::variables(values)); + break; + case 10: + extend(hj::DDScalar<2, double, 10>::variables(values)); + break; + case 11: + extend(hj::DDScalar<2, double, 11>::variables(values)); + break; + case 12: + extend(hj::DDScalar<2, double, 12>::variables(values)); + break; + case 13: + extend(hj::DDScalar<2, double, 13>::variables(values)); + break; + case 14: + extend(hj::DDScalar<2, double, 14>::variables(values)); + break; + case 15: + extend(hj::DDScalar<2, double, 15>::variables(values)); + break; + default: + extend(hj::DDScalar<2, double, -1>::variables(values)); + break; + } + break; + } + return results; + }, + "values"_a, "order"_a = 2); + } } diff --git a/test/src/test.cpp b/test/src/test.cpp index af9bcb3b..b316f37b 100644 --- a/test/src/test.cpp +++ b/test/src/test.cpp @@ -11,728 +11,692 @@ using namespace hyperjet; -// f g0 g1 g2 h00 h01 h02 h11 h12 h22 -const DDScalar<2, double, 3> dd1{3.0, 1.0, 6.0, 4.0, 0.0, 5.0, 9.0, 2.0, 7.0, 8.0}; -const DDScalar<2, double, 3> dd2{4.0, 7.0, 1.0, 0.0, 6.0, 8.0, 2.0, 9.0, 5.0, 3.0}; -const DDScalar<2, double, 3> dd3{0.3, 0.1, 0.8, 0.2, 0.5, 0.7, 0.9, 0.4, 0.6, 0.0}; +// f g0 g1 g2 h00 h01 h02 h11 h12 h22 +const DDScalar<2, double, 3> dd1{3.0, 1.0, 6.0, 4.0, 0.0, + 5.0, 9.0, 2.0, 7.0, 8.0}; +const DDScalar<2, double, 3> dd2{4.0, 7.0, 1.0, 0.0, 6.0, + 8.0, 2.0, 9.0, 5.0, 3.0}; +const DDScalar<2, double, 3> dd3{0.3, 0.1, 0.8, 0.2, 0.5, + 0.7, 0.9, 0.4, 0.6, 0.0}; const Eigen::Matrix, 1, 3> ddv1{dd1, dd2, dd3}; const Eigen::Matrix, 1, 3> ddv2{dd3, dd1, dd2}; -TEST_CASE("<< DD") -{ - std::stringstream output; - - output << dd3; - - REQUIRE(output.str() == "0.3hj"); -} - -TEST_CASE("Neg") -{ - const auto r1 = -dd1; - - REQUIRE(r1.f() == doctest::Approx(-3)); - REQUIRE(r1.g(0) == doctest::Approx(-1)); - REQUIRE(r1.g(1) == doctest::Approx(-6)); - REQUIRE(r1.g(2) == doctest::Approx(-4)); - REQUIRE(r1.h(0, 0) == doctest::Approx(-0)); - REQUIRE(r1.h(0, 1) == doctest::Approx(-5)); - REQUIRE(r1.h(0, 2) == doctest::Approx(-9)); - REQUIRE(r1.h(1, 1) == doctest::Approx(-2)); - REQUIRE(r1.h(1, 2) == doctest::Approx(-7)); - REQUIRE(r1.h(2, 2) == doctest::Approx(-8)); -} - -TEST_CASE("Add") -{ - const auto r1 = dd1 + dd2; - - REQUIRE(r1.f() == doctest::Approx(7)); - REQUIRE(r1.g(0) == doctest::Approx(8)); - REQUIRE(r1.g(1) == doctest::Approx(7)); - REQUIRE(r1.g(2) == doctest::Approx(4)); - REQUIRE(r1.h(0, 0) == doctest::Approx(6)); - REQUIRE(r1.h(0, 1) == doctest::Approx(13)); - REQUIRE(r1.h(0, 2) == doctest::Approx(11)); - REQUIRE(r1.h(1, 1) == doctest::Approx(11)); - REQUIRE(r1.h(1, 2) == doctest::Approx(12)); - REQUIRE(r1.h(2, 2) == doctest::Approx(11)); - - const auto r2 = dd1 + 3.5; - - REQUIRE(r2.f() == doctest::Approx(6.5)); - REQUIRE(r2.g(0) == doctest::Approx(1.0)); - REQUIRE(r2.g(1) == doctest::Approx(6.0)); - REQUIRE(r2.g(2) == doctest::Approx(4.0)); - REQUIRE(r2.h(0, 0) == doctest::Approx(0.0)); - REQUIRE(r2.h(0, 1) == doctest::Approx(5.0)); - REQUIRE(r2.h(0, 2) == doctest::Approx(9.0)); - REQUIRE(r2.h(1, 1) == doctest::Approx(2.0)); - REQUIRE(r2.h(1, 2) == doctest::Approx(7.0)); - REQUIRE(r2.h(2, 2) == doctest::Approx(8.0)); - - const auto r3 = 3.5 + dd1; - - REQUIRE(r3.f() == doctest::Approx(6.5)); - REQUIRE(r3.g(0) == doctest::Approx(1.0)); - REQUIRE(r3.g(1) == doctest::Approx(6.0)); - REQUIRE(r3.g(2) == doctest::Approx(4.0)); - REQUIRE(r3.h(0, 0) == doctest::Approx(0.0)); - REQUIRE(r3.h(0, 1) == doctest::Approx(5.0)); - REQUIRE(r3.h(0, 2) == doctest::Approx(9.0)); - REQUIRE(r3.h(1, 1) == doctest::Approx(2.0)); - REQUIRE(r3.h(1, 2) == doctest::Approx(7.0)); - REQUIRE(r3.h(2, 2) == doctest::Approx(8.0)); -} - -TEST_CASE("IncAdd") -{ - auto r1 = dd1; - r1 += dd2; - - REQUIRE(r1.f() == doctest::Approx(7)); - REQUIRE(r1.g(0) == doctest::Approx(8)); - REQUIRE(r1.g(1) == doctest::Approx(7)); - REQUIRE(r1.g(2) == doctest::Approx(4)); - REQUIRE(r1.h(0, 0) == doctest::Approx(6)); - REQUIRE(r1.h(0, 1) == doctest::Approx(13)); - REQUIRE(r1.h(0, 2) == doctest::Approx(11)); - REQUIRE(r1.h(1, 1) == doctest::Approx(11)); - REQUIRE(r1.h(1, 2) == doctest::Approx(12)); - REQUIRE(r1.h(2, 2) == doctest::Approx(11)); - - auto r2 = dd1; - r2 += 3.5; - - REQUIRE(r2.f() == doctest::Approx(6.5)); - REQUIRE(r2.g(0) == doctest::Approx(1.0)); - REQUIRE(r2.g(1) == doctest::Approx(6.0)); - REQUIRE(r2.g(2) == doctest::Approx(4.0)); - REQUIRE(r2.h(0, 0) == doctest::Approx(0.0)); - REQUIRE(r2.h(0, 1) == doctest::Approx(5.0)); - REQUIRE(r2.h(0, 2) == doctest::Approx(9.0)); - REQUIRE(r2.h(1, 1) == doctest::Approx(2.0)); - REQUIRE(r2.h(1, 2) == doctest::Approx(7.0)); - REQUIRE(r2.h(2, 2) == doctest::Approx(8.0)); -} - -TEST_CASE("Sub") -{ - const auto r1 = dd1 - dd2; - - REQUIRE(r1.f() == doctest::Approx(-1.0)); - REQUIRE(r1.g(0) == doctest::Approx(-6.0)); - REQUIRE(r1.g(1) == doctest::Approx(5.0)); - REQUIRE(r1.g(2) == doctest::Approx(4.0)); - REQUIRE(r1.h(0, 0) == doctest::Approx(-6.0)); - REQUIRE(r1.h(0, 1) == doctest::Approx(-3.0)); - REQUIRE(r1.h(0, 2) == doctest::Approx(7.0)); - REQUIRE(r1.h(1, 1) == doctest::Approx(-7.0)); - REQUIRE(r1.h(1, 2) == doctest::Approx(2.0)); - REQUIRE(r1.h(2, 2) == doctest::Approx(5.0)); - - const auto r2 = dd1 - 3.5; - - REQUIRE(r2.f() == doctest::Approx(-0.5)); - REQUIRE(r2.g(0) == doctest::Approx(1.0)); - REQUIRE(r2.g(1) == doctest::Approx(6.0)); - REQUIRE(r2.g(2) == doctest::Approx(4.0)); - REQUIRE(r2.h(0, 0) == doctest::Approx(0.0)); - REQUIRE(r2.h(0, 1) == doctest::Approx(5.0)); - REQUIRE(r2.h(0, 2) == doctest::Approx(9.0)); - REQUIRE(r2.h(1, 1) == doctest::Approx(2.0)); - REQUIRE(r2.h(1, 2) == doctest::Approx(7.0)); - REQUIRE(r2.h(2, 2) == doctest::Approx(8.0)); - - const auto r3 = 3.5 - dd1; - - REQUIRE(r3.f() == doctest::Approx(0.5)); - REQUIRE(r3.g(0) == doctest::Approx(-1.0)); - REQUIRE(r3.g(1) == doctest::Approx(-6.0)); - REQUIRE(r3.g(2) == doctest::Approx(-4.0)); - REQUIRE(r3.h(0, 0) == doctest::Approx(-0.0)); - REQUIRE(r3.h(0, 1) == doctest::Approx(-5.0)); - REQUIRE(r3.h(0, 2) == doctest::Approx(-9.0)); - REQUIRE(r3.h(1, 1) == doctest::Approx(-2.0)); - REQUIRE(r3.h(1, 2) == doctest::Approx(-7.0)); - REQUIRE(r3.h(2, 2) == doctest::Approx(-8.0)); -} - -TEST_CASE("IncSub") -{ - auto r1 = dd1; - r1 -= dd2; - - REQUIRE(r1.f() == doctest::Approx(-1.0)); - REQUIRE(r1.g(0) == doctest::Approx(-6.0)); - REQUIRE(r1.g(1) == doctest::Approx(5.0)); - REQUIRE(r1.g(2) == doctest::Approx(4.0)); - REQUIRE(r1.h(0, 0) == doctest::Approx(-6.0)); - REQUIRE(r1.h(0, 1) == doctest::Approx(-3.0)); - REQUIRE(r1.h(0, 2) == doctest::Approx(7.0)); - REQUIRE(r1.h(1, 1) == doctest::Approx(-7.0)); - REQUIRE(r1.h(1, 2) == doctest::Approx(2.0)); - REQUIRE(r1.h(2, 2) == doctest::Approx(5.0)); - - auto r2 = dd1; - r2 -= 3.5; - - REQUIRE(r2.f() == doctest::Approx(-0.5)); - REQUIRE(r2.g(0) == doctest::Approx(1.0)); - REQUIRE(r2.g(1) == doctest::Approx(6.0)); - REQUIRE(r2.g(2) == doctest::Approx(4.0)); - REQUIRE(r2.h(0, 0) == doctest::Approx(0.0)); - REQUIRE(r2.h(0, 1) == doctest::Approx(5.0)); - REQUIRE(r2.h(0, 2) == doctest::Approx(9.0)); - REQUIRE(r2.h(1, 1) == doctest::Approx(2.0)); - REQUIRE(r2.h(1, 2) == doctest::Approx(7.0)); - REQUIRE(r2.h(2, 2) == doctest::Approx(8.0)); -} - -TEST_CASE("Mul") -{ - const auto r1 = dd1 * dd2; - - REQUIRE(r1.f() == doctest::Approx(12.0)); - REQUIRE(r1.g(0) == doctest::Approx(25.0)); - REQUIRE(r1.g(1) == doctest::Approx(27.0)); - REQUIRE(r1.g(2) == doctest::Approx(16.0)); - REQUIRE(r1.h(0, 0) == doctest::Approx(32.0)); - REQUIRE(r1.h(0, 1) == doctest::Approx(87.0)); - REQUIRE(r1.h(0, 2) == doctest::Approx(70.0)); - REQUIRE(r1.h(1, 1) == doctest::Approx(47.0)); - REQUIRE(r1.h(1, 2) == doctest::Approx(47.0)); - REQUIRE(r1.h(2, 2) == doctest::Approx(41.0)); -} - -TEST_CASE("IncMul") -{ - auto r1 = dd1; - r1 *= dd2; - - REQUIRE(r1.f() == doctest::Approx(12.0)); - REQUIRE(r1.g(0) == doctest::Approx(25.0)); - REQUIRE(r1.g(1) == doctest::Approx(27.0)); - REQUIRE(r1.g(2) == doctest::Approx(16.0)); - REQUIRE(r1.h(0, 0) == doctest::Approx(32.0)); - REQUIRE(r1.h(0, 1) == doctest::Approx(87.0)); - REQUIRE(r1.h(0, 2) == doctest::Approx(70.0)); - REQUIRE(r1.h(1, 1) == doctest::Approx(47.0)); - REQUIRE(r1.h(1, 2) == doctest::Approx(47.0)); - REQUIRE(r1.h(2, 2) == doctest::Approx(41.0)); -} - -TEST_CASE("Div") -{ - const auto r1 = dd1 / dd2; - - REQUIRE(r1.f() == doctest::Approx(0.75000)); - REQUIRE(r1.g(0) == doctest::Approx(-1.06250)); - REQUIRE(r1.g(1) == doctest::Approx(1.31250)); - REQUIRE(r1.g(2) == doctest::Approx(1.00000)); - REQUIRE(r1.h(0, 0) == doctest::Approx(2.59375)); - REQUIRE(r1.h(0, 1) == doctest::Approx(-2.28125)); - REQUIRE(r1.h(0, 2) == doctest::Approx(0.12500)); - REQUIRE(r1.h(1, 1) == doctest::Approx(-1.84375)); - REQUIRE(r1.h(1, 2) == doctest::Approx(0.56250)); - REQUIRE(r1.h(2, 2) == doctest::Approx(1.43750)); -} - -TEST_CASE("IncDiv") -{ - auto r1 = dd1; - r1 /= dd2; - - REQUIRE(r1.f() == doctest::Approx(0.75000)); - REQUIRE(r1.g(0) == doctest::Approx(-1.06250)); - REQUIRE(r1.g(1) == doctest::Approx(1.31250)); - REQUIRE(r1.g(2) == doctest::Approx(1.00000)); - REQUIRE(r1.h(0, 0) == doctest::Approx(2.59375)); - REQUIRE(r1.h(0, 1) == doctest::Approx(-2.28125)); - REQUIRE(r1.h(0, 2) == doctest::Approx(0.12500)); - REQUIRE(r1.h(1, 1) == doctest::Approx(-1.84375)); - REQUIRE(r1.h(1, 2) == doctest::Approx(0.56250)); - REQUIRE(r1.h(2, 2) == doctest::Approx(1.43750)); -} - -TEST_CASE("Pow") -{ - using std::pow; - - const auto r1 = pow(dd1, 3.5); - - REQUIRE(r1.f() == doctest::Approx(46.765371804359690)); - REQUIRE(r1.g(0) == doctest::Approx(54.559600438419636)); - REQUIRE(r1.g(1) == doctest::Approx(327.357602630517800)); - REQUIRE(r1.g(2) == doctest::Approx(218.238401753678540)); - REQUIRE(r1.h(0, 0) == doctest::Approx(45.466333698683030)); - REQUIRE(r1.h(0, 1) == doctest::Approx(545.596004384196400)); - REQUIRE(r1.h(0, 2) == doctest::Approx(672.901738740508800)); - REQUIRE(r1.h(1, 1) == doctest::Approx(1745.907214029428400)); - REQUIRE(r1.h(1, 2) == doctest::Approx(1473.109211837330100)); - REQUIRE(r1.h(2, 2) == doctest::Approx(1163.938142686285600)); -} - -TEST_CASE("Sqrt") -{ - using std::sqrt; - - const auto r1 = sqrt(dd1); - - REQUIRE(r1.f() == doctest::Approx(1.732050807568877200)); - REQUIRE(r1.g(0) == doctest::Approx(0.288675134594812900)); - REQUIRE(r1.g(1) == doctest::Approx(1.732050807568877400)); - REQUIRE(r1.g(2) == doctest::Approx(1.154700538379251700)); - REQUIRE(r1.h(0, 0) == doctest::Approx(-0.048112522432468816)); - REQUIRE(r1.h(0, 1) == doctest::Approx(1.154700538379251700)); - REQUIRE(r1.h(0, 2) == doctest::Approx(2.405626121623441000)); - REQUIRE(r1.h(1, 1) == doctest::Approx(-1.154700538379251700)); - REQUIRE(r1.h(1, 2) == doctest::Approx(0.866025403784438700)); - REQUIRE(r1.h(2, 2) == doctest::Approx(1.539600717839002300)); -} - -TEST_CASE("Cos") -{ - using std::cos; - - const auto r1 = cos(dd1); - - REQUIRE(r1.f() == doctest::Approx(-0.9899924966004454)); - REQUIRE(r1.g(0) == doctest::Approx(-0.1411200080598672)); - REQUIRE(r1.g(1) == doctest::Approx(-0.8467200483592032)); - REQUIRE(r1.g(2) == doctest::Approx(-0.5644800322394689)); - REQUIRE(r1.h(0, 0) == doctest::Approx(0.9899924966004454)); - REQUIRE(r1.h(0, 1) == doctest::Approx(5.2343549393033370)); - REQUIRE(r1.h(0, 2) == doctest::Approx(2.6898899138629770)); - REQUIRE(r1.h(1, 1) == doctest::Approx(35.3574898614963000)); - REQUIRE(r1.h(1, 2) == doctest::Approx(22.7719798619916200)); - REQUIRE(r1.h(2, 2) == doctest::Approx(14.7109198811281900)); -} - -TEST_CASE("Sin") -{ - using std::sin; - - const auto r1 = dd1.sin(); - - REQUIRE(r1.f() == doctest::Approx(0.1411200080598672)); - REQUIRE(r1.g(0) == doctest::Approx(-0.9899924966004454)); - REQUIRE(r1.g(1) == doctest::Approx(-5.9399549796026730)); - REQUIRE(r1.g(2) == doctest::Approx(-3.9599699864017817)); - REQUIRE(r1.h(0, 0) == doctest::Approx(-0.1411200080598672)); - REQUIRE(r1.h(0, 1) == doctest::Approx(-5.7966825313614300)); - REQUIRE(r1.h(0, 2) == doctest::Approx(-9.4744125016434780)); - REQUIRE(r1.h(1, 1) == doctest::Approx(-7.0603052833561100)); - REQUIRE(r1.h(1, 2) == doctest::Approx(-10.3168276696399310)); - REQUIRE(r1.h(2, 2) == doctest::Approx(-10.1778601017614400)); -} - -TEST_CASE("Tan") -{ - using std::tan; - - const auto r1 = tan(dd1); - - REQUIRE(r1.f() == doctest::Approx(-0.14254654307427780)); - REQUIRE(r1.g(0) == doctest::Approx(1.02031951694242680)); - REQUIRE(r1.g(1) == doctest::Approx(6.12191710165456100)); - REQUIRE(r1.g(2) == doctest::Approx(4.08127806776970700)); - REQUIRE(r1.h(0, 0) == doctest::Approx(-0.29088603994271994)); - REQUIRE(r1.h(0, 1) == doctest::Approx(3.35628134505581470)); - REQUIRE(r1.h(0, 2) == doctest::Approx(8.01933149271096100)); - REQUIRE(r1.h(1, 1) == doctest::Approx(-8.43125840405306400)); - REQUIRE(r1.h(1, 2) == doctest::Approx(0.16097165997170980)); - REQUIRE(r1.h(2, 2) == doctest::Approx(3.50837949645589560)); -} - -TEST_CASE("Acos") -{ - using std::acos; - - const auto r1 = acos(dd3); - - REQUIRE(r1.f() == doctest::Approx(1.266103672779499200)); - REQUIRE(r1.g(0) == doctest::Approx(-0.104828483672191830)); - REQUIRE(r1.g(1) == doctest::Approx(-0.838627869377534600)); - REQUIRE(r1.g(2) == doctest::Approx(-0.209656967344383660)); - REQUIRE(r1.h(0, 0) == doctest::Approx(-0.527598302438064400)); - REQUIRE(r1.h(0, 1) == doctest::Approx(-0.761446458322184600)); - REQUIRE(r1.h(0, 2) == doctest::Approx(-0.950368121203936900)); - REQUIRE(r1.h(1, 1) == doctest::Approx(-0.640490515623501800)); - REQUIRE(r1.h(1, 2) == doctest::Approx(-0.684265047266834600)); - REQUIRE(r1.h(2, 2) == doctest::Approx(-0.013823536308420903)); -} - -TEST_CASE("Asin") -{ - using std::asin; - - const auto r1 = asin(dd3); - - REQUIRE(r1.f() == doctest::Approx(0.304692654015397500)); - REQUIRE(r1.g(0) == doctest::Approx(0.104828483672191830)); - REQUIRE(r1.g(1) == doctest::Approx(0.838627869377534600)); - REQUIRE(r1.g(2) == doctest::Approx(0.209656967344383660)); - REQUIRE(r1.h(0, 0) == doctest::Approx(0.527598302438064400)); - REQUIRE(r1.h(0, 1) == doctest::Approx(0.761446458322184600)); - REQUIRE(r1.h(0, 2) == doctest::Approx(0.950368121203936900)); - REQUIRE(r1.h(1, 1) == doctest::Approx(0.640490515623501700)); - REQUIRE(r1.h(1, 2) == doctest::Approx(0.684265047266834600)); - REQUIRE(r1.h(2, 2) == doctest::Approx(0.013823536308420899)); -} - -TEST_CASE("Atan") -{ - using std::atan; - - const auto r1 = atan(dd3); - - REQUIRE(r1.f() == doctest::Approx(0.291456794477867100)); - REQUIRE(r1.g(0) == doctest::Approx(0.091743119266055050)); - REQUIRE(r1.g(1) == doctest::Approx(0.733944954128440400)); - REQUIRE(r1.g(2) == doctest::Approx(0.183486238532110100)); - REQUIRE(r1.h(0, 0) == doctest::Approx(0.453665516370675800)); - REQUIRE(r1.h(0, 1) == doctest::Approx(0.601801195185590400)); - REQUIRE(r1.h(0, 2) == doctest::Approx(0.815587913475296700)); - REQUIRE(r1.h(1, 1) == doctest::Approx(0.043767359649861170)); - REQUIRE(r1.h(1, 2) == doctest::Approx(0.469657436242740500)); - REQUIRE(r1.h(2, 2) == doctest::Approx(-0.020200319838397436)); -} - -TEST_CASE("Atan2") -{ - using std::atan2; - - const auto r1 = atan2(dd1, dd2); - - REQUIRE(r1.f() == doctest::Approx(0.6435011087932844)); - REQUIRE(r1.g(0) == doctest::Approx(-0.6800000000000000)); - REQUIRE(r1.g(1) == doctest::Approx(0.8400000000000000)); - REQUIRE(r1.g(2) == doctest::Approx(0.6400000000000000)); - REQUIRE(r1.h(0, 0) == doctest::Approx(0.9664000000000000)); - REQUIRE(r1.h(0, 1) == doctest::Approx(-0.6032000000000000)); - REQUIRE(r1.h(0, 2) == doctest::Approx(0.7328000000000000)); - REQUIRE(r1.h(1, 1) == doctest::Approx(-2.2384000000000000)); - REQUIRE(r1.h(1, 2) == doctest::Approx(-0.4464000000000000)); - REQUIRE(r1.h(2, 2) == doctest::Approx(0.3056000000000000)); -} - -TEST_CASE("Dot") -{ - const auto r = ddv1.dot(ddv2); - - REQUIRE(r.f() == doctest::Approx(14.1)); - REQUIRE(r.g(0) == doctest::Approx(28.1)); - REQUIRE(r.g(1) == doctest::Approx(34.7)); - REQUIRE(r.g(2) == doctest::Approx(18.6)); - REQUIRE(r.h(0, 0) == doctest::Approx(38.9)); - REQUIRE(r.h(0, 1) == doctest::Approx(102.9)); - REQUIRE(r.h(0, 2) == doctest::Approx(81.6)); - REQUIRE(r.h(1, 1) == doctest::Approx(64.3)); - REQUIRE(r.h(1, 2) == doctest::Approx(59.4)); - REQUIRE(r.h(2, 2) == doctest::Approx(45.9)); -} - -TEST_CASE("Cross") -{ - const auto r = ddv1.cross(ddv2); - - const auto rx = r.x(); - const auto ry = r.y(); - const auto rz = r.z(); - - REQUIRE(rx.f() == doctest::Approx(15.1)); - REQUIRE(rx.g(0) == doctest::Approx(55.4)); - REQUIRE(rx.g(1) == doctest::Approx(3.8)); - REQUIRE(rx.g(2) == doctest::Approx(-1.8)); - REQUIRE(rx.h(0, 0) == doctest::Approx(144.3)); - REQUIRE(rx.h(0, 1) == doctest::Approx(73.0)); - REQUIRE(rx.h(0, 2) == doctest::Approx(10.0)); - REQUIRE(rx.h(1, 1) == doctest::Approx(62.6)); - REQUIRE(rx.h(1, 2) == doctest::Approx(31.7)); - REQUIRE(rx.h(2, 2) == doctest::Approx(20.0)); - - REQUIRE(ry.f() == doctest::Approx(-11.91)); - REQUIRE(ry.g(0) == doctest::Approx(-24.94)); - REQUIRE(ry.g(1) == doctest::Approx(-26.52)); - REQUIRE(ry.g(2) == doctest::Approx(-15.88)); - REQUIRE(ry.h(0, 0) == doctest::Approx(-31.68)); - REQUIRE(ry.h(0, 1) == doctest::Approx(-86.42)); - REQUIRE(ry.h(0, 2) == doctest::Approx(-69.42)); - REQUIRE(ry.h(1, 1) == doctest::Approx(-45.48)); - REQUIRE(ry.h(1, 2) == doctest::Approx(-46.32)); - REQUIRE(ry.h(2, 2) == doctest::Approx(-40.92)); - - REQUIRE(rz.f() == doctest::Approx(7.8)); - REQUIRE(rz.g(0) == doctest::Approx(3.5)); - REQUIRE(rz.g(1) == doctest::Approx(32.5)); - REQUIRE(rz.g(2) == doctest::Approx(23.2)); - REQUIRE(rz.h(0, 0) == doctest::Approx(-3.2)); - REQUIRE(rz.h(0, 1) == doctest::Approx(31.1)); - REQUIRE(rz.h(0, 2) == doctest::Approx(56.4)); - REQUIRE(rz.h(1, 1) == doctest::Approx(78.1)); - REQUIRE(rz.h(1, 2) == doctest::Approx(85.9)); - REQUIRE(rz.h(2, 2) == doctest::Approx(79.1)); -} - -TEST_CASE("Norm") -{ - const auto r = ddv1.norm(); - - REQUIRE(r.f() == doctest::Approx(5.0089919145472770)); - REQUIRE(r.g(0) == doctest::Approx(6.1948592709606230)); - REQUIRE(r.g(1) == doctest::Approx(4.4400151526317835)); - REQUIRE(r.g(2) == doctest::Approx(2.4076700872634587)); - REQUIRE(r.h(0, 0) == doctest::Approx(7.1438962616547620)); - REQUIRE(r.h(0, 1) == doctest::Approx(6.5451754620124020)); - REQUIRE(r.h(0, 2) == doctest::Approx(4.8662132130242100)); - REQUIRE(r.h(1, 1) == doctest::Approx(11.9876946237449200)); - REQUIRE(r.h(1, 2) == doctest::Approx(10.9103606598557140)); - REQUIRE(r.h(2, 2) == doctest::Approx(9.2320222391647280)); +TEST_CASE("<< DD") { + std::stringstream output; + + output << dd3; + + REQUIRE(output.str() == "0.3hj"); +} + +TEST_CASE("Neg") { + const auto r1 = -dd1; + + REQUIRE(r1.f() == doctest::Approx(-3)); + REQUIRE(r1.g(0) == doctest::Approx(-1)); + REQUIRE(r1.g(1) == doctest::Approx(-6)); + REQUIRE(r1.g(2) == doctest::Approx(-4)); + REQUIRE(r1.h(0, 0) == doctest::Approx(-0)); + REQUIRE(r1.h(0, 1) == doctest::Approx(-5)); + REQUIRE(r1.h(0, 2) == doctest::Approx(-9)); + REQUIRE(r1.h(1, 1) == doctest::Approx(-2)); + REQUIRE(r1.h(1, 2) == doctest::Approx(-7)); + REQUIRE(r1.h(2, 2) == doctest::Approx(-8)); +} + +TEST_CASE("Add") { + const auto r1 = dd1 + dd2; + + REQUIRE(r1.f() == doctest::Approx(7)); + REQUIRE(r1.g(0) == doctest::Approx(8)); + REQUIRE(r1.g(1) == doctest::Approx(7)); + REQUIRE(r1.g(2) == doctest::Approx(4)); + REQUIRE(r1.h(0, 0) == doctest::Approx(6)); + REQUIRE(r1.h(0, 1) == doctest::Approx(13)); + REQUIRE(r1.h(0, 2) == doctest::Approx(11)); + REQUIRE(r1.h(1, 1) == doctest::Approx(11)); + REQUIRE(r1.h(1, 2) == doctest::Approx(12)); + REQUIRE(r1.h(2, 2) == doctest::Approx(11)); + + const auto r2 = dd1 + 3.5; + + REQUIRE(r2.f() == doctest::Approx(6.5)); + REQUIRE(r2.g(0) == doctest::Approx(1.0)); + REQUIRE(r2.g(1) == doctest::Approx(6.0)); + REQUIRE(r2.g(2) == doctest::Approx(4.0)); + REQUIRE(r2.h(0, 0) == doctest::Approx(0.0)); + REQUIRE(r2.h(0, 1) == doctest::Approx(5.0)); + REQUIRE(r2.h(0, 2) == doctest::Approx(9.0)); + REQUIRE(r2.h(1, 1) == doctest::Approx(2.0)); + REQUIRE(r2.h(1, 2) == doctest::Approx(7.0)); + REQUIRE(r2.h(2, 2) == doctest::Approx(8.0)); + + const auto r3 = 3.5 + dd1; + + REQUIRE(r3.f() == doctest::Approx(6.5)); + REQUIRE(r3.g(0) == doctest::Approx(1.0)); + REQUIRE(r3.g(1) == doctest::Approx(6.0)); + REQUIRE(r3.g(2) == doctest::Approx(4.0)); + REQUIRE(r3.h(0, 0) == doctest::Approx(0.0)); + REQUIRE(r3.h(0, 1) == doctest::Approx(5.0)); + REQUIRE(r3.h(0, 2) == doctest::Approx(9.0)); + REQUIRE(r3.h(1, 1) == doctest::Approx(2.0)); + REQUIRE(r3.h(1, 2) == doctest::Approx(7.0)); + REQUIRE(r3.h(2, 2) == doctest::Approx(8.0)); +} + +TEST_CASE("IncAdd") { + auto r1 = dd1; + r1 += dd2; + + REQUIRE(r1.f() == doctest::Approx(7)); + REQUIRE(r1.g(0) == doctest::Approx(8)); + REQUIRE(r1.g(1) == doctest::Approx(7)); + REQUIRE(r1.g(2) == doctest::Approx(4)); + REQUIRE(r1.h(0, 0) == doctest::Approx(6)); + REQUIRE(r1.h(0, 1) == doctest::Approx(13)); + REQUIRE(r1.h(0, 2) == doctest::Approx(11)); + REQUIRE(r1.h(1, 1) == doctest::Approx(11)); + REQUIRE(r1.h(1, 2) == doctest::Approx(12)); + REQUIRE(r1.h(2, 2) == doctest::Approx(11)); + + auto r2 = dd1; + r2 += 3.5; + + REQUIRE(r2.f() == doctest::Approx(6.5)); + REQUIRE(r2.g(0) == doctest::Approx(1.0)); + REQUIRE(r2.g(1) == doctest::Approx(6.0)); + REQUIRE(r2.g(2) == doctest::Approx(4.0)); + REQUIRE(r2.h(0, 0) == doctest::Approx(0.0)); + REQUIRE(r2.h(0, 1) == doctest::Approx(5.0)); + REQUIRE(r2.h(0, 2) == doctest::Approx(9.0)); + REQUIRE(r2.h(1, 1) == doctest::Approx(2.0)); + REQUIRE(r2.h(1, 2) == doctest::Approx(7.0)); + REQUIRE(r2.h(2, 2) == doctest::Approx(8.0)); +} + +TEST_CASE("Sub") { + const auto r1 = dd1 - dd2; + + REQUIRE(r1.f() == doctest::Approx(-1.0)); + REQUIRE(r1.g(0) == doctest::Approx(-6.0)); + REQUIRE(r1.g(1) == doctest::Approx(5.0)); + REQUIRE(r1.g(2) == doctest::Approx(4.0)); + REQUIRE(r1.h(0, 0) == doctest::Approx(-6.0)); + REQUIRE(r1.h(0, 1) == doctest::Approx(-3.0)); + REQUIRE(r1.h(0, 2) == doctest::Approx(7.0)); + REQUIRE(r1.h(1, 1) == doctest::Approx(-7.0)); + REQUIRE(r1.h(1, 2) == doctest::Approx(2.0)); + REQUIRE(r1.h(2, 2) == doctest::Approx(5.0)); + + const auto r2 = dd1 - 3.5; + + REQUIRE(r2.f() == doctest::Approx(-0.5)); + REQUIRE(r2.g(0) == doctest::Approx(1.0)); + REQUIRE(r2.g(1) == doctest::Approx(6.0)); + REQUIRE(r2.g(2) == doctest::Approx(4.0)); + REQUIRE(r2.h(0, 0) == doctest::Approx(0.0)); + REQUIRE(r2.h(0, 1) == doctest::Approx(5.0)); + REQUIRE(r2.h(0, 2) == doctest::Approx(9.0)); + REQUIRE(r2.h(1, 1) == doctest::Approx(2.0)); + REQUIRE(r2.h(1, 2) == doctest::Approx(7.0)); + REQUIRE(r2.h(2, 2) == doctest::Approx(8.0)); + + const auto r3 = 3.5 - dd1; + + REQUIRE(r3.f() == doctest::Approx(0.5)); + REQUIRE(r3.g(0) == doctest::Approx(-1.0)); + REQUIRE(r3.g(1) == doctest::Approx(-6.0)); + REQUIRE(r3.g(2) == doctest::Approx(-4.0)); + REQUIRE(r3.h(0, 0) == doctest::Approx(-0.0)); + REQUIRE(r3.h(0, 1) == doctest::Approx(-5.0)); + REQUIRE(r3.h(0, 2) == doctest::Approx(-9.0)); + REQUIRE(r3.h(1, 1) == doctest::Approx(-2.0)); + REQUIRE(r3.h(1, 2) == doctest::Approx(-7.0)); + REQUIRE(r3.h(2, 2) == doctest::Approx(-8.0)); +} + +TEST_CASE("IncSub") { + auto r1 = dd1; + r1 -= dd2; + + REQUIRE(r1.f() == doctest::Approx(-1.0)); + REQUIRE(r1.g(0) == doctest::Approx(-6.0)); + REQUIRE(r1.g(1) == doctest::Approx(5.0)); + REQUIRE(r1.g(2) == doctest::Approx(4.0)); + REQUIRE(r1.h(0, 0) == doctest::Approx(-6.0)); + REQUIRE(r1.h(0, 1) == doctest::Approx(-3.0)); + REQUIRE(r1.h(0, 2) == doctest::Approx(7.0)); + REQUIRE(r1.h(1, 1) == doctest::Approx(-7.0)); + REQUIRE(r1.h(1, 2) == doctest::Approx(2.0)); + REQUIRE(r1.h(2, 2) == doctest::Approx(5.0)); + + auto r2 = dd1; + r2 -= 3.5; + + REQUIRE(r2.f() == doctest::Approx(-0.5)); + REQUIRE(r2.g(0) == doctest::Approx(1.0)); + REQUIRE(r2.g(1) == doctest::Approx(6.0)); + REQUIRE(r2.g(2) == doctest::Approx(4.0)); + REQUIRE(r2.h(0, 0) == doctest::Approx(0.0)); + REQUIRE(r2.h(0, 1) == doctest::Approx(5.0)); + REQUIRE(r2.h(0, 2) == doctest::Approx(9.0)); + REQUIRE(r2.h(1, 1) == doctest::Approx(2.0)); + REQUIRE(r2.h(1, 2) == doctest::Approx(7.0)); + REQUIRE(r2.h(2, 2) == doctest::Approx(8.0)); +} + +TEST_CASE("Mul") { + const auto r1 = dd1 * dd2; + + REQUIRE(r1.f() == doctest::Approx(12.0)); + REQUIRE(r1.g(0) == doctest::Approx(25.0)); + REQUIRE(r1.g(1) == doctest::Approx(27.0)); + REQUIRE(r1.g(2) == doctest::Approx(16.0)); + REQUIRE(r1.h(0, 0) == doctest::Approx(32.0)); + REQUIRE(r1.h(0, 1) == doctest::Approx(87.0)); + REQUIRE(r1.h(0, 2) == doctest::Approx(70.0)); + REQUIRE(r1.h(1, 1) == doctest::Approx(47.0)); + REQUIRE(r1.h(1, 2) == doctest::Approx(47.0)); + REQUIRE(r1.h(2, 2) == doctest::Approx(41.0)); +} + +TEST_CASE("IncMul") { + auto r1 = dd1; + r1 *= dd2; + + REQUIRE(r1.f() == doctest::Approx(12.0)); + REQUIRE(r1.g(0) == doctest::Approx(25.0)); + REQUIRE(r1.g(1) == doctest::Approx(27.0)); + REQUIRE(r1.g(2) == doctest::Approx(16.0)); + REQUIRE(r1.h(0, 0) == doctest::Approx(32.0)); + REQUIRE(r1.h(0, 1) == doctest::Approx(87.0)); + REQUIRE(r1.h(0, 2) == doctest::Approx(70.0)); + REQUIRE(r1.h(1, 1) == doctest::Approx(47.0)); + REQUIRE(r1.h(1, 2) == doctest::Approx(47.0)); + REQUIRE(r1.h(2, 2) == doctest::Approx(41.0)); +} + +TEST_CASE("Div") { + const auto r1 = dd1 / dd2; + + REQUIRE(r1.f() == doctest::Approx(0.75000)); + REQUIRE(r1.g(0) == doctest::Approx(-1.06250)); + REQUIRE(r1.g(1) == doctest::Approx(1.31250)); + REQUIRE(r1.g(2) == doctest::Approx(1.00000)); + REQUIRE(r1.h(0, 0) == doctest::Approx(2.59375)); + REQUIRE(r1.h(0, 1) == doctest::Approx(-2.28125)); + REQUIRE(r1.h(0, 2) == doctest::Approx(0.12500)); + REQUIRE(r1.h(1, 1) == doctest::Approx(-1.84375)); + REQUIRE(r1.h(1, 2) == doctest::Approx(0.56250)); + REQUIRE(r1.h(2, 2) == doctest::Approx(1.43750)); +} + +TEST_CASE("IncDiv") { + auto r1 = dd1; + r1 /= dd2; + + REQUIRE(r1.f() == doctest::Approx(0.75000)); + REQUIRE(r1.g(0) == doctest::Approx(-1.06250)); + REQUIRE(r1.g(1) == doctest::Approx(1.31250)); + REQUIRE(r1.g(2) == doctest::Approx(1.00000)); + REQUIRE(r1.h(0, 0) == doctest::Approx(2.59375)); + REQUIRE(r1.h(0, 1) == doctest::Approx(-2.28125)); + REQUIRE(r1.h(0, 2) == doctest::Approx(0.12500)); + REQUIRE(r1.h(1, 1) == doctest::Approx(-1.84375)); + REQUIRE(r1.h(1, 2) == doctest::Approx(0.56250)); + REQUIRE(r1.h(2, 2) == doctest::Approx(1.43750)); +} + +TEST_CASE("Pow") { + using std::pow; + + const auto r1 = pow(dd1, 3.5); + + REQUIRE(r1.f() == doctest::Approx(46.765371804359690)); + REQUIRE(r1.g(0) == doctest::Approx(54.559600438419636)); + REQUIRE(r1.g(1) == doctest::Approx(327.357602630517800)); + REQUIRE(r1.g(2) == doctest::Approx(218.238401753678540)); + REQUIRE(r1.h(0, 0) == doctest::Approx(45.466333698683030)); + REQUIRE(r1.h(0, 1) == doctest::Approx(545.596004384196400)); + REQUIRE(r1.h(0, 2) == doctest::Approx(672.901738740508800)); + REQUIRE(r1.h(1, 1) == doctest::Approx(1745.907214029428400)); + REQUIRE(r1.h(1, 2) == doctest::Approx(1473.109211837330100)); + REQUIRE(r1.h(2, 2) == doctest::Approx(1163.938142686285600)); +} + +TEST_CASE("Sqrt") { + using std::sqrt; + + const auto r1 = sqrt(dd1); + + REQUIRE(r1.f() == doctest::Approx(1.732050807568877200)); + REQUIRE(r1.g(0) == doctest::Approx(0.288675134594812900)); + REQUIRE(r1.g(1) == doctest::Approx(1.732050807568877400)); + REQUIRE(r1.g(2) == doctest::Approx(1.154700538379251700)); + REQUIRE(r1.h(0, 0) == doctest::Approx(-0.048112522432468816)); + REQUIRE(r1.h(0, 1) == doctest::Approx(1.154700538379251700)); + REQUIRE(r1.h(0, 2) == doctest::Approx(2.405626121623441000)); + REQUIRE(r1.h(1, 1) == doctest::Approx(-1.154700538379251700)); + REQUIRE(r1.h(1, 2) == doctest::Approx(0.866025403784438700)); + REQUIRE(r1.h(2, 2) == doctest::Approx(1.539600717839002300)); +} + +TEST_CASE("Cos") { + using std::cos; + + const auto r1 = cos(dd1); + + REQUIRE(r1.f() == doctest::Approx(-0.9899924966004454)); + REQUIRE(r1.g(0) == doctest::Approx(-0.1411200080598672)); + REQUIRE(r1.g(1) == doctest::Approx(-0.8467200483592032)); + REQUIRE(r1.g(2) == doctest::Approx(-0.5644800322394689)); + REQUIRE(r1.h(0, 0) == doctest::Approx(0.9899924966004454)); + REQUIRE(r1.h(0, 1) == doctest::Approx(5.2343549393033370)); + REQUIRE(r1.h(0, 2) == doctest::Approx(2.6898899138629770)); + REQUIRE(r1.h(1, 1) == doctest::Approx(35.3574898614963000)); + REQUIRE(r1.h(1, 2) == doctest::Approx(22.7719798619916200)); + REQUIRE(r1.h(2, 2) == doctest::Approx(14.7109198811281900)); +} + +TEST_CASE("Sin") { + using std::sin; + + const auto r1 = dd1.sin(); + + REQUIRE(r1.f() == doctest::Approx(0.1411200080598672)); + REQUIRE(r1.g(0) == doctest::Approx(-0.9899924966004454)); + REQUIRE(r1.g(1) == doctest::Approx(-5.9399549796026730)); + REQUIRE(r1.g(2) == doctest::Approx(-3.9599699864017817)); + REQUIRE(r1.h(0, 0) == doctest::Approx(-0.1411200080598672)); + REQUIRE(r1.h(0, 1) == doctest::Approx(-5.7966825313614300)); + REQUIRE(r1.h(0, 2) == doctest::Approx(-9.4744125016434780)); + REQUIRE(r1.h(1, 1) == doctest::Approx(-7.0603052833561100)); + REQUIRE(r1.h(1, 2) == doctest::Approx(-10.3168276696399310)); + REQUIRE(r1.h(2, 2) == doctest::Approx(-10.1778601017614400)); +} + +TEST_CASE("Tan") { + using std::tan; + + const auto r1 = tan(dd1); + + REQUIRE(r1.f() == doctest::Approx(-0.14254654307427780)); + REQUIRE(r1.g(0) == doctest::Approx(1.02031951694242680)); + REQUIRE(r1.g(1) == doctest::Approx(6.12191710165456100)); + REQUIRE(r1.g(2) == doctest::Approx(4.08127806776970700)); + REQUIRE(r1.h(0, 0) == doctest::Approx(-0.29088603994271994)); + REQUIRE(r1.h(0, 1) == doctest::Approx(3.35628134505581470)); + REQUIRE(r1.h(0, 2) == doctest::Approx(8.01933149271096100)); + REQUIRE(r1.h(1, 1) == doctest::Approx(-8.43125840405306400)); + REQUIRE(r1.h(1, 2) == doctest::Approx(0.16097165997170980)); + REQUIRE(r1.h(2, 2) == doctest::Approx(3.50837949645589560)); +} + +TEST_CASE("Acos") { + using std::acos; + + const auto r1 = acos(dd3); + + REQUIRE(r1.f() == doctest::Approx(1.266103672779499200)); + REQUIRE(r1.g(0) == doctest::Approx(-0.104828483672191830)); + REQUIRE(r1.g(1) == doctest::Approx(-0.838627869377534600)); + REQUIRE(r1.g(2) == doctest::Approx(-0.209656967344383660)); + REQUIRE(r1.h(0, 0) == doctest::Approx(-0.527598302438064400)); + REQUIRE(r1.h(0, 1) == doctest::Approx(-0.761446458322184600)); + REQUIRE(r1.h(0, 2) == doctest::Approx(-0.950368121203936900)); + REQUIRE(r1.h(1, 1) == doctest::Approx(-0.640490515623501800)); + REQUIRE(r1.h(1, 2) == doctest::Approx(-0.684265047266834600)); + REQUIRE(r1.h(2, 2) == doctest::Approx(-0.013823536308420903)); +} + +TEST_CASE("Asin") { + using std::asin; + + const auto r1 = asin(dd3); + + REQUIRE(r1.f() == doctest::Approx(0.304692654015397500)); + REQUIRE(r1.g(0) == doctest::Approx(0.104828483672191830)); + REQUIRE(r1.g(1) == doctest::Approx(0.838627869377534600)); + REQUIRE(r1.g(2) == doctest::Approx(0.209656967344383660)); + REQUIRE(r1.h(0, 0) == doctest::Approx(0.527598302438064400)); + REQUIRE(r1.h(0, 1) == doctest::Approx(0.761446458322184600)); + REQUIRE(r1.h(0, 2) == doctest::Approx(0.950368121203936900)); + REQUIRE(r1.h(1, 1) == doctest::Approx(0.640490515623501700)); + REQUIRE(r1.h(1, 2) == doctest::Approx(0.684265047266834600)); + REQUIRE(r1.h(2, 2) == doctest::Approx(0.013823536308420899)); +} + +TEST_CASE("Atan") { + using std::atan; + + const auto r1 = atan(dd3); + + REQUIRE(r1.f() == doctest::Approx(0.291456794477867100)); + REQUIRE(r1.g(0) == doctest::Approx(0.091743119266055050)); + REQUIRE(r1.g(1) == doctest::Approx(0.733944954128440400)); + REQUIRE(r1.g(2) == doctest::Approx(0.183486238532110100)); + REQUIRE(r1.h(0, 0) == doctest::Approx(0.453665516370675800)); + REQUIRE(r1.h(0, 1) == doctest::Approx(0.601801195185590400)); + REQUIRE(r1.h(0, 2) == doctest::Approx(0.815587913475296700)); + REQUIRE(r1.h(1, 1) == doctest::Approx(0.043767359649861170)); + REQUIRE(r1.h(1, 2) == doctest::Approx(0.469657436242740500)); + REQUIRE(r1.h(2, 2) == doctest::Approx(-0.020200319838397436)); +} + +TEST_CASE("Atan2") { + using std::atan2; + + const auto r1 = atan2(dd1, dd2); + + REQUIRE(r1.f() == doctest::Approx(0.6435011087932844)); + REQUIRE(r1.g(0) == doctest::Approx(-0.6800000000000000)); + REQUIRE(r1.g(1) == doctest::Approx(0.8400000000000000)); + REQUIRE(r1.g(2) == doctest::Approx(0.6400000000000000)); + REQUIRE(r1.h(0, 0) == doctest::Approx(0.9664000000000000)); + REQUIRE(r1.h(0, 1) == doctest::Approx(-0.6032000000000000)); + REQUIRE(r1.h(0, 2) == doctest::Approx(0.7328000000000000)); + REQUIRE(r1.h(1, 1) == doctest::Approx(-2.2384000000000000)); + REQUIRE(r1.h(1, 2) == doctest::Approx(-0.4464000000000000)); + REQUIRE(r1.h(2, 2) == doctest::Approx(0.3056000000000000)); +} + +TEST_CASE("Dot") { + const auto r = ddv1.dot(ddv2); + + REQUIRE(r.f() == doctest::Approx(14.1)); + REQUIRE(r.g(0) == doctest::Approx(28.1)); + REQUIRE(r.g(1) == doctest::Approx(34.7)); + REQUIRE(r.g(2) == doctest::Approx(18.6)); + REQUIRE(r.h(0, 0) == doctest::Approx(38.9)); + REQUIRE(r.h(0, 1) == doctest::Approx(102.9)); + REQUIRE(r.h(0, 2) == doctest::Approx(81.6)); + REQUIRE(r.h(1, 1) == doctest::Approx(64.3)); + REQUIRE(r.h(1, 2) == doctest::Approx(59.4)); + REQUIRE(r.h(2, 2) == doctest::Approx(45.9)); +} + +TEST_CASE("Cross") { + const auto r = ddv1.cross(ddv2); + + const auto rx = r.x(); + const auto ry = r.y(); + const auto rz = r.z(); + + REQUIRE(rx.f() == doctest::Approx(15.1)); + REQUIRE(rx.g(0) == doctest::Approx(55.4)); + REQUIRE(rx.g(1) == doctest::Approx(3.8)); + REQUIRE(rx.g(2) == doctest::Approx(-1.8)); + REQUIRE(rx.h(0, 0) == doctest::Approx(144.3)); + REQUIRE(rx.h(0, 1) == doctest::Approx(73.0)); + REQUIRE(rx.h(0, 2) == doctest::Approx(10.0)); + REQUIRE(rx.h(1, 1) == doctest::Approx(62.6)); + REQUIRE(rx.h(1, 2) == doctest::Approx(31.7)); + REQUIRE(rx.h(2, 2) == doctest::Approx(20.0)); + + REQUIRE(ry.f() == doctest::Approx(-11.91)); + REQUIRE(ry.g(0) == doctest::Approx(-24.94)); + REQUIRE(ry.g(1) == doctest::Approx(-26.52)); + REQUIRE(ry.g(2) == doctest::Approx(-15.88)); + REQUIRE(ry.h(0, 0) == doctest::Approx(-31.68)); + REQUIRE(ry.h(0, 1) == doctest::Approx(-86.42)); + REQUIRE(ry.h(0, 2) == doctest::Approx(-69.42)); + REQUIRE(ry.h(1, 1) == doctest::Approx(-45.48)); + REQUIRE(ry.h(1, 2) == doctest::Approx(-46.32)); + REQUIRE(ry.h(2, 2) == doctest::Approx(-40.92)); + + REQUIRE(rz.f() == doctest::Approx(7.8)); + REQUIRE(rz.g(0) == doctest::Approx(3.5)); + REQUIRE(rz.g(1) == doctest::Approx(32.5)); + REQUIRE(rz.g(2) == doctest::Approx(23.2)); + REQUIRE(rz.h(0, 0) == doctest::Approx(-3.2)); + REQUIRE(rz.h(0, 1) == doctest::Approx(31.1)); + REQUIRE(rz.h(0, 2) == doctest::Approx(56.4)); + REQUIRE(rz.h(1, 1) == doctest::Approx(78.1)); + REQUIRE(rz.h(1, 2) == doctest::Approx(85.9)); + REQUIRE(rz.h(2, 2) == doctest::Approx(79.1)); +} + +TEST_CASE("Norm") { + const auto r = ddv1.norm(); + + REQUIRE(r.f() == doctest::Approx(5.0089919145472770)); + REQUIRE(r.g(0) == doctest::Approx(6.1948592709606230)); + REQUIRE(r.g(1) == doctest::Approx(4.4400151526317835)); + REQUIRE(r.g(2) == doctest::Approx(2.4076700872634587)); + REQUIRE(r.h(0, 0) == doctest::Approx(7.1438962616547620)); + REQUIRE(r.h(0, 1) == doctest::Approx(6.5451754620124020)); + REQUIRE(r.h(0, 2) == doctest::Approx(4.8662132130242100)); + REQUIRE(r.h(1, 1) == doctest::Approx(11.9876946237449200)); + REQUIRE(r.h(1, 2) == doctest::Approx(10.9103606598557140)); + REQUIRE(r.h(2, 2) == doctest::Approx(9.2320222391647280)); } const SScalar s1(3.0, {{"x", 1.0}, {"y", 6.0}, {"z", 4.0}}); const SScalar s2(4.0, {{"x", 7.0}, {"y", 1.0}}); const SScalar s3(0.3, {{"x", 0.1}, {"y", 0.8}, {"z", 0.2}}); -TEST_CASE("SScalar init") -{ - using Dual = SScalar; +TEST_CASE("SScalar init") { + using Dual = SScalar; - const auto x = Dual(1.5, {{"x", 2.0}, {"y", 1.0}}); + const auto x = Dual(1.5, {{"x", 2.0}, {"y", 1.0}}); - REQUIRE(x.size() == 2); + REQUIRE(x.size() == 2); - REQUIRE(x.f() == doctest::Approx(1.5)); + REQUIRE(x.f() == doctest::Approx(1.5)); - REQUIRE(x.d("x") == doctest::Approx(2.0)); - REQUIRE(x.d("y") == doctest::Approx(1.0)); - REQUIRE(x.d("z") == doctest::Approx(0.0)); + REQUIRE(x.d("x") == doctest::Approx(2.0)); + REQUIRE(x.d("y") == doctest::Approx(1.0)); + REQUIRE(x.d("z") == doctest::Approx(0.0)); } -TEST_CASE("SScalar constant") -{ - using Dual = SScalar; +TEST_CASE("SScalar constant") { + using Dual = SScalar; - const auto x = Dual::constant(1.5); + const auto x = Dual::constant(1.5); - REQUIRE(x.size() == 0); + REQUIRE(x.size() == 0); - REQUIRE(x.f() == doctest::Approx(1.5)); + REQUIRE(x.f() == doctest::Approx(1.5)); - REQUIRE(x.d("x") == doctest::Approx(0.0)); - REQUIRE(x.d("y") == doctest::Approx(0.0)); + REQUIRE(x.d("x") == doctest::Approx(0.0)); + REQUIRE(x.d("y") == doctest::Approx(0.0)); } -TEST_CASE("SScalar variable") -{ - using Dual = SScalar; +TEST_CASE("SScalar variable") { + using Dual = SScalar; - const auto x = Dual::variable("x", 1.5); + const auto x = Dual::variable("x", 1.5); - REQUIRE(x.size() == 1); + REQUIRE(x.size() == 1); - REQUIRE(x.f() == doctest::Approx(1.5)); + REQUIRE(x.f() == doctest::Approx(1.5)); - REQUIRE(x.d("x") == doctest::Approx(1.0)); - REQUIRE(x.d("y") == doctest::Approx(0.0)); + REQUIRE(x.d("x") == doctest::Approx(1.0)); + REQUIRE(x.d("y") == doctest::Approx(0.0)); } -TEST_CASE("SScalar Neg") -{ - const auto r1 = -s1; +TEST_CASE("SScalar Neg") { + const auto r1 = -s1; - REQUIRE(r1.f() == doctest::Approx(-3)); - REQUIRE(r1.d("x") == doctest::Approx(-1)); - REQUIRE(r1.d("y") == doctest::Approx(-6)); - REQUIRE(r1.d("z") == doctest::Approx(-4)); + REQUIRE(r1.f() == doctest::Approx(-3)); + REQUIRE(r1.d("x") == doctest::Approx(-1)); + REQUIRE(r1.d("y") == doctest::Approx(-6)); + REQUIRE(r1.d("z") == doctest::Approx(-4)); } -TEST_CASE("SScalar Add") -{ - const auto r1 = s1 + s2; +TEST_CASE("SScalar Add") { + const auto r1 = s1 + s2; - REQUIRE(r1.f() == doctest::Approx(7)); - REQUIRE(r1.d("x") == doctest::Approx(8)); - REQUIRE(r1.d("y") == doctest::Approx(7)); - REQUIRE(r1.d("z") == doctest::Approx(4)); + REQUIRE(r1.f() == doctest::Approx(7)); + REQUIRE(r1.d("x") == doctest::Approx(8)); + REQUIRE(r1.d("y") == doctest::Approx(7)); + REQUIRE(r1.d("z") == doctest::Approx(4)); - const auto r2 = s1 + 3.5; + const auto r2 = s1 + 3.5; - REQUIRE(r2.f() == doctest::Approx(6.5)); - REQUIRE(r2.d("x") == doctest::Approx(1.0)); - REQUIRE(r2.d("y") == doctest::Approx(6.0)); - REQUIRE(r2.d("z") == doctest::Approx(4.0)); + REQUIRE(r2.f() == doctest::Approx(6.5)); + REQUIRE(r2.d("x") == doctest::Approx(1.0)); + REQUIRE(r2.d("y") == doctest::Approx(6.0)); + REQUIRE(r2.d("z") == doctest::Approx(4.0)); - const auto r3 = 3.5 + s1; + const auto r3 = 3.5 + s1; - REQUIRE(r3.f() == doctest::Approx(6.5)); - REQUIRE(r3.d("x") == doctest::Approx(1.0)); - REQUIRE(r3.d("y") == doctest::Approx(6.0)); - REQUIRE(r3.d("z") == doctest::Approx(4.0)); + REQUIRE(r3.f() == doctest::Approx(6.5)); + REQUIRE(r3.d("x") == doctest::Approx(1.0)); + REQUIRE(r3.d("y") == doctest::Approx(6.0)); + REQUIRE(r3.d("z") == doctest::Approx(4.0)); } -TEST_CASE("SScalar IncAdd") -{ - auto r1 = s1; - r1 += s2; +TEST_CASE("SScalar IncAdd") { + auto r1 = s1; + r1 += s2; - REQUIRE(r1.f() == doctest::Approx(7)); - REQUIRE(r1.d("x") == doctest::Approx(8)); - REQUIRE(r1.d("y") == doctest::Approx(7)); - REQUIRE(r1.d("z") == doctest::Approx(4)); + REQUIRE(r1.f() == doctest::Approx(7)); + REQUIRE(r1.d("x") == doctest::Approx(8)); + REQUIRE(r1.d("y") == doctest::Approx(7)); + REQUIRE(r1.d("z") == doctest::Approx(4)); - auto r2 = s1; - r2 += 3.5; + auto r2 = s1; + r2 += 3.5; - REQUIRE(r2.f() == doctest::Approx(6.5)); - REQUIRE(r2.d("x") == doctest::Approx(1.0)); - REQUIRE(r2.d("y") == doctest::Approx(6.0)); - REQUIRE(r2.d("z") == doctest::Approx(4.0)); + REQUIRE(r2.f() == doctest::Approx(6.5)); + REQUIRE(r2.d("x") == doctest::Approx(1.0)); + REQUIRE(r2.d("y") == doctest::Approx(6.0)); + REQUIRE(r2.d("z") == doctest::Approx(4.0)); } -TEST_CASE("SScalar Sub") -{ - const auto r1 = s1 - s2; +TEST_CASE("SScalar Sub") { + const auto r1 = s1 - s2; - REQUIRE(r1.f() == doctest::Approx(-1.0)); - REQUIRE(r1.d("x") == doctest::Approx(-6.0)); - REQUIRE(r1.d("y") == doctest::Approx(5.0)); - REQUIRE(r1.d("z") == doctest::Approx(4.0)); + REQUIRE(r1.f() == doctest::Approx(-1.0)); + REQUIRE(r1.d("x") == doctest::Approx(-6.0)); + REQUIRE(r1.d("y") == doctest::Approx(5.0)); + REQUIRE(r1.d("z") == doctest::Approx(4.0)); - const auto r2 = s1 - 3.5; + const auto r2 = s1 - 3.5; - REQUIRE(r2.f() == doctest::Approx(-0.5)); - REQUIRE(r2.d("x") == doctest::Approx(1.0)); - REQUIRE(r2.d("y") == doctest::Approx(6.0)); - REQUIRE(r2.d("z") == doctest::Approx(4.0)); + REQUIRE(r2.f() == doctest::Approx(-0.5)); + REQUIRE(r2.d("x") == doctest::Approx(1.0)); + REQUIRE(r2.d("y") == doctest::Approx(6.0)); + REQUIRE(r2.d("z") == doctest::Approx(4.0)); - const auto r3 = 3.5 - s1; + const auto r3 = 3.5 - s1; - REQUIRE(r3.f() == doctest::Approx(0.5)); - REQUIRE(r3.d("x") == doctest::Approx(-1.0)); - REQUIRE(r3.d("y") == doctest::Approx(-6.0)); - REQUIRE(r3.d("z") == doctest::Approx(-4.0)); + REQUIRE(r3.f() == doctest::Approx(0.5)); + REQUIRE(r3.d("x") == doctest::Approx(-1.0)); + REQUIRE(r3.d("y") == doctest::Approx(-6.0)); + REQUIRE(r3.d("z") == doctest::Approx(-4.0)); } -TEST_CASE("SScalar IncSub") -{ - auto r1 = s1; - r1 -= s2; +TEST_CASE("SScalar IncSub") { + auto r1 = s1; + r1 -= s2; - REQUIRE(r1.f() == doctest::Approx(-1.0)); - REQUIRE(r1.d("x") == doctest::Approx(-6.0)); - REQUIRE(r1.d("y") == doctest::Approx(5.0)); - REQUIRE(r1.d("z") == doctest::Approx(4.0)); + REQUIRE(r1.f() == doctest::Approx(-1.0)); + REQUIRE(r1.d("x") == doctest::Approx(-6.0)); + REQUIRE(r1.d("y") == doctest::Approx(5.0)); + REQUIRE(r1.d("z") == doctest::Approx(4.0)); - auto r2 = s1; - r2 -= 3.5; + auto r2 = s1; + r2 -= 3.5; - REQUIRE(r2.f() == doctest::Approx(-0.5)); - REQUIRE(r2.d("x") == doctest::Approx(1.0)); - REQUIRE(r2.d("y") == doctest::Approx(6.0)); - REQUIRE(r2.d("z") == doctest::Approx(4.0)); + REQUIRE(r2.f() == doctest::Approx(-0.5)); + REQUIRE(r2.d("x") == doctest::Approx(1.0)); + REQUIRE(r2.d("y") == doctest::Approx(6.0)); + REQUIRE(r2.d("z") == doctest::Approx(4.0)); } -TEST_CASE("SScalar Mul") -{ - const auto r1 = s1 * s2; +TEST_CASE("SScalar Mul") { + const auto r1 = s1 * s2; - REQUIRE(r1.f() == doctest::Approx(12.0)); - REQUIRE(r1.d("x") == doctest::Approx(25.0)); - REQUIRE(r1.d("y") == doctest::Approx(27.0)); - REQUIRE(r1.d("z") == doctest::Approx(16.0)); + REQUIRE(r1.f() == doctest::Approx(12.0)); + REQUIRE(r1.d("x") == doctest::Approx(25.0)); + REQUIRE(r1.d("y") == doctest::Approx(27.0)); + REQUIRE(r1.d("z") == doctest::Approx(16.0)); } -TEST_CASE("SScalar IncMul") -{ - auto r1 = s1; - r1 *= s2; +TEST_CASE("SScalar IncMul") { + auto r1 = s1; + r1 *= s2; - REQUIRE(r1.f() == doctest::Approx(12.0)); - REQUIRE(r1.d("x") == doctest::Approx(25.0)); - REQUIRE(r1.d("y") == doctest::Approx(27.0)); - REQUIRE(r1.d("z") == doctest::Approx(16.0)); + REQUIRE(r1.f() == doctest::Approx(12.0)); + REQUIRE(r1.d("x") == doctest::Approx(25.0)); + REQUIRE(r1.d("y") == doctest::Approx(27.0)); + REQUIRE(r1.d("z") == doctest::Approx(16.0)); } -TEST_CASE("SScalar Div") -{ - const auto r1 = s1 / s2; +TEST_CASE("SScalar Div") { + const auto r1 = s1 / s2; - REQUIRE(r1.f() == doctest::Approx(0.75000)); - REQUIRE(r1.d("x") == doctest::Approx(-1.06250)); - REQUIRE(r1.d("y") == doctest::Approx(1.31250)); - REQUIRE(r1.d("z") == doctest::Approx(1.00000)); + REQUIRE(r1.f() == doctest::Approx(0.75000)); + REQUIRE(r1.d("x") == doctest::Approx(-1.06250)); + REQUIRE(r1.d("y") == doctest::Approx(1.31250)); + REQUIRE(r1.d("z") == doctest::Approx(1.00000)); } -TEST_CASE("SScalar IncDiv") -{ - auto r1 = s1; - r1 /= s2; +TEST_CASE("SScalar IncDiv") { + auto r1 = s1; + r1 /= s2; - REQUIRE(r1.f() == doctest::Approx(0.75000)); - REQUIRE(r1.d("x") == doctest::Approx(-1.06250)); - REQUIRE(r1.d("y") == doctest::Approx(1.31250)); - REQUIRE(r1.d("z") == doctest::Approx(1.00000)); + REQUIRE(r1.f() == doctest::Approx(0.75000)); + REQUIRE(r1.d("x") == doctest::Approx(-1.06250)); + REQUIRE(r1.d("y") == doctest::Approx(1.31250)); + REQUIRE(r1.d("z") == doctest::Approx(1.00000)); } -TEST_CASE("SScalar Pow") -{ - using std::pow; +TEST_CASE("SScalar Pow") { + using std::pow; - const auto r1 = pow(s1, 3.5); + const auto r1 = pow(s1, 3.5); - REQUIRE(r1.f() == doctest::Approx(46.765371804359690)); - REQUIRE(r1.d("x") == doctest::Approx(54.559600438419636)); - REQUIRE(r1.d("y") == doctest::Approx(327.357602630517800)); - REQUIRE(r1.d("z") == doctest::Approx(218.238401753678540)); + REQUIRE(r1.f() == doctest::Approx(46.765371804359690)); + REQUIRE(r1.d("x") == doctest::Approx(54.559600438419636)); + REQUIRE(r1.d("y") == doctest::Approx(327.357602630517800)); + REQUIRE(r1.d("z") == doctest::Approx(218.238401753678540)); } -TEST_CASE("SScalar Sqrt") -{ - using std::sqrt; +TEST_CASE("SScalar Sqrt") { + using std::sqrt; - const auto r1 = sqrt(s1); + const auto r1 = sqrt(s1); - REQUIRE(r1.f() == doctest::Approx(1.732050807568877200)); - REQUIRE(r1.d("x") == doctest::Approx(0.288675134594812900)); - REQUIRE(r1.d("y") == doctest::Approx(1.732050807568877400)); - REQUIRE(r1.d("z") == doctest::Approx(1.154700538379251700)); + REQUIRE(r1.f() == doctest::Approx(1.732050807568877200)); + REQUIRE(r1.d("x") == doctest::Approx(0.288675134594812900)); + REQUIRE(r1.d("y") == doctest::Approx(1.732050807568877400)); + REQUIRE(r1.d("z") == doctest::Approx(1.154700538379251700)); } -TEST_CASE("SScalar Cos") -{ - using std::cos; +TEST_CASE("SScalar Cos") { + using std::cos; - const auto r1 = cos(s1); + const auto r1 = cos(s1); - REQUIRE(r1.f() == doctest::Approx(-0.9899924966004454)); - REQUIRE(r1.d("x") == doctest::Approx(-0.1411200080598672)); - REQUIRE(r1.d("y") == doctest::Approx(-0.8467200483592032)); - REQUIRE(r1.d("z") == doctest::Approx(-0.5644800322394689)); + REQUIRE(r1.f() == doctest::Approx(-0.9899924966004454)); + REQUIRE(r1.d("x") == doctest::Approx(-0.1411200080598672)); + REQUIRE(r1.d("y") == doctest::Approx(-0.8467200483592032)); + REQUIRE(r1.d("z") == doctest::Approx(-0.5644800322394689)); } -TEST_CASE("SScalar Sin") -{ - using std::sin; +TEST_CASE("SScalar Sin") { + using std::sin; - const auto r1 = s1.sin(); + const auto r1 = s1.sin(); - REQUIRE(r1.f() == doctest::Approx(0.1411200080598672)); - REQUIRE(r1.d("x") == doctest::Approx(-0.9899924966004454)); - REQUIRE(r1.d("y") == doctest::Approx(-5.9399549796026730)); - REQUIRE(r1.d("z") == doctest::Approx(-3.9599699864017817)); + REQUIRE(r1.f() == doctest::Approx(0.1411200080598672)); + REQUIRE(r1.d("x") == doctest::Approx(-0.9899924966004454)); + REQUIRE(r1.d("y") == doctest::Approx(-5.9399549796026730)); + REQUIRE(r1.d("z") == doctest::Approx(-3.9599699864017817)); } -TEST_CASE("SScalar Tan") -{ - using std::tan; +TEST_CASE("SScalar Tan") { + using std::tan; - const auto r1 = tan(s1); + const auto r1 = tan(s1); - REQUIRE(r1.f() == doctest::Approx(-0.14254654307427780)); - REQUIRE(r1.d("x") == doctest::Approx(1.02031951694242680)); - REQUIRE(r1.d("y") == doctest::Approx(6.12191710165456100)); - REQUIRE(r1.d("z") == doctest::Approx(4.08127806776970700)); + REQUIRE(r1.f() == doctest::Approx(-0.14254654307427780)); + REQUIRE(r1.d("x") == doctest::Approx(1.02031951694242680)); + REQUIRE(r1.d("y") == doctest::Approx(6.12191710165456100)); + REQUIRE(r1.d("z") == doctest::Approx(4.08127806776970700)); } \ No newline at end of file From 26ca12978a4b81c8e53506a52424102a10ba30a5 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 17 May 2026 10:24:44 +0200 Subject: [PATCH 14/14] add ruff auto format --- .github/workflows/format.yml | 9 +- pyproject.toml | 2 +- python/tests/test_DDScalar.py | 682 ++++++++++++++++++++++++++++------ python/tests/test_SScalar.py | 31 +- uv.lock | 31 +- 5 files changed, 618 insertions(+), 137 deletions(-) diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 5dfffd0a..c3c66bdb 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -11,8 +11,8 @@ concurrency: cancel-in-progress: true jobs: - clang-format: - name: clang-format + format: + name: format runs-on: ubuntu-latest steps: @@ -20,5 +20,8 @@ jobs: - uses: astral-sh/setup-uv@v6 - - name: Check formatting + - name: Check C++ formatting run: uv run --group dev clang-format --dry-run --Werror include/hyperjet/*.h python/src/*.h python/src/*.cpp test/src/*.cpp benchmark/src/*.cpp + + - name: Check Python formatting + run: uv run --group dev ruff format --check python/tests/ diff --git a/pyproject.toml b/pyproject.toml index ffd9f1cd..b352e27c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,7 @@ Homepage = "https://github.com/oberbichler/HyperJet" Repository = "https://github.com/oberbichler/HyperJet" [dependency-groups] -dev = ["clang-format>=19.0"] +dev = ["clang-format>=19.0", "ruff>=0.11"] test = ["pytest>=8.0"] [tool.scikit-build] diff --git a/python/tests/test_DDScalar.py b/python/tests/test_DDScalar.py index 250f90e0..e866bd11 100644 --- a/python/tests/test_DDScalar.py +++ b/python/tests/test_DDScalar.py @@ -4,10 +4,11 @@ from numpy.testing import assert_equal, assert_allclose from copy import copy -if __name__ == '__main__': +if __name__ == "__main__": import os import sys - print(f'pid: {os.getpid()}') + + print(f"pid: {os.getpid()}") pytest.main(sys.argv) @@ -27,35 +28,107 @@ def from_data(self, data): @property def u1(self): - return self.from_data([1.80000000000000, 1.20000000000000, -0.360000000000000, 0.400000000000000, -0.240000000000000, 0.144000000000000]) + return self.from_data( + [ + 1.80000000000000, + 1.20000000000000, + -0.360000000000000, + 0.400000000000000, + -0.240000000000000, + 0.144000000000000, + ] + ) @property def u2(self): - return self.from_data([1.41421356237310, -0.353553390593274, 0.353553390593274, -0.0883883476483184, 0.0883883476483184, -0.0883883476483184]) + return self.from_data( + [ + 1.41421356237310, + -0.353553390593274, + 0.353553390593274, + -0.0883883476483184, + 0.0883883476483184, + -0.0883883476483184, + ] + ) @property def u3(self): - return self.from_data([-0.227202094693087, -1.16861715705383, 0.350585147116150, -0.0623680359932327, 0.135572126503353, -0.110788667374236]) + return self.from_data( + [ + -0.227202094693087, + -1.16861715705383, + 0.350585147116150, + -0.0623680359932327, + 0.135572126503353, + -0.110788667374236, + ] + ) @property def u4(self): - return self.from_data([0.973847630878195, -0.272642513631704, 0.0817927540895113, -1.49322142634184, 0.475230679265721, -0.158927754597619]) + return self.from_data( + [ + 0.973847630878195, + -0.272642513631704, + 0.0817927540895113, + -1.49322142634184, + 0.475230679265721, + -0.158927754597619, + ] + ) @property def u5(self): - return self.from_data([-4.28626167462806, 23.2464469720624, -6.97393409161873, -231.388035688946, 67.0917660094774, -18.7327429845195]) + return self.from_data( + [ + -4.28626167462806, + 23.2464469720624, + -6.97393409161873, + -231.388035688946, + 67.0917660094774, + -18.7327429845195, + ] + ) @property def u6(self): - return self.from_data([2.94217428809568, 3.72896781158072, -1.11869034347422, 5.47972024538469, -2.01681285477348, 0.828781925126886]) + return self.from_data( + [ + 2.94217428809568, + 3.72896781158072, + -1.11869034347422, + 5.47972024538469, + -2.01681285477348, + 0.828781925126886, + ] + ) @property def u7(self): - return self.from_data([3.10747317631727, 3.53060914571482, -1.05918274371444, 5.65163108913514, -2.04855024131202, 0.826401621136496]) + return self.from_data( + [ + 3.10747317631727, + 3.53060914571482, + -1.05918274371444, + 5.65163108913514, + -2.04855024131202, + 0.826401621136496, + ] + ) @property def u8(self): - return self.from_data([0.946806012846268, 0.124270048845782, -0.0372810146537347, -0.240959761098066, 0.0598609234448416, -0.0105020741027055]) + return self.from_data( + [ + 0.946806012846268, + 0.124270048845782, + -0.0372810146537347, + -0.240959761098066, + 0.0598609234448416, + -0.0105020741027055, + ] + ) @property def u9(self): @@ -83,7 +156,12 @@ def data(self, data): test_data = dict( argvalues=[static_set_1, dynamic_set_1, static_set_2, dynamic_set_2], - ids=['static 1st order', 'dynamic 1st order', 'static 2nd order', 'dynamic 2nd order'], + ids=[ + "static 1st order", + "dynamic 1st order", + "static 2nd order", + "dynamic 2nd order", + ], ) @@ -390,7 +468,7 @@ def test_variables(): # properties -@pytest.mark.parametrize('ctx', **test_data) +@pytest.mark.parametrize("ctx", **test_data) def test_init_by_array(ctx): if ctx.dtype.order == 1: return # FIXME: @@ -399,7 +477,7 @@ def test_init_by_array(ctx): assert_allclose(u.data, [1, 2, 3, 4, 5, 6]) -@pytest.mark.parametrize('ctx', **test_data) +@pytest.mark.parametrize("ctx", **test_data) def test_values(ctx): # static size u = ctx.from_data([1, 2, 3, 4, 5, 6]) @@ -437,7 +515,7 @@ def test_values(ctx): assert_equal(u.h(1, 1), 1) -@pytest.mark.parametrize('ctx', **test_data) +@pytest.mark.parametrize("ctx", **test_data) def test_ndarray(ctx): # FIXME: Cleanup # static size @@ -447,8 +525,8 @@ def test_ndarray(ctx): if ctx.dtype.order == 2: assert_equal(u.hm(), [[4, 5], [5, 6]]) - assert_equal(u.hm(mode='full'), [[4, 5], [5, 6]]) - assert_equal(u.hm(mode='zeros'), [[4, 5], [0, 6]]) + assert_equal(u.hm(mode="full"), [[4, 5], [5, 6]]) + assert_equal(u.hm(mode="zeros"), [[4, 5], [0, 6]]) u.g[:] = [5, 4] assert_allclose(u.g, [5, 4]) @@ -456,8 +534,8 @@ def test_ndarray(ctx): if ctx.dtype.order == 2: u.set_hm([[3, 2], [0, 1]]) assert_equal(u.hm(), [[3, 2], [2, 1]]) - assert_equal(u.hm(mode='full'), [[3, 2], [2, 1]]) - assert_equal(u.hm(mode='zeros'), [[3, 2], [0, 1]]) + assert_equal(u.hm(mode="full"), [[3, 2], [2, 1]]) + assert_equal(u.hm(mode="zeros"), [[3, 2], [0, 1]]) ctx.check(u, [1, 5, 4, 3, 2, 1]) @@ -470,7 +548,7 @@ def test_is_dynamic(): assert_equal(dynamic_set_2.u1.is_dynamic, True) -@pytest.mark.parametrize('ctx', **test_data) +@pytest.mark.parametrize("ctx", **test_data) def test_size(ctx): u = ctx.u1 assert_equal(u.size, 2) @@ -479,7 +557,7 @@ def test_size(ctx): # resizing -@pytest.mark.parametrize('ctx', **test_data) +@pytest.mark.parametrize("ctx", **test_data) def test_resize(ctx): u = ctx.u9 @@ -496,7 +574,7 @@ def test_eval(): assert_equal(u.eval([11, 12, 13]), 5031.5) -@pytest.mark.parametrize('ctx', **test_data) +@pytest.mark.parametrize("ctx", **test_data) def test_pad_right(ctx): u = ctx.u9 @@ -508,7 +586,7 @@ def test_pad_right(ctx): u.pad_right(new_size=5) -@pytest.mark.parametrize('ctx', **test_data) +@pytest.mark.parametrize("ctx", **test_data) def test_pad_left(ctx): u = ctx.u9 @@ -523,7 +601,7 @@ def test_pad_left(ctx): # serialization -@pytest.mark.parametrize('ctx', **test_data) +@pytest.mark.parametrize("ctx", **test_data) def test_copy(ctx): u = ctx.u1 v = copy(u) @@ -533,195 +611,565 @@ def test_copy(ctx): # arithmetic operations -@pytest.mark.parametrize('ctx', **test_data) +@pytest.mark.parametrize("ctx", **test_data) def test_negative(ctx): r = np.negative(ctx.u1) ctx.check(r, [-1.8, -1.2, 0.36, -0.4, 0.24, -0.144]) -@pytest.mark.parametrize('ctx', **test_data) +@pytest.mark.parametrize("ctx", **test_data) def test_add(ctx): r = ctx.u1 + ctx.u2 - ctx.check(r, [3.21421356237310, 0.846446609406726, -0.00644660940672624, 0.311611652351682, -0.151611652351682, 0.0556116523516816]) + ctx.check( + r, + [ + 3.21421356237310, + 0.846446609406726, + -0.00644660940672624, + 0.311611652351682, + -0.151611652351682, + 0.0556116523516816, + ], + ) r = ctx.u1 + 3 - ctx.check(r, [4.80000000000000, 1.20000000000000, -0.360000000000000, 0.400000000000000, -0.240000000000000, 0.144000000000000]) + ctx.check( + r, + [ + 4.80000000000000, + 1.20000000000000, + -0.360000000000000, + 0.400000000000000, + -0.240000000000000, + 0.144000000000000, + ], + ) r = 3 + ctx.u1 - ctx.check(r, [4.80000000000000, 1.20000000000000, -0.360000000000000, 0.400000000000000, -0.240000000000000, 0.144000000000000]) + ctx.check( + r, + [ + 4.80000000000000, + 1.20000000000000, + -0.360000000000000, + 0.400000000000000, + -0.240000000000000, + 0.144000000000000, + ], + ) r = ctx.u1 r += ctx.u2 - ctx.check(r, [3.21421356237310, 0.846446609406726, -0.00644660940672624, 0.311611652351682, -0.151611652351682, 0.0556116523516816]) + ctx.check( + r, + [ + 3.21421356237310, + 0.846446609406726, + -0.00644660940672624, + 0.311611652351682, + -0.151611652351682, + 0.0556116523516816, + ], + ) r = ctx.u1 r += 3 - ctx.check(r, [4.80000000000000, 1.20000000000000, -0.360000000000000, 0.400000000000000, -0.240000000000000, 0.144000000000000]) - - -@pytest.mark.parametrize('ctx', **test_data) + ctx.check( + r, + [ + 4.80000000000000, + 1.20000000000000, + -0.360000000000000, + 0.400000000000000, + -0.240000000000000, + 0.144000000000000, + ], + ) + + +@pytest.mark.parametrize("ctx", **test_data) def test_sub(ctx): r = ctx.u1 - ctx.u2 - ctx.check(r, [0.385786437626905, 1.55355339059327, -0.713553390593274, 0.488388347648318, -0.328388347648318, 0.232388347648318]) + ctx.check( + r, + [ + 0.385786437626905, + 1.55355339059327, + -0.713553390593274, + 0.488388347648318, + -0.328388347648318, + 0.232388347648318, + ], + ) r = ctx.u1 - 3 - ctx.check(r, [-1.20000000000000, 1.20000000000000, -0.360000000000000, 0.400000000000000, -0.240000000000000, 0.144000000000000]) + ctx.check( + r, + [ + -1.20000000000000, + 1.20000000000000, + -0.360000000000000, + 0.400000000000000, + -0.240000000000000, + 0.144000000000000, + ], + ) r = 3 - ctx.u1 - ctx.check(r, [1.20000000000000, -1.20000000000000, 0.360000000000000, -0.400000000000000, 0.240000000000000, -0.144000000000000]) + ctx.check( + r, + [ + 1.20000000000000, + -1.20000000000000, + 0.360000000000000, + -0.400000000000000, + 0.240000000000000, + -0.144000000000000, + ], + ) r = ctx.u1 r -= ctx.u2 - ctx.check(r, [0.385786437626905, 1.55355339059327, -0.713553390593274, 0.488388347648318, -0.328388347648318, 0.232388347648318]) + ctx.check( + r, + [ + 0.385786437626905, + 1.55355339059327, + -0.713553390593274, + 0.488388347648318, + -0.328388347648318, + 0.232388347648318, + ], + ) r = ctx.u1 r -= 3 - ctx.check(r, [-1.20000000000000, 1.20000000000000, -0.360000000000000, 0.400000000000000, -0.240000000000000, 0.144000000000000]) - - -@pytest.mark.parametrize('ctx', **test_data) + ctx.check( + r, + [ + -1.20000000000000, + 1.20000000000000, + -0.360000000000000, + 0.400000000000000, + -0.240000000000000, + 0.144000000000000, + ], + ) + + +@pytest.mark.parametrize("ctx", **test_data) def test_mul(ctx): r = ctx.u1 * ctx.u2 - ctx.check(r, [2.54558441227157, 1.06066017177982, 0.127279220613579, -0.441941738241592, 0.371231060122937, -0.210010714012405]) + ctx.check( + r, + [ + 2.54558441227157, + 1.06066017177982, + 0.127279220613579, + -0.441941738241592, + 0.371231060122937, + -0.210010714012405, + ], + ) r = ctx.u1 * 3 - ctx.check(r, [5.40000000000000, 3.60000000000000, -1.08000000000000, 1.20000000000000, -0.720000000000000, 0.432000000000000]) + ctx.check( + r, + [ + 5.40000000000000, + 3.60000000000000, + -1.08000000000000, + 1.20000000000000, + -0.720000000000000, + 0.432000000000000, + ], + ) r = 3 * ctx.u1 - ctx.check(r, [5.40000000000000, 3.60000000000000, -1.08000000000000, 1.20000000000000, -0.720000000000000, 0.432000000000000]) + ctx.check( + r, + [ + 5.40000000000000, + 3.60000000000000, + -1.08000000000000, + 1.20000000000000, + -0.720000000000000, + 0.432000000000000, + ], + ) r = ctx.u1 r *= ctx.u2 - ctx.check(r, [2.54558441227157, 1.06066017177982, 0.127279220613579, -0.441941738241592, 0.371231060122937, -0.210010714012405]) + ctx.check( + r, + [ + 2.54558441227157, + 1.06066017177982, + 0.127279220613579, + -0.441941738241592, + 0.371231060122937, + -0.210010714012405, + ], + ) r = ctx.u1 r *= 3 - ctx.check(r, [5.40000000000000, 3.60000000000000, -1.08000000000000, 1.20000000000000, -0.720000000000000, 0.432000000000000]) - - -@pytest.mark.parametrize('ctx', **test_data) + ctx.check( + r, + [ + 5.40000000000000, + 3.60000000000000, + -1.08000000000000, + 1.20000000000000, + -0.720000000000000, + 0.432000000000000, + ], + ) + + +@pytest.mark.parametrize("ctx", **test_data) def test_div(ctx): r = ctx.u1 / ctx.u2 - ctx.check(r, [1.27279220613579, 1.16672618895780, -0.572756492761104, 0.945755319837007, -0.684125810797985, 0.467751135754901]) + ctx.check( + r, + [ + 1.27279220613579, + 1.16672618895780, + -0.572756492761104, + 0.945755319837007, + -0.684125810797985, + 0.467751135754901, + ], + ) r = ctx.u1 / 3 - ctx.check(r, [0.600000000000000, 0.400000000000000, -0.120000000000000, 0.133333333333333, -0.0800000000000000, 0.0480000000000000]) + ctx.check( + r, + [ + 0.600000000000000, + 0.400000000000000, + -0.120000000000000, + 0.133333333333333, + -0.0800000000000000, + 0.0480000000000000, + ], + ) r = 3 / ctx.u1 - ctx.check(r, [1.66666666666667, -1.11111111111111, 0.333333333333333, 1.11111111111111, -0.222222222222222, 0]) + ctx.check( + r, + [ + 1.66666666666667, + -1.11111111111111, + 0.333333333333333, + 1.11111111111111, + -0.222222222222222, + 0, + ], + ) r = ctx.u1 r /= ctx.u2 - ctx.check(r, [1.27279220613579, 1.16672618895780, -0.572756492761104, 0.945755319837007, -0.684125810797985, 0.467751135754901]) + ctx.check( + r, + [ + 1.27279220613579, + 1.16672618895780, + -0.572756492761104, + 0.945755319837007, + -0.684125810797985, + 0.467751135754901, + ], + ) r = ctx.u1 r /= 3 - ctx.check(r, [0.600000000000000, 0.400000000000000, -0.120000000000000, 0.133333333333333, -0.0800000000000000, 0.0480000000000000]) - - -@pytest.mark.parametrize('ctx', **test_data) + ctx.check( + r, + [ + 0.600000000000000, + 0.400000000000000, + -0.120000000000000, + 0.133333333333333, + -0.0800000000000000, + 0.0480000000000000, + ], + ) + + +@pytest.mark.parametrize("ctx", **test_data) def test_reciprocal(ctx): r = np.reciprocal(ctx.u1) - ctx.check(r, [0.555555555555556, -0.370370370370370, 0.111111111111111, 0.370370370370370, -0.0740740740740741, 0]) - - -@pytest.mark.parametrize('ctx', **test_data) + ctx.check( + r, + [ + 0.555555555555556, + -0.370370370370370, + 0.111111111111111, + 0.370370370370370, + -0.0740740740740741, + 0, + ], + ) + + +@pytest.mark.parametrize("ctx", **test_data) def test_sqrt(ctx): r = np.sqrt(ctx.u1) - ctx.check(r, [1.34164078649987, 0.447213595499958, -0.134164078649987, 0, -0.0447213595499958, 0.0402492235949962]) - - -@pytest.mark.parametrize('ctx', **test_data) + ctx.check( + r, + [ + 1.34164078649987, + 0.447213595499958, + -0.134164078649987, + 0, + -0.0447213595499958, + 0.0402492235949962, + ], + ) + + +@pytest.mark.parametrize("ctx", **test_data) def test_cbrt(ctx): r = np.cbrt(ctx.u1) - ctx.check(r, [1.21644039911468, 0.270320088692151, -0.0810960266076453, -0.0300355654102390, -0.0180213392461434, 0.0216256070953721]) + ctx.check( + r, + [ + 1.21644039911468, + 0.270320088692151, + -0.0810960266076453, + -0.0300355654102390, + -0.0180213392461434, + 0.0216256070953721, + ], + ) # trigonometric functions -@pytest.mark.parametrize('ctx', **test_data) +@pytest.mark.parametrize("ctx", **test_data) def test_cosh(ctx): r = np.cosh(ctx.u1) - ctx.check(r, [3.10747317631727, 3.53060914571482, -1.05918274371444, 5.65163108913514, -2.04855024131202, 0.826401621136496]) - - -@pytest.mark.parametrize('ctx', **test_data) + ctx.check( + r, + [ + 3.10747317631727, + 3.53060914571482, + -1.05918274371444, + 5.65163108913514, + -2.04855024131202, + 0.826401621136496, + ], + ) + + +@pytest.mark.parametrize("ctx", **test_data) def test_sinh(ctx): r = np.sinh(ctx.u1) - ctx.check(r, [2.94217428809568, 3.72896781158072, -1.11869034347422, 5.47972024538469, -2.01681285477348, 0.828781925126886]) - - -@pytest.mark.parametrize('ctx', **test_data) + ctx.check( + r, + [ + 2.94217428809568, + 3.72896781158072, + -1.11869034347422, + 5.47972024538469, + -2.01681285477348, + 0.828781925126886, + ], + ) + + +@pytest.mark.parametrize("ctx", **test_data) def test_tanh(ctx): r = np.tanh(ctx.u1) - ctx.check(r, [0.946806012846268, 0.124270048845782, -0.0372810146537347, -0.240959761098066, 0.0598609234448416, -0.0105020741027055]) - - -@pytest.mark.parametrize('ctx', **test_data) + ctx.check( + r, + [ + 0.946806012846268, + 0.124270048845782, + -0.0372810146537347, + -0.240959761098066, + 0.0598609234448416, + -0.0105020741027055, + ], + ) + + +@pytest.mark.parametrize("ctx", **test_data) def test_acosh(ctx): r = np.arccosh(ctx.u6) - ctx.check(r, [1.74207758739717, 1.34764847402516, -0.404294542207549, 0.0492485216214053, -0.149539403888938, 0.125720729608191]) - - -@pytest.mark.parametrize('ctx', **test_data) + ctx.check( + r, + [ + 1.74207758739717, + 1.34764847402516, + -0.404294542207549, + 0.0492485216214053, + -0.149539403888938, + 0.125720729608191, + ], + ) + + +@pytest.mark.parametrize("ctx", **test_data) def test_asinh(ctx): r = np.arcsinh(ctx.u7) - ctx.check(r, [1.85189546405173, 1.08154501033879, -0.324463503101638, 0.617782395949683, -0.293489219818784, 0.152939466565963]) - - -@pytest.mark.parametrize('ctx', **test_data) + ctx.check( + r, + [ + 1.85189546405173, + 1.08154501033879, + -0.324463503101638, + 0.617782395949683, + -0.293489219818784, + 0.152939466565963, + ], + ) + + +@pytest.mark.parametrize("ctx", **test_data) def test_hypot_2d(ctx): r = np.hypot(ctx.u7, ctx.u8) - ctx.check(r, [3.248512146736285, 3.4135420601625106, -1.0240626180487475, 5.591028639945467, -2.0186627979998866, 0.8104113630097172]) + ctx.check( + r, + [ + 3.248512146736285, + 3.4135420601625106, + -1.0240626180487475, + 5.591028639945467, + -2.0186627979998866, + 0.8104113630097172, + ], + ) r = hj.hypot(ctx.u7, ctx.u8) - ctx.check(r, [3.248512146736285, 3.4135420601625106, -1.0240626180487475, 5.591028639945467, -2.0186627979998866, 0.8104113630097172]) - - -@pytest.mark.parametrize('ctx', **test_data) + ctx.check( + r, + [ + 3.248512146736285, + 3.4135420601625106, + -1.0240626180487475, + 5.591028639945467, + -2.0186627979998866, + 0.8104113630097172, + ], + ) + + +@pytest.mark.parametrize("ctx", **test_data) def test_hypot_3d(ctx): r = ctx.u7.hypot(ctx.u8, ctx.u9) - ctx.check(r, [3.3989455964303383, 3.8508803611271274, -0.09611211609065046, 6.762542570418667, 0.38740979652217894, 5.493497125410167]) + ctx.check( + r, + [ + 3.3989455964303383, + 3.8508803611271274, + -0.09611211609065046, + 6.762542570418667, + 0.38740979652217894, + 5.493497125410167, + ], + ) r = hj.hypot(ctx.u7, ctx.u8, ctx.u9) - ctx.check(r, [3.3989455964303383, 3.8508803611271274, -0.09611211609065046, 6.762542570418667, 0.38740979652217894, 5.493497125410167]) - - -@pytest.mark.parametrize('ctx', **test_data) + ctx.check( + r, + [ + 3.3989455964303383, + 3.8508803611271274, + -0.09611211609065046, + 6.762542570418667, + 0.38740979652217894, + 5.493497125410167, + ], + ) + + +@pytest.mark.parametrize("ctx", **test_data) def test_atanh(ctx): r = np.arctanh(ctx.u8) ctx.check(r, [1.8, 1.2, -0.36, 0.4, -0.24, 0.144]) -@pytest.mark.parametrize('ctx', **test_data) +@pytest.mark.parametrize("ctx", **test_data) def test_exp(ctx): r = np.exp(ctx.u1) - ctx.check(r, [6.04964746441295, 7.25957695729554, -2.17787308718866, 11.1313513345198, -4.06536309608550, 1.65518354626338]) - - -@pytest.mark.parametrize('ctx', **test_data) + ctx.check( + r, + [ + 6.04964746441295, + 7.25957695729554, + -2.17787308718866, + 11.1313513345198, + -4.06536309608550, + 1.65518354626338, + ], + ) + + +@pytest.mark.parametrize("ctx", **test_data) def test_log(ctx): r = np.log(ctx.u1) - ctx.check(r, [0.587786664902119, 0.666666666666667, -0.200000000000000, -0.222222222222222, 0, 0.0400000000000000]) + ctx.check( + r, + [ + 0.587786664902119, + 0.666666666666667, + -0.200000000000000, + -0.222222222222222, + 0, + 0.0400000000000000, + ], + ) r = ctx.u1.log(2) - ctx.check(r, [0.847996906554950, 0.961796693925976, -0.288539008177793, -0.320598897975325, 0, 0.0577078016355585]) - - -@pytest.mark.parametrize('ctx', **test_data) + ctx.check( + r, + [ + 0.847996906554950, + 0.961796693925976, + -0.288539008177793, + -0.320598897975325, + 0, + 0.0577078016355585, + ], + ) + + +@pytest.mark.parametrize("ctx", **test_data) def test_log2(ctx): r = np.log2(ctx.u1) - ctx.check(r, [0.847996906554950, 0.961796693925976, -0.288539008177793, -0.320598897975325, 0, 0.0577078016355585]) - - -@pytest.mark.parametrize('ctx', **test_data) + ctx.check( + r, + [ + 0.847996906554950, + 0.961796693925976, + -0.288539008177793, + -0.320598897975325, + 0, + 0.0577078016355585, + ], + ) + + +@pytest.mark.parametrize("ctx", **test_data) def test_log10(ctx): r = np.log10(ctx.u1) - ctx.check(r, [0.255272505103306, 0.289529654602168, -0.0868588963806504, -0.0965098848673893, 0, 0.0173717792761301]) - - -@pytest.mark.parametrize('ctx', **test_data) + ctx.check( + r, + [ + 0.255272505103306, + 0.289529654602168, + -0.0868588963806504, + -0.0965098848673893, + 0, + 0.0173717792761301, + ], + ) + + +@pytest.mark.parametrize("ctx", **test_data) def test_f(ctx): u = [ctx.u1, ctx.u2] @@ -737,7 +1185,7 @@ def test_f(ctx): assert_equal(f, v.f) -@pytest.mark.parametrize('ctx', **test_data) +@pytest.mark.parametrize("ctx", **test_data) def test_d(ctx): u = [ctx.u1, ctx.u2] @@ -753,7 +1201,7 @@ def test_d(ctx): assert_equal(d, v.g) -@pytest.mark.parametrize('ctx', **test_data) +@pytest.mark.parametrize("ctx", **test_data) def test_dd(ctx): if ctx.dtype.order < 2: return diff --git a/python/tests/test_SScalar.py b/python/tests/test_SScalar.py index c34171bf..85f9e77b 100644 --- a/python/tests/test_SScalar.py +++ b/python/tests/test_SScalar.py @@ -4,10 +4,11 @@ from numpy.testing import assert_equal, assert_allclose from copy import copy -if __name__ == '__main__': +if __name__ == "__main__": import os import sys - print(f'pid: {os.getpid()}') + + print(f"pid: {os.getpid()}") pytest.main(sys.argv) @@ -18,24 +19,24 @@ def test_init(): u = hj.SScalar(f=1.2) assert_equal(len(u), 0) assert_allclose(u.f, 1.2) - assert_allclose(u.d('x'), 0) - assert_allclose(u.d('y'), 0) - assert_allclose(u.d('z'), 0) - - u = hj.SScalar(f=1.2, d={'x': 1, 'y': 2}) + assert_allclose(u.d("x"), 0) + assert_allclose(u.d("y"), 0) + assert_allclose(u.d("z"), 0) + + u = hj.SScalar(f=1.2, d={"x": 1, "y": 2}) assert_equal(len(u), 2) assert_allclose(u.f, 1.2) - assert_allclose(u.d('x'), 1) - assert_allclose(u.d('y'), 2) - assert_allclose(u.d('z'), 0) + assert_allclose(u.d("x"), 1) + assert_allclose(u.d("y"), 2) + assert_allclose(u.d("z"), 0) def test_mul(): - u = hj.SScalar(f=1, d={'x': 1}) - v = hj.SScalar(f=1, d={'y': 1}) + u = hj.SScalar(f=1, d={"x": 1}) + v = hj.SScalar(f=1, d={"y": 1}) r = u + v**2 assert_equal(len(r), 2) assert_allclose(r.f, 2) - assert_allclose(r.d('x'), 1) - assert_allclose(r.d('y'), 2) - assert_allclose(r.d('z'), 0) + assert_allclose(r.d("x"), 1) + assert_allclose(r.d("y"), 2) + assert_allclose(r.d("z"), 0) diff --git a/uv.lock b/uv.lock index ca227483..fa163407 100644 --- a/uv.lock +++ b/uv.lock @@ -53,6 +53,7 @@ test = [ [package.dev-dependencies] dev = [ { name = "clang-format" }, + { name = "ruff" }, ] test = [ { name = "pytest" }, @@ -67,7 +68,10 @@ requires-dist = [ provides-extras = ["test"] [package.metadata.requires-dev] -dev = [{ name = "clang-format", specifier = ">=19.0" }] +dev = [ + { name = "clang-format", specifier = ">=19.0" }, + { name = "ruff", specifier = ">=0.11" }, +] test = [{ name = "pytest", specifier = ">=8.0" }] [[package]] @@ -222,3 +226,28 @@ sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc wheels = [ { url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" }, ] + +[[package]] +name = "ruff" +version = "0.15.13" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/24/21/a7d5c126d5b557715ef81098f3db2fe20f622a039ff2e626af28d674ab80/ruff-0.15.13.tar.gz", hash = "sha256:f9d89f17f7ba7fb2ed42921f0df75da797a9a5d71bc39049e2c687cf2baf44b7", size = 4678180, upload-time = "2026-05-14T13:44:37.869Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c6/61/11d458dc6ac22504fd8e237b29dfd40504c7fbbcc8930402cfe51a8e63ed/ruff-0.15.13-py3-none-linux_armv6l.whl", hash = "sha256:444b580fc72fd6887e650acd3e575e18cdc79dbcf42fb4030b491057921f61f8", size = 10738279, upload-time = "2026-05-14T13:44:18.7Z" }, + { url = "https://files.pythonhosted.org/packages/86/ca/caa871ee7be718c45256fada4e16a218ee3e33f0c4a46b729a60a24912e6/ruff-0.15.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6590d009e7cb7ebf36f83dbdd44a3fa48a0994ff6f1cdc1b08006abe58f98dc7", size = 11124798, upload-time = "2026-05-14T13:44:06.427Z" }, + { url = "https://files.pythonhosted.org/packages/d3/19/43f5f2e568dddde567fc41f8471f9432c09563e19d3e617a48cfa52f8f0a/ruff-0.15.13-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1c26d2f66163deeb6e08d8b39fbbe983ce3c71cea06a6d7591cfd1421793c629", size = 10460761, upload-time = "2026-05-14T13:44:04.375Z" }, + { url = "https://files.pythonhosted.org/packages/99/df/cf938cd6de3003178f03ad7c1ea2a6c099468c03a35037985070b37e76be/ruff-0.15.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dbd6f94b434f896308e4d57fb7bfde0d02b99f7a64b3bdab0fdfa6a864203a5", size = 10804451, upload-time = "2026-05-14T13:44:25.221Z" }, + { url = "https://files.pythonhosted.org/packages/c7/7d/5d0973129b154ded2225729169d7068f26b467760b146493fde138415f23/ruff-0.15.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf3259f3be4d181bda591da5db2571aed6853c6a048157756448020bc6c5cd22", size = 10534285, upload-time = "2026-05-14T13:44:08.888Z" }, + { url = "https://files.pythonhosted.org/packages/1f/e3/6b999bbc66cd51e5f073842bc2a3995e99c5e0e72e16b15e7261f7abf57a/ruff-0.15.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae9c17e5eb4430c154e76abc25d79a318190f5a997f38fb6b114416c5319ffc9", size = 11312063, upload-time = "2026-05-14T13:44:11.274Z" }, + { url = "https://files.pythonhosted.org/packages/af/5a/642639e9f5db04f1e97fbd6e091c6fd20725bdf072fb114d00eefb9e6eb8/ruff-0.15.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e2e39bff6c341f4b577a21b801326fab0b11847f48fcaa83f00a113c9b3cb55", size = 12183079, upload-time = "2026-05-14T13:44:01.634Z" }, + { url = "https://files.pythonhosted.org/packages/19/4c/7585735f6b53b0f12de13618b2f7d250a844f018822efc899df2e7b8295f/ruff-0.15.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e8d9a8e08013542e94d3220bc5b62cc3e5ef87c5f74bff367d3fac14fab013e6", size = 11440833, upload-time = "2026-05-14T13:43:59.043Z" }, + { url = "https://files.pythonhosted.org/packages/e8/31/bf1a0803d077e679cfeee5f2f67290a0fa79c7385b5d9a8c17b9db2c48f0/ruff-0.15.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc411dfebe5eebe55ce041c6ae080eb7668955e866daa2fbb16692a784f1c4ca", size = 11434486, upload-time = "2026-05-14T13:44:27.761Z" }, + { url = "https://files.pythonhosted.org/packages/e1/4e/62c9b999875d4f14db80f277c030578f5e249c9852d65b7ac7ad0b43c041/ruff-0.15.13-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:768494eb08b9cee54e2fd27969966f74db5a57f6eaa7a90fcb3306af34dfc4bd", size = 11385189, upload-time = "2026-05-14T13:44:13.704Z" }, + { url = "https://files.pythonhosted.org/packages/fc/89/7e959047a104df3eb12863447c110140191fc5b6c4f379ea2e803fcdb0e4/ruff-0.15.13-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:fb75f9a3a7e42ffe117d734494e6c5e5cb3565d66e12612cb63d0e572a41a5b6", size = 10781380, upload-time = "2026-05-14T13:43:56.734Z" }, + { url = "https://files.pythonhosted.org/packages/ff/52/5fd18f3b88cab63e88aa11516b3b4e1e5f720e5c330f8dbe5c26210f41f8/ruff-0.15.13-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8cb74dd33bb2f6613faf7fc03b660053b5ac4f80e706d5788c6335e2a8048d51", size = 10540605, upload-time = "2026-05-14T13:44:20.748Z" }, + { url = "https://files.pythonhosted.org/packages/e8/e0/9e35f338990d3e41a82875ff7053ffe97541dae81c9d02143177f381d572/ruff-0.15.13-py3-none-musllinux_1_2_i686.whl", hash = "sha256:7ef823f817fcd191dc934e984be9cf4094f808effa16f2542ad8e821ba02bbf2", size = 11036554, upload-time = "2026-05-14T13:44:16.256Z" }, + { url = "https://files.pythonhosted.org/packages/c2/13/070fb048c24080fba188f66371e2a92785be257ad02242066dc7255ac6e9/ruff-0.15.13-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:f345a13937bd7f09f6f5d19fa0721b0c103e00e7f62bc67089a8e5e037719e0b", size = 11528133, upload-time = "2026-05-14T13:44:22.808Z" }, + { url = "https://files.pythonhosted.org/packages/6b/8c/b1e1666aef7fc6555094d73ae6cd981701781ae85b97ceefc0eebd0b4668/ruff-0.15.13-py3-none-win32.whl", hash = "sha256:4044f94208b3b05ba0fc4a4abd0558cf4d6459bd18325eead7fd8cc66f909b41", size = 10721455, upload-time = "2026-05-14T13:44:35.697Z" }, + { url = "https://files.pythonhosted.org/packages/ab/a6/870a3e8a50590bb92be184ad928c2922f088b00d9dc5c5ec7b924ee08c22/ruff-0.15.13-py3-none-win_amd64.whl", hash = "sha256:7064884d442b7d477b4e7473d12da7f08851d2b1982763c5d3f388a19468a1a4", size = 11900409, upload-time = "2026-05-14T13:44:30.389Z" }, + { url = "https://files.pythonhosted.org/packages/9b/36/9c015cd052fca743dae8cb2aeb16b551444787467db42ceab0fc968865af/ruff-0.15.13-py3-none-win_arm64.whl", hash = "sha256:2471da9bd1068c8c064b5fd9c0c4b6dddffd6369cb1cd68b29993b1709ff1b21", size = 11179336, upload-time = "2026-05-14T13:44:33.026Z" }, +]