diff --git a/.github/windows_arm64_steps/action.yml b/.github/windows_arm64_steps/action.yml new file mode 100644 index 000000000..14b7f41a1 --- /dev/null +++ b/.github/windows_arm64_steps/action.yml @@ -0,0 +1,22 @@ +name: Build Dependencies(Win-ARM64) +description: "Setup LLVM for Win-ARM64 builds" +# https://github.com/numpy/numpy-release/blob/295d6a70a867972774ff05ae98d7a560a659e2b4/.github/windows_arm64_steps/action.yml + +runs: + using: "composite" + steps: + - name: Install LLVM with checksum verification + shell: pwsh + run: | + Invoke-WebRequest https://github.com/llvm/llvm-project/releases/download/llvmorg-20.1.6/LLVM-20.1.6-woa64.exe -UseBasicParsing -OutFile LLVM-woa64.exe + $expectedHash = "92f69a1134e32e54b07d51c6e24d9594852f6476f32c3d70471ae00fffc2d462" + $fileHash = (Get-FileHash -Path "LLVM-woa64.exe" -Algorithm SHA256).Hash + if ($fileHash -ne $expectedHash) { + Write-Error "Checksum verification failed. The downloaded file may be corrupted or tampered with." + exit 1 + } + Start-Process -FilePath ".\LLVM-woa64.exe" -ArgumentList "/S" -Wait + echo "C:\Program Files\LLVM\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + echo "CC=clang-cl" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + echo "CXX=clang-cl" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + echo "FC=flang-new" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 5f3ae717b..51c826c0d 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -95,10 +95,11 @@ jobs: run: python3 -m build working-directory: python + # This is needed for publishing to PyPI - name: Publish artifacts uses: actions/upload-artifact@v4 with: - name: moocore-wheels-${{ matrix.os }}-${{ matrix.python-version }} + name: moocore-wheels-sdist-${{ matrix.os }}-${{ matrix.python-version }} path: python/dist/*.tar.gz build-doc: @@ -120,7 +121,6 @@ jobs: with: python-version: '3.10' cache: 'pip' - cache-dependency-path: '**/requirements_dev.txt' - name: Ensure Pip and Build run: | @@ -131,13 +131,8 @@ jobs: run: python3 -m build working-directory: python - - name: install the package - run: python3 -m pip install . - working-directory: python - - - name: install the doc build requirements - run: | - python3 -m pip install -r requirements_dev.txt + - name: Install the package and the doc build requirements + run: python3 -m pip install .[docs] working-directory: python - name: Build the docs 🔧 @@ -161,7 +156,6 @@ jobs: name: Coverage ${{ matrix.os }} (${{ matrix.python-version }}) runs-on: ${{ matrix.os }} strategy: - # When set to true, GitHub cancels all in-progress jobs if any matrix job fails. matrix: os: [ubuntu-latest] python-version: ['3.10'] @@ -203,10 +197,15 @@ jobs: matrix: # FIXME: add windows-11-arm and ubuntu-24.04-arm # https://github.com/scipy/scipy/blob/6b79a4dec1f9ca2db4e49c328d04d293880991c6/.github/workflows/wheels.yml#L78 - # macos-14 is apple silicon - os: [ubuntu-22.04, windows-2025, macos-14] + # https://github.com/numpy/numpy-release/blob/main/.github/workflows/wheels.yml + # macos-14 is Apple Silicon (arm64), but we build an universal2 wheel. + # The configuration of cibuildwheel can be found in pyproject.toml + os: [ubuntu-22.04, ubuntu-22.04-arm, windows-2025, macos-14] python-version: ['3.10'] - CIBW_ARCHS_MACOS: ['universal2'] + include: + # 3.11 is the earliest version on windows-arm + - os: windows-11-arm + python-version: "3.11" steps: - uses: actions/checkout@v5 @@ -215,18 +214,14 @@ jobs: uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} + cache: 'pip' - - name: Set up QEMU - if: runner.os == 'Linux' - uses: docker/setup-qemu-action@v3 - with: - platforms: arm64 + - name: Setup LLVM for Windows ARM64 (NOT WORKING/FIXME) + if: ${{ matrix.os == 'windows-11-arm' }} + uses: ./.github/windows_arm64_steps - name: Build wheels - uses: pypa/cibuildwheel@v2.23.3 - env: - CIBW_ARCHS_MACOS: ${{ matrix.CIBW_ARCHS_MACOS }} - CIBW_TEST_SKIP: ${{ matrix.CIBW_TEST_SKIP }} + uses: pypa/cibuildwheel@v3.2.1 with: package-dir: python output-dir: wheelhouse diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d6062d98d..9f2d2bd4d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,10 +14,13 @@ repos: - id: no-print-statement - id: no-debug-statement - id: deps-in-desc - args: [--root=r/] + args: [--root=./r/] exclude: '(do\.R|vignettes/articles/.+\.Rmd)' - id: roxygenize - args: [--root=] + args: [--root=./r/] + additional_dependencies: + - doctest + - Rdpack - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 diff --git a/python/Makefile b/python/Makefile index 78c51fa46..b88ba9d27 100644 --- a/python/Makefile +++ b/python/Makefile @@ -20,7 +20,7 @@ pre-commit: pre-commit run -a docdeps: - python3 -m pip install -r requirements_dev.txt --disable-pip-version-check --quiet + python3 -m pip install .[docs] --disable-pip-version-check --quiet show: $(MAKE) -C doc show diff --git a/python/benchmarks/bench_ndom.py b/python/benchmarks/bench_ndom.py index aa81f4f2f..ed4f90f38 100644 --- a/python/benchmarks/bench_ndom.py +++ b/python/benchmarks/bench_ndom.py @@ -65,7 +65,7 @@ def get_dataset(name): z, maximise=True, keep_weakly=False ), "botorch": lambda z: botorch_is_nondominated(z, deduplicate=True), - "paretoset": lambda z: paretoset( + "paretoset (numba)": lambda z: paretoset( z, sense=z.shape[1] * ["max"], distinct=True, use_numba=True ), }, @@ -116,7 +116,7 @@ def get_dataset(name): "botorch": lambda z: bool2pos( botorch_is_nondominated(z, deduplicate=False) ), - "paretoset": lambda z: bool2pos( + "paretoset (numba)": lambda z: bool2pos( paretoset( z, sense=z.shape[1] * ["max"], diff --git a/python/benchmarks/python-requirements.txt b/python/benchmarks/python-requirements.txt index 33fe23d4c..bf2dcd640 100644 --- a/python/benchmarks/python-requirements.txt +++ b/python/benchmarks/python-requirements.txt @@ -1,10 +1,11 @@ +botorch cpuinfo +desdeo +jmetal +matplotlib +nevergrad +numba numpy pandas -matplotlib -botorch -pymoo -jmetal -desdeo paretoset -nevergrad +pymoo diff --git a/python/doc/source/REFERENCES.bib b/python/doc/source/REFERENCES.bib index 89f42d001..ecfb5ed1e 100644 --- a/python/doc/source/REFERENCES.bib +++ b/python/doc/source/REFERENCES.bib @@ -200,8 +200,7 @@ @article{DiaLop2020ejor @article{DubLopStu2011amai, author = { J{\'e}r{\'e}mie Dubois-Lacoste and Manuel L{\'o}pez-Ib{\'a}{\~n}ez and Thomas St{\"u}tzle }, - title = {Improving the Anytime Behavior of Two-Phase Local - Search}, + title = {Improving the Anytime Behavior of Two-Phase Local Search}, journal = {Annals of Mathematics and Artificial Intelligence}, year = 2011, volume = 61, @@ -233,7 +232,8 @@ @article{GueFonPaq2021hv year = 2021, volume = 54, number = 6, - pages = {1--42} + pages = {1--42}, + doi = {10.1145/3453474} } @article{HerWer1987tabucol, @@ -296,6 +296,9 @@ @article{LopVerDreDoe2025 Single-objective Black-box Optimization Algorithms}, journal = {IEEE Transactions on Evolutionary Computation}, year = 2025, + volume = 29, + number = 5, + pages = {1774--1782}, annote = {Pre-print: \url{https://doi.org/10.48550/arXiv.2404.02031}}, doi = {10.1109/TEVC.2024.3462758}, abstract = {A widely accepted way to assess the performance of iterative @@ -366,10 +369,11 @@ @article{ZitThiLauFon2003:tec year = 2003, volume = 7, number = 2, - amonth = apr, pages = {117--132}, - doi = {10.1109/TEVC.2003.810758}, - annote = {Proposed the combination of quality indicators; proposed epsilon-indicator} + annote = {Proposed the combination of quality indicators; proposed + epsilon-indicator}, + amonth = apr, + doi = {10.1109/TEVC.2003.810758} } @incollection{AugBadBroZit2009gecco, diff --git a/python/doc/source/whatsnew/index.rst b/python/doc/source/whatsnew/index.rst index d0144e3a1..49780a49f 100644 --- a/python/doc/source/whatsnew/index.rst +++ b/python/doc/source/whatsnew/index.rst @@ -7,15 +7,20 @@ What's new Version 0.1.9 (dev) ------------------- -- :func:`~moocore.hv_contributions` ignores dominated points by default. Set ``ignore_dominated=False`` to restore the previous behavior. The 3D case uses the HVC3D algorithm. +- :func:`~moocore.hv_contributions` ignores dominated points by default. + Set ``ignore_dominated=False`` to restore the previous behavior. + The 3D case uses the HVC3D algorithm. - New function :func:`~moocore.any_dominated` to quickly detect if a set is nondominated. - New function :func:`~moocore.generate_ndset` to generate random nondominated sets with different shapes. - New example :ref:`sphx_glr_auto_examples_plot_generate.py`. -- :func:`~moocore.is_nondominated`, :func:`~moocore.any_dominated`, :func:`~moocore.pareto_rank` now handle single-objective inputs correctly (:issue:`27`, :issue:`29`). +- :func:`~moocore.is_nondominated`, :func:`~moocore.any_dominated`, + :func:`~moocore.pareto_rank` now handle single-objective inputs correctly (:issue:`27`, :issue:`29`). - Ranks returned by :func:`~moocore.pareto_rank` are 0-based. - :func:`~moocore.is_nondominated` and :func:`~moocore.filter_dominated` are faster for dimensions larger than 3. +- ``moocore`` wheels are now built for ``aarch64`` (ARM64) in Linux and Windows. + See the `installation instructions `_. Version 0.1.8 (15/07/2025) -------------------------- diff --git a/python/pyproject.toml b/python/pyproject.toml index ace69a2c8..6fefe3ef0 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -86,45 +86,45 @@ skip = [ "*_ppc64le", "*_s390x", "*_i686", # Skip 32-bit builds + "cp313t-*", + "cp314t-*", # Skip free-threaded builds ] build-verbosity = 2 -# Will cause the wheel to be installed with these groups of dependencies -test-groups = [ "test" ] +# Will cause the wheel to be installed with these optional-dependencies +test-extras = [ "test" ] test-command = [ "pytest --doctest-modules --doctest-continue-on-failure {package}/tests {package}/src/moocore/_moocore.py", ] -test-skip = "*-*linux_{aarch64,ppc64le,s390x}" +#test-skip = "*-*linux_{aarch64,ppc64le,s390x}" [tool.cibuildwheel.linux] -archs = [ - "x86_64", - # "aarch64", FAILS doctests -] +archs = [ "native" ] manylinux-x86_64-image = "manylinux_2_28" +manylinux-aarch64-image = "manylinux_2_28" +musllinux-x86_64-image = "musllinux_1_2" +musllinux-aarch64-image = "musllinux_1_2" # Use abi3audit to catch issues with Limited API wheels +before-build = "pip install abi3audit" repair-wheel-command = [ "auditwheel repair -w {dest_dir} {wheel}", - # "pipx run abi3audit --verbose --strict --report {wheel}", + "abi3audit --verbose --strict --report {wheel}", ] [tool.cibuildwheel.windows] -archs = [ - "AMD64", -] +archs = [ "native" ] # Use delvewheel on windows -before-build = "pip install delvewheel" +before-build = "pip install delvewheel abi3audit" repair-wheel-command = [ "delvewheel repair -w {dest_dir} {wheel}", - # "pipx run abi3audit --verbose --strict --report {wheel}", + "abi3audit --verbose --strict --report {wheel}", ] [tool.cibuildwheel.macos] -archs = [ - "universal2", -] +archs = [ "universal2" ] +before-build = "pip install abi3audit" repair-wheel-command = [ "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}", - # "pipx run abi3audit --verbose --strict --report {wheel}", + "abi3audit --verbose --strict --report {wheel}", ] [tool.ruff] diff --git a/python/requirements_dev.txt b/python/requirements_dev.txt deleted file mode 100644 index c5d5b4923..000000000 --- a/python/requirements_dev.txt +++ /dev/null @@ -1,32 +0,0 @@ -# Sync with .pre-commit-config.yaml -setuptools>=77.0.3 -cffi >= 1.17.1 -numpy >= 1.23.0 - -pre-commit >= 3.3.2 -ruff >= 0.11.2 - -tox >= 4.6.2 # Sync with tox.ini -pytest >= 7 # Sync with tox.ini -pytest-cov >= 4.1.0 -virtualenv >= 20 -build - -sphinx >= 6.0 -pydata_sphinx_theme>=0.16.0 -jupyter -ipykernel -kaleido -sphinx-gallery>=0.19.0 -sphinxcontrib-napoleon -sphinxcontrib-bibtex -sphinx-autodoc-typehints -sphinx-copybutton -sphinx-design -jupyterlab -ipywidgets - -# Gallery examples -pandas >=2.0.0 -seaborn -plotly diff --git a/python/setup.py b/python/setup.py index 40c41b354..ac7925f0b 100644 --- a/python/setup.py +++ b/python/setup.py @@ -3,17 +3,19 @@ from wheel.bdist_wheel import bdist_wheel as _bdist_wheel -class bdist_wheel_abi_none(_bdist_wheel): +class bdist_wheel_abi3(_bdist_wheel): def finalize_options(self): _bdist_wheel.finalize_options(self) - self.root_is_pure = False - - def get_tag(self): - _python, _abi, plat = _bdist_wheel.get_tag(self) - return "py3", "none", plat + # Automatically detect py_limited_api from extension modules + if not self.py_limited_api: + for ext in self.distribution.ext_modules or []: + if getattr(ext, "py_limited_api", False): + # Use cp310 as the minimum Python version for abi3 + self.py_limited_api = "cp310" + break setup( cffi_modules=["src/moocore/_ffi_build.py:ffibuilder"], - cmdclass={"bdist_wheel": bdist_wheel_abi_none}, + cmdclass={"bdist_wheel": bdist_wheel_abi3}, ) diff --git a/python/src/moocore/_ffi_build.py b/python/src/moocore/_ffi_build.py index 3f120aec8..a7d53c1a7 100644 --- a/python/src/moocore/_ffi_build.py +++ b/python/src/moocore/_ffi_build.py @@ -47,9 +47,6 @@ sources = [sources_path + f for f in sources] -is_windows = platform.system() == "Windows" - - def get_config(): from distutils.core import Distribution from distutils.sysconfig import get_config_vars @@ -64,8 +61,8 @@ def uses_msvc(): return config.try_compile('#ifndef _MSC_VER\n#error "not MSVC"\n#endif') -# Try to detect cross-compilation. -def _get_target_platform(arch_flags, default): +def _get_target_platform(): + arch_flags = os.environ.get("ARCHFLAGS", "") flags = [f for f in arch_flags.split(" ") if f.strip() != ""] try: pos = flags.index("-arch") @@ -74,10 +71,15 @@ def _get_target_platform(arch_flags, default): except ValueError: pass - return default + return platform.machine() -MSVC_CFLAGS = ["/GL", "/O2", "/GS-", "/wd4996"] +is_windows = platform.system() == "Windows" +target_platform = _get_target_platform() +is_x86_64 = target_platform in ("i686", "x86", "x86_64", "AMD64") + +# Compiler flags. +MSVC_CFLAGS = ["/GL", "/O2", "/GS-", "/wd4996", "/DMOOCORE_SHARED_LIB"] MSVC_LDFLAGS = ["/LTCG"] GCC_CFLAGS = ["-flto", "-O3"] @@ -86,17 +88,14 @@ def _get_target_platform(arch_flags, default): if is_windows and uses_msvc(): extra_compile_args.extend(MSVC_CFLAGS) extra_link_args.extend(MSVC_LDFLAGS) + if is_x86_64: + extra_compile_args.append("/arch:AVX") else: extra_compile_args.extend(GCC_CFLAGS) extra_link_args.extend(GCC_CFLAGS) - target_platform = _get_target_platform( - os.environ.get("ARCHFLAGS", ""), platform.machine() - ) - # Optimized version requires SSE2 extensions. They have been around since - # 2001 so we try to compile it on every recent-ish x86. - sse2 = target_platform in ("i686", "x86", "x86_64", "AMD64") - if sse2: - extra_compile_args.append("-msse2") + # Compile for sufficiently old x86-64 architecture. + if is_x86_64: + extra_compile_args.append("-march=x86-64-v2") cflags = os.environ.get("CFLAGS", "") if cflags != "": @@ -119,7 +118,8 @@ def _get_target_platform(arch_flags, default): sources=sources, include_dirs=[libmoocore_path], extra_compile_args=extra_compile_args, - extra_link_args=extra_compile_args, + extra_link_args=extra_link_args, + py_limited_api=True, ) if __name__ == "__main__": diff --git a/python/src/moocore/_moocore.py b/python/src/moocore/_moocore.py index 0894c730f..44c5d6e3b 100644 --- a/python/src/moocore/_moocore.py +++ b/python/src/moocore/_moocore.py @@ -1024,9 +1024,9 @@ def generate_ndset( :footcite:p:`RubMel1998simulation`. Values sampled from the exponential distribution are guaranteed to be positive. - Sampling from either the standard normal distribution, as suggested by - :footcite:t:`GueFonPaq2021hv`, or the uniform distribution, as suggested by - :footcite:t:`LacKlaFon2017box`, does not produce a uniform distribution + Sampling from either the standard normal distribution + :footcite:p:`GueFonPaq2021hv` or the uniform distribution + :footcite:p:`LacKlaFon2017box` does not produce a uniform distribution when projected into the simplex. Method ``"concave-sphere"`` uniformly samples points on the positive @@ -1038,8 +1038,8 @@ def generate_ndset( :math:`z_i = \frac{|x_i|}{\|\vec{x}\|_2}` :footcite:p:`Muller1959sphere`. The absolute value in the numerator ensures that points are sampled on the positive orthant of the hyper-sphere. - Sampling from the uniform distribution, as suggested by - :footcite:t:`LacKlaFon2017box`, does not result in a uniform sampling when + Sampling from the uniform distribution :footcite:p:`LacKlaFon2017box` + does not result in a uniform sampling when projected onto the surface of the hyper-sphere. Method ``"convex-sphere"`` is quivalent to ``1 - generate_ndset(..., diff --git a/python/tox.ini b/python/tox.ini index 1afa12d37..a3e89a824 100644 --- a/python/tox.ini +++ b/python/tox.ini @@ -1,6 +1,6 @@ [tox] requires = - tox>=4.2 + tox>=4.6.2 env_list = numpy-v2 py{312, 311, 310} @@ -11,10 +11,9 @@ package = wheel wheel_build_env = .pkg deps = numpy<2 - pandas>=2 - pytest>=7 - cov: coverage[toml] - cov: gcovr +extras = + test + cov: coverage commands = pytest --doctest-modules --doctest-continue-on-failure --import-mode=importlib {envsitepackagesdir}/moocore tests @@ -25,10 +24,9 @@ package = wheel wheel_build_env = .pkg deps = numpy>=2 - pandas>=2 - pytest>=7 - cov: coverage[toml] - cov: gcovr +extras = + test + cov: coverage commands = pytest --doctest-modules --doctest-continue-on-failure --import-mode=importlib {envsitepackagesdir}/moocore tests @@ -51,10 +49,8 @@ commands = [testenv:docs] description = Build documentation -deps = - -r{toxinidir}/requirements_dev.txt extras = - doc + docs commands = sphinx-build -M html ./doc/source ./doc/_build/ -WT --keep-going -d ./doc/_build/doctrees diff --git a/r/R/generate.R b/r/R/generate.R index 87b3e890c..103242ebb 100644 --- a/r/R/generate.R +++ b/r/R/generate.R @@ -42,10 +42,9 @@ #' \eqn{z_i = x_i / \sum_{i=1}^d x_i} \citep{RubMel1998simulation}. Values #' sampled from the exponential distribution are guaranteed to be positive. #' -#' Sampling from either the standard normal distribution, as suggested by -#' \citet{GueFonPaq2021hv}, or the uniform distribution, as suggested by -#' \citet{LacKlaFon2017box}, does not produce a uniform distribution when -#' projected into the simplex. +#' Sampling from either the standard normal distribution +#' \citep{GueFonPaq2021hv} or the uniform distribution \citep{LacKlaFon2017box} +#' does not produce a uniform distribution when projected into the simplex. #' #' Method `"concave-sphere"` uniformly samples points on the positive orthant #' of the hyper-sphere, which is concave when all objectives are minimised. @@ -55,8 +54,8 @@ #' then dividing each value by the l2-norm of the vector, \eqn{z_i = #' \frac{|x_i|}{\|\vec{x}\|_2}} \citep{Muller1959sphere}. The absolute value in #' the numerator ensures that points are sampled on the positive orthant of the -#' hyper-sphere. Sampling from the uniform distribution, as suggested by -#' \citet{LacKlaFon2017box}, does not result in a uniform sampling when +#' hyper-sphere. Sampling from the uniform distribution +#' \citep{LacKlaFon2017box} does not result in a uniform sampling when #' projected onto the surface of the hyper-sphere. #' #' Method `"convex-sphere"` is quivalent to `1 - generate_ndset(..., diff --git a/r/inst/REFERENCES.bib b/r/inst/REFERENCES.bib index 89f42d001..ecfb5ed1e 100644 --- a/r/inst/REFERENCES.bib +++ b/r/inst/REFERENCES.bib @@ -200,8 +200,7 @@ @article{DiaLop2020ejor @article{DubLopStu2011amai, author = { J{\'e}r{\'e}mie Dubois-Lacoste and Manuel L{\'o}pez-Ib{\'a}{\~n}ez and Thomas St{\"u}tzle }, - title = {Improving the Anytime Behavior of Two-Phase Local - Search}, + title = {Improving the Anytime Behavior of Two-Phase Local Search}, journal = {Annals of Mathematics and Artificial Intelligence}, year = 2011, volume = 61, @@ -233,7 +232,8 @@ @article{GueFonPaq2021hv year = 2021, volume = 54, number = 6, - pages = {1--42} + pages = {1--42}, + doi = {10.1145/3453474} } @article{HerWer1987tabucol, @@ -296,6 +296,9 @@ @article{LopVerDreDoe2025 Single-objective Black-box Optimization Algorithms}, journal = {IEEE Transactions on Evolutionary Computation}, year = 2025, + volume = 29, + number = 5, + pages = {1774--1782}, annote = {Pre-print: \url{https://doi.org/10.48550/arXiv.2404.02031}}, doi = {10.1109/TEVC.2024.3462758}, abstract = {A widely accepted way to assess the performance of iterative @@ -366,10 +369,11 @@ @article{ZitThiLauFon2003:tec year = 2003, volume = 7, number = 2, - amonth = apr, pages = {117--132}, - doi = {10.1109/TEVC.2003.810758}, - annote = {Proposed the combination of quality indicators; proposed epsilon-indicator} + annote = {Proposed the combination of quality indicators; proposed + epsilon-indicator}, + amonth = apr, + doi = {10.1109/TEVC.2003.810758} } @incollection{AugBadBroZit2009gecco, diff --git a/r/man/generate_ndset.Rd b/r/man/generate_ndset.Rd index 421d28b08..1f3a60226 100644 --- a/r/man/generate_ndset.Rd +++ b/r/man/generate_ndset.Rd @@ -55,10 +55,9 @@ distribution, then dividing each value by the L1-norm of the vector, \eqn{z_i = x_i / \sum_{i=1}^d x_i} \citep{RubMel1998simulation}. Values sampled from the exponential distribution are guaranteed to be positive. -Sampling from either the standard normal distribution, as suggested by -\citet{GueFonPaq2021hv}, or the uniform distribution, as suggested by -\citet{LacKlaFon2017box}, does not produce a uniform distribution when -projected into the simplex. +Sampling from either the standard normal distribution +\citep{GueFonPaq2021hv} or the uniform distribution \citep{LacKlaFon2017box} +does not produce a uniform distribution when projected into the simplex. Method \code{"concave-sphere"} uniformly samples points on the positive orthant of the hyper-sphere, which is concave when all objectives are minimised. @@ -68,8 +67,8 @@ sampling \eqn{d} independent and identically distributed values then dividing each value by the l2-norm of the vector, \eqn{z_i = \frac{|x_i|}{\|\vec{x}\|_2}} \citep{Muller1959sphere}. The absolute value in the numerator ensures that points are sampled on the positive orthant of the -hyper-sphere. Sampling from the uniform distribution, as suggested by -\citet{LacKlaFon2017box}, does not result in a uniform sampling when +hyper-sphere. Sampling from the uniform distribution +\citep{LacKlaFon2017box} does not result in a uniform sampling when projected onto the surface of the hyper-sphere. Method \code{"convex-sphere"} is quivalent to \code{1 - generate_ndset(..., method="concave-sphere")}, which is convex for minimisation problems. It diff --git a/update_bib.sh b/update_bib.sh index 22e7e134c..b9907f335 100755 --- a/update_bib.sh +++ b/update_bib.sh @@ -12,18 +12,17 @@ for file in $BIBFILES; do done tmpbib=$(mktemp --tmpdir tmpXXXXXXXXXX.bib) keys=$(paste -d '#' -s bibkeys.txt | sed 's/#/\\\|/g') -bib2bib --warn-error --expand --expand-xrefs --no-comment --expand-xrefs $BIBFILES --remove pdf --remove alias -c "(\$key : \"$keys\")" -ob $tmpbib -oc /dev/null +bib2bib --warn-error --expand --expand-xrefs --no-comment --expand-xrefs $BIBFILES --remove pdf --remove ids -c "(\$key : \"$keys\")" -ob $tmpbib -oc /dev/null if [ ! -s "${tmpbib}" ]; then echo "error: ${tmpbib} is empty! keys:= $keys" exit 1 fi # Workaround https://github.com/GeoBosh/rbibutils/issues/9 -sed -i 's#\\slash #~/ #g' $tmpbib -sed -i 's#\\hspace{0pt}#{}{}{}#g' $tmpbib -# Work around broken URL: -sed -i 's%researchrepository.napier.ac.uk/id/eprint/3044%lopez-ibanez.eu/publications#LopezIbanezPhD%g' $tmpbib +sed -i -e 's#\\slash #~/ #g' \ + -e 's#\\hspace{0pt}#{}{}{}#g' \ + -e 's%researchrepository.napier.ac.uk/id/eprint/3044%lopez-ibanez.eu/publications#LopezIbanezPhD%g' \ + $tmpbib comment='% DO NOT EDIT THIS FILE. It is auto-generated by "update_bib.sh".' -PYTHON_DOC_DIR="./python/doc/source" echo $comment | cat --squeeze-blank - $tmpbib > r/inst/REFERENCES.bib -echo $comment | cat --squeeze-blank - $tmpbib > $PYTHON_DOC_DIR/REFERENCES.bib +cp --force r/inst/REFERENCES.bib ./python/doc/source/REFERENCES.bib rm -f $BIBFILES $tmpbib