Use other mechanism to determine whether an edge is already copied or not.
[libfirm] / matrix.c
1 #include <assert.h>
2 #include <string.h>
3
4 #include "pbqp_t.h"
5 #include "vector.h"
6 #include "matrix.h"
7
8 pbqp_matrix *pbqp_matrix_alloc(pbqp *pbqp, unsigned rows, unsigned cols)
9 {
10         assert(cols> 0);
11         assert(rows> 0);
12
13         unsigned length = rows * cols;
14
15         pbqp_matrix *mat = obstack_alloc(&pbqp->obstack, sizeof(*mat) + sizeof(*mat->entries) * length);
16         assert(mat);
17
18         mat->cols = cols;
19         mat->rows = rows;
20         memset(mat->entries, 0, sizeof(*mat->entries) * length);
21
22         return mat;
23 }
24
25 pbqp_matrix *pbqp_matrix_copy(pbqp *pbqp, pbqp_matrix *m)
26 {
27         unsigned     len  = m->rows * m->cols;
28         pbqp_matrix *copy = obstack_copy(&pbqp->obstack, m, sizeof(*copy) + sizeof(*copy->entries) * len);
29         assert(copy);
30
31         return copy;
32 }
33
34 pbqp_matrix *pbqp_matrix_copy_and_transpose(pbqp *pbqp, pbqp_matrix *m)
35 {
36         unsigned     i;
37         unsigned     j;
38         unsigned     cols = m->cols;
39         unsigned     rows = m->rows;
40         unsigned     len  = rows * cols;
41         pbqp_matrix *copy = obstack_alloc(&pbqp->obstack, sizeof(*copy) + sizeof(*copy->entries) * len);
42         assert(copy);
43
44         for (i = 0; i < rows; ++i) {
45                 for (j = 0; j < cols; ++j) {
46                         copy->entries[j*rows+i] = m->entries[i*cols+j];
47                 }
48         }
49
50         copy->cols = rows;
51         copy->rows = cols;
52
53         return copy;
54 }
55
56 void pbqp_matrix_transpose(pbqp *pbqp, pbqp_matrix *mat)
57 {
58         unsigned len;
59
60         assert(mat);
61         len = mat->rows * mat->cols;
62
63         pbqp_matrix *tmp = pbqp_matrix_copy_and_transpose(pbqp, mat);
64
65         memcpy(mat, tmp, sizeof(*mat) + sizeof(*mat->entries) * len);
66
67         obstack_free(&pbqp->obstack, tmp);
68 }
69
70 void pbqp_matrix_add(pbqp_matrix *sum, pbqp_matrix *summand)
71 {
72         int i;
73         int len;
74
75         assert(sum);
76         assert(summand);
77         assert(sum->cols == summand->cols);
78         assert(sum->rows == summand->rows);
79
80         len = sum->rows * sum->cols;
81
82         for (i = 0; i < len; ++i) {
83                 sum->entries[i] = pbqp_add(sum->entries[i], summand->entries[i]);
84         }
85 }
86
87 void pbqp_matrix_set_col_value(pbqp_matrix *mat, unsigned col, num value)
88 {
89         unsigned row_index;
90         unsigned row_len;
91
92         assert(mat);
93         assert(col < mat->cols);
94
95         row_len = mat->rows;
96
97         for (row_index = 0; row_index < row_len; ++row_index) {
98                 mat->entries[row_index * mat->cols + col] = value;
99         }
100 }
101
102 void pbqp_matrix_set_row_value(pbqp_matrix *mat, unsigned row, num value)
103 {
104         unsigned col_index;
105         unsigned col_len;
106
107         assert(mat);
108         assert(row < mat->rows);
109
110         col_len = mat->cols;
111
112         for (col_index = 0; col_index < col_len; ++col_index) {
113                 mat->entries[row * mat->cols + col_index] = value;
114         }
115 }
116
117 void pbqp_matrix_set(pbqp_matrix *mat, unsigned row, unsigned col, num value)
118 {
119         assert(mat);
120         assert(col < mat->cols);
121         assert(row < mat->rows);
122
123         mat->entries[row * mat->cols + col] = value;
124 }
125
126 num pbqp_matrix_get_col_min(pbqp_matrix *matrix, unsigned col_index, vector *flags)
127 {
128         unsigned row_index;
129         num min = INF_COSTS;
130
131         assert(matrix);
132         assert(flags);
133         assert(matrix->rows == flags->len);
134
135         unsigned col_len = matrix->cols;
136         unsigned row_len = matrix->rows;
137
138         for (row_index = 0; row_index < row_len; ++row_index) {
139                 /* Ignore virtual deleted columns. */
140                 if (flags->entries[row_index].data == INF_COSTS) continue;
141
142                 num elem = matrix->entries[row_index * col_len + col_index];
143
144                 if (elem < min) {
145                         min = elem;
146                 }
147         }
148
149         return min;
150 }
151
152 void pbqp_matrix_sub_col_value(pbqp_matrix *matrix, unsigned col_index,
153                 vector *flags, num value)
154 {
155         unsigned col_len;
156         unsigned row_index;
157         unsigned row_len;
158
159         assert(matrix);
160         assert(flags);
161         assert(matrix->rows == flags->len);
162
163         col_len = matrix->cols;
164         row_len = matrix->rows;
165
166         for (row_index = 0; row_index < row_len; ++row_index) {
167                 if (flags->entries[row_index].data == INF_COSTS) {
168                         matrix->entries[row_index * col_len + col_index] = 0;
169                         continue;
170                 }
171                 /* inf - x = inf if x < inf */
172                 if (matrix->entries[row_index * col_len + col_index] == INF_COSTS && value
173                                 != INF_COSTS)
174                         continue;
175                 matrix->entries[row_index * col_len + col_index] -= value;
176         }
177 }
178
179 num pbqp_matrix_get_row_min(pbqp_matrix *matrix, unsigned row_index, vector *flags)
180 {
181         unsigned col_index;
182         num min = INF_COSTS;
183
184         assert(matrix);
185         assert(flags);
186         assert(matrix->cols == flags->len);
187
188         unsigned len = flags->len;
189
190         for (col_index = 0; col_index < len; ++col_index) {
191                 /* Ignore virtual deleted columns. */
192                 if (flags->entries[col_index].data == INF_COSTS) continue;
193
194                 num elem = matrix->entries[row_index * len + col_index];
195
196                 if (elem < min) {
197                         min = elem;
198                 }
199         }
200
201         return min;
202 }
203
204 void pbqp_matrix_sub_row_value(pbqp_matrix *matrix, unsigned row_index,
205                 vector *flags, num value)
206 {
207         unsigned col_index;
208         unsigned col_len;
209
210         assert(matrix);
211         assert(flags);
212         assert(matrix->cols == flags->len);
213
214         col_len = matrix->cols;
215
216         for (col_index = 0; col_index < col_len; ++col_index) {
217                 if (flags->entries[col_index].data == INF_COSTS) {
218                         matrix->entries[row_index * col_len + col_index] = 0;
219                         continue;
220                 }
221                 /* inf - x = inf if x < inf */
222                 if (matrix->entries[row_index * col_len + col_index] == INF_COSTS && value
223                                 != INF_COSTS)
224                         continue;
225                 matrix->entries[row_index * col_len + col_index] -= value;
226         }
227 }
228
229 int pbqp_matrix_is_zero(pbqp_matrix *mat, vector *src_vec, vector *tgt_vec)
230 {
231         unsigned col_index;
232         unsigned col_len;
233         unsigned row_index;
234         unsigned row_len;
235
236         assert(mat);
237         assert(src_vec);
238         assert(tgt_vec);
239         assert(mat->cols = tgt_vec->len);
240         assert(mat->rows = src_vec->len);
241
242         col_len = mat->cols;
243         row_len = mat->rows;
244
245         for (row_index = 0; row_index < row_len; ++row_index) {
246                 if (src_vec->entries[row_index].data == INF_COSTS) continue;
247                 for (col_index = 0; col_index < col_len; ++col_index) {
248                         if (tgt_vec->entries[col_index].data == INF_COSTS) continue;
249
250                         if (mat->entries[row_index * col_len + col_index] != 0) {
251                                 return 0;
252                         }
253                 }
254         }
255
256         return 1;
257 }
258
259 void pbqp_matrix_add_to_all_cols(pbqp_matrix *mat, vector *vec)
260 {
261         unsigned col_index;
262         unsigned col_len;
263         unsigned row_index;
264         unsigned row_len;
265
266         assert(mat);
267         assert(vec);
268         assert(mat->rows == vec->len);
269
270         col_len = mat->cols;
271         row_len = mat->rows;
272
273         for (row_index = 0; row_index < row_len; ++row_index) {
274                 num value = vec->entries[row_index].data;
275                 for (col_index = 0; col_index < col_len; ++col_index) {
276                         mat->entries[row_index * col_len + col_index] = pbqp_add(
277                                         mat->entries[row_index * col_len + col_index], value);
278                 }
279         }
280 }
281
282 void pbqp_matrix_add_to_all_rows(pbqp_matrix *mat, vector *vec)
283 {
284         unsigned col_index;
285         unsigned col_len;
286         unsigned row_index;
287         unsigned row_len;
288
289         assert(mat);
290         assert(vec);
291         assert(mat->cols == vec->len);
292
293         col_len = mat->cols;
294         row_len = mat->rows;
295
296         for (row_index = 0; row_index < row_len; ++row_index) {
297                 for (col_index = 0; col_index < col_len; ++col_index) {
298                         num value = vec->entries[col_index].data;
299
300                         mat->entries[row_index * col_len + col_index] = pbqp_add(mat->entries[row_index * col_len + col_index], value);
301                 }
302         }
303 }