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 __isl_give
MULTI(BASE
) *FN(MULTI(BASE
),add
)(__isl_take
MULTI(BASE
) *multi1
,
19 __isl_take
MULTI(BASE
) *multi2
)
21 return FN(MULTI(BASE
),bin_op
)(multi1
, multi2
, &FN(EL
,add
));
24 /* Subtract "multi2" from "multi1" and return the result.
26 __isl_give
MULTI(BASE
) *FN(MULTI(BASE
),sub
)(__isl_take
MULTI(BASE
) *multi1
,
27 __isl_take
MULTI(BASE
) *multi2
)
29 return FN(MULTI(BASE
),bin_op
)(multi1
, multi2
, &FN(EL
,sub
));
32 /* Multiply the elements of "multi" by "v" and return the result.
34 __isl_give
MULTI(BASE
) *FN(MULTI(BASE
),scale_val
)(__isl_take
MULTI(BASE
) *multi
,
35 __isl_take isl_val
*v
)
42 if (isl_val_is_one(v
)) {
47 if (!isl_val_is_rat(v
))
48 isl_die(isl_val_get_ctx(v
), isl_error_invalid
,
49 "expecting rational factor", goto error
);
51 multi
= FN(MULTI(BASE
),cow
)(multi
);
55 for (i
= 0; i
< multi
->n
; ++i
) {
56 multi
->u
.p
[i
] = FN(EL
,scale_val
)(multi
->u
.p
[i
],
66 return FN(MULTI(BASE
),free
)(multi
);
69 /* Divide the elements of "multi" by "v" and return the result.
71 __isl_give
MULTI(BASE
) *FN(MULTI(BASE
),scale_down_val
)(
72 __isl_take
MULTI(BASE
) *multi
, __isl_take isl_val
*v
)
79 if (isl_val_is_one(v
)) {
84 if (!isl_val_is_rat(v
))
85 isl_die(isl_val_get_ctx(v
), isl_error_invalid
,
86 "expecting rational factor", goto error
);
87 if (isl_val_is_zero(v
))
88 isl_die(isl_val_get_ctx(v
), isl_error_invalid
,
89 "cannot scale down by zero", goto error
);
91 multi
= FN(MULTI(BASE
),cow
)(multi
);
95 for (i
= 0; i
< multi
->n
; ++i
) {
96 multi
->u
.p
[i
] = FN(EL
,scale_down_val
)(multi
->u
.p
[i
],
106 return FN(MULTI(BASE
),free
)(multi
);
109 /* Multiply the elements of "multi" by the corresponding element of "mv"
110 * and return the result.
112 __isl_give
MULTI(BASE
) *FN(MULTI(BASE
),scale_multi_val
)(
113 __isl_take
MULTI(BASE
) *multi
, __isl_take isl_multi_val
*mv
)
120 if (!isl_space_tuple_is_equal(multi
->space
, isl_dim_out
,
121 mv
->space
, isl_dim_set
))
122 isl_die(isl_multi_val_get_ctx(mv
), isl_error_invalid
,
123 "spaces don't match", goto error
);
125 multi
= FN(MULTI(BASE
),cow
)(multi
);
129 for (i
= 0; i
< multi
->n
; ++i
) {
132 v
= isl_multi_val_get_val(mv
, i
);
133 multi
->u
.p
[i
] = FN(EL
,scale_val
)(multi
->u
.p
[i
], v
);
138 isl_multi_val_free(mv
);
141 isl_multi_val_free(mv
);
142 return FN(MULTI(BASE
),free
)(multi
);
145 /* Divide the elements of "multi" by the corresponding element of "mv"
146 * and return the result.
148 __isl_give
MULTI(BASE
) *FN(MULTI(BASE
),scale_down_multi_val
)(
149 __isl_take
MULTI(BASE
) *multi
, __isl_take isl_multi_val
*mv
)
156 if (!isl_space_tuple_is_equal(multi
->space
, isl_dim_out
,
157 mv
->space
, isl_dim_set
))
158 isl_die(isl_multi_val_get_ctx(mv
), isl_error_invalid
,
159 "spaces don't match", goto error
);
161 multi
= FN(MULTI(BASE
),cow
)(multi
);
165 for (i
= 0; i
< multi
->n
; ++i
) {
168 v
= isl_multi_val_get_val(mv
, i
);
169 multi
->u
.p
[i
] = FN(EL
,scale_down_val
)(multi
->u
.p
[i
], v
);
174 isl_multi_val_free(mv
);
177 isl_multi_val_free(mv
);
178 return FN(MULTI(BASE
),free
)(multi
);
181 /* Compute the residues of the elements of "multi" modulo
182 * the corresponding element of "mv" and return the result.
184 __isl_give
MULTI(BASE
) *FN(MULTI(BASE
),mod_multi_val
)(
185 __isl_take
MULTI(BASE
) *multi
, __isl_take isl_multi_val
*mv
)
192 if (!isl_space_tuple_is_equal(multi
->space
, isl_dim_out
,
193 mv
->space
, isl_dim_set
))
194 isl_die(isl_multi_val_get_ctx(mv
), isl_error_invalid
,
195 "spaces don't match", goto error
);
197 multi
= FN(MULTI(BASE
),cow
)(multi
);
201 for (i
= 0; i
< multi
->n
; ++i
) {
204 v
= isl_multi_val_get_val(mv
, i
);
205 multi
->u
.p
[i
] = FN(EL
,mod_val
)(multi
->u
.p
[i
], v
);
210 isl_multi_val_free(mv
);
213 isl_multi_val_free(mv
);
214 return FN(MULTI(BASE
),free
)(multi
);
217 /* Return the opposite of "multi".
219 __isl_give
MULTI(BASE
) *FN(MULTI(BASE
),neg
)(__isl_take
MULTI(BASE
) *multi
)
223 multi
= FN(MULTI(BASE
),cow
)(multi
);
227 for (i
= 0; i
< multi
->n
; ++i
) {
228 multi
->u
.p
[i
] = FN(EL
,neg
)(multi
->u
.p
[i
]);
230 return FN(MULTI(BASE
),free
)(multi
);