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
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
)
64 if (isl_val_is_one(v
)) {
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
);
77 for (i
= 0; i
< multi
->n
; ++i
) {
78 multi
->u
.p
[i
] = FN(EL
,scale_val
)(multi
->u
.p
[i
],
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
)
101 if (isl_val_is_one(v
)) {
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
);
117 for (i
= 0; i
< multi
->n
; ++i
) {
118 multi
->u
.p
[i
] = FN(EL
,scale_down_val
)(multi
->u
.p
[i
],
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
)
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
);
151 for (i
= 0; i
< multi
->n
; ++i
) {
154 v
= isl_multi_val_get_val(mv
, i
);
155 multi
->u
.p
[i
] = FN(EL
,scale_val
)(multi
->u
.p
[i
], v
);
160 isl_multi_val_free(mv
);
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
)
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
);
187 for (i
= 0; i
< multi
->n
; ++i
) {
190 v
= isl_multi_val_get_val(mv
, i
);
191 multi
->u
.p
[i
] = FN(EL
,scale_down_val
)(multi
->u
.p
[i
], v
);
196 isl_multi_val_free(mv
);
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
)
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
);
223 for (i
= 0; i
< multi
->n
; ++i
) {
226 v
= isl_multi_val_get_val(mv
, i
);
227 multi
->u
.p
[i
] = FN(EL
,mod_val
)(multi
->u
.p
[i
], v
);
232 isl_multi_val_free(mv
);
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
)
245 multi
= FN(MULTI(BASE
),cow
)(multi
);
249 for (i
= 0; i
< multi
->n
; ++i
) {
250 multi
->u
.p
[i
] = FN(EL
,neg
)(multi
->u
.p
[i
]);
252 return FN(MULTI(BASE
),free
)(multi
);