4 #include "isl_piplib.h"
5 #include "isl_sample_piplib.h"
7 static void swap_inequality(struct isl_basic_set
*bset
, int a
, int b
)
9 isl_int
*t
= bset
->ineq
[a
];
10 bset
->ineq
[a
] = bset
->ineq
[b
];
14 static struct isl_mat
*independent_bounds(struct isl_ctx
*ctx
,
15 struct isl_basic_set
*bset
)
18 struct isl_mat
*dirs
= NULL
;
19 struct isl_mat
*bounds
= NULL
;
25 dim
= isl_basic_set_n_dim(bset
);
26 bounds
= isl_mat_alloc(ctx
, 1+dim
, 1+dim
);
30 isl_int_set_si(bounds
->row
[0][0], 1);
31 isl_seq_clr(bounds
->row
[0]+1, dim
);
34 if (bset
->n_ineq
== 0)
37 dirs
= isl_mat_alloc(ctx
, dim
, dim
);
39 isl_mat_free(ctx
, bounds
);
42 isl_seq_cpy(dirs
->row
[0], bset
->ineq
[0]+1, dirs
->n_col
);
43 isl_seq_cpy(bounds
->row
[1], bset
->ineq
[0], bounds
->n_col
);
44 for (j
= 1, n
= 1; n
< dim
&& j
< bset
->n_ineq
; ++j
) {
47 isl_seq_cpy(dirs
->row
[n
], bset
->ineq
[j
]+1, dirs
->n_col
);
49 pos
= isl_seq_first_non_zero(dirs
->row
[n
], dirs
->n_col
);
52 for (i
= 0; i
< n
; ++i
) {
54 pos_i
= isl_seq_first_non_zero(dirs
->row
[i
], dirs
->n_col
);
59 isl_seq_elim(dirs
->row
[n
], dirs
->row
[i
], pos
,
61 pos
= isl_seq_first_non_zero(dirs
->row
[n
], dirs
->n_col
);
69 isl_int
*t
= dirs
->row
[n
];
70 for (k
= n
; k
> i
; --k
)
71 dirs
->row
[k
] = dirs
->row
[k
-1];
75 isl_seq_cpy(bounds
->row
[n
], bset
->ineq
[j
], bounds
->n_col
);
77 isl_mat_free(ctx
, dirs
);
82 /* Skew into positive orthant and project out lineality space */
83 static struct isl_basic_set
*isl_basic_set_skew_to_positive_orthant(
84 struct isl_basic_set
*bset
, struct isl_mat
**T
)
86 struct isl_mat
*U
= NULL
;
87 struct isl_mat
*bounds
= NULL
;
89 unsigned old_dim
, new_dim
;
97 isl_assert(ctx
, isl_basic_set_n_param(bset
) == 0, goto error
);
98 isl_assert(ctx
, bset
->n_div
== 0, goto error
);
99 isl_assert(ctx
, bset
->n_eq
== 0, goto error
);
101 old_dim
= isl_basic_set_n_dim(bset
);
102 /* Try to move (multiples of) unit rows up. */
103 for (i
= 0, j
= 0; i
< bset
->n_ineq
; ++i
) {
104 int pos
= isl_seq_first_non_zero(bset
->ineq
[i
]+1, old_dim
);
107 if (isl_seq_first_non_zero(bset
->ineq
[i
]+1+pos
+1,
111 swap_inequality(bset
, i
, j
);
114 bounds
= independent_bounds(ctx
, bset
);
117 new_dim
= bounds
->n_row
- 1;
118 bounds
= isl_mat_left_hermite(ctx
, bounds
, 1, &U
, NULL
);
121 U
= isl_mat_drop_cols(ctx
, U
, 1 + new_dim
, old_dim
- new_dim
);
122 bset
= isl_basic_set_preimage(bset
, isl_mat_copy(ctx
, U
));
126 isl_mat_free(ctx
, bounds
);
129 isl_mat_free(ctx
, bounds
);
130 isl_mat_free(ctx
, U
);
131 isl_basic_set_free(bset
);
135 struct isl_vec
*isl_pip_basic_set_sample(struct isl_basic_set
*bset
)
137 PipOptions
*options
= NULL
;
138 PipMatrix
*domain
= NULL
;
139 PipQuast
*sol
= NULL
;
140 struct isl_vec
*vec
= NULL
;
148 isl_assert(ctx
, isl_basic_set_n_param(bset
) == 0, goto error
);
149 isl_assert(ctx
, bset
->n_div
== 0, goto error
);
150 bset
= isl_basic_set_skew_to_positive_orthant(bset
, &T
);
153 dim
= isl_basic_set_n_dim(bset
);
154 domain
= isl_basic_map_to_pip((struct isl_basic_map
*)bset
, 0, 0, 0);
158 options
= pip_options_init();
161 sol
= pip_solve(domain
, NULL
, -1, options
);
165 vec
= isl_vec_alloc(ctx
, 0);
166 isl_mat_free(ctx
, T
);
170 vec
= isl_vec_alloc(ctx
, 1 + dim
);
173 isl_int_set_si(vec
->block
.data
[0], 1);
174 for (i
= 0, l
= sol
->list
; l
&& i
< dim
; ++i
, l
= l
->next
) {
175 isl_seq_cpy_from_pip(&vec
->block
.data
[1+i
],
176 &l
->vector
->the_vector
[0], 1);
177 isl_assert(ctx
, !entier_zero_p(l
->vector
->the_deno
[0]),
180 isl_assert(ctx
, i
== dim
, goto error
);
181 vec
= isl_mat_vec_product(ctx
, T
, vec
);
185 pip_options_free(options
);
186 pip_matrix_free(domain
);
188 isl_basic_set_free(bset
);
191 isl_vec_free(ctx
, vec
);
192 isl_basic_set_free(bset
);
196 pip_matrix_free(domain
);