1 //===-- PBQPMath.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_PBQPMATH_H
11 #define LLVM_CODEGEN_PBQP_PBQPMATH_H
19 typedef double 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_PBQPMATH_HPP