LLVM API Documentation
00001 //===---------------- PBQP.cpp --------- PBQP Solver ------------*- 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 // Developed by: Bernhard Scholz 00011 // The University of Sydney 00012 // http://www.it.usyd.edu.au/~scholz 00013 //===----------------------------------------------------------------------===// 00014 00015 // TODO: 00016 // 00017 // * Default to null costs on vector initialisation? 00018 // * C++-ify the rest of the solver. 00019 00020 #ifndef LLVM_CODEGEN_PBQPSOLVER_H 00021 #define LLVM_CODEGEN_PBQPSOLVER_H 00022 00023 #include <cassert> 00024 #include <algorithm> 00025 #include <functional> 00026 00027 namespace llvm { 00028 00029 //! \brief Floating point type to use in PBQP solver. 00030 typedef double PBQPNum; 00031 00032 //! \brief PBQP Vector class. 00033 class PBQPVector { 00034 public: 00035 00036 //! \brief Construct a PBQP vector of the given size. 00037 explicit PBQPVector(unsigned length) : 00038 length(length), data(new PBQPNum[length]) { 00039 std::fill(data, data + length, 0); 00040 } 00041 00042 //! \brief Copy construct a PBQP vector. 00043 PBQPVector(const PBQPVector &v) : 00044 length(v.length), data(new PBQPNum[length]) { 00045 std::copy(v.data, v.data + length, data); 00046 } 00047 00048 ~PBQPVector() { delete[] data; } 00049 00050 //! \brief Assignment operator. 00051 PBQPVector& operator=(const PBQPVector &v) { 00052 delete[] data; 00053 length = v.length; 00054 data = new PBQPNum[length]; 00055 std::copy(v.data, v.data + length, data); 00056 return *this; 00057 } 00058 00059 //! \brief Return the length of the vector 00060 unsigned getLength() const throw () { 00061 return length; 00062 } 00063 00064 //! \brief Element access. 00065 PBQPNum& operator[](unsigned index) { 00066 assert(index < length && "PBQPVector element access out of bounds."); 00067 return data[index]; 00068 } 00069 00070 //! \brief Const element access. 00071 const PBQPNum& operator[](unsigned index) const { 00072 assert(index < length && "PBQPVector element access out of bounds."); 00073 return data[index]; 00074 } 00075 00076 //! \brief Add another vector to this one. 00077 PBQPVector& operator+=(const PBQPVector &v) { 00078 assert(length == v.length && "PBQPVector length mismatch."); 00079 std::transform(data, data + length, v.data, data, std::plus<PBQPNum>()); 00080 return *this; 00081 } 00082 00083 //! \brief Subtract another vector from this one. 00084 PBQPVector& operator-=(const PBQPVector &v) { 00085 assert(length == v.length && "PBQPVector length mismatch."); 00086 std::transform(data, data + length, v.data, data, std::minus<PBQPNum>()); 00087 return *this; 00088 } 00089 00090 //! \brief Returns the index of the minimum value in this vector 00091 unsigned minIndex() const { 00092 return std::min_element(data, data + length) - data; 00093 } 00094 00095 private: 00096 unsigned length; 00097 PBQPNum *data; 00098 }; 00099 00100 00101 //! \brief PBQP Matrix class 00102 class PBQPMatrix { 00103 public: 00104 00105 //! \brief Construct a PBQP Matrix with the given dimensions. 00106 PBQPMatrix(unsigned rows, unsigned cols) : 00107 rows(rows), cols(cols), data(new PBQPNum[rows * cols]) { 00108 std::fill(data, data + (rows * cols), 0); 00109 } 00110 00111 //! \brief Copy construct a PBQP matrix. 00112 PBQPMatrix(const PBQPMatrix &m) : 00113 rows(m.rows), cols(m.cols), data(new PBQPNum[rows * cols]) { 00114 std::copy(m.data, m.data + (rows * cols), data); 00115 } 00116 00117 ~PBQPMatrix() { delete[] data; } 00118 00119 //! \brief Assignment operator. 00120 PBQPMatrix& operator=(const PBQPMatrix &m) { 00121 delete[] data; 00122 rows = m.rows; cols = m.cols; 00123 data = new PBQPNum[rows * cols]; 00124 std::copy(m.data, m.data + (rows * cols), data); 00125 return *this; 00126 } 00127 00128 //! \brief Return the number of rows in this matrix. 00129 unsigned getRows() const throw () { return rows; } 00130 00131 //! \brief Return the number of cols in this matrix. 00132 unsigned getCols() const throw () { return cols; } 00133 00134 //! \brief Matrix element access. 00135 PBQPNum* operator[](unsigned r) { 00136 assert(r < rows && "Row out of bounds."); 00137 return data + (r * cols); 00138 } 00139 00140 //! \brief Matrix element access. 00141 const PBQPNum* operator[](unsigned r) const { 00142 assert(r < rows && "Row out of bounds."); 00143 return data + (r * cols); 00144 } 00145 00146 //! \brief Returns the given row as a vector. 00147 PBQPVector getRowAsVector(unsigned r) const { 00148 PBQPVector v(cols); 00149 for (unsigned c = 0; c < cols; ++c) 00150 v[c] = (*this)[r][c]; 00151 return v; 00152 } 00153 00154 //! \brief Reset the matrix to the given value. 00155 PBQPMatrix& reset(PBQPNum val = 0) { 00156 std::fill(data, data + (rows * cols), val); 00157 return *this; 00158 } 00159 00160 //! \brief Set a single row of this matrix to the given value. 00161 PBQPMatrix& setRow(unsigned r, PBQPNum val) { 00162 assert(r < rows && "Row out of bounds."); 00163 std::fill(data + (r * cols), data + ((r + 1) * cols), val); 00164 return *this; 00165 } 00166 00167 //! \brief Set a single column of this matrix to the given value. 00168 PBQPMatrix& setCol(unsigned c, PBQPNum val) { 00169 assert(c < cols && "Column out of bounds."); 00170 for (unsigned r = 0; r < rows; ++r) 00171 (*this)[r][c] = val; 00172 return *this; 00173 } 00174 00175 //! \brief Matrix transpose. 00176 PBQPMatrix transpose() const { 00177 PBQPMatrix m(cols, rows); 00178 for (unsigned r = 0; r < rows; ++r) 00179 for (unsigned c = 0; c < cols; ++c) 00180 m[c][r] = (*this)[r][c]; 00181 return m; 00182 } 00183 00184 //! \brief Returns the diagonal of the matrix as a vector. 00185 //! 00186 //! Matrix must be square. 00187 PBQPVector diagonalize() const { 00188 assert(rows == cols && "Attempt to diagonalize non-square matrix."); 00189 00190 PBQPVector v(rows); 00191 for (unsigned r = 0; r < rows; ++r) 00192 v[r] = (*this)[r][r]; 00193 return v; 00194 } 00195 00196 //! \brief Add the given matrix to this one. 00197 PBQPMatrix& operator+=(const PBQPMatrix &m) { 00198 assert(rows == m.rows && cols == m.cols && 00199 "Matrix dimensions mismatch."); 00200 std::transform(data, data + (rows * cols), m.data, data, 00201 std::plus<PBQPNum>()); 00202 return *this; 00203 } 00204 00205 //! \brief Returns the minimum of the given row 00206 PBQPNum getRowMin(unsigned r) const { 00207 assert(r < rows && "Row out of bounds"); 00208 return *std::min_element(data + (r * cols), data + ((r + 1) * cols)); 00209 } 00210 00211 //! \brief Returns the minimum of the given column 00212 PBQPNum getColMin(unsigned c) const { 00213 PBQPNum minElem = (*this)[0][c]; 00214 for (unsigned r = 1; r < rows; ++r) 00215 if ((*this)[r][c] < minElem) minElem = (*this)[r][c]; 00216 return minElem; 00217 } 00218 00219 //! \brief Subtracts the given scalar from the elements of the given row. 00220 PBQPMatrix& subFromRow(unsigned r, PBQPNum val) { 00221 assert(r < rows && "Row out of bounds"); 00222 std::transform(data + (r * cols), data + ((r + 1) * cols), 00223 data + (r * cols), 00224 std::bind2nd(std::minus<PBQPNum>(), val)); 00225 return *this; 00226 } 00227 00228 //! \brief Subtracts the given scalar from the elements of the given column. 00229 PBQPMatrix& subFromCol(unsigned c, PBQPNum val) { 00230 for (unsigned r = 0; r < rows; ++r) 00231 (*this)[r][c] -= val; 00232 return *this; 00233 } 00234 00235 //! \brief Returns true if this is a zero matrix. 00236 bool isZero() const { 00237 return find_if(data, data + (rows * cols), 00238 std::bind2nd(std::not_equal_to<PBQPNum>(), 0)) == 00239 data + (rows * cols); 00240 } 00241 00242 private: 00243 unsigned rows, cols; 00244 PBQPNum *data; 00245 }; 00246 00247 #define EPS (1E-8) 00248 00249 #ifndef PBQP_TYPE 00250 #define PBQP_TYPE 00251 struct pbqp; 00252 typedef struct pbqp pbqp; 00253 #endif 00254 00255 /***************** 00256 * PBQP routines * 00257 *****************/ 00258 00259 /* allocate pbqp problem */ 00260 pbqp *alloc_pbqp(int num); 00261 00262 /* add node costs */ 00263 void add_pbqp_nodecosts(pbqp *this_,int u, PBQPVector *costs); 00264 00265 /* add edge mat */ 00266 void add_pbqp_edgecosts(pbqp *this_,int u,int v,PBQPMatrix *costs); 00267 00268 /* solve PBQP problem */ 00269 void solve_pbqp(pbqp *this_); 00270 00271 /* get solution of a node */ 00272 int get_pbqp_solution(pbqp *this_,int u); 00273 00274 /* alloc PBQP */ 00275 pbqp *alloc_pbqp(int num); 00276 00277 /* free PBQP */ 00278 void free_pbqp(pbqp *this_); 00279 00280 /* is optimal */ 00281 bool is_pbqp_optimal(pbqp *this_); 00282 00283 } 00284 #endif
This web site is hosted by the Computer Science Department at the University of Illinois at Urbana-Champaign.