1
//===------ Math.h - PBQP Vector and Matrix classes -------------*- C++ -*-===//
3
// The LLVM Compiler Infrastructure
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
8
//===----------------------------------------------------------------------===//
10
#ifndef LLVM_CODEGEN_PBQP_MATH_H
11
#define LLVM_CODEGEN_PBQP_MATH_H
19
typedef float PBQPNum;
21
/// \brief PBQP Vector class.
25
/// \brief Construct a PBQP vector of the given size.
26
explicit Vector(unsigned length) :
27
length(length), data(new PBQPNum[length]) {
30
/// \brief Construct a PBQP vector with initializer.
31
Vector(unsigned length, PBQPNum initVal) :
32
length(length), data(new PBQPNum[length]) {
33
std::fill(data, data + length, initVal);
36
/// \brief Copy construct a PBQP vector.
37
Vector(const Vector &v) :
38
length(v.length), data(new PBQPNum[length]) {
39
std::copy(v.data, v.data + length, data);
42
/// \brief Destroy this vector, return its memory.
43
~Vector() { delete[] data; }
45
/// \brief Assignment operator.
46
Vector& operator=(const Vector &v) {
49
data = new PBQPNum[length];
50
std::copy(v.data, v.data + length, data);
54
/// \brief Return the length of the vector
55
unsigned getLength() const {
59
/// \brief Element access.
60
PBQPNum& operator[](unsigned index) {
61
assert(index < length && "Vector element access out of bounds.");
65
/// \brief Const element access.
66
const PBQPNum& operator[](unsigned index) const {
67
assert(index < length && "Vector element access out of bounds.");
71
/// \brief Add another vector to this one.
72
Vector& operator+=(const Vector &v) {
73
assert(length == v.length && "Vector length mismatch.");
74
std::transform(data, data + length, v.data, data, std::plus<PBQPNum>());
78
/// \brief Subtract another vector from this one.
79
Vector& operator-=(const Vector &v) {
80
assert(length == v.length && "Vector length mismatch.");
81
std::transform(data, data + length, v.data, data, std::minus<PBQPNum>());
85
/// \brief Returns the index of the minimum value in this vector
86
unsigned minIndex() const {
87
return std::min_element(data, data + length) - data;
95
/// \brief Output a textual representation of the given vector on the given
97
template <typename OStream>
98
OStream& operator<<(OStream &os, const Vector &v) {
99
assert((v.getLength() != 0) && "Zero-length vector badness.");
102
for (unsigned i = 1; i < v.getLength(); ++i) {
111
/// \brief PBQP Matrix class
115
/// \brief Construct a PBQP Matrix with the given dimensions.
116
Matrix(unsigned rows, unsigned cols) :
117
rows(rows), cols(cols), data(new PBQPNum[rows * cols]) {
120
/// \brief Construct a PBQP Matrix with the given dimensions and initial
122
Matrix(unsigned rows, unsigned cols, PBQPNum initVal) :
123
rows(rows), cols(cols), data(new PBQPNum[rows * cols]) {
124
std::fill(data, data + (rows * cols), initVal);
127
/// \brief Copy construct a PBQP matrix.
128
Matrix(const Matrix &m) :
129
rows(m.rows), cols(m.cols), data(new PBQPNum[rows * cols]) {
130
std::copy(m.data, m.data + (rows * cols), data);
133
/// \brief Destroy this matrix, return its memory.
134
~Matrix() { delete[] data; }
136
/// \brief Assignment operator.
137
Matrix& operator=(const Matrix &m) {
139
rows = m.rows; cols = m.cols;
140
data = new PBQPNum[rows * cols];
141
std::copy(m.data, m.data + (rows * cols), data);
145
/// \brief Return the number of rows in this matrix.
146
unsigned getRows() const { return rows; }
148
/// \brief Return the number of cols in this matrix.
149
unsigned getCols() const { return cols; }
151
/// \brief Matrix element access.
152
PBQPNum* operator[](unsigned r) {
153
assert(r < rows && "Row out of bounds.");
154
return data + (r * cols);
157
/// \brief Matrix element access.
158
const PBQPNum* operator[](unsigned r) const {
159
assert(r < rows && "Row out of bounds.");
160
return data + (r * cols);
163
/// \brief Returns the given row as a vector.
164
Vector getRowAsVector(unsigned r) const {
166
for (unsigned c = 0; c < cols; ++c)
167
v[c] = (*this)[r][c];
171
/// \brief Returns the given column as a vector.
172
Vector getColAsVector(unsigned c) const {
174
for (unsigned r = 0; r < rows; ++r)
175
v[r] = (*this)[r][c];
179
/// \brief Reset the matrix to the given value.
180
Matrix& reset(PBQPNum val = 0) {
181
std::fill(data, data + (rows * cols), val);
185
/// \brief Set a single row of this matrix to the given value.
186
Matrix& setRow(unsigned r, PBQPNum val) {
187
assert(r < rows && "Row out of bounds.");
188
std::fill(data + (r * cols), data + ((r + 1) * cols), val);
192
/// \brief Set a single column of this matrix to the given value.
193
Matrix& setCol(unsigned c, PBQPNum val) {
194
assert(c < cols && "Column out of bounds.");
195
for (unsigned r = 0; r < rows; ++r)
200
/// \brief Matrix transpose.
201
Matrix transpose() const {
202
Matrix m(cols, rows);
203
for (unsigned r = 0; r < rows; ++r)
204
for (unsigned c = 0; c < cols; ++c)
205
m[c][r] = (*this)[r][c];
209
/// \brief Returns the diagonal of the matrix as a vector.
211
/// Matrix must be square.
212
Vector diagonalize() const {
213
assert(rows == cols && "Attempt to diagonalize non-square matrix.");
216
for (unsigned r = 0; r < rows; ++r)
217
v[r] = (*this)[r][r];
221
/// \brief Add the given matrix to this one.
222
Matrix& operator+=(const Matrix &m) {
223
assert(rows == m.rows && cols == m.cols &&
224
"Matrix dimensions mismatch.");
225
std::transform(data, data + (rows * cols), m.data, data,
226
std::plus<PBQPNum>());
230
/// \brief Returns the minimum of the given row
231
PBQPNum getRowMin(unsigned r) const {
232
assert(r < rows && "Row out of bounds");
233
return *std::min_element(data + (r * cols), data + ((r + 1) * cols));
236
/// \brief Returns the minimum of the given column
237
PBQPNum getColMin(unsigned c) const {
238
PBQPNum minElem = (*this)[0][c];
239
for (unsigned r = 1; r < rows; ++r)
240
if ((*this)[r][c] < minElem) minElem = (*this)[r][c];
244
/// \brief Subtracts the given scalar from the elements of the given row.
245
Matrix& subFromRow(unsigned r, PBQPNum val) {
246
assert(r < rows && "Row out of bounds");
247
std::transform(data + (r * cols), data + ((r + 1) * cols),
249
std::bind2nd(std::minus<PBQPNum>(), val));
253
/// \brief Subtracts the given scalar from the elements of the given column.
254
Matrix& subFromCol(unsigned c, PBQPNum val) {
255
for (unsigned r = 0; r < rows; ++r)
256
(*this)[r][c] -= val;
260
/// \brief Returns true if this is a zero matrix.
261
bool isZero() const {
262
return find_if(data, data + (rows * cols),
263
std::bind2nd(std::not_equal_to<PBQPNum>(), 0)) ==
264
data + (rows * cols);
272
/// \brief Output a textual representation of the given matrix on the given
274
template <typename OStream>
275
OStream& operator<<(OStream &os, const Matrix &m) {
277
assert((m.getRows() != 0) && "Zero-row matrix badness.");
279
for (unsigned i = 0; i < m.getRows(); ++i) {
280
os << m.getRowAsVector(i);
288
#endif // LLVM_CODEGEN_PBQP_MATH_H