15 #include "CoinTime.hpp"
16 #include "CoinHelperFunctions.hpp"
24 #define drand48() ((double) (rand () * (RAND_MAX + 1) + rand ()) / (RAND_MAX + 1) * (RAND_MAX + 1))
31 #define SPARSIFY_MAX_CARD 10000
32 #define WISE_SPARSIFY_GAP 0.0001
34 #define SPARSIFY_OLD_DELTA 0.50
35 #define SPARSIFY_NEW_DELTA 0.50
37 #define SPARSIFY_OLD_NZ_THRESHOLD 0.50
38 #define SPARSIFY_NEW_NZ_THRESHOLD 0.70
42 using namespace Couenne;
46 const double *A,
double **sparse_v_mat,
47 int *card_v_mat,
int min_nz,
int *evdec_num)
const {
54 rnsq = (running_n - 1) * (running_n - 1),
55 card_ev_best = running_n - 1;
59 *matrix = CoinCopyOfArray (A, n*n),
63 *matrixCopy = CoinCopyOfArray (matrix, running_n * running_n),
65 *T =
new double [rnsq],
66 *Tcopy =
new double [rnsq],
67 *Tbest =
new double [rnsq],
69 *wbest =
new double [running_n - 1],
70 *zbest =
new double [rnsq],
77 while (running_n > 1) {
79 rnsq = (running_n - 1) * (running_n - 1);
84 for (
int k=0;
k < running_n; ++
k) {
88 for (
int i=0, ii=0; i<running_n; i++) {
92 for (
int j=0, jj=0;
j<running_n;
j++) {
97 idx1 = (running_n - 1) * ii + jj,
98 idx2 = (running_n - 1) * jj + ii;
100 double val2 = matrixCopy [running_n*i +
j];
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);
123 if (val < best_val) {
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));
132 card_ev_best = card_ev;
146 if (del_idx == NULL) {
147 del_idx =
new bool[
n];
148 CoinFillN (del_idx, n,
false);
151 int cnt_idx_orig = 0;
152 int cnt_idx_minor = 0;
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;
167 if (running_n - 1 == min_nz) {
169 for (
int i=0; i < card_ev_best && wbest [i] < 0; i++) {
171 CoinFillN (sparse_v_mat [i], n, 0.);
173 double *curr_ev = zbest + i * (running_n - 1);
175 for (
int idx_orig = 0, idx_minor = 0; idx_orig <
n; ++idx_orig)
177 if (!(del_idx [idx_orig]))
178 sparse_v_mat [i] [idx_orig] = curr_ev [idx_minor++];
187 CoinCopyN (Tbest, (n-1) * (n-1), matrixCopy);
200 delete [] matrixCopy;
219 const double *vector,
222 *indices =
new int [
n],
225 double threshold = 1 / (10 * sqrt ((
double) n));
227 for (
int i=0; i <
n; i++)
228 indices [i] = ((fabs (vector [i]) > threshold) ? (cnt++) : -1);
230 double *subA =
new double [cnt*cnt];
232 for (
register int i=0,
k=0; i<
n; i++)
234 if (indices [i] >= 0) {
236 for (
register int j=0, k2 = 0;
j<
n;
j++)
238 if (indices [
j] >= 0) {
239 subA [cnt *
k + k2] =
240 subA [cnt * k2 +
k ] = A [n*i +
j];
247 double *
w = NULL, *z = NULL;
258 *newv =
new double [
n];
260 for (
int k=0;
k<
m;
k++) {
265 double *zbase = z +
k * cnt;
267 for (
int j=0;
j<cnt;
j++)
270 for(
int j=0;
j<
n;
j++)
271 newv [
j] = (indices [
j] >= 0) ? v [indices [
j]] : 0.;
273 genSDPcut (si, cs, minor, newv, newv, indA);
289 double* margin,
double* A,
double *lhs,
290 const int *zeroed,
int evidx,
bool decompose,
291 int *evdec_num)
const {
295 if (zeroed != NULL) {
296 for (
int i=0; i<
n; i++)
301 if (decompose && (minor_n > 2)) {
315 double *minor_A =
new double [n*
n];
316 double *minor_w =
new double [
n];
317 double *minor_z =
new double [n*
n];
325 for (
int i=0;i<
n;i++) {
331 for (
int j=0;
j<
n;
j++) {
334 minor_A [minor_n*ii + jj] = A [n * i +
j];
351 for (
int i=0;i<
n;i++) {
364 for (
int i=0; i<
n; ++i)
365 for (
int j=0;
j<
n; ++
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;
374 for (
int i=0; i<
n; i++) {
378 for(
int j=0;
j<
n;
j++)
379 margin[i] += A [i*n +
j];
392 int *ploc_card_selected,
393 int *ploc_card_new_selected,
405 static int zerocount;
406 bool local_wise =
false;
407 if (wise && (*ploc_lhs - delta > *threshold)) {
408 (*threshold) = (*ploc_lhs)-delta + (*recomp_gap);
414 loc_selected[ind_i] = 0;
415 (*ploc_card_selected)--;
417 if (selected [ind_i] != 1)
418 (*ploc_card_new_selected)--;
420 (*ploc_lhs) -= delta;
432 const int min_card_new_selected,
433 const double min_delta,
434 const int start_point,
437 int *ploc_card_selected,
438 int *ploc_card_new_selected,
448 int *evdec_num)
const {
450 int curr_ind = curr_i;
453 for (
int i=0; i<
n; i++) {
458 int ind_i = order[curr_ind];
461 ((((selected [ind_i] == 0) && (min_card_new_selected >= *ploc_card_new_selected)) ||
462 (curr_ind == start_point) ||
463 (loc_selected[ind_i] == 0))))
466 ((selected[ind_i] == 0) || (loc_selected[ind_i] == 0))))
469 double delta = 2 * locmargin [ind_i] - locmat [ind_i * n + ind_i];
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);
484 const int *loc_selected,
485 const int loc_card_selected,
487 const int init_card_selected,
int *has_init_vect,
488 int *selected,
int *pcard_selected,
490 double **sparse_v_mat,
491 int *pcard_v_mat)
const {
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) {
505 sparse_v_mat [*pcard_v_mat][i] = 0;
508 #ifdef NORMALIZE_SPARSE_CUTS
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]);
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;
520 if (loc_card_selected + init_card_selected == n) {
521 if (*has_init_vect == 1)
return;
523 (*has_init_vect) = 1;
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 {
538 min_number_new_per_cut = 1,
539 loc_card_new_selected = 0,
541 loc_card_selected = 0,
543 *selected =
new int [
n],
544 *loc_selected =
new int [
n],
545 *order =
new int [
n];
549 is_zero = 1 / (10 * sqrt ((
double) n)),
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);
562 for (
int i=0; i<
n; i++) {
567 if (fabs (v[i]) < is_zero) {
575 locv_orig [i] = v[i];
580 for (
int i=0; i<
n; ++i) {
583 newpos = i + (
int) floor (((
double) (n - i) - 1.
e-3) * drand48 ()),
584 tmp = order [newpos];
586 order [newpos] = order [i];
601 init_card_selected = card_selected,
607 while (card_selected < n) {
609 for (
int i=0; i<
n; i++)
611 if (selected [order [i]] == 0) {
616 loc_card_selected =
n;
617 loc_card_new_selected =
n;
625 CoinCopyN (locv_orig, n, locv);
626 CoinCopyN (mat, n*n, locmat);
636 for(
int i=0; i<
n; i++) {
637 if(selected[i] == -1) {
640 loc_card_new_selected--;
644 if (selected[i] == 1)
645 loc_card_new_selected--;
648 locmargin[i] = margin[i];
651 if (loc_lhs >= min_delta) {
659 int new_selected = 0;
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);
673 int curr_i = start_point;
677 int curr_nchanged = -1;
679 while (curr_nchanged) {
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,
693 nchanged += curr_nchanged;
698 while (curr_nchanged) {
701 n, order, selected, min_number_new_per_cut,
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,
710 nchanged += curr_nchanged;
718 curr_i = start_point;
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,
734 nchanged += curr_nchanged;
742 int new_selected = 0;
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);
749 selected [order [start_point]] = 1;
766 delete[] loc_selected;
#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
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
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
#define SPARSIFY_OLD_DELTA
#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 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
bool onlyNegEV_
only use negative eigenvalues (default: yes)