CutGenSparse.cpp
Go to the documentation of this file.
1 /* $Id: CutGenSparse.cpp 960 2013-05-24 11:35:37Z pbelotti $
2  *
3  * Name: CutGenSparse.cpp
4  * Authors: Andrea Qualizza
5  * Pietro Belotti
6  * Purpose: Generation of sparse cuts
7  *
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #include "stdlib.h"
12 #include "stdio.h"
13 #include "math.h"
14 
15 #include "CoinTime.hpp"
16 #include "CoinHelperFunctions.hpp"
17 
19 #include "CouenneSdpCuts.hpp"
20 
21 #include "dsyevx_wrapper.hpp"
22 
23 #ifdef _WIN32
24 #define drand48() ((double) (rand () * (RAND_MAX + 1) + rand ()) / (RAND_MAX + 1) * (RAND_MAX + 1))
25 #endif
26 
27 //#define DEBUG
28 
29 const bool WISE_SPARSIFY = true;
30 
31 #define SPARSIFY_MAX_CARD 10000
32 #define WISE_SPARSIFY_GAP 0.0001
33 
34 #define SPARSIFY_OLD_DELTA 0.50
35 #define SPARSIFY_NEW_DELTA 0.50
36 
37 #define SPARSIFY_OLD_NZ_THRESHOLD 0.50
38 #define SPARSIFY_NEW_NZ_THRESHOLD 0.70
39 
40 #define EV_TOL 1e-13
41 
42 using namespace Couenne;
43 
44 /************************************************************************/
45 void CouenneSdpCuts::sparsify2 (const int n,
46  const double *A, double **sparse_v_mat,
47  int *card_v_mat, int min_nz, int *evdec_num) const {
48 
49  bool *del_idx = NULL;
50 
51  int
52  running_n = n,
53  best_idx,
54  rnsq = (running_n - 1) * (running_n - 1),
55  card_ev_best = running_n - 1;
56 
57  double
58 
59  *matrix = CoinCopyOfArray (A, n*n),
60 
61  best_val,
62 
63  *matrixCopy = CoinCopyOfArray (matrix, running_n * running_n),
64 
65  *T = new double [rnsq],
66  *Tcopy = new double [rnsq],
67  *Tbest = new double [rnsq],
68 
69  *wbest = new double [running_n - 1],
70  *zbest = new double [rnsq],
71 
72  *w = NULL,//new double [running_n - 1],
73  *z = NULL;//new double [rnsq];
74 
75  // remove one column/row at a time to get smaller and smaller minor
76 
77  while (running_n > 1) {
78 
79  rnsq = (running_n - 1) * (running_n - 1);
80 
81  best_val = 0.;
82  best_idx = -1;
83 
84  for (int k=0; k < running_n; ++k) {
85 
87 
88  for (int i=0, ii=0; i<running_n; i++) {
89 
90  if (i==k) continue;
91 
92  for (int j=0, jj=0; j<running_n; j++) {
93 
94  if (j==k) continue;
95 
96  int
97  idx1 = (running_n - 1) * ii + jj,
98  idx2 = (running_n - 1) * jj + ii;
99 
100  double val2 = matrixCopy [running_n*i + j];
101 
102  T [idx1] =
103  T [idx2] =
104  Tcopy [idx1] =
105  Tcopy [idx2] = val2;
106 
107  ++jj;
108  }
109 
110  ++ii;
111  }
112 
113  int card_ev;
114 
115  (*evdec_num)++;
116 
117  //--------------------------------------------------------------------------------------------------------------------------------
118  dsyevx_interface (running_n - 1, T, card_ev, w, z, EV_TOL, -COIN_DBL_MAX, 0., 1, (running_n - 1 == min_nz) ? (running_n - 1) : 1);
119  //--------------------------------------------------------------------------------------------------------------------------------
120 
121  double val = w [0]; // minimum eigenvalue
122 
123  if (val < best_val) {
124 
125  best_val = val;
126  best_idx = k;
127 
128  std::memcpy (Tbest, Tcopy, rnsq * sizeof (double));
129  std::memcpy (zbest, z, rnsq * sizeof (double));
130  std::memcpy (wbest, w, (running_n - 1) * sizeof (double));
131 
132  card_ev_best = card_ev;
133  }
134 
135  delete [] w;
136  delete [] z;
137 
138  w = z = NULL;
139  }
140 
141  // For this value of k, now we have in Tbest the best minor of size
142  // running_n
143 
144  if (best_idx >= 0) {
145 
146  if (del_idx == NULL) {
147  del_idx = new bool[n];
148  CoinFillN (del_idx, n, false);
149  }
150 
151  int cnt_idx_orig = 0;
152  int cnt_idx_minor = 0;
153 
154  while (cnt_idx_minor < running_n) {
155  if (del_idx [cnt_idx_orig] == false) {
156  if (cnt_idx_minor == best_idx) {
157  del_idx [cnt_idx_orig] = true;
158  break;
159  }
160 
161  cnt_idx_minor++;
162  }
163 
164  cnt_idx_orig++;
165  }
166 
167  if (running_n - 1 == min_nz) {
168 
169  for (int i=0; i < card_ev_best && wbest [i] < 0; i++) {
170 
171  CoinFillN (sparse_v_mat [i], n, 0.);
172 
173  double *curr_ev = zbest + i * (running_n - 1);
174 
175  for (int idx_orig = 0, idx_minor = 0; idx_orig < n; ++idx_orig)
176 
177  if (!(del_idx [idx_orig]))
178  sparse_v_mat [i] [idx_orig] = curr_ev [idx_minor++];
179 
180  ++ *card_v_mat;
181  }
182 
183  break; // done when reached min_nz dimension
184  }
185  }
186 
187  CoinCopyN (Tbest, (n-1) * (n-1), matrixCopy);
188 
189  --running_n;
190 
191  } // end while
192 
193  delete [] del_idx;
194 
195  delete [] z;
196  delete [] w;
197 
198  delete [] T;
199  delete [] Tcopy;
200  delete [] matrixCopy;
201 
202  delete [] Tbest;
203  delete [] zbest;
204  delete [] wbest;
205 
206  delete [] matrix;
207 } // sparsify2 ()
208 
209 
210 // Adds SDP cuts using negative eigenvectors where small (smaller than
211 // 1 / (10 sqrt n)) components are fixed to zero
212 
213 /************************************************************************/
214 void CouenneSdpCuts::additionalSDPcuts (const OsiSolverInterface &si,
215  OsiCuts &cs,
216  CouenneExprMatrix *minor,
217  int n,
218  const double *A,
219  const double *vector,
220  int **indA) const {
221  int
222  *indices = new int [n],
223  cnt = 0;
224 
225  double threshold = 1 / (10 * sqrt ((double) n));
226 
227  for (int i=0; i < n; i++)
228  indices [i] = ((fabs (vector [i]) > threshold) ? (cnt++) : -1);
229 
230  double *subA = new double [cnt*cnt];
231 
232  for (register int i=0, k=0; i<n; i++)
233 
234  if (indices [i] >= 0) {
235 
236  for (register int j=0, k2 = 0; j<n; j++)
237 
238  if (indices [j] >= 0) {
239  subA [cnt * k + k2] =
240  subA [cnt * k2 + k ] = A [n*i + j];
241  ++k2;
242  }
243 
244  ++k;
245  }
246 
247  double *w = NULL, *z = NULL;
248  int m;
249 
250  //printf ("calling dsyevx ADDITIONAL SDP CUTS\n");
251 
253  dsyevx_interface (cnt, subA, m, w, z, EV_TOL, -COIN_DBL_MAX, onlyNegEV_ ? 0. : COIN_DBL_MAX, 1, cnt);
255 
256  double
257  *v = new double [n],
258  *newv = new double [n];
259 
260  for (int k=0; k<m; k++) {
261 
262  if (onlyNegEV_ && (w [k] >= 0.))
263  break;
264 
265  double *zbase = z + k * cnt;
266 
267  for (int j=0; j<cnt; j++)
268  v [j] = *zbase++;
269 
270  for(int j=0; j<n; j++)
271  newv [j] = (indices [j] >= 0) ? v [indices [j]] : 0.;
272 
273  genSDPcut (si, cs, minor, newv, newv, indA);
274  }
275 
276  delete [] v;
277  delete [] newv;
278 
279  delete [] w;
280  delete [] z;
281 
282  delete [] subA;
283  delete [] indices;
284 } // additionalSDPcuts
285 
286 
287 /************************************************************************/
289  double* margin, double* A, double *lhs,
290  const int *zeroed, int evidx, bool decompose,
291  int *evdec_num) const {
292 
293  int minor_n = n;
294 
295  if (zeroed != NULL) {
296  for (int i=0; i<n; i++)
297  if (zeroed [i] == 0)
298  --minor_n;
299  }
300 
301  if (decompose && (minor_n > 2)) {
302 
303  /*
304  if (minor_n < n) {
305  add_v_cut(n, loc_selected, loc_card_selected, locv,
306  init_card_selected, &has_init_vect,
307  selected, &card_selected, &new_selected,
308  trace_bin, trace_bin_size,
309  sparse_v_mat, card_v_mat);
310  }
311  */
312 
313  (*evdec_num)++;
314 
315  double *minor_A = new double [n*n];
316  double *minor_w = new double [n];
317  double *minor_z = new double [n*n];
318 
319  // prepare active submatrix (induced by zeroed vector)
320 
321  int
322  ii = 0,
323  jj = 0;
324 
325  for (int i=0;i<n;i++) {
326  if (zeroed[i] == 0)
327  continue;
328 
329  jj = 0;
330 
331  for (int j=0;j<n;j++) {
332  if (zeroed [j] == 0)
333  continue;
334  minor_A [minor_n*ii + jj] = A [n * i + j];
335  jj++;
336  }
337 
338  ii++;
339  }
340 
341  int m;
342 
343  //printf ("calling dsyevx UPDATE_SPARSIFY_STRUCTURES\n");
344 
345  //----------------------------------------------------------------------------------------
346  dsyevx_interface (minor_n, minor_A, m, minor_w, minor_z, EV_TOL, -COIN_DBL_MAX, 0., 1, 1);
347  //----------------------------------------------------------------------------------------
348 
349  // update v (reindex the evidx-th eigenvector entries)
350  ii = 0;
351  for (int i=0;i<n;i++) {
352  v[i] = 0;
353  if (zeroed[i] == 0)
354  continue;
355  v[i] = minor_z[ii];
356  ii++;
357  }
358 
359  delete [] minor_A;
360  delete [] minor_w;
361  delete [] minor_z;
362  }
363 
364  for (int i=0; i<n; ++i)
365  for (int j=0; j<n; ++j) {
366  A [i*n + j] = //*= v[i] * v[j];
367  A [j*n + i] *= v[i] * v[j];
368  if ((zeroed != NULL) && (zeroed [j] == 0))
369  A [i*n + j] = A [j*n + i] = 0;
370  }
371 
372  *lhs = 0.;
373 
374  for (int i=0; i<n; i++) {
375 
376  margin[i] = 0;
377 
378  for(int j=0; j<n; j++)
379  margin[i] += A [i*n + j];
380 
381  *lhs += margin[i];
382  }
383 }
384 
385 
386 /************************************************************************/
387 void CouenneSdpCuts::zero_comp (const int ind_i,
388  const double delta,
389  const int n,
390  const int *selected,
391  int *loc_selected,
392  int *ploc_card_selected,
393  int *ploc_card_new_selected,
394  double *ploc_lhs,
395  double *locmargin,
396  double *locmat,
397  double *locv,
398  const int evidx,
399  bool wise,
400  int *evdec_num,
401  double *recomp_gap,
402  double *threshold) const {
403 
404  //double curr_lhs = (*ploc_lhs);
405  static int zerocount;
406  bool local_wise = false;
407  if (wise && (*ploc_lhs - delta > *threshold)) {
408  (*threshold) = (*ploc_lhs)-delta + (*recomp_gap);
409  local_wise = true;
410  }
411 
412  zerocount++;
413 
414  loc_selected[ind_i] = 0;
415  (*ploc_card_selected)--;
416 
417  if (selected [ind_i] != 1)
418  (*ploc_card_new_selected)--;
419 
420  (*ploc_lhs) -= delta;
421 
422  update_sparsify_structures (n,locv, locmargin, locmat, ploc_lhs, loc_selected, evidx, local_wise, evdec_num);
423 
424 }
425 
426 
427 /************************************************************************/
429  const int n,
430  const int *order,
431  const int *selected,
432  const int min_card_new_selected,
433  const double min_delta,
434  const int start_point,
435  const int curr_i,
436  int *loc_selected,
437  int *ploc_card_selected,
438  int *ploc_card_new_selected,
439  double *ploc_lhs,
440  double *locmargin,
441  double *locmat,
442  int *pnchanged,
443  double *locv,
444  const int evidx,
445  bool wise,
446  double *recomp_gap,
447  double *threshold,
448  int *evdec_num) const {
449 
450  int curr_ind = curr_i;
451 
452  *pnchanged = 0;
453  for (int i=0; i<n; i++) {
454 
455  if (++curr_ind == n)
456  curr_ind = 0;
457 
458  int ind_i = order[curr_ind];
459 
460  if (((type == POS_DELTA || type == VALID_DELTA) &&
461  ((((selected [ind_i] == 0) && (min_card_new_selected >= *ploc_card_new_selected)) ||
462  (curr_ind == start_point) ||
463  (loc_selected[ind_i] == 0))))
464  ||
465  ((type == SELECTED) &&
466  ((selected[ind_i] == 0) || (loc_selected[ind_i] == 0))))
467  continue;
468 
469  double delta = 2 * locmargin [ind_i] - locmat [ind_i * n + ind_i];
470  if (((type == VALID_DELTA || type == SELECTED) && (*ploc_lhs - delta < min_delta)) ||
471  ((type == POS_DELTA) && (delta > 0))) {
472 
473  zero_comp (ind_i, delta, n, selected, loc_selected,
474  ploc_card_selected, ploc_card_new_selected,
475  ploc_lhs, locmargin, locmat, locv, evidx, wise, evdec_num, recomp_gap, threshold);
476  (*pnchanged)++;
477  }
478  }
479 }
480 
481 
482 /************************************************************************/
484  const int *loc_selected,
485  const int loc_card_selected,
486  const double *locv,
487  const int init_card_selected, int *has_init_vect,
488  int *selected, int *pcard_selected,
489  int *pnew_selected,
490  double **sparse_v_mat,
491  int *pcard_v_mat) const {
492 
493  *pnew_selected = 0;
494 
495  for (int i=0; i<n; i++) {
496  if (loc_selected[i]) {
497  sparse_v_mat [*pcard_v_mat] [i] = locv [i];
498  if(selected[i] == 0) {
499  selected[i] = 1;
500  (*pcard_selected)++;
501  (*pnew_selected)++;
502  }
503  }
504  else
505  sparse_v_mat [*pcard_v_mat][i] = 0;
506  }
507 
508 #ifdef NORMALIZE_SPARSE_CUTS
509  //normalization (setting vector norm to 1)
510  double curr_norm = 0.0;
511  for (int i=0;i<n;i++) {
512  curr_norm += fabs(sparse_v_mat[*pcard_v_mat][i]);
513  }
514  for (int i=0;i<n;i++) {
515  if (sparse_v_mat[*pcard_v_mat][i] != 0.0)
516  sparse_v_mat[*pcard_v_mat][i] /= curr_norm;
517  }
518 #endif
519 
520  if (loc_card_selected + init_card_selected == n) {
521  if (*has_init_vect == 1) return;
522  else
523  (*has_init_vect) = 1;
524  }
525 
526  (*pcard_v_mat)++;
527 }
528 
529 
530 /************************************************************************/
531 void CouenneSdpCuts::sparsify (bool use_new_sparsify,
532  const int evidx, const double eigen_val,
533  const double *v, const int n,
534  const double *A, double **sparse_v_mat,
535  int *card_v_mat, int *evdec_num) const {
536 
537  int nchanged = 0,
538  min_number_new_per_cut = 1,
539  loc_card_new_selected = 0,
540  card_selected = 0,
541  loc_card_selected = 0,
542 
543  *selected = new int [n],
544  *loc_selected = new int [n],
545  *order = new int [n];
546 
547  double
548  min_delta,
549  is_zero = 1 / (10 * sqrt ((double) n)),
550  lhs = 0.,
551  loc_lhs = 0.,
552 
553  *margin = new double [n],
554  *locv = new double [n],
555  *locv_orig = new double [n],
556  *locmargin = new double [n],
557  *locmat = new double [n*n],
558  *mat = CoinCopyOfArray (A, n*n);
559 
560  *card_v_mat = 0;
561 
562  for (int i=0; i<n; i++) {
563 
564  order [i] = i;
565 
566  // zero small components in v
567  if (fabs (v[i]) < is_zero) {
568 
569  locv_orig [i] = 0;
570  selected [i] = -1; // -1: ind will be set to 0 in loc_selected
571  card_selected++;
572 
573  } else {
574  selected [i] = 0;
575  locv_orig [i] = v[i];
576  }
577  }
578 
580  for (int i=0; i<n; ++i) {
581 
582  int
583  newpos = i + (int) floor (((double) (n - i) - 1.e-3) * drand48 ()),
584  tmp = order [newpos];
585 
586  order [newpos] = order [i];
587  order [i] = tmp;
588  }
589 
590  // printf ("matrix:\n=================================\n");
591  // for (int i=0; i<n; ++i) {
592  // for (int j=0; j<n; ++j)
593  // printf ("%g ", mat [i*n+j]);
594  // printf ("\n");
595  // }
596  // printf ("=================================\n");
597 
598  update_sparsify_structures (n, locv_orig, margin, mat, &lhs, NULL, evidx, false, evdec_num);
599 
600  int
601  init_card_selected = card_selected, // to recognize if cut from original
602  has_init_vect = 0, // vector is generated
603  start_point = -1; // order [start_point]: index that should not be removed
604 
605  min_delta = lhs * (use_new_sparsify ? SPARSIFY_NEW_DELTA : SPARSIFY_OLD_DELTA); // do not weaken the cut too much
606 
607  while (card_selected < n) {
608 
609  for (int i=0; i<n; i++)
610 
611  if (selected [order [i]] == 0) {
612  start_point = i;
613  break;
614  }
615 
616  loc_card_selected = n;
617  loc_card_new_selected = n;
618  loc_lhs = lhs;
619 
620  double
621  recomp_gap = fabs (lhs * WISE_SPARSIFY_GAP),
622  threshold = lhs + recomp_gap;
623 
624  // restore locv (might have been changed by WISE_SPARSIFY during the generation of the last sparse cut)
625  CoinCopyN (locv_orig, n, locv);
626  CoinCopyN (mat, n*n, locmat);
627 
628  // printf ("LOCMAT :\n:::::::::::::::::::::::::::::::::\n");
629  // for (int i=0; i<n; ++i) {
630  // for (int j=0; j<n; ++j)
631  // printf ("%g ", locmat [i*n+j]);
632  // printf ("\n");
633  // }
634  // printf (":::::::::::::::::::::::::::::::::\n");
635 
636  for(int i=0; i<n; i++) {
637  if(selected[i] == -1) {
638  loc_selected[i] = 0;
639  loc_card_selected--;
640  loc_card_new_selected--;
641  } else {
642  loc_selected[i] = 1;
643 
644  if (selected[i] == 1)
645  loc_card_new_selected--;
646  }
647 
648  locmargin[i] = margin[i];
649  }
650 
651  if (loc_lhs >= min_delta) { // CASE 1 ////////////////////
652 
653  // use vector as is
654 
655  card_selected = n;
656 
657  if (onlyNegEV_) {
658 
659  int new_selected = 0;
660 
661  add_v_cut (n, loc_selected, loc_card_selected, locv,
662  init_card_selected, &has_init_vect,
663  selected, &card_selected, &new_selected,
664  sparse_v_mat, card_v_mat);
665  }
666 
667  } else { // CASE 2 ///////////////////////////////////////
668 
669  int changed = 1;
670 
671  while (changed) {
672 
673  int curr_i = start_point;
674 
675  changed = 0;
676 
677  int curr_nchanged = -1;
678 
679  while (curr_nchanged) {
680 
682  n, order, selected, min_number_new_per_cut,
683  min_delta, start_point,
684  curr_i, loc_selected,
685  &loc_card_selected, &loc_card_new_selected,
686  &loc_lhs, locmargin, locmat,
687  &curr_nchanged,locv,evidx, use_new_sparsify,
688  &recomp_gap,
689  &threshold,
690  evdec_num);
691 
692  if (curr_nchanged)
693  nchanged += curr_nchanged;
694  }
695 
696  curr_nchanged = -1;
697 
698  while (curr_nchanged) {
699 
701  n, order, selected, min_number_new_per_cut,
702  min_delta, // unused
703  start_point, start_point, loc_selected,
704  &loc_card_selected, &loc_card_new_selected,
705  &loc_lhs, locmargin, locmat,
706  &curr_nchanged,locv,evidx,use_new_sparsify, &recomp_gap,&threshold,
707  evdec_num);
708 
709  if (curr_nchanged) {
710  nchanged += curr_nchanged;
711  changed = 1;
712  }
713  } /* while(pos_nchanged != 0) */
714 
715  if (changed)
716  continue;
717 
718  curr_i = start_point;
719 
720  curr_nchanged = -1;
721 
722  if (curr_nchanged) {
723 
725  n, order, selected, min_number_new_per_cut,
726  min_delta, start_point,
727  curr_i, loc_selected,
728  &loc_card_selected, &loc_card_new_selected,
729  &loc_lhs, locmargin, locmat,
730  &curr_nchanged,locv,evidx, use_new_sparsify, &recomp_gap,&threshold,
731  evdec_num);
732 
733  if (curr_nchanged) {
734  nchanged += curr_nchanged;
735  changed = 1;
736  }
737  }
738  } /* while(changed) */
739 
740  if ((loc_card_selected < n * (use_new_sparsify ? SPARSIFY_NEW_NZ_THRESHOLD : SPARSIFY_OLD_NZ_THRESHOLD)) || (*card_v_mat == 0)) {
741 
742  int new_selected = 0;
743 
744  add_v_cut (n, loc_selected, loc_card_selected, locv,
745  init_card_selected, &has_init_vect,
746  selected, &card_selected, &new_selected,
747  sparse_v_mat, card_v_mat);
748  } else {
749  selected [order [start_point]] = 1;
750  card_selected++;
751  }
752  }
753  } /* while (card_selected < n) */
754 
755  delete[] order;
756 
757  delete [] mat;
758  delete [] locmat;
759 
760  delete[] locv;
761  delete[] locv_orig;
762  delete[] margin;
763  delete[] locmargin;
764 
765  delete[] selected;
766  delete[] loc_selected;
767 }
#define SPARSIFY_NEW_DELTA
void sparsify(bool sparsify_new, const int evidx, const double eigen_val, const double *v, const int n, const double *sol, double **sparse_v_mat, int *card_v_mat, int *evdec_num) const
void genSDPcut(const OsiSolverInterface &si, OsiCuts &cs, CouenneExprMatrix *XX, double *v1, double *v2, int **) const
Definition: CutGen.cpp:274
const bool WISE_SPARSIFY
Definition: CutGen.cpp:29
void char char int double int double double int int double int double double int double int int int int *int dsyevx_interface(int n, double *A, int &m, double *&w, double *&z, double tolerance, double lb_ev, double ub_ev, int firstidx, int lastidx)
#define WISE_SPARSIFY_GAP
#define SPARSIFY_NEW_NZ_THRESHOLD
void zero_unified(enum zero_type type, const int np, const int *order, const int *selected, const int min_card_new_selected, const double min_delta, const int start_point, const int curr_i, int *loc_selected, int *ploc_card_selected, int *ploc_card_new_selected, double *ploc_lhs, double *locmargin, double *locmat, int *pnchanged, double *locv, const int evidx, bool wise, double *recomp_gap, double *threshold, int *evdec_num) const
static char * j
Definition: OSdtoa.cpp:3622
void fint fint fint real fint real real real real real real real real real * e
void zero_comp(const int ind_i, const double delta, const int np, const int *selected, int *loc_selected, int *ploc_card_selected, int *ploc_card_new_selected, double *ploc_lhs, double *locmargin, double *locmat, double *locv, const int evidx, bool wise, int *evdec_num, double *recomp_gap, double *threshold) const
void fint fint * k
#define SPARSIFY_OLD_DELTA
#define EV_TOL
static int
Definition: OSdtoa.cpp:2173
#define SPARSIFY_OLD_NZ_THRESHOLD
void sparsify2(const int n, const double *A, double **sparse_v_mat, int *card_v_mat, int min_nz, int *evdec_num) const
void add_v_cut(const int np, const int *loc_selected, const int loc_card_selected, const double *locv, const int init_card_selected, int *has_init_vect, int *selected, int *pcard_selected, int *pnew_selected, double **sparse_v_mat, int *pcard_v_mat) const
void fint * m
void update_sparsify_structures(const int np, double *v, double *margin, double *A, double *lhs, const int *zeroed, int evidx, bool decompose, int *evdec_num) const
void additionalSDPcuts(const OsiSolverInterface &si, OsiCuts &cs, CouenneExprMatrix *minor, int np, const double *A, const double *vector, int **) const
void fint fint fint real fint real real real real real real real real * w
void fint * n
bool onlyNegEV_
only use negative eigenvalues (default: yes)