• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
MULTI(BASE)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(EL,add));
22 }
23 
24 /* Subtract "multi2" from "multi1" and return the result.
25  */
MULTI(BASE)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(EL,sub));
30 }
31 
32 /* Multiply the elements of "multi" by "v" and return the result.
33  */
MULTI(BASE)34 __isl_give MULTI(BASE) *FN(MULTI(BASE),scale_val)(__isl_take MULTI(BASE) *multi,
35 	__isl_take isl_val *v)
36 {
37 	int i;
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 	multi = FN(MULTI(BASE),cow)(multi);
52 	if (!multi)
53 		return NULL;
54 
55 	for (i = 0; i < multi->n; ++i) {
56 		multi->u.p[i] = FN(EL,scale_val)(multi->u.p[i],
57 						isl_val_copy(v));
58 		if (!multi->u.p[i])
59 			goto error;
60 	}
61 
62 	isl_val_free(v);
63 	return multi;
64 error:
65 	isl_val_free(v);
66 	return FN(MULTI(BASE),free)(multi);
67 }
68 
69 /* Divide the elements of "multi" by "v" and return the result.
70  */
MULTI(BASE)71 __isl_give MULTI(BASE) *FN(MULTI(BASE),scale_down_val)(
72 	__isl_take MULTI(BASE) *multi, __isl_take isl_val *v)
73 {
74 	int i;
75 
76 	if (!multi || !v)
77 		goto error;
78 
79 	if (isl_val_is_one(v)) {
80 		isl_val_free(v);
81 		return multi;
82 	}
83 
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);
90 
91 	multi = FN(MULTI(BASE),cow)(multi);
92 	if (!multi)
93 		return NULL;
94 
95 	for (i = 0; i < multi->n; ++i) {
96 		multi->u.p[i] = FN(EL,scale_down_val)(multi->u.p[i],
97 						    isl_val_copy(v));
98 		if (!multi->u.p[i])
99 			goto error;
100 	}
101 
102 	isl_val_free(v);
103 	return multi;
104 error:
105 	isl_val_free(v);
106 	return FN(MULTI(BASE),free)(multi);
107 }
108 
109 /* Multiply the elements of "multi" by the corresponding element of "mv"
110  * and return the result.
111  */
MULTI(BASE)112 __isl_give MULTI(BASE) *FN(MULTI(BASE),scale_multi_val)(
113 	__isl_take MULTI(BASE) *multi, __isl_take isl_multi_val *mv)
114 {
115 	int i;
116 
117 	if (!multi || !mv)
118 		goto error;
119 
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);
124 
125 	multi = FN(MULTI(BASE),cow)(multi);
126 	if (!multi)
127 		goto error;
128 
129 	for (i = 0; i < multi->n; ++i) {
130 		isl_val *v;
131 
132 		v = isl_multi_val_get_val(mv, i);
133 		multi->u.p[i] = FN(EL,scale_val)(multi->u.p[i], v);
134 		if (!multi->u.p[i])
135 			goto error;
136 	}
137 
138 	isl_multi_val_free(mv);
139 	return multi;
140 error:
141 	isl_multi_val_free(mv);
142 	return FN(MULTI(BASE),free)(multi);
143 }
144 
145 /* Divide the elements of "multi" by the corresponding element of "mv"
146  * and return the result.
147  */
MULTI(BASE)148 __isl_give MULTI(BASE) *FN(MULTI(BASE),scale_down_multi_val)(
149 	__isl_take MULTI(BASE) *multi, __isl_take isl_multi_val *mv)
150 {
151 	int i;
152 
153 	if (!multi || !mv)
154 		goto error;
155 
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);
160 
161 	multi = FN(MULTI(BASE),cow)(multi);
162 	if (!multi)
163 		return NULL;
164 
165 	for (i = 0; i < multi->n; ++i) {
166 		isl_val *v;
167 
168 		v = isl_multi_val_get_val(mv, i);
169 		multi->u.p[i] = FN(EL,scale_down_val)(multi->u.p[i], v);
170 		if (!multi->u.p[i])
171 			goto error;
172 	}
173 
174 	isl_multi_val_free(mv);
175 	return multi;
176 error:
177 	isl_multi_val_free(mv);
178 	return FN(MULTI(BASE),free)(multi);
179 }
180 
181 /* Compute the residues of the elements of "multi" modulo
182  * the corresponding element of "mv" and return the result.
183  */
MULTI(BASE)184 __isl_give MULTI(BASE) *FN(MULTI(BASE),mod_multi_val)(
185 	__isl_take MULTI(BASE) *multi, __isl_take isl_multi_val *mv)
186 {
187 	int i;
188 
189 	if (!multi || !mv)
190 		goto error;
191 
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);
196 
197 	multi = FN(MULTI(BASE),cow)(multi);
198 	if (!multi)
199 		goto error;
200 
201 	for (i = 0; i < multi->n; ++i) {
202 		isl_val *v;
203 
204 		v = isl_multi_val_get_val(mv, i);
205 		multi->u.p[i] = FN(EL,mod_val)(multi->u.p[i], v);
206 		if (!multi->u.p[i])
207 			goto error;
208 	}
209 
210 	isl_multi_val_free(mv);
211 	return multi;
212 error:
213 	isl_multi_val_free(mv);
214 	return FN(MULTI(BASE),free)(multi);
215 }
216 
217 /* Return the opposite of "multi".
218  */
MULTI(BASE)219 __isl_give MULTI(BASE) *FN(MULTI(BASE),neg)(__isl_take MULTI(BASE) *multi)
220 {
221 	int i;
222 
223 	multi = FN(MULTI(BASE),cow)(multi);
224 	if (!multi)
225 		return NULL;
226 
227 	for (i = 0; i < multi->n; ++i) {
228 		multi->u.p[i] = FN(EL,neg)(multi->u.p[i]);
229 		if (!multi->u.p[i])
230 			return FN(MULTI(BASE),free)(multi);
231 	}
232 
233 	return multi;
234 }
235