LLVM API Documentation
00001 //===------ Math.h - PBQP Vector and Matrix classes -------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #ifndef LLVM_CODEGEN_PBQP_MATH_H 00011 #define LLVM_CODEGEN_PBQP_MATH_H 00012 00013 #include <algorithm> 00014 #include <cassert> 00015 #include <functional> 00016 00017 namespace PBQP { 00018 00019 typedef float PBQPNum; 00020 00021 /// \brief PBQP Vector class. 00022 class Vector { 00023 friend class VectorComparator; 00024 public: 00025 00026 /// \brief Construct a PBQP vector of the given size. 00027 explicit Vector(unsigned Length) 00028 : Length(Length), Data(new PBQPNum[Length]) { 00029 // llvm::dbgs() << "Constructing PBQP::Vector " 00030 // << this << " (length " << Length << ")\n"; 00031 } 00032 00033 /// \brief Construct a PBQP vector with initializer. 00034 Vector(unsigned Length, PBQPNum InitVal) 00035 : Length(Length), Data(new PBQPNum[Length]) { 00036 // llvm::dbgs() << "Constructing PBQP::Vector " 00037 // << this << " (length " << Length << ", fill " 00038 // << InitVal << ")\n"; 00039 std::fill(Data, Data + Length, InitVal); 00040 } 00041 00042 /// \brief Copy construct a PBQP vector. 00043 Vector(const Vector &V) 00044 : Length(V.Length), Data(new PBQPNum[Length]) { 00045 // llvm::dbgs() << "Copy-constructing PBQP::Vector " << this 00046 // << " from PBQP::Vector " << &V << "\n"; 00047 std::copy(V.Data, V.Data + Length, Data); 00048 } 00049 00050 /// \brief Move construct a PBQP vector. 00051 Vector(Vector &&V) 00052 : Length(V.Length), Data(V.Data) { 00053 V.Length = 0; 00054 V.Data = nullptr; 00055 } 00056 00057 /// \brief Destroy this vector, return its memory. 00058 ~Vector() { 00059 // llvm::dbgs() << "Deleting PBQP::Vector " << this << "\n"; 00060 delete[] Data; 00061 } 00062 00063 /// \brief Copy-assignment operator. 00064 Vector& operator=(const Vector &V) { 00065 // llvm::dbgs() << "Assigning to PBQP::Vector " << this 00066 // << " from PBQP::Vector " << &V << "\n"; 00067 delete[] Data; 00068 Length = V.Length; 00069 Data = new PBQPNum[Length]; 00070 std::copy(V.Data, V.Data + Length, Data); 00071 return *this; 00072 } 00073 00074 /// \brief Move-assignment operator. 00075 Vector& operator=(Vector &&V) { 00076 delete[] Data; 00077 Length = V.Length; 00078 Data = V.Data; 00079 V.Length = 0; 00080 V.Data = nullptr; 00081 return *this; 00082 } 00083 00084 /// \brief Comparison operator. 00085 bool operator==(const Vector &V) const { 00086 assert(Length != 0 && Data != nullptr && "Invalid vector"); 00087 if (Length != V.Length) 00088 return false; 00089 return std::equal(Data, Data + Length, V.Data); 00090 } 00091 00092 /// \brief Return the length of the vector 00093 unsigned getLength() const { 00094 assert(Length != 0 && Data != nullptr && "Invalid vector"); 00095 return Length; 00096 } 00097 00098 /// \brief Element access. 00099 PBQPNum& operator[](unsigned Index) { 00100 assert(Length != 0 && Data != nullptr && "Invalid vector"); 00101 assert(Index < Length && "Vector element access out of bounds."); 00102 return Data[Index]; 00103 } 00104 00105 /// \brief Const element access. 00106 const PBQPNum& operator[](unsigned Index) const { 00107 assert(Length != 0 && Data != nullptr && "Invalid vector"); 00108 assert(Index < Length && "Vector element access out of bounds."); 00109 return Data[Index]; 00110 } 00111 00112 /// \brief Add another vector to this one. 00113 Vector& operator+=(const Vector &V) { 00114 assert(Length != 0 && Data != nullptr && "Invalid vector"); 00115 assert(Length == V.Length && "Vector length mismatch."); 00116 std::transform(Data, Data + Length, V.Data, Data, std::plus<PBQPNum>()); 00117 return *this; 00118 } 00119 00120 /// \brief Subtract another vector from this one. 00121 Vector& operator-=(const Vector &V) { 00122 assert(Length != 0 && Data != nullptr && "Invalid vector"); 00123 assert(Length == V.Length && "Vector length mismatch."); 00124 std::transform(Data, Data + Length, V.Data, Data, std::minus<PBQPNum>()); 00125 return *this; 00126 } 00127 00128 /// \brief Returns the index of the minimum value in this vector 00129 unsigned minIndex() const { 00130 assert(Length != 0 && Data != nullptr && "Invalid vector"); 00131 return std::min_element(Data, Data + Length) - Data; 00132 } 00133 00134 private: 00135 unsigned Length; 00136 PBQPNum *Data; 00137 }; 00138 00139 class VectorComparator { 00140 public: 00141 bool operator()(const Vector &A, const Vector &B) { 00142 if (A.Length < B.Length) 00143 return true; 00144 if (B.Length < A.Length) 00145 return false; 00146 char *AData = reinterpret_cast<char*>(A.Data); 00147 char *BData = reinterpret_cast<char*>(B.Data); 00148 return std::lexicographical_compare(AData, 00149 AData + A.Length * sizeof(PBQPNum), 00150 BData, 00151 BData + A.Length * sizeof(PBQPNum)); 00152 } 00153 }; 00154 00155 /// \brief Output a textual representation of the given vector on the given 00156 /// output stream. 00157 template <typename OStream> 00158 OStream& operator<<(OStream &OS, const Vector &V) { 00159 assert((V.getLength() != 0) && "Zero-length vector badness."); 00160 00161 OS << "[ " << V[0]; 00162 for (unsigned i = 1; i < V.getLength(); ++i) 00163 OS << ", " << V[i]; 00164 OS << " ]"; 00165 00166 return OS; 00167 } 00168 00169 00170 /// \brief PBQP Matrix class 00171 class Matrix { 00172 private: 00173 friend class MatrixComparator; 00174 public: 00175 00176 /// \brief Construct a PBQP Matrix with the given dimensions. 00177 Matrix(unsigned Rows, unsigned Cols) : 00178 Rows(Rows), Cols(Cols), Data(new PBQPNum[Rows * Cols]) { 00179 } 00180 00181 /// \brief Construct a PBQP Matrix with the given dimensions and initial 00182 /// value. 00183 Matrix(unsigned Rows, unsigned Cols, PBQPNum InitVal) 00184 : Rows(Rows), Cols(Cols), Data(new PBQPNum[Rows * Cols]) { 00185 std::fill(Data, Data + (Rows * Cols), InitVal); 00186 } 00187 00188 /// \brief Copy construct a PBQP matrix. 00189 Matrix(const Matrix &M) 00190 : Rows(M.Rows), Cols(M.Cols), Data(new PBQPNum[Rows * Cols]) { 00191 std::copy(M.Data, M.Data + (Rows * Cols), Data); 00192 } 00193 00194 /// \brief Move construct a PBQP matrix. 00195 Matrix(Matrix &&M) 00196 : Rows(M.Rows), Cols(M.Cols), Data(M.Data) { 00197 M.Rows = M.Cols = 0; 00198 M.Data = nullptr; 00199 } 00200 00201 /// \brief Destroy this matrix, return its memory. 00202 ~Matrix() { delete[] Data; } 00203 00204 /// \brief Copy-assignment operator. 00205 Matrix& operator=(const Matrix &M) { 00206 delete[] Data; 00207 Rows = M.Rows; Cols = M.Cols; 00208 Data = new PBQPNum[Rows * Cols]; 00209 std::copy(M.Data, M.Data + (Rows * Cols), Data); 00210 return *this; 00211 } 00212 00213 /// \brief Move-assignment operator. 00214 Matrix& operator=(Matrix &&M) { 00215 delete[] Data; 00216 Rows = M.Rows; 00217 Cols = M.Cols; 00218 Data = M.Data; 00219 M.Rows = M.Cols = 0; 00220 M.Data = nullptr; 00221 return *this; 00222 } 00223 00224 /// \brief Comparison operator. 00225 bool operator==(const Matrix &M) const { 00226 assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix"); 00227 if (Rows != M.Rows || Cols != M.Cols) 00228 return false; 00229 return std::equal(Data, Data + (Rows * Cols), M.Data); 00230 } 00231 00232 /// \brief Return the number of rows in this matrix. 00233 unsigned getRows() const { 00234 assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix"); 00235 return Rows; 00236 } 00237 00238 /// \brief Return the number of cols in this matrix. 00239 unsigned getCols() const { 00240 assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix"); 00241 return Cols; 00242 } 00243 00244 /// \brief Matrix element access. 00245 PBQPNum* operator[](unsigned R) { 00246 assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix"); 00247 assert(R < Rows && "Row out of bounds."); 00248 return Data + (R * Cols); 00249 } 00250 00251 /// \brief Matrix element access. 00252 const PBQPNum* operator[](unsigned R) const { 00253 assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix"); 00254 assert(R < Rows && "Row out of bounds."); 00255 return Data + (R * Cols); 00256 } 00257 00258 /// \brief Returns the given row as a vector. 00259 Vector getRowAsVector(unsigned R) const { 00260 assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix"); 00261 Vector V(Cols); 00262 for (unsigned C = 0; C < Cols; ++C) 00263 V[C] = (*this)[R][C]; 00264 return V; 00265 } 00266 00267 /// \brief Returns the given column as a vector. 00268 Vector getColAsVector(unsigned C) const { 00269 assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix"); 00270 Vector V(Rows); 00271 for (unsigned R = 0; R < Rows; ++R) 00272 V[R] = (*this)[R][C]; 00273 return V; 00274 } 00275 00276 /// \brief Reset the matrix to the given value. 00277 Matrix& reset(PBQPNum Val = 0) { 00278 assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix"); 00279 std::fill(Data, Data + (Rows * Cols), Val); 00280 return *this; 00281 } 00282 00283 /// \brief Set a single row of this matrix to the given value. 00284 Matrix& setRow(unsigned R, PBQPNum Val) { 00285 assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix"); 00286 assert(R < Rows && "Row out of bounds."); 00287 std::fill(Data + (R * Cols), Data + ((R + 1) * Cols), Val); 00288 return *this; 00289 } 00290 00291 /// \brief Set a single column of this matrix to the given value. 00292 Matrix& setCol(unsigned C, PBQPNum Val) { 00293 assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix"); 00294 assert(C < Cols && "Column out of bounds."); 00295 for (unsigned R = 0; R < Rows; ++R) 00296 (*this)[R][C] = Val; 00297 return *this; 00298 } 00299 00300 /// \brief Matrix transpose. 00301 Matrix transpose() const { 00302 assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix"); 00303 Matrix M(Cols, Rows); 00304 for (unsigned r = 0; r < Rows; ++r) 00305 for (unsigned c = 0; c < Cols; ++c) 00306 M[c][r] = (*this)[r][c]; 00307 return M; 00308 } 00309 00310 /// \brief Returns the diagonal of the matrix as a vector. 00311 /// 00312 /// Matrix must be square. 00313 Vector diagonalize() const { 00314 assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix"); 00315 assert(Rows == Cols && "Attempt to diagonalize non-square matrix."); 00316 Vector V(Rows); 00317 for (unsigned r = 0; r < Rows; ++r) 00318 V[r] = (*this)[r][r]; 00319 return V; 00320 } 00321 00322 /// \brief Add the given matrix to this one. 00323 Matrix& operator+=(const Matrix &M) { 00324 assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix"); 00325 assert(Rows == M.Rows && Cols == M.Cols && 00326 "Matrix dimensions mismatch."); 00327 std::transform(Data, Data + (Rows * Cols), M.Data, Data, 00328 std::plus<PBQPNum>()); 00329 return *this; 00330 } 00331 00332 Matrix operator+(const Matrix &M) { 00333 assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix"); 00334 Matrix Tmp(*this); 00335 Tmp += M; 00336 return Tmp; 00337 } 00338 00339 /// \brief Returns the minimum of the given row 00340 PBQPNum getRowMin(unsigned R) const { 00341 assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix"); 00342 assert(R < Rows && "Row out of bounds"); 00343 return *std::min_element(Data + (R * Cols), Data + ((R + 1) * Cols)); 00344 } 00345 00346 /// \brief Returns the minimum of the given column 00347 PBQPNum getColMin(unsigned C) const { 00348 assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix"); 00349 PBQPNum MinElem = (*this)[0][C]; 00350 for (unsigned R = 1; R < Rows; ++R) 00351 if ((*this)[R][C] < MinElem) 00352 MinElem = (*this)[R][C]; 00353 return MinElem; 00354 } 00355 00356 /// \brief Subtracts the given scalar from the elements of the given row. 00357 Matrix& subFromRow(unsigned R, PBQPNum Val) { 00358 assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix"); 00359 assert(R < Rows && "Row out of bounds"); 00360 std::transform(Data + (R * Cols), Data + ((R + 1) * Cols), 00361 Data + (R * Cols), 00362 std::bind2nd(std::minus<PBQPNum>(), Val)); 00363 return *this; 00364 } 00365 00366 /// \brief Subtracts the given scalar from the elements of the given column. 00367 Matrix& subFromCol(unsigned C, PBQPNum Val) { 00368 assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix"); 00369 for (unsigned R = 0; R < Rows; ++R) 00370 (*this)[R][C] -= Val; 00371 return *this; 00372 } 00373 00374 /// \brief Returns true if this is a zero matrix. 00375 bool isZero() const { 00376 assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix"); 00377 return find_if(Data, Data + (Rows * Cols), 00378 std::bind2nd(std::not_equal_to<PBQPNum>(), 0)) == 00379 Data + (Rows * Cols); 00380 } 00381 00382 private: 00383 unsigned Rows, Cols; 00384 PBQPNum *Data; 00385 }; 00386 00387 class MatrixComparator { 00388 public: 00389 bool operator()(const Matrix &A, const Matrix &B) { 00390 if (A.Rows < B.Rows) 00391 return true; 00392 if (B.Rows < A.Rows) 00393 return false; 00394 if (A.Cols < B.Cols) 00395 return true; 00396 if (B.Cols < A.Cols) 00397 return false; 00398 char *AData = reinterpret_cast<char*>(A.Data); 00399 char *BData = reinterpret_cast<char*>(B.Data); 00400 return std::lexicographical_compare( 00401 AData, AData + (A.Rows * A.Cols * sizeof(PBQPNum)), 00402 BData, BData + (A.Rows * A.Cols * sizeof(PBQPNum))); 00403 } 00404 }; 00405 00406 /// \brief Output a textual representation of the given matrix on the given 00407 /// output stream. 00408 template <typename OStream> 00409 OStream& operator<<(OStream &OS, const Matrix &M) { 00410 assert((M.getRows() != 0) && "Zero-row matrix badness."); 00411 for (unsigned i = 0; i < M.getRows(); ++i) 00412 OS << M.getRowAsVector(i); 00413 return OS; 00414 } 00415 00416 template <typename Metadata> 00417 class MDVector : public Vector { 00418 public: 00419 MDVector(const Vector &v) : Vector(v), md(*this) { } 00420 MDVector(Vector &&v) : Vector(std::move(v)), md(*this) { } 00421 const Metadata& getMetadata() const { return md; } 00422 private: 00423 Metadata md; 00424 }; 00425 00426 template <typename Metadata> 00427 class MDMatrix : public Matrix { 00428 public: 00429 MDMatrix(const Matrix &m) : Matrix(m), md(*this) { } 00430 MDMatrix(Matrix &&m) : Matrix(std::move(m)), md(*this) { } 00431 const Metadata& getMetadata() const { return md; } 00432 private: 00433 Metadata md; 00434 }; 00435 00436 } 00437 00438 #endif // LLVM_CODEGEN_PBQP_MATH_H