isl_test.c: test_lexmin: abort on failed test
[isl.git] / isl_multi_arith_templ.c
blob2cef5dfc177eba3498f7ee7f7dc3b66de53d703a
1 /*
2 * Copyright 2011 Sven Verdoolaege
3 * Copyright 2012-2013 Ecole Normale Superieure
5 * Use of this software is governed by the MIT license
7 * Written by Sven Verdoolaege,
8 * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
9 */
11 #include <isl/space.h>
12 #include <isl_val_private.h>
14 #include <isl_multi_macro.h>
16 /* Add "multi2" to "multi1" and return the result.
18 * The parameters of "multi1" and "multi2" are assumed to have been aligned.
20 static __isl_give MULTI(BASE) *FN(MULTI(BASE),add_aligned)(
21 __isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2)
23 return FN(MULTI(BASE),bin_op)(multi1, multi2, &FN(EL,add));
26 /* Add "multi2" to "multi1" and return the result.
28 __isl_give MULTI(BASE) *FN(MULTI(BASE),add)(__isl_take MULTI(BASE) *multi1,
29 __isl_take MULTI(BASE) *multi2)
31 return FN(MULTI(BASE),align_params_multi_multi_and)(multi1, multi2,
32 &FN(MULTI(BASE),add_aligned));
35 /* Subtract "multi2" from "multi1" and return the result.
37 * The parameters of "multi1" and "multi2" are assumed to have been aligned.
39 static __isl_give MULTI(BASE) *FN(MULTI(BASE),sub_aligned)(
40 __isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2)
42 return FN(MULTI(BASE),bin_op)(multi1, multi2, &FN(EL,sub));
45 /* Subtract "multi2" from "multi1" and return the result.
47 __isl_give MULTI(BASE) *FN(MULTI(BASE),sub)(__isl_take MULTI(BASE) *multi1,
48 __isl_take MULTI(BASE) *multi2)
50 return FN(MULTI(BASE),align_params_multi_multi_and)(multi1, multi2,
51 &FN(MULTI(BASE),sub_aligned));
54 /* Multiply the elements of "multi" by "v" and return the result.
56 __isl_give MULTI(BASE) *FN(MULTI(BASE),scale_val)(__isl_take MULTI(BASE) *multi,
57 __isl_take isl_val *v)
59 int i;
61 if (!multi || !v)
62 goto error;
64 if (isl_val_is_one(v)) {
65 isl_val_free(v);
66 return multi;
69 if (!isl_val_is_rat(v))
70 isl_die(isl_val_get_ctx(v), isl_error_invalid,
71 "expecting rational factor", goto error);
73 multi = FN(MULTI(BASE),cow)(multi);
74 if (!multi)
75 return NULL;
77 for (i = 0; i < multi->n; ++i) {
78 multi->u.p[i] = FN(EL,scale_val)(multi->u.p[i],
79 isl_val_copy(v));
80 if (!multi->u.p[i])
81 goto error;
84 isl_val_free(v);
85 return multi;
86 error:
87 isl_val_free(v);
88 return FN(MULTI(BASE),free)(multi);
91 /* Divide the elements of "multi" by "v" and return the result.
93 __isl_give MULTI(BASE) *FN(MULTI(BASE),scale_down_val)(
94 __isl_take MULTI(BASE) *multi, __isl_take isl_val *v)
96 int i;
98 if (!multi || !v)
99 goto error;
101 if (isl_val_is_one(v)) {
102 isl_val_free(v);
103 return multi;
106 if (!isl_val_is_rat(v))
107 isl_die(isl_val_get_ctx(v), isl_error_invalid,
108 "expecting rational factor", goto error);
109 if (isl_val_is_zero(v))
110 isl_die(isl_val_get_ctx(v), isl_error_invalid,
111 "cannot scale down by zero", goto error);
113 multi = FN(MULTI(BASE),cow)(multi);
114 if (!multi)
115 return NULL;
117 for (i = 0; i < multi->n; ++i) {
118 multi->u.p[i] = FN(EL,scale_down_val)(multi->u.p[i],
119 isl_val_copy(v));
120 if (!multi->u.p[i])
121 goto error;
124 isl_val_free(v);
125 return multi;
126 error:
127 isl_val_free(v);
128 return FN(MULTI(BASE),free)(multi);
131 /* Multiply the elements of "multi" by the corresponding element of "mv"
132 * and return the result.
134 __isl_give MULTI(BASE) *FN(MULTI(BASE),scale_multi_val)(
135 __isl_take MULTI(BASE) *multi, __isl_take isl_multi_val *mv)
137 int i;
139 if (!multi || !mv)
140 goto error;
142 if (!isl_space_tuple_is_equal(multi->space, isl_dim_out,
143 mv->space, isl_dim_set))
144 isl_die(isl_multi_val_get_ctx(mv), isl_error_invalid,
145 "spaces don't match", goto error);
147 multi = FN(MULTI(BASE),cow)(multi);
148 if (!multi)
149 goto error;
151 for (i = 0; i < multi->n; ++i) {
152 isl_val *v;
154 v = isl_multi_val_get_val(mv, i);
155 multi->u.p[i] = FN(EL,scale_val)(multi->u.p[i], v);
156 if (!multi->u.p[i])
157 goto error;
160 isl_multi_val_free(mv);
161 return multi;
162 error:
163 isl_multi_val_free(mv);
164 return FN(MULTI(BASE),free)(multi);
167 /* Divide the elements of "multi" by the corresponding element of "mv"
168 * and return the result.
170 __isl_give MULTI(BASE) *FN(MULTI(BASE),scale_down_multi_val)(
171 __isl_take MULTI(BASE) *multi, __isl_take isl_multi_val *mv)
173 int i;
175 if (!multi || !mv)
176 goto error;
178 if (!isl_space_tuple_is_equal(multi->space, isl_dim_out,
179 mv->space, isl_dim_set))
180 isl_die(isl_multi_val_get_ctx(mv), isl_error_invalid,
181 "spaces don't match", goto error);
183 multi = FN(MULTI(BASE),cow)(multi);
184 if (!multi)
185 return NULL;
187 for (i = 0; i < multi->n; ++i) {
188 isl_val *v;
190 v = isl_multi_val_get_val(mv, i);
191 multi->u.p[i] = FN(EL,scale_down_val)(multi->u.p[i], v);
192 if (!multi->u.p[i])
193 goto error;
196 isl_multi_val_free(mv);
197 return multi;
198 error:
199 isl_multi_val_free(mv);
200 return FN(MULTI(BASE),free)(multi);
203 /* Compute the residues of the elements of "multi" modulo
204 * the corresponding element of "mv" and return the result.
206 __isl_give MULTI(BASE) *FN(MULTI(BASE),mod_multi_val)(
207 __isl_take MULTI(BASE) *multi, __isl_take isl_multi_val *mv)
209 int i;
211 if (!multi || !mv)
212 goto error;
214 if (!isl_space_tuple_is_equal(multi->space, isl_dim_out,
215 mv->space, isl_dim_set))
216 isl_die(isl_multi_val_get_ctx(mv), isl_error_invalid,
217 "spaces don't match", goto error);
219 multi = FN(MULTI(BASE),cow)(multi);
220 if (!multi)
221 goto error;
223 for (i = 0; i < multi->n; ++i) {
224 isl_val *v;
226 v = isl_multi_val_get_val(mv, i);
227 multi->u.p[i] = FN(EL,mod_val)(multi->u.p[i], v);
228 if (!multi->u.p[i])
229 goto error;
232 isl_multi_val_free(mv);
233 return multi;
234 error:
235 isl_multi_val_free(mv);
236 return FN(MULTI(BASE),free)(multi);
239 /* Return the opposite of "multi".
241 __isl_give MULTI(BASE) *FN(MULTI(BASE),neg)(__isl_take MULTI(BASE) *multi)
243 int i;
245 multi = FN(MULTI(BASE),cow)(multi);
246 if (!multi)
247 return NULL;
249 for (i = 0; i < multi->n; ++i) {
250 multi->u.p[i] = FN(EL,neg)(multi->u.p[i]);
251 if (!multi->u.p[i])
252 return FN(MULTI(BASE),free)(multi);
255 return multi;