Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
Mickaël Binois,
Leonardo C.T. Bezerra,
Fergus Rooney,
[Lennart Schäpermeier](https://schaepermeier.github.io).
[Lennart Schäpermeier](https://schaepermeier.github.io),
Jonathan Fieldsend.

---------------------------------------

Expand Down
14 changes: 14 additions & 0 deletions TODO-archiving
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

# Unbounded Archive
- [ ] .add_many() is currently a loop in Python and it is not available in C.
First, it could loop in C.
Also, it could filter before adding unless the user specifies "nondominated=True".
If it is nondominated, it could do a faster merge operation.

- Benchmark against: https://github.com/alandefreitas/pareto


# Bounded size archives.

- [ ] Hypervolume archiver
- [ ] MGA
2 changes: 2 additions & 0 deletions bibkeys.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
AraSei1989rst
AugBadBroZit2009gecco
BeuFonLopPaqVah09:tec
BezLopStu2017assessment
Expand Down Expand Up @@ -27,6 +28,7 @@ HanJas1998
HerWer1987tabucol
IshHeSha2019regular
IshMasTanNoj2015igd
JasLus2018ndtree
Jen03
JohAraMcGSch1991
KnoCor2002cec
Expand Down
35 changes: 22 additions & 13 deletions c/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ SRCS = avl.c \
igd.c \
io.c \
libutil.c \
main-archiver.o \
main-hv.c \
main-hvapprox.c \
main-nondominated.c \
Expand All @@ -81,11 +82,12 @@ SRCS = avl.c \
pareto.c \
rng.c \
timer.c \
treap2d_fixed_size.c \
treap_archive.c \
whv.c \
whv_hype.c

HDRS = avl.h \
avl_tiny.h \
bit_array.h \
cmdline.h \
common.h \
Expand All @@ -112,6 +114,9 @@ HDRS = avl.h \
rng.h \
sort.h \
timer.h \
treap2d.h \
treap2d_dlnode.h \
treap2d_fixed_size.h \
whv.h \
whv_hype.h \
ziggurat_constants.h
Expand Down Expand Up @@ -160,7 +165,7 @@ EXE_CFLAGS += $(SANITIZERS) $(OPT_CFLAGS) $(MARCH_FLAGS) $(WARN_CFLAGS) \


# List of test target base names
TEST_NAMES := eaf nondominated hv hvapprox igd epsilon dominatedsets ndsort
TEST_NAMES := archiver eaf nondominated hv hvapprox igd epsilon dominatedsets ndsort
ASAN_TARGETS := $(addprefix asan-,$(TEST_NAMES))
UBSAN_TARGETS:= $(addprefix ubsan-,$(TEST_NAMES))
TEST_TARGETS := $(addprefix test-,$(TEST_NAMES))
Expand Down Expand Up @@ -192,14 +197,15 @@ $(ALL_NAMES): %: $(BINDIR)/%$(EXE)

include libhv.mk

$(BINDIR)/dominatedsets$(EXE): dominatedsets.o nondominated.o
$(BINDIR)/archiver$(EXE): main-archiver.o io.o treap_archive.o nondominated.o treap2d_fixed_size.o
$(BINDIR)/dominatedsets$(EXE): dominatedsets.o nondominated.o treap2d_fixed_size.o
$(BINDIR)/eaf$(EXE): eaf.o eaf_main.o eaf3d.o avl.o
$(BINDIR)/epsilon$(EXE): epsilon.o nondominated.o
$(BINDIR)/epsilon$(EXE): epsilon.o nondominated.o treap2d_fixed_size.o
$(BINDIR)/hv$(EXE): main-hv.o timer.o $(LIBHV_OBJS)
$(BINDIR)/hvapprox$(EXE): main-hvapprox.o timer.o hvapprox.o rng.o mt19937/mt19937.o nondominated.o
$(BINDIR)/igd$(EXE): igd.o nondominated.o
$(BINDIR)/ndsort$(EXE): ndsort.o pareto.o nondominated.o $(LIBHV_OBJS)
$(BINDIR)/nondominated$(EXE): main-nondominated.o timer.o nondominated.o
$(BINDIR)/hvapprox$(EXE): main-hvapprox.o timer.o hvapprox.o rng.o mt19937/mt19937.o nondominated.o treap2d_fixed_size.o
$(BINDIR)/igd$(EXE): igd.o nondominated.o treap2d_fixed_size.o
$(BINDIR)/ndsort$(EXE): ndsort.o pareto.o $(LIBHV_OBJS)
$(BINDIR)/nondominated$(EXE): main-nondominated.o timer.o nondominated.o treap2d_fixed_size.o

$(EXE_FILES): cmdline.o io.o
$(call MKDIR, $(BINDIR)/)
Expand All @@ -214,22 +220,25 @@ eaf3d.o: eaf.h io.h bit_array.h cvector.h avl.h
eaf_main.o: cmdline.h io.h eaf.h bit_array.h cvector.h
epsilon.o: cmdline.h io.h nondominated.h epsilon.h
hv.o: hv.h hv_priv.h hvc4d_priv.h sort.h libmoocore-config.h
hv3dplus.o: hv_priv.h sort.h hv3d_priv.h avl_tiny.h
hv3dplus.o: hv_priv.h sort.h hv3d_priv.h treap2d.h
hv4d.o: hv4d_priv.h hv_priv.h sort.h
hv_contrib.o: hv.h libmoocore-config.h nondominated.h
hvapprox.o: hvapprox.h pow_int.h rng.h mt19937/mt19937.h
hvc3d.o: hv_priv.h sort.h hv3d_priv.h avl_tiny.h
hvc3d.o: hv_priv.h sort.h hv3d_priv.h treap2d.h
igd.o: cmdline.h io.h nondominated.h igd.h pow_int.h
io.o: io.h io_priv.h
main-archiver.o: cmdline.h io.h treap_archive.h treap2d.h nd_tree.h libmoocore-config.h
main-hv.o: cmdline.h io.h hv.h timer.h libmoocore-config.h nondominated.h hvapprox.h
main-hvapprox.o: cmdline.h io.h hvapprox.h
main-nondominated.o : cmdline.h io.h nondominated.h nondominated_kung.h
ndsort.o: cmdline.h io.h nondominated.h hv.h
nondominated.h: avl_tiny.h nondominated_kung.h
nondominated.o: nondominated.h nondominated_kung.h
pareto.o: nondominated.h
nondominated.h: nondominated_kung.h
nondominated.o: nondominated.h nondominated_kung.h treap2d_fixed_size.h
pareto.o: nondominated.h treap2d_fixed_size.h
rng.o: rng.h mt19937/mt19937.h ziggurat_constants.h
timer.o: timer.h
treap2d_fixed_size.o: treap2d_fixed_size.h
treap2d_fixed_size.h: treap2d.h
$(OBJS): common.h gcc_attribs.h config.h maxminclamp.h

shlibs: clean $(SHLIB) $(CXXSHLIB)
Expand Down
3 changes: 3 additions & 0 deletions c/NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
* main-nondominated.c: Renamed from nondominated.c.
* hv and hvapprox executables now use -U instead of -u for --union to be
consistent with nondominated.
* treap2d.h: New.
* pareto.c, nondominated.c, hv3d_priv.h: Use Treap instead of AVL-tree.
* avl_tiny.h: Delete.


## 0.19.2
Expand Down
1 change: 1 addition & 0 deletions c/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ The [**moocore** project](https://github.com/multi-objective/moocore/) collects
* Computation of the Empirical Attainment Function. The empirical attainment
function (EAF) describes the probabilistic distribution of the outcomes
obtained by a stochastic algorithm in the objective space.
* Archivers that allow efficiently storing a nondominated set from points given one-by-one as a sequence.

The goal of **moocore** is to provide an implementation of these functions that is efficient, thoroughly tested, well-documented, multi-platform (Windows, Linux, MacOS), multi-language (C, R, and Python, so far), with minimal dependencies and reusable from other libraries and packages, thus providing an easy-to-use and high-performance building block.

Expand Down
110 changes: 110 additions & 0 deletions c/archive.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#ifndef _ARCHIVE_H_
#define _ARCHIVE_H_

#include "treap_archive.h"
#include "nd_tree.h"

enum unbounded_archive_type_t {
UNBOUNDED_ARCHIVE_TREAP,
UNBOUNDED_ARCHIVE_NDTREE,
};

typedef struct UnboundedArchive {
enum unbounded_archive_type_t archive_type;
union {
TreapArchive treap;
NDTreeArchive ndtree;
};
} UnboundedArchive;

#define UNBOUNDED_ARCHIVE_DISPATCH(SELF, TREAP_CODE, NDTREE_CODE) \
switch ((SELF)->archive_type) { \
case UNBOUNDED_ARCHIVE_TREAP: do { TREAP_CODE; } while(0); break; \
case UNBOUNDED_ARCHIVE_NDTREE: do { NDTREE_CODE; } while(0); break; \
default: unreachable(); \
}


static inline UnboundedArchive *
archive_new(enum unbounded_archive_type_t type)
{
UnboundedArchive * arch = malloc(sizeof(*arch));
arch->archive_type = type;
return arch;

}
static inline UnboundedArchive *
archive_ndtree_new(dimension_t dim, NDTreeConfig config)
{
UnboundedArchive * archive = archive_new(UNBOUNDED_ARCHIVE_NDTREE);
ndtree_init(&archive->ndtree, dim, config.max_children, config.max_bucket_size, config.allow_duplicates);
return archive;
}

static inline UnboundedArchive *
archive_treap_new(void)
{
UnboundedArchive * archive = archive_new(UNBOUNDED_ARCHIVE_TREAP);
treap_archive_init(&archive->treap);
return archive;
}

/**

*/
static inline int
archive_add(UnboundedArchive * restrict arch, const double * restrict z, const void * restrict x)
{
UNBOUNDED_ARCHIVE_DISPATCH(
arch,
return treap_archive_add_discard(&arch->treap, z, x),
return ndtree_add_discard(&arch->ndtree, z, x));
}

static inline size_t
archive_total_size(const UnboundedArchive *arch)
{
UNBOUNDED_ARCHIVE_DISPATCH(
arch,
return treap_archive_total_size(&arch->treap),
return ndtree_total_size(&arch->ndtree));
}

static inline size_t
archive_unique_size(const UnboundedArchive *arch)
{
UNBOUNDED_ARCHIVE_DISPATCH(
arch,
return treap_archive_unique_size(&arch->treap),
return ndtree_unique_size(&arch->ndtree));
}

static inline void
archive_get_contents(const UnboundedArchive *arch, double * z_list, const void ** x_list)
{
UNBOUNDED_ARCHIVE_DISPATCH(
arch,
treap_archive_get_contents(&arch->treap, z_list, x_list),
ndtree_get_contents(&arch->ndtree, z_list, x_list));
}

static inline void
archive_free(UnboundedArchive *arch)
{
UNBOUNDED_ARCHIVE_DISPATCH(
arch,
treap_archive_free_nodes(&arch->treap),
ndtree_free_nodes(&arch->ndtree));
free(arch);
}

static inline void
archive_print_stats(FILE * stream, const UnboundedArchive *arch)
{
UNBOUNDED_ARCHIVE_DISPATCH(
arch,
(void)0,
ndtree_print_stats(stream, &arch->ndtree));
}

#endif // _ARCHIVE_H_
19 changes: 19 additions & 0 deletions c/archiving.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*****************************************************************************

Public definitions that are common to all types of archives.

*****************************************************************************/
#ifndef _ARCHIVING_H_
#define _ARCHIVING_H_

enum archive_insert_result_t {
ARCHIVE_INSERT_UKNOWN_ERROR = -4,
ARCHIVE_INSERT_X_MUST_BE_NOT_NULL = -3,
ARCHIVE_INSERT_X_MUST_BE_NULL = -2,
ARCHIVE_INSERT_MEMORY_ERROR = -1,
ARCHIVE_INSERT_REJECTED = 0,
ARCHIVE_INSERT_ACCEPTED = 1,
ARCHIVE_INSERT_DUPLICATED = 2,
};

#endif // _ARCHIVING_H_
26 changes: 26 additions & 0 deletions c/archiving_priv.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef _ARCHIVING_PRIV_H_
#define _ARCHIVING_PRIV_H_

#include <stdint.h>
#include <stdlib.h>
#include <assert.h>

#include "archiving.h"

/**
Returns 0 if OK, negative values if there is a problem.
*/
static inline int
wrong_x_is_null(signed char * restrict x_is_null, const void * restrict x)
{
if (*x_is_null == 0)
return x != NULL ? 0 : ARCHIVE_INSERT_X_MUST_BE_NOT_NULL;
if (*x_is_null == 1)
return x == NULL ? 0 : ARCHIVE_INSERT_X_MUST_BE_NULL;

*x_is_null = (x == NULL);
return 0;
}


#endif // _ARCHIVING_PRIV_H_
Loading
Loading