LLVM  3.7.0
Math.h
Go to the documentation of this file.
1 //===------ Math.h - PBQP Vector and Matrix classes -------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLVM_CODEGEN_PBQP_MATH_H
11 #define LLVM_CODEGEN_PBQP_MATH_H
12 
13 #include "llvm/ADT/Hashing.h"
14 #include <algorithm>
15 #include <cassert>
16 #include <functional>
17 
18 namespace llvm {
19 namespace PBQP {
20 
21 typedef float PBQPNum;
22 
23 /// \brief PBQP Vector class.
24 class Vector {
25  friend hash_code hash_value(const Vector &);
26 public:
27 
28  /// \brief Construct a PBQP vector of the given size.
29  explicit Vector(unsigned Length)
30  : Length(Length), Data(new PBQPNum[Length]) {
31  // llvm::dbgs() << "Constructing PBQP::Vector "
32  // << this << " (length " << Length << ")\n";
33  }
34 
35  /// \brief Construct a PBQP vector with initializer.
36  Vector(unsigned Length, PBQPNum InitVal)
37  : Length(Length), Data(new PBQPNum[Length]) {
38  // llvm::dbgs() << "Constructing PBQP::Vector "
39  // << this << " (length " << Length << ", fill "
40  // << InitVal << ")\n";
41  std::fill(Data, Data + Length, InitVal);
42  }
43 
44  /// \brief Copy construct a PBQP vector.
45  Vector(const Vector &V)
46  : Length(V.Length), Data(new PBQPNum[Length]) {
47  // llvm::dbgs() << "Copy-constructing PBQP::Vector " << this
48  // << " from PBQP::Vector " << &V << "\n";
49  std::copy(V.Data, V.Data + Length, Data);
50  }
51 
52  /// \brief Move construct a PBQP vector.
54  : Length(V.Length), Data(V.Data) {
55  V.Length = 0;
56  V.Data = nullptr;
57  }
58 
59  /// \brief Destroy this vector, return its memory.
60  ~Vector() {
61  // llvm::dbgs() << "Deleting PBQP::Vector " << this << "\n";
62  delete[] Data;
63  }
64 
65  /// \brief Copy-assignment operator.
66  Vector& operator=(const Vector &V) {
67  // llvm::dbgs() << "Assigning to PBQP::Vector " << this
68  // << " from PBQP::Vector " << &V << "\n";
69  delete[] Data;
70  Length = V.Length;
71  Data = new PBQPNum[Length];
72  std::copy(V.Data, V.Data + Length, Data);
73  return *this;
74  }
75 
76  /// \brief Move-assignment operator.
78  delete[] Data;
79  Length = V.Length;
80  Data = V.Data;
81  V.Length = 0;
82  V.Data = nullptr;
83  return *this;
84  }
85 
86  /// \brief Comparison operator.
87  bool operator==(const Vector &V) const {
88  assert(Length != 0 && Data != nullptr && "Invalid vector");
89  if (Length != V.Length)
90  return false;
91  return std::equal(Data, Data + Length, V.Data);
92  }
93 
94  /// \brief Return the length of the vector
95  unsigned getLength() const {
96  assert(Length != 0 && Data != nullptr && "Invalid vector");
97  return Length;
98  }
99 
100  /// \brief Element access.
101  PBQPNum& operator[](unsigned Index) {
102  assert(Length != 0 && Data != nullptr && "Invalid vector");
103  assert(Index < Length && "Vector element access out of bounds.");
104  return Data[Index];
105  }
106 
107  /// \brief Const element access.
108  const PBQPNum& operator[](unsigned Index) const {
109  assert(Length != 0 && Data != nullptr && "Invalid vector");
110  assert(Index < Length && "Vector element access out of bounds.");
111  return Data[Index];
112  }
113 
114  /// \brief Add another vector to this one.
115  Vector& operator+=(const Vector &V) {
116  assert(Length != 0 && Data != nullptr && "Invalid vector");
117  assert(Length == V.Length && "Vector length mismatch.");
118  std::transform(Data, Data + Length, V.Data, Data, std::plus<PBQPNum>());
119  return *this;
120  }
121 
122  /// \brief Subtract another vector from this one.
123  Vector& operator-=(const Vector &V) {
124  assert(Length != 0 && Data != nullptr && "Invalid vector");
125  assert(Length == V.Length && "Vector length mismatch.");
126  std::transform(Data, Data + Length, V.Data, Data, std::minus<PBQPNum>());
127  return *this;
128  }
129 
130  /// \brief Returns the index of the minimum value in this vector
131  unsigned minIndex() const {
132  assert(Length != 0 && Data != nullptr && "Invalid vector");
133  return std::min_element(Data, Data + Length) - Data;
134  }
135 
136 private:
137  unsigned Length;
138  PBQPNum *Data;
139 };
140 
141 /// \brief Return a hash_value for the given vector.
142 inline hash_code hash_value(const Vector &V) {
143  unsigned *VBegin = reinterpret_cast<unsigned*>(V.Data);
144  unsigned *VEnd = reinterpret_cast<unsigned*>(V.Data + V.Length);
145  return hash_combine(V.Length, hash_combine_range(VBegin, VEnd));
146 }
147 
148 /// \brief Output a textual representation of the given vector on the given
149 /// output stream.
150 template <typename OStream>
151 OStream& operator<<(OStream &OS, const Vector &V) {
152  assert((V.getLength() != 0) && "Zero-length vector badness.");
153 
154  OS << "[ " << V[0];
155  for (unsigned i = 1; i < V.getLength(); ++i)
156  OS << ", " << V[i];
157  OS << " ]";
158 
159  return OS;
160 }
161 
162 /// \brief PBQP Matrix class
163 class Matrix {
164 private:
165  friend hash_code hash_value(const Matrix &);
166 public:
167 
168  /// \brief Construct a PBQP Matrix with the given dimensions.
169  Matrix(unsigned Rows, unsigned Cols) :
170  Rows(Rows), Cols(Cols), Data(new PBQPNum[Rows * Cols]) {
171  }
172 
173  /// \brief Construct a PBQP Matrix with the given dimensions and initial
174  /// value.
175  Matrix(unsigned Rows, unsigned Cols, PBQPNum InitVal)
176  : Rows(Rows), Cols(Cols), Data(new PBQPNum[Rows * Cols]) {
177  std::fill(Data, Data + (Rows * Cols), InitVal);
178  }
179 
180  /// \brief Copy construct a PBQP matrix.
181  Matrix(const Matrix &M)
182  : Rows(M.Rows), Cols(M.Cols), Data(new PBQPNum[Rows * Cols]) {
183  std::copy(M.Data, M.Data + (Rows * Cols), Data);
184  }
185 
186  /// \brief Move construct a PBQP matrix.
188  : Rows(M.Rows), Cols(M.Cols), Data(M.Data) {
189  M.Rows = M.Cols = 0;
190  M.Data = nullptr;
191  }
192 
193  /// \brief Destroy this matrix, return its memory.
194  ~Matrix() { delete[] Data; }
195 
196  /// \brief Copy-assignment operator.
197  Matrix& operator=(const Matrix &M) {
198  delete[] Data;
199  Rows = M.Rows; Cols = M.Cols;
200  Data = new PBQPNum[Rows * Cols];
201  std::copy(M.Data, M.Data + (Rows * Cols), Data);
202  return *this;
203  }
204 
205  /// \brief Move-assignment operator.
207  delete[] Data;
208  Rows = M.Rows;
209  Cols = M.Cols;
210  Data = M.Data;
211  M.Rows = M.Cols = 0;
212  M.Data = nullptr;
213  return *this;
214  }
215 
216  /// \brief Comparison operator.
217  bool operator==(const Matrix &M) const {
218  assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
219  if (Rows != M.Rows || Cols != M.Cols)
220  return false;
221  return std::equal(Data, Data + (Rows * Cols), M.Data);
222  }
223 
224  /// \brief Return the number of rows in this matrix.
225  unsigned getRows() const {
226  assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
227  return Rows;
228  }
229 
230  /// \brief Return the number of cols in this matrix.
231  unsigned getCols() const {
232  assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
233  return Cols;
234  }
235 
236  /// \brief Matrix element access.
237  PBQPNum* operator[](unsigned R) {
238  assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
239  assert(R < Rows && "Row out of bounds.");
240  return Data + (R * Cols);
241  }
242 
243  /// \brief Matrix element access.
244  const PBQPNum* operator[](unsigned R) const {
245  assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
246  assert(R < Rows && "Row out of bounds.");
247  return Data + (R * Cols);
248  }
249 
250  /// \brief Returns the given row as a vector.
251  Vector getRowAsVector(unsigned R) const {
252  assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
253  Vector V(Cols);
254  for (unsigned C = 0; C < Cols; ++C)
255  V[C] = (*this)[R][C];
256  return V;
257  }
258 
259  /// \brief Returns the given column as a vector.
260  Vector getColAsVector(unsigned C) const {
261  assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
262  Vector V(Rows);
263  for (unsigned R = 0; R < Rows; ++R)
264  V[R] = (*this)[R][C];
265  return V;
266  }
267 
268  /// \brief Reset the matrix to the given value.
269  Matrix& reset(PBQPNum Val = 0) {
270  assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
271  std::fill(Data, Data + (Rows * Cols), Val);
272  return *this;
273  }
274 
275  /// \brief Set a single row of this matrix to the given value.
276  Matrix& setRow(unsigned R, PBQPNum Val) {
277  assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
278  assert(R < Rows && "Row out of bounds.");
279  std::fill(Data + (R * Cols), Data + ((R + 1) * Cols), Val);
280  return *this;
281  }
282 
283  /// \brief Set a single column of this matrix to the given value.
284  Matrix& setCol(unsigned C, PBQPNum Val) {
285  assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
286  assert(C < Cols && "Column out of bounds.");
287  for (unsigned R = 0; R < Rows; ++R)
288  (*this)[R][C] = Val;
289  return *this;
290  }
291 
292  /// \brief Matrix transpose.
293  Matrix transpose() const {
294  assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
295  Matrix M(Cols, Rows);
296  for (unsigned r = 0; r < Rows; ++r)
297  for (unsigned c = 0; c < Cols; ++c)
298  M[c][r] = (*this)[r][c];
299  return M;
300  }
301 
302  /// \brief Returns the diagonal of the matrix as a vector.
303  ///
304  /// Matrix must be square.
305  Vector diagonalize() const {
306  assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
307  assert(Rows == Cols && "Attempt to diagonalize non-square matrix.");
308  Vector V(Rows);
309  for (unsigned r = 0; r < Rows; ++r)
310  V[r] = (*this)[r][r];
311  return V;
312  }
313 
314  /// \brief Add the given matrix to this one.
315  Matrix& operator+=(const Matrix &M) {
316  assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
317  assert(Rows == M.Rows && Cols == M.Cols &&
318  "Matrix dimensions mismatch.");
319  std::transform(Data, Data + (Rows * Cols), M.Data, Data,
320  std::plus<PBQPNum>());
321  return *this;
322  }
323 
324  Matrix operator+(const Matrix &M) {
325  assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
326  Matrix Tmp(*this);
327  Tmp += M;
328  return Tmp;
329  }
330 
331  /// \brief Returns the minimum of the given row
332  PBQPNum getRowMin(unsigned R) const {
333  assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
334  assert(R < Rows && "Row out of bounds");
335  return *std::min_element(Data + (R * Cols), Data + ((R + 1) * Cols));
336  }
337 
338  /// \brief Returns the minimum of the given column
339  PBQPNum getColMin(unsigned C) const {
340  assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
341  PBQPNum MinElem = (*this)[0][C];
342  for (unsigned R = 1; R < Rows; ++R)
343  if ((*this)[R][C] < MinElem)
344  MinElem = (*this)[R][C];
345  return MinElem;
346  }
347 
348  /// \brief Subtracts the given scalar from the elements of the given row.
349  Matrix& subFromRow(unsigned R, PBQPNum Val) {
350  assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
351  assert(R < Rows && "Row out of bounds");
352  std::transform(Data + (R * Cols), Data + ((R + 1) * Cols),
353  Data + (R * Cols),
354  std::bind2nd(std::minus<PBQPNum>(), Val));
355  return *this;
356  }
357 
358  /// \brief Subtracts the given scalar from the elements of the given column.
359  Matrix& subFromCol(unsigned C, PBQPNum Val) {
360  assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
361  for (unsigned R = 0; R < Rows; ++R)
362  (*this)[R][C] -= Val;
363  return *this;
364  }
365 
366  /// \brief Returns true if this is a zero matrix.
367  bool isZero() const {
368  assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
369  return find_if(Data, Data + (Rows * Cols),
370  std::bind2nd(std::not_equal_to<PBQPNum>(), 0)) ==
371  Data + (Rows * Cols);
372  }
373 
374 private:
375  unsigned Rows, Cols;
376  PBQPNum *Data;
377 };
378 
379 /// \brief Return a hash_code for the given matrix.
380 inline hash_code hash_value(const Matrix &M) {
381  unsigned *MBegin = reinterpret_cast<unsigned*>(M.Data);
382  unsigned *MEnd = reinterpret_cast<unsigned*>(M.Data + (M.Rows * M.Cols));
383  return hash_combine(M.Rows, M.Cols, hash_combine_range(MBegin, MEnd));
384 }
385 
386 /// \brief Output a textual representation of the given matrix on the given
387 /// output stream.
388 template <typename OStream>
389 OStream& operator<<(OStream &OS, const Matrix &M) {
390  assert((M.getRows() != 0) && "Zero-row matrix badness.");
391  for (unsigned i = 0; i < M.getRows(); ++i)
392  OS << M.getRowAsVector(i) << "\n";
393  return OS;
394 }
395 
396 template <typename Metadata>
397 class MDVector : public Vector {
398 public:
399  MDVector(const Vector &v) : Vector(v), md(*this) { }
400  MDVector(Vector &&v) : Vector(std::move(v)), md(*this) { }
401  const Metadata& getMetadata() const { return md; }
402 private:
403  Metadata md;
404 };
405 
406 template <typename Metadata>
408  return hash_value(static_cast<const Vector&>(V));
409 }
410 
411 template <typename Metadata>
412 class MDMatrix : public Matrix {
413 public:
414  MDMatrix(const Matrix &m) : Matrix(m), md(*this) { }
415  MDMatrix(Matrix &&m) : Matrix(std::move(m)), md(*this) { }
416  const Metadata& getMetadata() const { return md; }
417 private:
418  Metadata md;
419 };
420 
421 template <typename Metadata>
423  return hash_value(static_cast<const Matrix&>(M));
424 }
425 
426 } // namespace PBQP
427 } // namespace llvm
428 
429 #endif // LLVM_CODEGEN_PBQP_MATH_H
OStream & operator<<(OStream &OS, const Vector &V)
Output a textual representation of the given vector on the given output stream.
Definition: Math.h:151
unsigned getCols() const
Return the number of cols in this matrix.
Definition: Math.h:231
MDMatrix(Matrix &&m)
Definition: Math.h:415
unsigned minIndex() const
Returns the index of the minimum value in this vector.
Definition: Math.h:131
Matrix & operator=(const Matrix &M)
Copy-assignment operator.
Definition: Math.h:197
friend hash_code hash_value(const Matrix &)
Return a hash_code for the given matrix.
Definition: Math.h:380
Vector & operator-=(const Vector &V)
Subtract another vector from this one.
Definition: Math.h:123
Matrix & reset(PBQPNum Val=0)
Reset the matrix to the given value.
Definition: Math.h:269
Matrix & setRow(unsigned R, PBQPNum Val)
Set a single row of this matrix to the given value.
Definition: Math.h:276
PBQPNum * operator[](unsigned R)
Matrix element access.
Definition: Math.h:237
Matrix & operator=(Matrix &&M)
Move-assignment operator.
Definition: Math.h:206
PBQPNum & operator[](unsigned Index)
Element access.
Definition: Math.h:101
MDMatrix(const Matrix &m)
Definition: Math.h:414
Matrix(unsigned Rows, unsigned Cols, PBQPNum InitVal)
Construct a PBQP Matrix with the given dimensions and initial value.
Definition: Math.h:175
Matrix(unsigned Rows, unsigned Cols)
Construct a PBQP Matrix with the given dimensions.
Definition: Math.h:169
MDVector(Vector &&v)
Definition: Math.h:400
bool isZero() const
Returns true if this is a zero matrix.
Definition: Math.h:367
bool operator==(const Matrix &M) const
Comparison operator.
Definition: Math.h:217
Vector getRowAsVector(unsigned R) const
Returns the given row as a vector.
Definition: Math.h:251
PBQPNum getRowMin(unsigned R) const
Returns the minimum of the given row.
Definition: Math.h:332
Vector getColAsVector(unsigned C) const
Returns the given column as a vector.
Definition: Math.h:260
~Vector()
Destroy this vector, return its memory.
Definition: Math.h:60
const PBQPNum & operator[](unsigned Index) const
Const element access.
Definition: Math.h:108
Matrix & setCol(unsigned C, PBQPNum Val)
Set a single column of this matrix to the given value.
Definition: Math.h:284
Vector(unsigned Length)
Construct a PBQP vector of the given size.
Definition: Math.h:29
Vector & operator=(Vector &&V)
Move-assignment operator.
Definition: Math.h:77
PBQP Matrix class.
Definition: Math.h:163
Matrix & operator+=(const Matrix &M)
Add the given matrix to this one.
Definition: Math.h:315
friend hash_code hash_value(const Vector &)
Return a hash_value for the given vector.
Definition: Math.h:142
PBQP Vector class.
Definition: Math.h:24
Vector & operator=(const Vector &V)
Copy-assignment operator.
Definition: Math.h:66
unsigned getLength() const
Return the length of the vector.
Definition: Math.h:95
Matrix(Matrix &&M)
Move construct a PBQP matrix.
Definition: Math.h:187
const Metadata & getMetadata() const
Definition: Math.h:416
Vector(const Vector &V)
Copy construct a PBQP vector.
Definition: Math.h:45
float PBQPNum
Definition: Math.h:21
hash_code hash_value(const Vector &V)
Return a hash_value for the given vector.
Definition: Math.h:142
bool operator==(const Vector &V) const
Comparison operator.
Definition: Math.h:87
Matrix & subFromCol(unsigned C, PBQPNum Val)
Subtracts the given scalar from the elements of the given column.
Definition: Math.h:359
const PBQPNum * operator[](unsigned R) const
Matrix element access.
Definition: Math.h:244
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
Definition: Hashing.h:603
Matrix operator+(const Matrix &M)
Definition: Math.h:324
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
Definition: Hashing.h:481
An opaque object representing a hash code.
Definition: Hashing.h:73
const Metadata & getMetadata() const
Definition: Math.h:401
unsigned getRows() const
Return the number of rows in this matrix.
Definition: Math.h:225
Vector(Vector &&V)
Move construct a PBQP vector.
Definition: Math.h:53
Vector & operator+=(const Vector &V)
Add another vector to this one.
Definition: Math.h:115
Matrix & subFromRow(unsigned R, PBQPNum Val)
Subtracts the given scalar from the elements of the given row.
Definition: Math.h:349
PBQPNum getColMin(unsigned C) const
Returns the minimum of the given column.
Definition: Math.h:339
Matrix(const Matrix &M)
Copy construct a PBQP matrix.
Definition: Math.h:181
Matrix transpose() const
Matrix transpose.
Definition: Math.h:293
Vector diagonalize() const
Returns the diagonal of the matrix as a vector.
Definition: Math.h:305
Root of the metadata hierarchy.
Definition: Metadata.h:45
Vector(unsigned Length, PBQPNum InitVal)
Construct a PBQP vector with initializer.
Definition: Math.h:36
~Matrix()
Destroy this matrix, return its memory.
Definition: Math.h:194
MDVector(const Vector &v)
Definition: Math.h:399