1 | /* |
2 | * Copyright 2011 Sven Verdoolaege |
3 | * Copyright 2012-2013 Ecole Normale Superieure |
4 | * |
5 | * Use of this software is governed by the MIT license |
6 | * |
7 | * Written by Sven Verdoolaege, |
8 | * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France |
9 | */ |
10 | |
11 | #include <isl/space.h> |
12 | #include <isl_val_private.h> |
13 | |
14 | #include <isl_multi_macro.h> |
15 | |
16 | /* Add "multi2" to "multi1" and return the result. |
17 | */ |
18 | __isl_give MULTI(BASE) *FN(MULTI(BASE),add)(__isl_take MULTI(BASE) *multi1, |
19 | __isl_take MULTI(BASE) *multi2) |
20 | { |
21 | return FN(MULTI(BASE),bin_op)(multi1, multi2, fn: &FN(EL,add)); |
22 | } |
23 | |
24 | /* Subtract "multi2" from "multi1" and return the result. |
25 | */ |
26 | __isl_give MULTI(BASE) *FN(MULTI(BASE),sub)(__isl_take MULTI(BASE) *multi1, |
27 | __isl_take MULTI(BASE) *multi2) |
28 | { |
29 | return FN(MULTI(BASE),bin_op)(multi1, multi2, fn: &FN(EL,sub)); |
30 | } |
31 | |
32 | /* Depending on "fn", multiply or divide the elements of "multi" by "v" and |
33 | * return the result. |
34 | */ |
35 | static __isl_give MULTI(BASE) *FN(MULTI(BASE),scale_val_fn)( |
36 | __isl_take MULTI(BASE) *multi, __isl_take isl_val *v, |
37 | __isl_give EL *(*fn)(__isl_take EL *el, __isl_take isl_val *v)) |
38 | { |
39 | if (!multi || !v) |
40 | goto error; |
41 | |
42 | if (isl_val_is_one(v)) { |
43 | isl_val_free(v); |
44 | return multi; |
45 | } |
46 | |
47 | if (!isl_val_is_rat(v)) |
48 | isl_die(isl_val_get_ctx(v), isl_error_invalid, |
49 | "expecting rational factor" , goto error); |
50 | |
51 | return FN(MULTI(BASE),fn_val)(multi, fn, v); |
52 | error: |
53 | isl_val_free(v); |
54 | return FN(MULTI(BASE),free)(multi); |
55 | } |
56 | |
57 | /* Multiply the elements of "multi" by "v" and return the result. |
58 | */ |
59 | __isl_give MULTI(BASE) *FN(MULTI(BASE),scale_val)(__isl_take MULTI(BASE) *multi, |
60 | __isl_take isl_val *v) |
61 | { |
62 | return FN(MULTI(BASE),scale_val_fn)(multi, v, fn: &FN(EL,scale_val)); |
63 | } |
64 | |
65 | /* Divide the elements of "multi" by "v" and return the result. |
66 | */ |
67 | __isl_give MULTI(BASE) *FN(MULTI(BASE),scale_down_val)( |
68 | __isl_take MULTI(BASE) *multi, __isl_take isl_val *v) |
69 | { |
70 | if (!v) |
71 | goto error; |
72 | if (isl_val_is_zero(v)) |
73 | isl_die(isl_val_get_ctx(v), isl_error_invalid, |
74 | "cannot scale down by zero" , goto error); |
75 | return FN(MULTI(BASE),scale_val_fn)(multi, v, fn: &FN(EL,scale_down_val)); |
76 | error: |
77 | isl_val_free(v); |
78 | return FN(MULTI(BASE),free)(multi); |
79 | } |
80 | |
81 | /* Multiply the elements of "multi" by the corresponding element of "mv" |
82 | * and return the result. |
83 | */ |
84 | __isl_give MULTI(BASE) *FN(MULTI(BASE),scale_multi_val)( |
85 | __isl_take MULTI(BASE) *multi, __isl_take isl_multi_val *mv) |
86 | { |
87 | return FN(MULTI(BASE),fn_multi_val)(multi, fn: &FN(EL,scale_val), mv); |
88 | } |
89 | |
90 | /* Divide the elements of "multi" by the corresponding element of "mv" |
91 | * and return the result. |
92 | */ |
93 | __isl_give MULTI(BASE) *FN(MULTI(BASE),scale_down_multi_val)( |
94 | __isl_take MULTI(BASE) *multi, __isl_take isl_multi_val *mv) |
95 | { |
96 | return FN(MULTI(BASE),fn_multi_val)(multi, fn: &FN(EL,scale_down_val), mv); |
97 | } |
98 | |
99 | /* Compute the residues of the elements of "multi" modulo |
100 | * the corresponding element of "mv" and return the result. |
101 | */ |
102 | __isl_give MULTI(BASE) *FN(MULTI(BASE),mod_multi_val)( |
103 | __isl_take MULTI(BASE) *multi, __isl_take isl_multi_val *mv) |
104 | { |
105 | return FN(MULTI(BASE),fn_multi_val)(multi, fn: &FN(EL,mod_val), mv); |
106 | } |
107 | |
108 | /* Return the opposite of "multi". |
109 | */ |
110 | __isl_give MULTI(BASE) *FN(MULTI(BASE),neg)(__isl_take MULTI(BASE) *multi) |
111 | { |
112 | return FN(MULTI(BASE),un_op)(multi, fn: &FN(EL,neg)); |
113 | } |
114 | |