LLVM API Documentation

PBQP.h

Go to the documentation of this file.
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.