Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
53ece9f
Start development of v0.2.0
MLopez-Ibanez Nov 2, 2025
8f89f5e
c/hv4d.c (restart_base_setup_z_and_closest): Simplify. Help autovecto…
MLopez-Ibanez Oct 31, 2025
09b4186
c/eaf.c (eaf_check_polygons): Do not call polygons_intersect() twice.
MLopez-Ibanez Nov 1, 2025
faa5579
README.md, c/README.md: Fix testsuite badge.
MLopez-Ibanez Nov 2, 2025
2b29d73
* python/src/moocore/_utils.py (_get_seed_for_c): New.
MLopez-Ibanez Nov 2, 2025
2224a59
* python/tests/test_moocore.py (test_hv_approx_default_seed): New test.
MLopez-Ibanez Nov 2, 2025
dd1ddbb
* c/hv_priv.h (init_sentinels): Make sure HV_DIMENSION is correct.
MLopez-Ibanez Nov 2, 2025
9f4c5de
* c/mt19937/mt19937.c (mt19937_init_by_array,init_genrand): Remove u…
MLopez-Ibanez Nov 3, 2025
5d5a7df
c/Makefile (clean): Clean .i and .s.
MLopez-Ibanez Nov 3, 2025
0232647
c/epsilon.c: Fix error message.
MLopez-Ibanez Nov 3, 2025
b899ffc
c/epsilon.h: Use _attr_optimize_finite_math. Improve function special…
MLopez-Ibanez Nov 3, 2025
5ee51d1
[pre-commit.ci] pre-commit autoupdate
pre-commit-ci[bot] Nov 3, 2025
ccb2dd8
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 3, 2025
d443ecf
r/DESCRIPTION: Edit Description.
MLopez-Ibanez Nov 4, 2025
8290a66
c/hvapprox.c: Simplify ASSUME conditions.
MLopez-Ibanez Nov 4, 2025
f28adef
README.md: Mention QuantumAnnealingMOO.
MLopez-Ibanez Nov 4, 2025
958a090
README.md: Mention IOHinspector
MLopez-Ibanez Nov 5, 2025
3dff60b
* python/doc/source/whatsnew/index.rst: Fix link.
MLopez-Ibanez Nov 6, 2025
f40e169
* c/whv.c (print_point): Rename to debug_print_point.
MLopez-Ibanez Nov 5, 2025
cdde0c8
c/hv_priv.h: Use restrict for x.
MLopez-Ibanez Nov 7, 2025
3654bd6
c/hv4d.c: Remove unlikely.
MLopez-Ibanez Nov 11, 2025
d570c48
* c/gcc.mk: Add notes about GCC options.
MLopez-Ibanez Nov 12, 2025
8b8e97d
c/hv.c: Remove unused code.
MLopez-Ibanez Nov 5, 2025
52d521b
c/hv.c (fpli_setup_cdllist): Simplify.
MLopez-Ibanez Nov 11, 2025
da0f2f7
c/hv.c: Separate fpli_hv_ge5d() from hv_recursive(). Add debug counters.
MLopez-Ibanez Nov 6, 2025
ccba320
* c/gcc_attribs.h (ASAN_POISON_MEMORY_REGION): New.
MLopez-Ibanez Nov 13, 2025
7eef75e
* c/hv.c: Merge fpli_dlnode_t into dlnode_t.
MLopez-Ibanez Nov 13, 2025
bdc4689
DEVEL-README.md, c/README.md: More details about building and testing.
MLopez-Ibanez Nov 14, 2025
81cef38
c/Makefile: Handle LDLIBS and LDFLAGS.
MLopez-Ibanez Nov 14, 2025
2914c29
* c/gcc_attribs.h (_attr_optimize_finite_and_associative_math): New …
MLopez-Ibanez Nov 14, 2025
df7b603
* python/src/moocore/_moocore.py: Mention nondominated sorting in doc.
MLopez-Ibanez Nov 14, 2025
521f0f3
c/README.md: Move testsuite up.
MLopez-Ibanez Nov 14, 2025
3bca9fc
* python/doc/source/index.rst: Move benchmarks to separate file.
MLopez-Ibanez Nov 14, 2025
b3614ab
* python/src/moocore/_moocore.py (pareto_rank): Clarify example.
MLopez-Ibanez Nov 14, 2025
561f81f
c/nondominated.h (get_nondominated_set): Use restrict.
MLopez-Ibanez Nov 14, 2025
34dcd5d
r/R/nondominated.R (pareto_rank): Improve doc and examples.
MLopez-Ibanez Nov 14, 2025
662b328
Implement O(k * n log n) nondominated sorting in 3D.
MLopez-Ibanez Nov 14, 2025
bbe039b
python/tests/test_moocore.py (test_pareto_rank): Use keep_weakly=True.
MLopez-Ibanez Nov 14, 2025
cfd1fe4
R/Python: Document new algorithm for pareto_rank() in 3D and update b…
MLopez-Ibanez Nov 14, 2025
3cb4158
python/benchmarks/bench_igdplus.py: Add DESDEO but comment it out.
MLopez-Ibanez Nov 14, 2025
28689d6
python/Makefile (doc,fastdoc): Do not clean.
MLopez-Ibanez Nov 15, 2025
027dd30
* python/pyproject.toml: Set pytest timeout to 10 seconds. Print 5 s…
MLopez-Ibanez Nov 15, 2025
d1c52a4
python/src/moocore/_ffi_build.py: Add -march= to link flags. Handle D…
MLopez-Ibanez Nov 15, 2025
1df096b
c/config.h: Make sure to disable assert() with DEBUG=0.
MLopez-Ibanez Nov 15, 2025
fc94226
c/io_priv.h: Formatting.
MLopez-Ibanez Nov 15, 2025
2a7f920
c/nondominated.h (find_nondominated_set_agree_): Slight simplification.
MLopez-Ibanez Nov 16, 2025
c22f43e
c/pareto.c (pareto_rank_naive): Simplify.
MLopez-Ibanez Nov 16, 2025
90016ab
* python/doc/source/_static/bench/ndsort_bench-ran-2d-time.png: Update.
MLopez-Ibanez Nov 17, 2025
708f97d
c/hvapprox.c (compute_hua_wang_direction): Help the vectorizer by pre…
MLopez-Ibanez Nov 16, 2025
3209774
README.md: Mention seqme.
MLopez-Ibanez Nov 17, 2025
4facb36
python/ Improve typing.
MLopez-Ibanez Nov 19, 2025
5793261
* c/common.h: Honor NDEBUG when building the R_PACKAGE.
MLopez-Ibanez Nov 19, 2025
d2de9f6
r/Makefile (check): Run with DEBUG=1
MLopez-Ibanez Nov 19, 2025
89a24a9
* r/DESCRIPTION: Require R >= 4.1.
MLopez-Ibanez Nov 19, 2025
f73f5a7
* python/benchmarks/bench.py: Add support for setup= and check= argu…
MLopez-Ibanez Nov 20, 2025
fcb69bb
c/pareto.c (pareto_rank_2d): Simplify.
MLopez-Ibanez Nov 24, 2025
b35ac44
c/io.h: Use restrict when appropriate.
MLopez-Ibanez Nov 24, 2025
e03c25d
python/tests/test_bugs.py (test_bug38): New test.
MLopez-Ibanez Nov 24, 2025
11b55a6
[pre-commit.ci] pre-commit autoupdate
pre-commit-ci[bot] Nov 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/workflows/R.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ jobs:
os: [ ubuntu-22.04, windows-latest, macos-15-intel, macos-14 ]
r: [ release ]
include:
# Use 4.0 to check with rtools40's older compiler
- { os: windows-latest, r: '4.0' }
- { os: windows-latest, r: '4.1' }
# Use latest ubuntu to make it easier to install dependencies
- { os: ubuntu-24.04, r: 'devel', http-user-agent: 'release' }
env:
Expand Down
10 changes: 5 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ci:
repos:
- repo: https://github.com/lorenzwalthert/precommit
rev: v0.4.3.9014
rev: v0.4.3.9017
hooks:
- id: parsable-R
- id: no-browser-statement
Expand Down Expand Up @@ -43,19 +43,19 @@ repos:
exclude: '(\.Rd|python/doc/source/reference/.*|test-doctest-.*)'

- repo: https://github.com/tox-dev/tox-ini-fmt
rev: "1.6.0"
rev: "1.7.0"
hooks:
- id: tox-ini-fmt

- repo: https://github.com/tox-dev/pyproject-fmt
rev: "v2.6.0"
rev: "v2.11.1"
hooks:
- id: pyproject-fmt
additional_dependencies: ["tox>=4.12.1"]

- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.13.0
rev: v0.14.6
hooks:
# Run the formatter.
- id: ruff-format
Expand All @@ -67,6 +67,6 @@ repos:
require_serial: true

- repo: https://github.com/sphinx-contrib/sphinx-lint
rev: v1.0.0
rev: v1.0.2
hooks:
- id: sphinx-lint
26 changes: 26 additions & 0 deletions DEVEL-README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,32 @@ How to release
1. `git ci -a -m "Start development of v{NEW_VERSION}"`


Building the code
=================

C code
-----

See [*Compilation*](https://github.com/multi-objective/moocore/tree/main/c#compilation) to compile the C code under `c/`.

R and Python packages
---------------------

Under `r/` or `python/`, the commands `make build` and `make install` will build and install the R and Python packages.


Testing
========

The C code and the Python and R packages have their own testsuites. See [C testsuite](https://github.com/multi-objective/moocore/tree/main/c#testsuite) to setup and run the C testsuite.

The Python and R testsuites are run automatically via Github Actions for every push and pull request. You can run then manually by running `make test` under `r/` or `python/`.

You can run all testsuites at once by executing at the top-level:

make test


How to extend the Python API
============================

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
PACKAGEVERSION=0.1.9
PACKAGEVERSION=0.2.0

.PHONY: default clean check test pre-commit

Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ The following projects currently use `moocore`:
- [`pymoo`](https://pymoo.org/)
- [`Liger`](https://www.ide.uk/project-liger)
- [`DESDEO`](https://github.com/industrial-optimization-group/DESDEO/)
- [`IOHInspector`](https://github.com/IOHprofiler/IOHinspector?tab=readme-ov-file)
- [QuantumAnnealingMOO](https://github.com/andrew-d-king/QuantumAnnealingMOO) (D-Wave Quantum Inc)
- [`seqme`](https://github.com/szczurek-lab/seqme)


[c-build-badge]: https://github.com/multi-objective/moocore/actions/workflows/C.yml/badge.svg?event=push
Expand All @@ -79,5 +82,5 @@ The following projects currently use `moocore`:
[r-universe-build-link]: https://github.com/r-universe/multi-objective/actions/workflows/build.yml
[r-universe-version]: https://multi-objective.r-universe.dev/moocore
[r-universe-version-badge]: https://multi-objective.r-universe.dev/badges/moocore
[testsuite-badge]: https://github.com/multi-objective/testsuite/actions/workflows/moocore.yml/badge.svg?event=push
[testsuite-badge]: https://github.com/multi-objective/testsuite/actions/workflows/moocore.yml/badge.svg
[testsuite-link]: https://github.com/multi-objective/testsuite/actions/workflows/moocore.yml
17 changes: 10 additions & 7 deletions c/Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#-----------------------------------------------------------------------
# Makefile for moocore
#-----------------------------------------------------------------------
VERSION = 0.17.0
VERSION = 0.18$(REVISION)

S=
## Quiet / verbose output:
Expand Down Expand Up @@ -96,6 +96,7 @@ HDRS = avl.h \
hvapprox.h \
hv_priv.h \
hv3d_priv.h \
hv4d_priv.h \
igd.h \
io.h \
io_priv.h \
Expand All @@ -116,7 +117,8 @@ DIST_ROOT_FILES = Makefile README.md LICENSE
OBJS = $(SRCS:.c=.o)
OBJS := $(OBJS:.cpp=.o)

EXE_LDFLAGS=-lm
LDLIBS=-lm
EXE_LDFLAGS=$(LDLIBS)

include gitversion.mk

Expand All @@ -135,12 +137,12 @@ SHLIB_LDFLAGS = -shared
# Platform-specific linker flags
ifeq ($(uname_S),Linux)
SHLIB_CFLAGS += -fPIC
SHLIB_LDFLAGS += -lm -Wl,--no-undefined
SHLIB_LDFLAGS += $(LDLIBS) -Wl,--no-undefined
SHLIB_EXT=so
endif
ifeq ($(uname_S),Darwin)
SHLIB_CFLAGS += -fPIC
SHLIB_LDFLAGS += -lm
SHLIB_LDFLAGS += $(LDLIBS)
SHLIB_EXT=dylib
endif
ifeq ($(uname_S),Windows)
Expand All @@ -156,10 +158,10 @@ EXE_CFLAGS += $(SANITIZERS) $(OPT_CFLAGS) $(MARCH_FLAGS) $(WARN_CFLAGS) \


# List of test target base names
TEST_NAMES := eaf nondominated hv hvapprox igd epsilon dominatedsets
TEST_NAMES := eaf nondominated hv hvapprox igd epsilon dominatedsets ndsort
TEST_TARGETS := $(addprefix test-,$(TEST_NAMES))
TIME_TARGETS := $(addprefix time-,$(TEST_NAMES))
ALL_NAMES := $(TEST_NAMES) ndsort
ALL_NAMES := $(TEST_NAMES)

EXE_FILES := $(addsuffix $(EXE), $(addprefix $(BINDIR)/,$(ALL_NAMES)))

Expand Down Expand Up @@ -195,7 +197,7 @@ $(BINDIR)/nondominated$(EXE): nondominated.o timer.o
$(EXE_FILES): cmdline.o io.o
$(call MKDIR, $(BINDIR)/)
$(call ECHO,--> Building $@ version $(VERSION) <---)
$(QUIET_LINK)$(CC) -o $@ $^ $(EXE_CFLAGS) $(CFLAGS) $(EXE_LDFLAGS)
$(QUIET_LINK)$(CC) -o $@ $^ $(EXE_CFLAGS) $(CFLAGS) $(EXE_LDFLAGS) $(LDFLAGS)

dominatedsets.o: cmdline.h io.h nondominated.h
eaf_main.o: cmdline.h io.h eaf.h
Expand Down Expand Up @@ -224,6 +226,7 @@ $(CXXSHLIB): $(LIBHV_OBJS)
$(CXX) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $^ $(SHLIB_LDFLAGS)

clean:
@-$(RM) *.s *.i
@-$(RM) config.status config.log
@-$(RM) Hypervolume_MEX.mex
@-$(RM) $(SHLIB) $(CXXSHLIB)
Expand Down
4 changes: 4 additions & 0 deletions c/NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# moocore C library

## 0.18

* `pareto_rank()` is now O(k * n log n) in 3D, which is faster than the naive O(n^3).

## 0.17.0

* `hv_contributions()` gains a parameter `ignore_dominated`. The 3D case uses the HVC3D algorithm implemented in `hvc3d()`.
Expand Down
59 changes: 36 additions & 23 deletions c/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,17 @@ This uses the option `"-march=native"`. If your GCC version does not support `"n

make all MARCH=x86-64-v2

See the [GCC manual](https://gcc.gnu.org/onlinedocs/gcc/Submodel-Options.html** for the names of the architectures supported by your version of GCC.
See the [GCC manual](https://gcc.gnu.org/onlinedocs/gcc/Submodel-Options.html) for the names of the architectures supported by your version of GCC.

You can compile the code with various runtime checks enabled using the option `DEBUG=1`. This will slow down the code significantly.
You can compile the code with various runtime checks enabled using the option `DEBUG=1`. This will slow down the code significantly. If this is too slow for your purposes, you can disable the [sanitizers](https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#index-fsanitize_003daddress) using `make all DEBUG=1 SANITIZERS=""`.

The build system will try to pick good compiler flags for you, but if you need to, you can override them by passing the option `OPT_CFLAGS`. For example, to disable compiler optimization and enabled debug symbols, you could run:

make all OPT_CFLAGS="-O0 -g"


If you do not want to see the command line of each compiler
invocation, pass `S=1` to `make`.
invocation, you pass `S=1` to `make`.


Embedding (shared library)
Expand All @@ -68,6 +68,38 @@ Most functions are implemented in headers such as `nondominated.h`. For other fu
Functions exported by the library are marked with `MOOCORE_API`.


Testsuite
=========

The **moocore** executables are validated using a [comprehensive testsuite](https://github.com/multi-objective/testsuite). Running the testsuite requires [Python](https://www.python.org/downloads/) `>= 3.10` and additional Python packages (see [`testsuite/requirements.txt`](https://github.com/multi-objective/testsuite/blob/main/requirements.txt)). To run the testsuite yourself, follow these steps:

```bash
# Download moocore
git clone https://github.com/multi-objective/moocore moocore
# Download the testsuite
git clone https://github.com/multi-objective/testsuite moocore/testsuite
# Install required python packages
python3 -m pip install -r testsuite/requirements.txt
# Testing
make -C moocore/c/ test
# Timing
make -C moocore/c/ time
```

Under `moocore/c/`, `make test` will compile the code with `DEBUG=1 SANTIZERS="" OPT_CFLAGS="-Og -g3"`. This is useful for debugging failures.

`make time` will compile the code with `DEBUG=0 SANITIZERS="" OPT_CLAGS="-O3 -ftlo -march=native"`. This is useful for benchmarking code and making sure compiler optimizations do not break anything.

Neither `make test` nor `make time` recompile the code that has not been modified. So you can compile the code first with your preferred compiler flags and then run the testsuite. For example, if you compile with `make all DEBUG=1`, the code will be compiler with several [sanitizers](https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#index-fsanitize_003daddress) enabled. You can then call `make test` to run the testsuite with the sanitizers enabled. This is much slower, but very helpful to track crashes.

Under `c/` there are various targets to run only parts of the testsuite, for example:

make test-hv
make test-nondominated
...



Command-line executables
========================

Expand Down Expand Up @@ -304,25 +336,6 @@ Options:
or maximised (+). By default all are minimised;
```

Testsuite
=========

The **moocore** executables are validated using a [comprehensive testsuite](https://github.com/multi-objective/testsuite). Running the testsuite requires [Python](https://www.python.org/downloads/) `>= 3.10` and additional Python packages (see [`testsuite/requirements.txt`](https://github.com/multi-objective/testsuite/blob/main/requirements.txt)). To run the testsuite yourself, follow these steps:

```bash
# Download moocore
git clone https://github.com/multi-objective/moocore moocore
# Download the testsuite
git clone https://github.com/multi-objective/testsuite moocore/testsuite
# Testing
make -C moocore/c/ test
# Timing
make -C moocore/c/ time
```




License
========

Expand All @@ -348,5 +361,5 @@ See the [LICENSE](/LICENSE) and [COPYRIGHTS](/r/inst/COPYRIGHTS) files.
[r-moocore-cran]: https://cran.r-project.org/package=moocore
[r-moocore-github]: https://github.com/multi-objective/moocore/tree/main/r#readme
[r-moocore-homepage]: https://multi-objective.github.io/moocore/r/
[testsuite-badge]: https://github.com/multi-objective/testsuite/actions/workflows/moocore.yml/badge.svg?event=push
[testsuite-badge]: https://github.com/multi-objective/testsuite/actions/workflows/moocore.yml/badge.svg
[testsuite-link]: https://github.com/multi-objective/testsuite/actions/workflows/moocore.yml
5 changes: 5 additions & 0 deletions c/avl_tiny.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ avl_init_tree(avl_tree_t *rc, avl_compare_t cmp) {
/* Reinitializes the tree structure for reuse. Nothing is free()d.
* Compare and freeitem functions are left alone.
* O(1) */
static inline void
avl_clear_tree(avl_tree_t *avltree) {
avltree->top = avltree->head = avltree->tail = NULL;
}

static void
avl_clear_node(avl_node_t *newnode) {
newnode->left = newnode->right = NULL;
Expand Down
10 changes: 7 additions & 3 deletions c/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@
#ifdef R_PACKAGE
#define R_NO_REMAP
#include <R.h>
#define assert(EXP) \
do { if (unlikely(!(EXP))) { Rf_error("error: assertion failed: '%s' at %s:%d", \
#EXP, __FILE__, __LINE__);}} while(0)
#ifdef NDEBUG
# define assert(EXP) ((void)0)
#else
# define assert(EXP) do { if (unlikely(!(EXP))) \
Rf_error("error: assertion failed: '%s' at %s:%d", \
#EXP, __FILE__, __LINE__);} while(0)
#endif
#include "gcc_attribs.h"
#define fatal_error(...) Rf_error(__VA_ARGS__)
#define moocore_perror(...) Rf_error(__VA_ARGS__)
Expand Down
6 changes: 6 additions & 0 deletions c/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,10 @@
# define _CRT_SECURE_NO_WARNINGS 1
#endif

#if DEBUG == 0 && !defined(NDEBUG)
# define NDEBUG // Disable assert()
#elif DEBUG > 0 && defined(NDEBUG)
# undef NDEBUG // Enable assert()
#endif

#endif // _MOOCORE_CONFIG_H_
2 changes: 1 addition & 1 deletion c/eaf.c
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ eaf_check_polygons(eaf_polygon_t *p, int nobj)
polygon_print(pi, nobj);
polygon_print(pj, nobj);
#endif
assert(!polygons_intersect(pi, pj, nobj));
assert(false);
}
pj = next_polygon(pj, nobj, end);
}
Expand Down
2 changes: 1 addition & 1 deletion c/epsilon.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ do_file (const char *filename, double *reference, size_t reference_size,
// time_elapsed = Timer_elapsed_virtual ();
fprintf (outfile, indicator_printf_format "\n", epsilon);
if ((additive_flag && epsilon < 0) || (!additive_flag && epsilon < 1)) {
errprintf ("%s: some points are not dominated by the reference set",
errprintf ("%s: some points are not dominated by the reference set",
filename);
exit (EXIT_FAILURE);
}/*
Expand Down
Loading
Loading