summaryrefslogtreecommitdiff
path: root/isl_lp.c
blob: df09b751a089c3dc7ceac0cb96695aae69d58765 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include "isl_ctx.h"
#include "isl_lp.h"
#include "isl_lp_piplib.h"
#include "isl_seq.h"
#include "isl_tab.h"
#include "isl_map_private.h"

enum isl_lp_result isl_tab_solve_lp(struct isl_basic_map *bmap, int maximize,
				      isl_int *f, isl_int denom, isl_int *opt,
				      isl_int *opt_denom,
				      struct isl_vec **sol)
{
	struct isl_tab *tab;
	enum isl_lp_result res;
	unsigned dim = isl_basic_map_total_dim(bmap);

	if (maximize)
		isl_seq_neg(f, f, 1 + dim);

	bmap = isl_basic_map_gauss(bmap, NULL);
	tab = isl_tab_from_basic_map(bmap);
	res = isl_tab_min(tab, f, bmap->ctx->one, opt, opt_denom, 0);
	if (res == isl_lp_ok && sol) {
		*sol = isl_tab_get_sample_value(tab);
		if (!*sol)
			res = isl_lp_error;
	}
	isl_tab_free(tab);

	if (maximize)
		isl_seq_neg(f, f, 1 + dim);

	return res;
}

/* Given a basic map "bmap" and an affine combination of the variables "f"
 * with denominator "denom", set *opt/*opt_denom to the minimal
 * (or maximal if "maximize" is true) value attained by f/d over "bmap",
 * assuming the basic map is not empty and the expression cannot attain
 * arbitrarily small (or large) values.
 * If opt_denom is NULL, then *opt is rounded up (or down)
 * to the nearest integer.
 * The return value reflects the nature of the result (empty, unbounded,
 * minmimal or maximal value returned in *opt).
 */
enum isl_lp_result isl_basic_map_solve_lp(struct isl_basic_map *bmap, int max,
				      isl_int *f, isl_int d, isl_int *opt,
				      isl_int *opt_denom,
				      struct isl_vec **sol)
{
	if (sol)
		*sol = NULL;

	if (!bmap)
		return isl_lp_error;

	switch (bmap->ctx->lp_solver) {
	case ISL_LP_PIP:
		return isl_pip_solve_lp(bmap, max, f, d, opt, opt_denom, sol);
	case ISL_LP_TAB:
		return isl_tab_solve_lp(bmap, max, f, d, opt, opt_denom, sol);
	default:
		return isl_lp_error;
	}
}

enum isl_lp_result isl_basic_set_solve_lp(struct isl_basic_set *bset, int max,
				      isl_int *f, isl_int d, isl_int *opt,
				      isl_int *opt_denom,
				      struct isl_vec **sol)
{
	return isl_basic_map_solve_lp((struct isl_basic_map *)bset, max,
					f, d, opt, opt_denom, sol);
}