source: trunk/Couenne/src/cut/sdpcuts/CouenneMatrix.cpp @ 964

Last change on this file since 964 was 964, checked in by pbelotti, 8 years ago

de-macroized a function in CouMatrix?

  • Property svn:keywords set to Id
File size: 7.9 KB
Line 
1/* $Id: CouenneMatrix.cpp 964 2013-05-30 02:45:36Z pbelotti $
2 *
3 * Name:    CouenneMatrix.cpp
4 * Author:  Pietro Belotti
5 * Purpose: implementation of the class of expression matrices
6 *
7 * This file is licensed under the Eclipse Public License (EPL)
8 */
9
10#include "CoinHelperFunctions.hpp"
11#include "CoinFinite.hpp"
12
13#include <stdio.h>
14
15#include "CouenneMatrix.hpp"
16#include "CouenneExprConst.hpp"
17
18using namespace Couenne;
19
20
21// copy constructor
22CouenneSparseVector::CouenneSparseVector (const CouenneSparseVector &rhs) {
23
24  for (register std::set <CouenneScalar *, CouenneSparseVector::compare_scalars>::const_iterator
25         i  = rhs. elem_. begin ();
26       i   != rhs. elem_. end   (); ++i)
27
28    elem_. insert (new CouenneScalar (**i));
29}
30
31
32// assignment operator
33CouenneSparseVector &CouenneSparseVector::operator= (const CouenneSparseVector &rhs) {
34
35  for (register std::set <CouenneScalar *, CouenneSparseVector::compare_scalars>::const_iterator
36         i  = rhs. elem_. begin ();
37       i   != rhs. elem_. end   (); ++i)
38
39    elem_. insert (new CouenneScalar (**i));
40
41  return *this;
42}
43
44#define copy_vectors(from, to) {                                                                                         \
45  for (std::set <std::pair <int, CouenneSparseVector *>, CouenneExprMatrix::compare_pair_ind>::const_iterator            \
46         rowIt  = from. begin ();                                                                                        \
47       rowIt   != from. end   (); ++rowIt) {                                                                             \
48    to . insert (std::pair <int, CouenneSparseVector *> (rowIt -> first, new CouenneSparseVector (*(rowIt -> second)))); \
49  }                                                                                                                      \
50}
51
52/// copy constructor
53CouenneExprMatrix::CouenneExprMatrix (const CouenneExprMatrix &rhs):
54  varIndices_ (rhs.varIndices_) {
55
56  copy_vectors(rhs.row_, row_);
57  copy_vectors(rhs.col_, col_);
58}
59
60/// Assignment operator
61CouenneExprMatrix &CouenneExprMatrix::operator= (const CouenneExprMatrix &rhs) {
62
63  varIndices_ = rhs.varIndices_;
64
65  copy_vectors(rhs.row_, row_);
66  copy_vectors(rhs.col_, col_);
67
68  return *this;
69}
70
71void CouenneScalar::print () const {
72  printf ("[%d,", index_); 
73  if (elem_) 
74    elem_ -> print (); 
75  printf ("]");
76}
77
78
79/// Insertion into vector
80void CouenneSparseVector::add_element (int index, expression *elem) {
81
82  CouenneScalar *element = new CouenneScalar (index, elem);
83  elem_ . insert (element);
84}
85
86
87/// return size of (square sub-) matrix
88long unsigned int CouenneExprMatrix::size () 
89{return CoinMax (row_ . size (), col_ . size ());}
90
91/// used by add_elem below
92inline void check_and_insert (int indMaj, int indMin, 
93                              std::set <std::pair <int, CouenneSparseVector *>, CouenneExprMatrix::compare_pair_ind> &vecMaj, 
94                              expression *elem) {
95
96  std::          pair <int, CouenneSparseVector *> findme (indMaj, NULL);
97  std::set <std::pair <int, CouenneSparseVector *>,
98            CouenneExprMatrix::compare_pair_ind>::const_iterator check = vecMaj.find (findme);
99
100  if (check == vecMaj. end ()) {
101    std::pair <int, CouenneSparseVector *> new_vector (indMaj, new CouenneSparseVector);
102    new_vector.second -> add_element (indMin, elem);
103    vecMaj. insert (new_vector);
104  } else check -> second -> add_element (indMin, elem);
105}
106
107
108/// Insertion into matrix
109void CouenneExprMatrix::add_element (int rowInd, int colInd, expression *elem) {
110
111  check_and_insert (rowInd, colInd, row_, elem);
112  if (elem -> code () == COU_EXPRCONST) 
113    elem = new exprClone (elem);
114  check_and_insert (colInd, rowInd, col_, elem);
115}
116
117
118/// Dot product
119inline double CouenneSparseVector::operator * (const CouenneSparseVector &v2) const 
120{return multiply_thres (v2, COIN_DBL_MAX);}
121
122
123/// Threshold dot product
124double CouenneSparseVector::multiply_thres (const CouenneSparseVector &v2, double thres) const {
125
126  double prod = 0.;
127
128  for (register std::set <CouenneScalar *, CouenneSparseVector::compare_scalars>::const_iterator
129         i1 =    elem_. begin (),
130         i2 = v2.elem_. begin ();
131
132         ((i1 !=    elem_.end ()) && 
133          (i2 != v2.elem_.end ()));) {
134
135    while ((i1 !=    elem_.end ()) && ((*i1) -> getIndex () < (*i2) -> getIndex ())) ++i1; if (i1 ==     elem_. end ()) return prod;
136    while ((i2 != v2.elem_.end ()) && ((*i2) -> getIndex () < (*i1) -> getIndex ())) ++i2; if (i2 == v2. elem_. end ()) return prod;
137
138    prod += 
139      (*((*i1) -> getElem ())) () * 
140      (*((*i2) -> getElem ())) ();
141
142    if (prod > thres) 
143      break;
144  }
145
146  return prod;
147}
148
149
150/// vector * matrix
151CouenneSparseVector &CouenneSparseVector::operator * (const CouenneExprMatrix &post) const {
152
153  CouenneSparseVector *product = new CouenneSparseVector;
154
155  const std::set <std::pair <int, CouenneSparseVector *>, CouenneExprMatrix::compare_pair_ind> &columns = post. getCols ();
156
157  for (std::set <std::pair <int, CouenneSparseVector *>, CouenneExprMatrix::compare_pair_ind>::const_iterator colIt = columns. begin (); 
158       colIt != columns. end (); ++colIt) {
159
160    double single = operator* (*(colIt -> second));
161
162    if (single != 0.)
163      product -> add_element (colIt -> first, new exprConst (single));
164  }
165
166  return *product;
167}
168
169
170/// matrix * vector
171CouenneSparseVector &CouenneExprMatrix::operator * (const CouenneSparseVector &post) const {
172
173  CouenneSparseVector *product = new CouenneSparseVector;
174
175  for (std::set <std::pair <int, CouenneSparseVector *>, CouenneExprMatrix::compare_pair_ind>::const_iterator rowIt = row_. begin (); 
176       rowIt != row_. end (); ++rowIt) {
177
178    double single = post. operator* (*(rowIt -> second));
179
180    if (single != 0.)
181      product -> add_element (rowIt -> first, new exprConst (single));
182  }
183
184  return *product;
185}
186
187
188/// matrix * matrix
189CouenneExprMatrix &CouenneExprMatrix::operator * (const CouenneExprMatrix &post) const {
190
191  CouenneExprMatrix *product = new CouenneExprMatrix;
192  return *product;
193}
194
195/// Destructor
196CouenneExprMatrix::~CouenneExprMatrix () {
197
198  for (std::set <std::pair <int, CouenneSparseVector *>, CouenneExprMatrix::compare_pair_ind>::iterator
199         i  = row_ . begin ();
200       i   != row_ . end   (); ++i)
201
202    delete i -> second;
203
204  for (std::set <std::pair <int, CouenneSparseVector *>, CouenneExprMatrix::compare_pair_ind>::iterator
205         i  = col_ . begin ();
206       i   != col_ . end   (); ++i)
207
208    delete i -> second;
209}
210
211
212/// Destructor
213CouenneSparseVector::~CouenneSparseVector () {
214
215  for (register std::set <CouenneScalar *, CouenneSparseVector::compare_scalars>::iterator
216         i  = elem_. begin ();
217       i   != elem_. end   (); ++i)
218    delete (*i);
219}
220
221
222CouenneScalar::~CouenneScalar () 
223{delete elem_;} 
224
225#define WRAP 20
226
227/// Pretty print
228void CouenneSparseVector::print () const {
229
230  int cnt=0;
231
232  printf ("Vector (%ld) (", elem_ .  size ());
233
234  for (std::set <CouenneScalar *, CouenneSparseVector::compare_scalars>::const_iterator i = elem_ . begin (); 
235       i != elem_ . end (); ++i) {
236
237    if (i != elem_ . begin ())
238      printf (",");
239
240    (*i) -> print ();
241
242    if ((++cnt) % WRAP == 0)
243      printf ("\n   ");
244  }
245
246  printf (")");
247}
248
249
250/// Pretty print
251void CouenneExprMatrix::print () const {
252
253  printf ("Matrix (%ld x %ld):\n", 
254          row_ . size (), 
255          col_ . size ());
256
257  // print rows
258
259  for (std::set <std::pair <int, CouenneSparseVector *>, CouenneExprMatrix::compare_pair_ind>::const_iterator
260         i  = row_ . begin ();
261       i   != row_ . end (); ++i) {
262
263    printf ("Row [%d]: ", (*i) . first);
264    (*i) . second -> print ();
265    printf ("\n");
266  }
267
268  // print columns
269
270  for (std::set <std::pair <int, CouenneSparseVector *>, CouenneExprMatrix::compare_pair_ind>::const_iterator
271         i  = col_ . begin ();
272       i   != col_ . end (); ++i) {
273
274    printf ("Col [%d]: ", (*i) . first);
275    (*i) . second -> print ();
276    printf ("\n");
277  }
278
279  if (varIndices_ . size () > 0) {
280    printf ("varIndices: (");
281    for (std::vector <expression *>::const_iterator
282           i  = varIndices_ . begin (); 
283         i   != varIndices_ . end   (); ++i) {
284      if (i != varIndices_ . begin ())
285        printf (",");
286      (*i) -> print ();
287    }
288    printf (")\n");
289  }
290}
Note: See TracBrowser for help on using the repository browser.