1408dcd3ebe187e2c098928caf9c4ce8928a30ba0Lang Hames//===------ Math.h - PBQP Vector and Matrix classes -------------*- C++ -*-===// 225e9651afb26a004a9debda42da3f90234cc05e2Lang Hames// 325e9651afb26a004a9debda42da3f90234cc05e2Lang Hames// The LLVM Compiler Infrastructure 425e9651afb26a004a9debda42da3f90234cc05e2Lang Hames// 525e9651afb26a004a9debda42da3f90234cc05e2Lang Hames// This file is distributed under the University of Illinois Open Source 625e9651afb26a004a9debda42da3f90234cc05e2Lang Hames// License. See LICENSE.TXT for details. 725e9651afb26a004a9debda42da3f90234cc05e2Lang Hames// 825e9651afb26a004a9debda42da3f90234cc05e2Lang Hames//===----------------------------------------------------------------------===// 925e9651afb26a004a9debda42da3f90234cc05e2Lang Hames 10408dcd3ebe187e2c098928caf9c4ce8928a30ba0Lang Hames#ifndef LLVM_CODEGEN_PBQP_MATH_H 11408dcd3ebe187e2c098928caf9c4ce8928a30ba0Lang Hames#define LLVM_CODEGEN_PBQP_MATH_H 123ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 133ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames#include <cassert> 143ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames#include <algorithm> 153ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames#include <functional> 163ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 173ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hamesnamespace PBQP { 183ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 19408dcd3ebe187e2c098928caf9c4ce8928a30ba0Lang Hamestypedef float PBQPNum; 203ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 213ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames/// \brief PBQP Vector class. 223ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hamesclass Vector { 233ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames public: 243ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 253ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Construct a PBQP vector of the given size. 263ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames explicit Vector(unsigned length) : 273ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames length(length), data(new PBQPNum[length]) { 283ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 293ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 303ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Construct a PBQP vector with initializer. 313ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames Vector(unsigned length, PBQPNum initVal) : 323ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames length(length), data(new PBQPNum[length]) { 333ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames std::fill(data, data + length, initVal); 343ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 353ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 363ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Copy construct a PBQP vector. 373ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames Vector(const Vector &v) : 383ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames length(v.length), data(new PBQPNum[length]) { 393ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames std::copy(v.data, v.data + length, data); 403ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 413ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 423ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Destroy this vector, return its memory. 433ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames ~Vector() { delete[] data; } 443ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 453ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Assignment operator. 463ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames Vector& operator=(const Vector &v) { 473ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames delete[] data; 483ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames length = v.length; 493ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames data = new PBQPNum[length]; 503ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames std::copy(v.data, v.data + length, data); 513ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return *this; 523ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 533ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 543ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Return the length of the vector 55d1e9ec57081f3b62d3595d9e3a66dd0d35fc02d4Dan Gohman unsigned getLength() const { 563ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return length; 573ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 583ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 593ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Element access. 603ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames PBQPNum& operator[](unsigned index) { 613ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames assert(index < length && "Vector element access out of bounds."); 623ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return data[index]; 633ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 643ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 653ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Const element access. 663ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames const PBQPNum& operator[](unsigned index) const { 673ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames assert(index < length && "Vector element access out of bounds."); 683ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return data[index]; 693ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 703ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 713ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Add another vector to this one. 723ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames Vector& operator+=(const Vector &v) { 733ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames assert(length == v.length && "Vector length mismatch."); 743ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames std::transform(data, data + length, v.data, data, std::plus<PBQPNum>()); 753ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return *this; 763ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 773ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 783ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Subtract another vector from this one. 793ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames Vector& operator-=(const Vector &v) { 803ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames assert(length == v.length && "Vector length mismatch."); 813ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames std::transform(data, data + length, v.data, data, std::minus<PBQPNum>()); 823ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return *this; 833ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 843ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 853ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Returns the index of the minimum value in this vector 863ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames unsigned minIndex() const { 873ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return std::min_element(data, data + length) - data; 883ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 893ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 903ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames private: 913ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames unsigned length; 923ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames PBQPNum *data; 933ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames}; 943ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 953ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames/// \brief Output a textual representation of the given vector on the given 963ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames/// output stream. 973ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hamestemplate <typename OStream> 983ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang HamesOStream& operator<<(OStream &os, const Vector &v) { 993ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames assert((v.getLength() != 0) && "Zero-length vector badness."); 1003ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 1013ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames os << "[ " << v[0]; 1023ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames for (unsigned i = 1; i < v.getLength(); ++i) { 1033ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames os << ", " << v[i]; 1043ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 1053ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames os << " ]"; 1063ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 1073ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return os; 1083ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames} 1093ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 1103ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 1113ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames/// \brief PBQP Matrix class 1123ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hamesclass Matrix { 1133ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames public: 1143ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 1153ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Construct a PBQP Matrix with the given dimensions. 1163ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames Matrix(unsigned rows, unsigned cols) : 1173ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames rows(rows), cols(cols), data(new PBQPNum[rows * cols]) { 1183ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 1193ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 1203ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Construct a PBQP Matrix with the given dimensions and initial 1213ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// value. 1223ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames Matrix(unsigned rows, unsigned cols, PBQPNum initVal) : 1233ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames rows(rows), cols(cols), data(new PBQPNum[rows * cols]) { 1243ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames std::fill(data, data + (rows * cols), initVal); 1253ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 1263ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 1273ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Copy construct a PBQP matrix. 1283ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames Matrix(const Matrix &m) : 1293ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames rows(m.rows), cols(m.cols), data(new PBQPNum[rows * cols]) { 1303ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames std::copy(m.data, m.data + (rows * cols), data); 1313ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 1323ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 1333ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Destroy this matrix, return its memory. 1343ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames ~Matrix() { delete[] data; } 1353ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 1363ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Assignment operator. 1373ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames Matrix& operator=(const Matrix &m) { 1383ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames delete[] data; 1393ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames rows = m.rows; cols = m.cols; 1403ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames data = new PBQPNum[rows * cols]; 1413ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames std::copy(m.data, m.data + (rows * cols), data); 1423ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return *this; 1433ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 1443ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 1453ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Return the number of rows in this matrix. 146d1e9ec57081f3b62d3595d9e3a66dd0d35fc02d4Dan Gohman unsigned getRows() const { return rows; } 1473ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 1483ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Return the number of cols in this matrix. 149d1e9ec57081f3b62d3595d9e3a66dd0d35fc02d4Dan Gohman unsigned getCols() const { return cols; } 1503ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 1513ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Matrix element access. 1523ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames PBQPNum* operator[](unsigned r) { 1533ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames assert(r < rows && "Row out of bounds."); 1543ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return data + (r * cols); 1553ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 1563ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 1573ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Matrix element access. 1583ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames const PBQPNum* operator[](unsigned r) const { 1593ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames assert(r < rows && "Row out of bounds."); 1603ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return data + (r * cols); 1613ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 1623ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 1633ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Returns the given row as a vector. 1643ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames Vector getRowAsVector(unsigned r) const { 1653ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames Vector v(cols); 1663ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames for (unsigned c = 0; c < cols; ++c) 1673ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames v[c] = (*this)[r][c]; 1683ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return v; 1693ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 1703ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 1713ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Returns the given column as a vector. 1723ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames Vector getColAsVector(unsigned c) const { 1733ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames Vector v(rows); 1743ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames for (unsigned r = 0; r < rows; ++r) 1753ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames v[r] = (*this)[r][c]; 1763ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return v; 1773ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 1783ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 1793ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Reset the matrix to the given value. 1803ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames Matrix& reset(PBQPNum val = 0) { 1813ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames std::fill(data, data + (rows * cols), val); 1823ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return *this; 1833ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 1843ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 1853ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Set a single row of this matrix to the given value. 1863ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames Matrix& setRow(unsigned r, PBQPNum val) { 1873ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames assert(r < rows && "Row out of bounds."); 1883ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames std::fill(data + (r * cols), data + ((r + 1) * cols), val); 1893ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return *this; 1903ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 1913ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 1923ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Set a single column of this matrix to the given value. 1933ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames Matrix& setCol(unsigned c, PBQPNum val) { 1943ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames assert(c < cols && "Column out of bounds."); 1953ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames for (unsigned r = 0; r < rows; ++r) 1963ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames (*this)[r][c] = val; 1973ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return *this; 1983ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 1993ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 2003ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Matrix transpose. 2013ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames Matrix transpose() const { 2023ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames Matrix m(cols, rows); 2033ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames for (unsigned r = 0; r < rows; ++r) 2043ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames for (unsigned c = 0; c < cols; ++c) 2053ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames m[c][r] = (*this)[r][c]; 2063ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return m; 2073ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 2083ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 2093ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Returns the diagonal of the matrix as a vector. 2103ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// 2113ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// Matrix must be square. 2123ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames Vector diagonalize() const { 2133ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames assert(rows == cols && "Attempt to diagonalize non-square matrix."); 2143ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 2153ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames Vector v(rows); 2163ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames for (unsigned r = 0; r < rows; ++r) 2173ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames v[r] = (*this)[r][r]; 2183ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return v; 2193ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 2203ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 2213ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Add the given matrix to this one. 2223ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames Matrix& operator+=(const Matrix &m) { 2233ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames assert(rows == m.rows && cols == m.cols && 2243ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames "Matrix dimensions mismatch."); 2253ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames std::transform(data, data + (rows * cols), m.data, data, 2263ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames std::plus<PBQPNum>()); 2273ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return *this; 2283ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 2293ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 2303ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Returns the minimum of the given row 2313ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames PBQPNum getRowMin(unsigned r) const { 2323ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames assert(r < rows && "Row out of bounds"); 2333ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return *std::min_element(data + (r * cols), data + ((r + 1) * cols)); 2343ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 2353ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 2363ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Returns the minimum of the given column 2373ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames PBQPNum getColMin(unsigned c) const { 2383ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames PBQPNum minElem = (*this)[0][c]; 2393ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames for (unsigned r = 1; r < rows; ++r) 2403ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames if ((*this)[r][c] < minElem) minElem = (*this)[r][c]; 2413ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return minElem; 2423ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 2433ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 2443ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Subtracts the given scalar from the elements of the given row. 2453ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames Matrix& subFromRow(unsigned r, PBQPNum val) { 2463ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames assert(r < rows && "Row out of bounds"); 2473ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames std::transform(data + (r * cols), data + ((r + 1) * cols), 2483ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames data + (r * cols), 2493ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames std::bind2nd(std::minus<PBQPNum>(), val)); 2503ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return *this; 2513ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 2523ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 2533ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Subtracts the given scalar from the elements of the given column. 2543ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames Matrix& subFromCol(unsigned c, PBQPNum val) { 2553ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames for (unsigned r = 0; r < rows; ++r) 2563ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames (*this)[r][c] -= val; 2573ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return *this; 2583ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 2593ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 2603ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames /// \brief Returns true if this is a zero matrix. 2613ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames bool isZero() const { 2623ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return find_if(data, data + (rows * cols), 2633ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames std::bind2nd(std::not_equal_to<PBQPNum>(), 0)) == 2643ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames data + (rows * cols); 2653ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 2663ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 2673ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames private: 2683ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames unsigned rows, cols; 2693ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames PBQPNum *data; 2703ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames}; 2713ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 2723ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames/// \brief Output a textual representation of the given matrix on the given 2733ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames/// output stream. 2743ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hamestemplate <typename OStream> 2753ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang HamesOStream& operator<<(OStream &os, const Matrix &m) { 2763ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 2773ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames assert((m.getRows() != 0) && "Zero-row matrix badness."); 2783ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 2793ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames for (unsigned i = 0; i < m.getRows(); ++i) { 2803ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames os << m.getRowAsVector(i); 2813ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames } 2823ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 2833ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames return os; 2843ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames} 2853ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 2863ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames} 2873ca9a5bb440033db33cc5fa3318fa7f6f7c6a1ebLang Hames 288408dcd3ebe187e2c098928caf9c4ce8928a30ba0Lang Hames#endif // LLVM_CODEGEN_PBQP_MATH_H 289