Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

288 lines
8.2 KiB

  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. #ifndef LLVM_CODEGEN_PBQP_MATH_H
  10. #define LLVM_CODEGEN_PBQP_MATH_H
  11. #include <algorithm>
  12. #include <cassert>
  13. #include <functional>
  14. namespace PBQP {
  15. typedef float PBQPNum;
  16. /// \brief PBQP Vector class.
  17. class Vector {
  18. public:
  19. /// \brief Construct a PBQP vector of the given size.
  20. explicit Vector(unsigned length) :
  21. length(length), data(new PBQPNum[length]) {
  22. }
  23. /// \brief Construct a PBQP vector with initializer.
  24. Vector(unsigned length, PBQPNum initVal) :
  25. length(length), data(new PBQPNum[length]) {
  26. std::fill(data, data + length, initVal);
  27. }
  28. /// \brief Copy construct a PBQP vector.
  29. Vector(const Vector &v) :
  30. length(v.length), data(new PBQPNum[length]) {
  31. std::copy(v.data, v.data + length, data);
  32. }
  33. /// \brief Destroy this vector, return its memory.
  34. ~Vector() { delete[] data; }
  35. /// \brief Assignment operator.
  36. Vector& operator=(const Vector &v) {
  37. delete[] data;
  38. length = v.length;
  39. data = new PBQPNum[length];
  40. std::copy(v.data, v.data + length, data);
  41. return *this;
  42. }
  43. /// \brief Return the length of the vector
  44. unsigned getLength() const {
  45. return length;
  46. }
  47. /// \brief Element access.
  48. PBQPNum& operator[](unsigned index) {
  49. assert(index < length && "Vector element access out of bounds.");
  50. return data[index];
  51. }
  52. /// \brief Const element access.
  53. const PBQPNum& operator[](unsigned index) const {
  54. assert(index < length && "Vector element access out of bounds.");
  55. return data[index];
  56. }
  57. /// \brief Add another vector to this one.
  58. Vector& operator+=(const Vector &v) {
  59. assert(length == v.length && "Vector length mismatch.");
  60. std::transform(data, data + length, v.data, data, std::plus<PBQPNum>());
  61. return *this;
  62. }
  63. /// \brief Subtract another vector from this one.
  64. Vector& operator-=(const Vector &v) {
  65. assert(length == v.length && "Vector length mismatch.");
  66. std::transform(data, data + length, v.data, data, std::minus<PBQPNum>());
  67. return *this;
  68. }
  69. /// \brief Returns the index of the minimum value in this vector
  70. unsigned minIndex() const {
  71. return std::min_element(data, data + length) - data;
  72. }
  73. private:
  74. unsigned length;
  75. PBQPNum *data;
  76. };
  77. /// \brief Output a textual representation of the given vector on the given
  78. /// output stream.
  79. template <typename OStream>
  80. OStream& operator<<(OStream &os, const Vector &v) {
  81. assert((v.getLength() != 0) && "Zero-length vector badness.");
  82. os << "[ " << v[0];
  83. for (unsigned i = 1; i < v.getLength(); ++i) {
  84. os << ", " << v[i];
  85. }
  86. os << " ]";
  87. return os;
  88. }
  89. /// \brief PBQP Matrix class
  90. class Matrix {
  91. public:
  92. /// \brief Construct a PBQP Matrix with the given dimensions.
  93. Matrix(unsigned rows, unsigned cols) :
  94. rows(rows), cols(cols), data(new PBQPNum[rows * cols]) {
  95. }
  96. /// \brief Construct a PBQP Matrix with the given dimensions and initial
  97. /// value.
  98. Matrix(unsigned rows, unsigned cols, PBQPNum initVal) :
  99. rows(rows), cols(cols), data(new PBQPNum[rows * cols]) {
  100. std::fill(data, data + (rows * cols), initVal);
  101. }
  102. /// \brief Copy construct a PBQP matrix.
  103. Matrix(const Matrix &m) :
  104. rows(m.rows), cols(m.cols), data(new PBQPNum[rows * cols]) {
  105. std::copy(m.data, m.data + (rows * cols), data);
  106. }
  107. /// \brief Destroy this matrix, return its memory.
  108. ~Matrix() { delete[] data; }
  109. /// \brief Assignment operator.
  110. Matrix& operator=(const Matrix &m) {
  111. delete[] data;
  112. rows = m.rows; cols = m.cols;
  113. data = new PBQPNum[rows * cols];
  114. std::copy(m.data, m.data + (rows * cols), data);
  115. return *this;
  116. }
  117. /// \brief Return the number of rows in this matrix.
  118. unsigned getRows() const { return rows; }
  119. /// \brief Return the number of cols in this matrix.
  120. unsigned getCols() const { return cols; }
  121. /// \brief Matrix element access.
  122. PBQPNum* operator[](unsigned r) {
  123. assert(r < rows && "Row out of bounds.");
  124. return data + (r * cols);
  125. }
  126. /// \brief Matrix element access.
  127. const PBQPNum* operator[](unsigned r) const {
  128. assert(r < rows && "Row out of bounds.");
  129. return data + (r * cols);
  130. }
  131. /// \brief Returns the given row as a vector.
  132. Vector getRowAsVector(unsigned r) const {
  133. Vector v(cols);
  134. for (unsigned c = 0; c < cols; ++c)
  135. v[c] = (*this)[r][c];
  136. return v;
  137. }
  138. /// \brief Returns the given column as a vector.
  139. Vector getColAsVector(unsigned c) const {
  140. Vector v(rows);
  141. for (unsigned r = 0; r < rows; ++r)
  142. v[r] = (*this)[r][c];
  143. return v;
  144. }
  145. /// \brief Reset the matrix to the given value.
  146. Matrix& reset(PBQPNum val = 0) {
  147. std::fill(data, data + (rows * cols), val);
  148. return *this;
  149. }
  150. /// \brief Set a single row of this matrix to the given value.
  151. Matrix& setRow(unsigned r, PBQPNum val) {
  152. assert(r < rows && "Row out of bounds.");
  153. std::fill(data + (r * cols), data + ((r + 1) * cols), val);
  154. return *this;
  155. }
  156. /// \brief Set a single column of this matrix to the given value.
  157. Matrix& setCol(unsigned c, PBQPNum val) {
  158. assert(c < cols && "Column out of bounds.");
  159. for (unsigned r = 0; r < rows; ++r)
  160. (*this)[r][c] = val;
  161. return *this;
  162. }
  163. /// \brief Matrix transpose.
  164. Matrix transpose() const {
  165. Matrix m(cols, rows);
  166. for (unsigned r = 0; r < rows; ++r)
  167. for (unsigned c = 0; c < cols; ++c)
  168. m[c][r] = (*this)[r][c];
  169. return m;
  170. }
  171. /// \brief Returns the diagonal of the matrix as a vector.
  172. ///
  173. /// Matrix must be square.
  174. Vector diagonalize() const {
  175. assert(rows == cols && "Attempt to diagonalize non-square matrix.");
  176. Vector v(rows);
  177. for (unsigned r = 0; r < rows; ++r)
  178. v[r] = (*this)[r][r];
  179. return v;
  180. }
  181. /// \brief Add the given matrix to this one.
  182. Matrix& operator+=(const Matrix &m) {
  183. assert(rows == m.rows && cols == m.cols &&
  184. "Matrix dimensions mismatch.");
  185. std::transform(data, data + (rows * cols), m.data, data,
  186. std::plus<PBQPNum>());
  187. return *this;
  188. }
  189. /// \brief Returns the minimum of the given row
  190. PBQPNum getRowMin(unsigned r) const {
  191. assert(r < rows && "Row out of bounds");
  192. return *std::min_element(data + (r * cols), data + ((r + 1) * cols));
  193. }
  194. /// \brief Returns the minimum of the given column
  195. PBQPNum getColMin(unsigned c) const {
  196. PBQPNum minElem = (*this)[0][c];
  197. for (unsigned r = 1; r < rows; ++r)
  198. if ((*this)[r][c] < minElem) minElem = (*this)[r][c];
  199. return minElem;
  200. }
  201. /// \brief Subtracts the given scalar from the elements of the given row.
  202. Matrix& subFromRow(unsigned r, PBQPNum val) {
  203. assert(r < rows && "Row out of bounds");
  204. std::transform(data + (r * cols), data + ((r + 1) * cols),
  205. data + (r * cols),
  206. std::bind2nd(std::minus<PBQPNum>(), val));
  207. return *this;
  208. }
  209. /// \brief Subtracts the given scalar from the elements of the given column.
  210. Matrix& subFromCol(unsigned c, PBQPNum val) {
  211. for (unsigned r = 0; r < rows; ++r)
  212. (*this)[r][c] -= val;
  213. return *this;
  214. }
  215. /// \brief Returns true if this is a zero matrix.
  216. bool isZero() const {
  217. return find_if(data, data + (rows * cols),
  218. std::bind2nd(std::not_equal_to<PBQPNum>(), 0)) ==
  219. data + (rows * cols);
  220. }
  221. private:
  222. unsigned rows, cols;
  223. PBQPNum *data;
  224. };
  225. /// \brief Output a textual representation of the given matrix on the given
  226. /// output stream.
  227. template <typename OStream>
  228. OStream& operator<<(OStream &os, const Matrix &m) {
  229. assert((m.getRows() != 0) && "Zero-row matrix badness.");
  230. for (unsigned i = 0; i < m.getRows(); ++i) {
  231. os << m.getRowAsVector(i);
  232. }
  233. return os;
  234. }
  235. }
  236. #endif // LLVM_CODEGEN_PBQP_MATH_H