00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "CoinHelperFunctions.hpp"
00011 #include "CoinFinite.hpp"
00012
00013 #include <stdio.h>
00014
00015 #include "CouenneMatrix.hpp"
00016 #include "CouenneExprConst.hpp"
00017
00018 using namespace Couenne;
00019
00020
00021
00022 CouenneSparseVector::CouenneSparseVector (const CouenneSparseVector &rhs) {
00023
00024 for (register std::set <CouenneScalar *, CouenneSparseVector::compare_scalars>::const_iterator
00025 i = rhs. elem_. begin ();
00026 i != rhs. elem_. end (); ++i)
00027
00028 elem_. insert (new CouenneScalar (**i));
00029 }
00030
00031
00032
00033 CouenneSparseVector &CouenneSparseVector::operator= (const CouenneSparseVector &rhs) {
00034
00035 for (register std::set <CouenneScalar *, CouenneSparseVector::compare_scalars>::const_iterator
00036 i = rhs. elem_. begin ();
00037 i != rhs. elem_. end (); ++i)
00038
00039 elem_. insert (new CouenneScalar (**i));
00040
00041 return *this;
00042 }
00043
00044 #define copy_vectors(from, to) { \
00045 for (std::set <std::pair <int, CouenneSparseVector *>, CouenneExprMatrix::compare_pair_ind>::const_iterator \
00046 rowIt = from. begin (); \
00047 rowIt != from. end (); ++rowIt) { \
00048 to . insert (std::pair <int, CouenneSparseVector *> (rowIt -> first, new CouenneSparseVector (*(rowIt -> second)))); \
00049 } \
00050 }
00051
00053 CouenneExprMatrix::CouenneExprMatrix (const CouenneExprMatrix &rhs):
00054 varIndices_ (rhs.varIndices_) {
00055
00056 copy_vectors(rhs.row_, row_);
00057 copy_vectors(rhs.col_, col_);
00058 }
00059
00061 CouenneExprMatrix &CouenneExprMatrix::operator= (const CouenneExprMatrix &rhs) {
00062
00063 varIndices_ = rhs.varIndices_;
00064
00065 copy_vectors(rhs.row_, row_);
00066 copy_vectors(rhs.col_, col_);
00067
00068 return *this;
00069 }
00070
00071 void CouenneScalar::print () const {
00072 printf ("[%d,", index_);
00073 if (elem_)
00074 elem_ -> print ();
00075 printf ("]");
00076 }
00077
00078
00080 void CouenneSparseVector::add_element (int index, expression *elem) {
00081
00082 CouenneScalar *element = new CouenneScalar (index, elem);
00083 elem_ . insert (element);
00084 }
00085
00086
00088 long unsigned int CouenneExprMatrix::size ()
00089 {return CoinMax (row_ . size (), col_ . size ());}
00090
00092 inline void check_and_insert (int indMaj, int indMin,
00093 std::set <std::pair <int, CouenneSparseVector *>, CouenneExprMatrix::compare_pair_ind> &vecMaj,
00094 expression *elem) {
00095
00096 std:: pair <int, CouenneSparseVector *> findme (indMaj, (CouenneSparseVector *) NULL);
00097 std::set <std::pair <int, CouenneSparseVector *>,
00098 CouenneExprMatrix::compare_pair_ind>::const_iterator check = vecMaj.find (findme);
00099
00100 if (check == vecMaj. end ()) {
00101 std::pair <int, CouenneSparseVector *> new_vector (indMaj, new CouenneSparseVector);
00102 new_vector.second -> add_element (indMin, elem);
00103 vecMaj. insert (new_vector);
00104 } else check -> second -> add_element (indMin, elem);
00105 }
00106
00107
00109 void CouenneExprMatrix::add_element (int rowInd, int colInd, expression *elem) {
00110
00111 check_and_insert (rowInd, colInd, row_, elem);
00112 if (elem -> code () == COU_EXPRCONST)
00113 elem = new exprClone (elem);
00114 check_and_insert (colInd, rowInd, col_, elem);
00115 }
00116
00117
00119 inline double CouenneSparseVector::operator * (const CouenneSparseVector &v2) const
00120 {return multiply_thres (v2, COIN_DBL_MAX);}
00121
00122
00124 double CouenneSparseVector::multiply_thres (const CouenneSparseVector &v2, double thres) const {
00125
00126 double prod = 0.;
00127
00128 for (register std::set <CouenneScalar *, CouenneSparseVector::compare_scalars>::const_iterator
00129 i1 = elem_. begin (),
00130 i2 = v2.elem_. begin ();
00131
00132 ((i1 != elem_.end ()) &&
00133 (i2 != v2.elem_.end ()));) {
00134
00135 while ((i1 != elem_.end ()) && ((*i1) -> getIndex () < (*i2) -> getIndex ())) ++i1; if (i1 == elem_. end ()) return prod;
00136 while ((i2 != v2.elem_.end ()) && ((*i2) -> getIndex () < (*i1) -> getIndex ())) ++i2; if (i2 == v2. elem_. end ()) return prod;
00137
00138 prod +=
00139 (*((*i1) -> getElem ())) () *
00140 (*((*i2) -> getElem ())) ();
00141
00142 if (prod > thres)
00143 break;
00144 }
00145
00146 return prod;
00147 }
00148
00149
00151 CouenneSparseVector &CouenneSparseVector::operator * (const CouenneExprMatrix &post) const {
00152
00153 CouenneSparseVector *product = new CouenneSparseVector;
00154
00155 const std::set <std::pair <int, CouenneSparseVector *>, CouenneExprMatrix::compare_pair_ind> &columns = post. getCols ();
00156
00157 for (std::set <std::pair <int, CouenneSparseVector *>, CouenneExprMatrix::compare_pair_ind>::const_iterator colIt = columns. begin ();
00158 colIt != columns. end (); ++colIt) {
00159
00160 double single = operator* (*(colIt -> second));
00161
00162 if (single != 0.)
00163 product -> add_element (colIt -> first, new exprConst (single));
00164 }
00165
00166 return *product;
00167 }
00168
00169
00171 CouenneSparseVector &CouenneExprMatrix::operator * (const CouenneSparseVector &post) const {
00172
00173 CouenneSparseVector *product = new CouenneSparseVector;
00174
00175 for (std::set <std::pair <int, CouenneSparseVector *>, CouenneExprMatrix::compare_pair_ind>::const_iterator rowIt = row_. begin ();
00176 rowIt != row_. end (); ++rowIt) {
00177
00178 double single = post. operator* (*(rowIt -> second));
00179
00180 if (single != 0.)
00181 product -> add_element (rowIt -> first, new exprConst (single));
00182 }
00183
00184 return *product;
00185 }
00186
00187
00189 CouenneExprMatrix &CouenneExprMatrix::operator * (const CouenneExprMatrix &post) const {
00190
00191 CouenneExprMatrix *product = new CouenneExprMatrix;
00192 return *product;
00193 }
00194
00196 CouenneExprMatrix::~CouenneExprMatrix () {
00197
00198 for (std::set <std::pair <int, CouenneSparseVector *>, CouenneExprMatrix::compare_pair_ind>::iterator
00199 i = row_ . begin ();
00200 i != row_ . end (); ++i)
00201
00202 delete i -> second;
00203
00204 for (std::set <std::pair <int, CouenneSparseVector *>, CouenneExprMatrix::compare_pair_ind>::iterator
00205 i = col_ . begin ();
00206 i != col_ . end (); ++i)
00207
00208 delete i -> second;
00209 }
00210
00211
00213 CouenneSparseVector::~CouenneSparseVector () {
00214
00215 for (register std::set <CouenneScalar *, CouenneSparseVector::compare_scalars>::iterator
00216 i = elem_. begin ();
00217 i != elem_. end (); ++i)
00218 delete (*i);
00219 }
00220
00221
00222 CouenneScalar::~CouenneScalar ()
00223 {delete elem_;}
00224
00225 #define WRAP 20
00226
00228 void CouenneSparseVector::print () const {
00229
00230 int cnt=0;
00231
00232 printf ("Vector (%ld) (", elem_ . size ());
00233
00234 for (std::set <CouenneScalar *, CouenneSparseVector::compare_scalars>::const_iterator i = elem_ . begin ();
00235 i != elem_ . end (); ++i) {
00236
00237 if (i != elem_ . begin ())
00238 printf (",");
00239
00240 (*i) -> print ();
00241
00242 if ((++cnt) % WRAP == 0)
00243 printf ("\n ");
00244 }
00245
00246 printf (")");
00247 }
00248
00249
00251 void CouenneExprMatrix::print () const {
00252
00253 printf ("Matrix (%ld x %ld):\n",
00254 row_ . size (),
00255 col_ . size ());
00256
00257
00258
00259 for (std::set <std::pair <int, CouenneSparseVector *>, CouenneExprMatrix::compare_pair_ind>::const_iterator
00260 i = row_ . begin ();
00261 i != row_ . end (); ++i) {
00262
00263 printf ("Row [%d]: ", (*i) . first);
00264 (*i) . second -> print ();
00265 printf ("\n");
00266 }
00267
00268
00269
00270 for (std::set <std::pair <int, CouenneSparseVector *>, CouenneExprMatrix::compare_pair_ind>::const_iterator
00271 i = col_ . begin ();
00272 i != col_ . end (); ++i) {
00273
00274 printf ("Col [%d]: ", (*i) . first);
00275 (*i) . second -> print ();
00276 printf ("\n");
00277 }
00278
00279 if (varIndices_ . size () > 0) {
00280 printf ("varIndices: (");
00281 for (std::vector <expression *>::const_iterator
00282 i = varIndices_ . begin ();
00283 i != varIndices_ . end (); ++i) {
00284 if (i != varIndices_ . begin ())
00285 printf (",");
00286 (*i) -> print ();
00287 }
00288 printf (")\n");
00289 }
00290 }