summaryrefslogtreecommitdiffhomepage
path: root/ir/kaps/vector.c
blob: 5a78225f05397983075b66f40cfa4d4d78928ff7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
 * This file is part of libFirm.
 * Copyright (C) 2012 University of Karlsruhe.
 */

/**
 * @file
 * @brief   PBQP vector.
 * @date    02.10.2008
 * @author  Sebastian Buchwald
 */
#include "vector.h"

#include "adt/array.h"
#include <string.h>

num pbqp_add(num x, num y)
{
	if (x == INF_COSTS || y == INF_COSTS)
		return INF_COSTS;

	num res = x + y;

#if !KAPS_USE_UNSIGNED
	/* No positive overflow. */
	assert(x < 0 || y < 0 || res >= x);
	assert(x < 0 || y < 0 || res >= y);
#endif

	/* No negative overflow. */
	assert(x > 0 || y > 0 || res <= x);
	assert(x > 0 || y > 0 || res <= y);

	/* Result is not infinity.*/
	assert(res < INF_COSTS);

	return res;
}

vector_t *vector_alloc(pbqp_t *pbqp, unsigned length)
{
	vector_t *vec = (vector_t *)obstack_alloc(&pbqp->obstack, sizeof(*vec) + sizeof(*vec->entries) * length);
	assert(length > 0);

	vec->len = length;
	memset(vec->entries, 0, sizeof(*vec->entries) * length);

	return vec;
}

vector_t *vector_copy(pbqp_t *pbqp, vector_t *v)
{
	unsigned  len  = v->len;
	vector_t *copy = (vector_t *)obstack_copy(&pbqp->obstack, v, sizeof(*copy) + sizeof(*copy->entries) * len);
	assert(copy);

	return copy;
}

void vector_add(vector_t *sum, vector_t *summand)
{
	unsigned len = sum->len;

	assert(len == summand->len);

	for (unsigned i = 0; i < len; ++i) {
		sum->entries[i].data = pbqp_add(sum->entries[i].data, summand->entries[i].data);
	}
}

void vector_set(vector_t *vec, unsigned index, num value)
{
	assert(index < vec->len);
	vec->entries[index].data = value;
}

#if KAPS_ENABLE_VECTOR_NAMES
void vector_set_description(vector_t *vec, unsigned index, const char *name)
{
	assert(index < vec->len);
	vec->entries[index].name = name;
}
#endif

void vector_add_value(vector_t *vec, num value)
{
	unsigned len = vec->len;

	for (unsigned index = 0; index < len; ++index) {
		vec->entries[index].data = pbqp_add(vec->entries[index].data, value);
	}
}

void vector_add_matrix_col(vector_t *vec, pbqp_matrix_t *mat, unsigned col_index)
{
	unsigned len = vec->len;

	assert(len == mat->rows);
	assert(col_index < mat->cols);

	for (unsigned index = 0; index < len; ++index) {
		vec->entries[index].data = pbqp_add(vec->entries[index].data, mat->entries[index * mat->cols + col_index]);
	}
}

void vector_add_matrix_row(vector_t *vec, pbqp_matrix_t *mat, unsigned row_index)
{
	unsigned len = vec->len;

	assert(len == mat->cols);
	assert(row_index < mat->rows);


	for (unsigned index = 0; index < len; ++index) {
		vec->entries[index].data = pbqp_add(vec->entries[index].data, mat->entries[row_index * mat->cols + index]);
	}
}

num vector_get_min(vector_t *vec)
{
	unsigned len = vec->len;
	num      min = INF_COSTS;

	assert(len > 0);

	for (unsigned index = 0; index < len; ++index) {
		num elem = vec->entries[index].data;

		if (elem < min) {
			min = elem;
		}
	}

	return min;
}

unsigned vector_get_min_index(vector_t *vec)
{
	unsigned len       = vec->len;
	unsigned min_index = 0;
	num      min       = INF_COSTS;

	assert(len > 0);

	for (unsigned index = 0; index < len; ++index) {
		num elem = vec->entries[index].data;

		if (elem < min) {
			min = elem;
			min_index = index;
		}
	}

	return min_index;
}