Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integer handling for feasible sets #83

Merged
merged 8 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from 7 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
15 changes: 15 additions & 0 deletions include/feasibility_set.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,26 @@ int lp_feasibility_set_is_full(const lp_feasibility_set_t* set);
*/
int lp_feasibility_set_is_point(const lp_feasibility_set_t* set);

/**
* Check if the set contains only one integer value.
*/
int lp_feasibility_set_is_point_int(const lp_feasibility_set_t* set);

/**
* Returns the number of integers in set (up to LONG_MAX).
*/
long lp_feasibility_set_count_int(const lp_feasibility_set_t* set);

/**
* Check if the given value belongs to the set.
*/
int lp_feasibility_set_contains(const lp_feasibility_set_t* set, const lp_value_t* value);

/**
* Checks if the set contains an integer value.
*/
int lp_feasibility_set_contains_int(const lp_feasibility_set_t* set);

/**
* Pick a value from the feasible set (must be non-empty). If an integer value
* is available it will be picked.
Expand Down
5 changes: 5 additions & 0 deletions include/integer.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ int lp_integer_print_matrix(const lp_integer_t* c_array, size_t m, size_t n, FIL
*/
char* lp_integer_to_string(const lp_integer_t* c);

/**
* Returns true if the integer fits in long.
*/
int lp_integer_fits_int(const lp_integer_t* c);

/**
* Returns the int representation of the integer (truncated but keeps sign).
*/
Expand Down
13 changes: 11 additions & 2 deletions include/interval.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ extern "C" {
#endif

/**
* An interval (a, b) with both point being values. This side is open is _open
* An interval (a, b) with both point being values. A side is open if _open
* is true. If interval is a point [a,a], then the value b is not used (it is
* not constructed).
*/
Expand Down Expand Up @@ -83,6 +83,12 @@ void lp_interval_swap(lp_interval_t* I1, lp_interval_t* I2);
/** Check if the value is contained in the interval */
int lp_interval_contains(const lp_interval_t* I, const lp_value_t* v);

/** Check if the interval contains an integer value */
int lp_interval_contains_int(const lp_interval_t* I);

/** Counts the number of integers in the interval (up to LONG_MAX) */
long lp_interval_count_int(const lp_interval_t* I);

/** Returns an approximation of the log interval size */
int lp_interval_size_approx(const lp_interval_t* I);

Expand Down Expand Up @@ -113,9 +119,12 @@ void lp_interval_pick_value(const lp_interval_t* I, lp_value_t* v);
/** Compares the lower bounds of the intervals */
int lp_interval_cmp_lower_bounds(const lp_interval_t* I1, const lp_interval_t* I2);

/** Compares the uppoer bounds of the intervals */
/** Compares the upper bounds of the intervals */
int lp_interval_cmp_upper_bounds(const lp_interval_t* I1, const lp_interval_t* I2);

/** Compares an interval I with a value v. Returns 0 if v in I, 1 if v is below I, -1 if v is above I. */
int lp_interval_cmp_value(const lp_interval_t* I, const lp_value_t* v);

/**
* Comparison of intervals based on upper bounds, with additional intersect info.
*/
Expand Down
4 changes: 4 additions & 0 deletions include/polyxx/interval.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ namespace poly {

/** Check whether an interval contains some value. */
bool contains(const Interval& i, const Value& v);
/** Check whether an interval contains an integer value. */
bool contains_int(const Interval& i);
/** Counts the number of integers in the interval up to LONG_MAX. */
long count_int(const Interval& i);
/** Get an approximation of the log interval size. */
int log_size(const Interval& i);

Expand Down
45 changes: 43 additions & 2 deletions python/polypyFeasibilitySet2.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,17 @@ FeasibilitySet_pick_value(PyObject* self);
static PyObject*
FeasibilitySet_intersect(PyObject* self, PyObject* args);

static PyObject*
FeasibilitySet_contains_value(PyObject* self, PyObject* args);

static PyObject*
FeasibilitySet_contains_int(PyObject* self);

PyMethodDef FeasibilitySet_methods[] = {
{"pick_value", (PyCFunction)FeasibilitySet_pick_value, METH_NOARGS, "Returns a value from the interval."},
{"intersect", (PyCFunction)FeasibilitySet_intersect, METH_VARARGS, "Returns the intersection of the interval with another one."},
{"intersect", (PyCFunction)FeasibilitySet_intersect, METH_VARARGS, "Returns the intersection of the set with another one."},
{"contains", (PyCFunction)FeasibilitySet_contains_value, METH_VARARGS, "Returns true if the value is in the feasibility set."},
{"contains_int", (PyCFunction)FeasibilitySet_contains_int, METH_NOARGS, "Returns true if the set contains an integer value."},
{NULL} /* Sentinel */
};

Expand Down Expand Up @@ -159,9 +167,42 @@ FeasibilitySet_intersect(PyObject* self, PyObject* args) {
lp_feasibility_set_t* S1 = ((FeasibilitySet*) self)->S;
lp_feasibility_set_t* S2 = ((FeasibilitySet*) feasibility_set_obj)->S;

// The intersect
// The intersection
lp_feasibility_set_t* P = lp_feasibility_set_intersect(S1, S2);
PyObject* P_obj = PyFeasibilitySet_create(P);

return P_obj;
}

static PyObject*
FeasibilitySet_contains_value(PyObject* self, PyObject* args) {

if (!PyTuple_Check(args) || PyTuple_Size(args) != 1) {
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}

PyObject* value_obj = PyTuple_GetItem(args, 0);

if (!PyValue_CHECK(value_obj)) {
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}

lp_feasibility_set_t* S = ((FeasibilitySet*) self)->S;
lp_value_t* v = &((Value*) value_obj)->v;

int result = lp_feasibility_set_contains(S, v);

PyObject* result_object = result ? Py_True : Py_False;
Py_INCREF(result_object);
return result_object;
}

static PyObject*
FeasibilitySet_contains_int(PyObject* self) {
lp_feasibility_set_t* S = ((FeasibilitySet*) self)->S;
PyObject* result_object = lp_feasibility_set_contains_int(S) ? Py_True : Py_False;
Py_INCREF(result_object);
return result_object;
}
51 changes: 45 additions & 6 deletions python/polypyFeasibilitySet3.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,17 @@ FeasibilitySet_pick_value(PyObject* self);
static PyObject*
FeasibilitySet_intersect(PyObject* self, PyObject* args);

static PyObject*
FeasibilitySet_contains_value(PyObject* self, PyObject* args);

static PyObject*
FeasibilitySet_contains_int(PyObject* self);

PyMethodDef FeasibilitySet_methods[] = {
{"pick_value", (PyCFunction)FeasibilitySet_pick_value, METH_NOARGS, "Returns a value from the interval."},
{"intersect", (PyCFunction)FeasibilitySet_intersect, METH_VARARGS, "Returns the intersection of the interval with another one."},
{"intersect", (PyCFunction)FeasibilitySet_intersect, METH_VARARGS, "Returns the intersection of the set with another one."},
{"contains", (PyCFunction)FeasibilitySet_contains_value, METH_VARARGS, "Returns true if the value is in the feasibility set."},
{"contains_int", (PyCFunction)FeasibilitySet_contains_int, METH_NOARGS, "Returns true if the set contains an integer value."},
{NULL} /* Sentinel */
};

Expand Down Expand Up @@ -98,8 +106,7 @@ PyTypeObject FeasibilitySetType = {
};

static void
FeasibilitySet_dealloc(FeasibilitySet* self)
{
FeasibilitySet_dealloc(FeasibilitySet* self) {
lp_feasibility_set_delete(self->S);
((PyObject*)self)->ob_type->tp_free((PyObject*)self);
}
Expand All @@ -120,8 +127,7 @@ FeasibilitySet_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
}

static int
FeasibilitySet_init(FeasibilitySet* self, PyObject* args)
{
FeasibilitySet_init(FeasibilitySet* self, PyObject* args) {
if (PyTuple_Check(args) && PyTuple_Size(args) == 0) {
// Defaults to (-inf, +inf)
self->S = lp_feasibility_set_new_full();
Expand Down Expand Up @@ -168,9 +174,42 @@ FeasibilitySet_intersect(PyObject* self, PyObject* args) {
lp_feasibility_set_t* S1 = ((FeasibilitySet*) self)->S;
lp_feasibility_set_t* S2 = ((FeasibilitySet*) feasibility_set_obj)->S;

// The intersect
// The intersection
lp_feasibility_set_t* P = lp_feasibility_set_intersect(S1, S2);
PyObject* P_obj = PyFeasibilitySet_create(P);

return P_obj;
}

static PyObject*
FeasibilitySet_contains_value(PyObject* self, PyObject* args) {

if (!PyTuple_Check(args) || PyTuple_Size(args) != 1) {
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}

PyObject* value_obj = PyTuple_GetItem(args, 0);

if (!PyValue_CHECK(value_obj)) {
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}

lp_feasibility_set_t* S = ((FeasibilitySet*) self)->S;
lp_value_t* v = &((Value*) value_obj)->v;

int result = lp_feasibility_set_contains(S, v);

PyObject* result_object = result ? Py_True : Py_False;
Py_INCREF(result_object);
return result_object;
}

static PyObject*
FeasibilitySet_contains_int(PyObject* self) {
lp_feasibility_set_t* S = ((FeasibilitySet*) self)->S;
PyObject* result_object = lp_feasibility_set_contains_int(S) ? Py_True : Py_False;
Py_INCREF(result_object);
return result_object;
}
14 changes: 12 additions & 2 deletions python/polypyInterval2.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,13 @@ Interval_pick_value(PyObject* self);
static PyObject*
Interval_contains_value(PyObject* self, PyObject* args);

static PyObject*
Interval_contains_int(PyObject* self);

PyMethodDef Interval_methods[] = {
{"pick_value", (PyCFunction)Interval_pick_value, METH_NOARGS, "Returns a value from the interval."},
{"contains", (PyCFunction)Interval_contains_value, METH_VARARGS, "Returns true if the value is in the interval."},
{"contains_int", (PyCFunction)Interval_contains_int, METH_NOARGS, "Returns true if the interval contains an integer value."},
{NULL} /* Sentinel */
};

Expand Down Expand Up @@ -89,8 +93,7 @@ PyTypeObject IntervalType = {
};

static void
Interval_dealloc(Interval* self)
{
Interval_dealloc(Interval* self) {
lp_interval_destruct(&self->I);
self->ob_type->tp_free((PyObject*)self);
}
Expand Down Expand Up @@ -163,6 +166,13 @@ Interval_contains_value(PyObject* self, PyObject* args) {

PyObject* result_object = result ? Py_True : Py_False;
Py_INCREF(result_object);
return result_object;
}

static PyObject*
Interval_contains_int(PyObject* self) {
Interval* I = (Interval*) self;
PyObject* result_object = lp_interval_contains_int(&I->I) ? Py_True : Py_False;
Py_INCREF(result_object);
return result_object;
}
17 changes: 13 additions & 4 deletions python/polypyInterval3.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,13 @@ Interval_pick_value(PyObject* self);
static PyObject*
Interval_contains_value(PyObject* self, PyObject* args);

static PyObject*
Interval_contains_int(PyObject* self);

PyMethodDef Interval_methods[] = {
{"pick_value", (PyCFunction)Interval_pick_value, METH_NOARGS, "Returns a value from the interval."},
{"contains", (PyCFunction)Interval_contains_value, METH_VARARGS, "Returns true if the value is in the interval."},
{"contains_int", (PyCFunction)Interval_contains_int, METH_NOARGS, "Returns true if the interval contains an integer value."},
{NULL} /* Sentinel */
};

Expand Down Expand Up @@ -98,8 +102,7 @@ PyTypeObject IntervalType = {
};

static void
Interval_dealloc(Interval* self)
{
Interval_dealloc(Interval* self) {
lp_interval_destruct(&self->I);
((PyObject*)self)->ob_type->tp_free((PyObject*)self);
}
Expand All @@ -120,8 +123,7 @@ Interval_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
}

static int
Interval_init(Interval* self, PyObject* args)
{
Interval_init(Interval* self, PyObject* args) {
if (PyTuple_Check(args) && PyTuple_Size(args) == 0) {
// Defaults to (-inf, +inf)
lp_interval_construct_full(&self->I);
Expand Down Expand Up @@ -172,6 +174,13 @@ Interval_contains_value(PyObject* self, PyObject* args) {

PyObject* result_object = result ? Py_True : Py_False;
Py_INCREF(result_object);
return result_object;
}

static PyObject*
Interval_contains_int(PyObject* self) {
Interval* I = (Interval*) self;
PyObject* result_object = lp_interval_contains_int(&I->I) ? Py_True : Py_False;
Py_INCREF(result_object);
return result_object;
}
Loading
Loading