Re: Patch for pseudocost branching with product score
Chris Matrakidis <[email protected]>
| Newsgroups | gmane.comp.gnu.glpk |
|---|---|
| Message-ID | <CAEaJ3S6aWJcpx1EOm+43Fh+i-XczGYThmu0rZfweSqnhvSfOZg@mail.gmail.com> |
Hi Andrew, > At first I'd like to finish the dual simplex routines (including your > patch from May 2016), and then inspect and implement your improvements > related to the mip solver. This patch is orthogonal to any changes in the simplex solver, and shouldn't affect the default behaviour. So, if you are worried that it will be hard to evaluate the changes to the simplex solver between the releases, I think it is safe. > BTW, how did you implement bfd_copy? I missed that. I'm re-sending the relevant patch, which adds a copy operation in each factorisation driver and the bfd_copy function that uses them. The copy operations reuse existing allocations in the destination when possible. Best Regards, Chris Matrakidis _______________________________________________ Help-glpk mailing list [email protected] https://lists.gnu.org/mailman/listinfo/help-glpk
pcost2.patch
(application/octet-stream, 19.5 KB)
diff --git a/src/bfd.c b/src/bfd.c
index dece376..89d547a 100644
--- a/src/bfd.c
+++ b/src/bfd.c
@@ -541,4 +541,44 @@ void bfd_delete_it(BFD *bfd)
return;
}
+void bfd_copy(BFD *dst, BFD *src)
+{ /* copy LP basis factorization */
+#ifdef GLP_DEBUG
+ int i;
+#endif
+ xassert(dst != NULL);
+ dst->valid = src->valid;
+ dst->type = src->type;
+ dst->parm = src->parm;
+ dst->upd_cnt = src->upd_cnt;
+ dst->i_norm = src->i_norm;
+#ifdef GLP_DEBUG
+ if (dst->B != NULL)
+ spm_delete_mat(dst->B);
+ dst->B = spm_create_mat(src->B->m, src->B->n);
+ for (i = 1; i <= src->B->m; i++)
+ { SPME *e;
+ for (e = src->B->row[i]; e != NULL; e = e->r_next)
+ spm_new_elem(dst->B, i, e->j, e->val);
+ }
+#endif
+ switch (dst->type)
+ { case 0:
+ break;
+ case 1:
+ if (dst->u.fhvi == NULL)
+ dst->u.fhvi = fhvint_create();
+ fhvint_copy(dst->u.fhvi, src->u.fhvi);
+ break;
+ case 2:
+ if (dst->u.scfi == NULL)
+ dst->u.scfi = scfint_create(src->u.scfi->scf.type);
+ scfint_copy(dst->u.scfi, src->u.scfi);
+ break;
+ default:
+ xassert(dst != dst);
+ }
+ return;
+}
+
/* eof */
diff --git a/src/bfd.h b/src/bfd.h
index 0ef4c02..3f63099 100644
--- a/src/bfd.h
+++ b/src/bfd.h
@@ -102,6 +102,10 @@ int bfd_get_count(BFD *bfd);
void bfd_delete_it(BFD *bfd);
/* delete LP basis factorization */
+#define bfd_copy _glp_bfd_copy
+void bfd_copy(BFD *dst, BFD *src);
+/* copy LP basis factorization */
+
#endif
/* eof */
diff --git a/src/bflib/btfint.c b/src/bflib/btfint.c
index 378d3a8..f4c0123 100644
--- a/src/bflib/btfint.c
+++ b/src/bflib/btfint.c
@@ -404,4 +404,100 @@ void btfint_delete(BTFINT *fi)
return;
}
+void btfint_copy(BTFINT *dst, BTFINT *src)
+{ /* copy interface to BT-factorization */
+ int n, n_max;
+ n = src->btf->n;
+ n_max = dst->n_max;
+ if (n > n_max)
+ { n_max = dst->n_max = src->n_max;
+ if (dst->btf != NULL)
+ { tfree(dst->btf->pp_ind);
+ tfree(dst->btf->pp_inv);
+ tfree(dst->btf->qq_ind);
+ tfree(dst->btf->qq_inv);
+ tfree(dst->btf->beg);
+ tfree(dst->btf->vr_piv);
+ tfree(dst->btf->p1_ind);
+ tfree(dst->btf->p1_inv);
+ tfree(dst->btf->q1_ind);
+ tfree(dst->btf->q1_inv);
+ }
+ else
+ dst->btf = talloc(1, BTF);
+ dst->btf->pp_ind = talloc(1+n_max, int);
+ dst->btf->pp_inv = talloc(1+n_max, int);
+ dst->btf->qq_ind = talloc(1+n_max, int);
+ dst->btf->qq_inv = talloc(1+n_max, int);
+ dst->btf->beg = talloc(1+n_max+1, int);
+ dst->btf->vr_piv = talloc(1+n_max, double);
+ dst->btf->p1_ind = talloc(1+n_max, int);
+ dst->btf->p1_inv = talloc(1+n_max, int);
+ dst->btf->q1_ind = talloc(1+n_max, int);
+ dst->btf->q1_inv = talloc(1+n_max, int);
+ if (dst->sgf != NULL)
+ { tfree(dst->sgf->rs_head);
+ tfree(dst->sgf->rs_prev);
+ tfree(dst->sgf->rs_next);
+ tfree(dst->sgf->cs_head);
+ tfree(dst->sgf->cs_prev);
+ tfree(dst->sgf->cs_next);
+ tfree(dst->sgf->vr_max);
+ tfree(dst->sgf->flag);
+ tfree(dst->sgf->work);
+ }
+ else
+ dst->sgf = talloc(1, SGF);
+ dst->sgf->rs_head = talloc(1+n_max, int);
+ dst->sgf->rs_prev = talloc(1+n_max, int);
+ dst->sgf->rs_next = talloc(1+n_max, int);
+ dst->sgf->cs_head = talloc(1+n_max, int);
+ dst->sgf->cs_prev = talloc(1+n_max, int);
+ dst->sgf->cs_next = talloc(1+n_max, int);
+ dst->sgf->vr_max = talloc(1+n_max, double);
+ dst->sgf->flag = talloc(1+n_max, char);
+ dst->sgf->work = talloc(1+n_max, double);
+ }
+ dst->valid = src->valid;
+ dst->sva_n_max = src->sva_n_max;
+ dst->sva_size = src->sva_size;
+ dst->delta_n0 = src->delta_n0;
+ dst->delta_n = src->delta_n;
+ dst->sgf_piv_tol = src->sgf_piv_tol;
+ dst->sgf_piv_lim = src->sgf_piv_lim;
+ dst->sgf_suhl = src->sgf_suhl;
+ dst->sgf_eps_tol = src->sgf_eps_tol;
+ if (dst->sva == NULL)
+ dst->sva = sva_create_area(src->sva->n_max, src->sva->size);
+ sva_copy_area(dst->sva, src->sva);
+ dst->btf->n = n;
+ dst->btf->num =src->btf->num;
+ dst->btf->ar_ref = src->btf->ar_ref;
+ dst->btf->ac_ref = src->btf->ac_ref;
+ dst->btf->fr_ref = src->btf->fr_ref;
+ dst->btf->fc_ref = src->btf->fc_ref;
+ dst->btf->vr_ref = src->btf->vr_ref;
+ dst->btf->vc_ref = src->btf->vc_ref;
+ memcpy(dst->btf->vr_piv, src->btf->vr_piv,
+ (1+n) * sizeof(double));
+ memcpy(dst->btf->pp_ind, src->btf->pp_ind,(1+n) * sizeof(int));
+ memcpy(dst->btf->pp_inv, src->btf->pp_inv, (1+n) * sizeof(int));
+ memcpy(dst->btf->qq_ind, src->btf->qq_ind, (1+n) * sizeof(int));
+ memcpy(dst->btf->qq_inv, src->btf->qq_inv, (1+n) * sizeof(int));
+ memcpy(dst->btf->beg, src->btf->beg,
+ (1+src->btf->num+1) * sizeof(int));
+ memcpy(dst->btf->p1_ind, src->btf->p1_ind, (1+n) * sizeof(int));
+ memcpy(dst->btf->p1_inv, src->btf->p1_inv, (1+n) * sizeof(int));
+ memcpy(dst->btf->q1_ind, src->btf->q1_ind, (1+n) * sizeof(int));
+ memcpy(dst->btf->q1_inv, src->btf->q1_inv, (1+n) * sizeof(int));
+ dst->btf->sva = dst->sva;
+ dst->sgf->luf = src->sgf->luf;
+ dst->sgf->updat = src->sgf->updat;
+ dst->sgf->piv_tol = src->sgf->piv_tol;
+ dst->sgf->piv_lim = src->sgf->piv_lim;
+ dst->sgf->suhl = src->sgf->suhl;
+ dst->sgf->eps_tol = src->sgf->eps_tol;
+ return;
+}
+
/* eof */
diff --git a/src/bflib/btfint.h b/src/bflib/btfint.h
index 8d0e70e..0bfb9cf 100644
--- a/src/bflib/btfint.h
+++ b/src/bflib/btfint.h
@@ -68,6 +68,10 @@ int btfint_factorize(BTFINT *fi, int n, int (*col)(void *info, int j,
void btfint_delete(BTFINT *fi);
/* delete interface to BT-factorization */
+#define btfint_copy _glp_btfint_copy
+void btfint_copy(BTFINT *dst, BTFINT *src);
+/* copy interface to BT-factorization */
+
#endif
/* eof */
diff --git a/src/bflib/fhvint.c b/src/bflib/fhvint.c
index a21b71c..40852f8 100644
--- a/src/bflib/fhvint.c
+++ b/src/bflib/fhvint.c
@@ -165,4 +165,51 @@ void fhvint_delete(FHVINT *fi)
return;
}
+void fhvint_copy(FHVINT *dst, FHVINT *src)
+{ /* copy interface to FHV-factorization */
+ int nfs_max, n_max, n, nfs;
+ nfs_max = dst->nfs_max;
+ nfs = src->fhv.nfs;
+ n_max = (dst->lufi != NULL) ? dst->lufi->n_max : 0;
+ n = src->lufi->luf->n;
+ if(nfs_max < nfs)
+ { nfs_max = src->nfs_max;
+ if (dst->fhv.hh_ind != NULL)
+ { tfree(dst->fhv.hh_ind);
+ dst->fhv.hh_ind = NULL;
+ }
+ }
+ if(n_max < n)
+ { n_max = src->lufi->n_max;
+ if (dst->fhv.p0_ind != NULL)
+ { tfree(dst->fhv.p0_ind);
+ dst->fhv.p0_ind = NULL;
+ }
+ if (dst->fhv.p0_inv != NULL)
+ { tfree(dst->fhv.p0_inv);
+ dst->fhv.p0_inv = NULL;
+ }
+ }
+ if (dst->fhv.hh_ind == NULL)
+ dst->fhv.hh_ind = talloc(1+nfs_max, int);
+ if (dst->fhv.p0_ind == NULL)
+ dst->fhv.p0_ind = talloc(1+n_max, int);
+ if (dst->fhv.p0_inv == NULL)
+ dst->fhv.p0_inv = talloc(1+n_max, int);
+ if (src->fhv.hh_ind != NULL)
+ memcpy(dst->fhv.hh_ind, src->fhv.hh_ind,
+ (1+nfs) * sizeof(int));
+ if (src->fhv.p0_ind != NULL)
+ memcpy(dst->fhv.p0_ind, src->fhv.p0_ind, (1+n) * sizeof(int));
+ if (src->fhv.p0_inv != NULL)
+ memcpy(dst->fhv.p0_inv, src->fhv.p0_inv, (1+n) * sizeof(int));
+ dst->valid = src->valid;
+ dst->fhv.nfs_max = nfs_max;
+ dst->fhv.nfs = nfs;
+ dst->fhv.hh_ref = src->fhv.hh_ref;
+ dst->nfs_max = nfs_max;
+ lufint_copy(dst->lufi, src->lufi);
+ dst->fhv.luf = dst->lufi->luf;
+ return;
+}
/* eof */
diff --git a/src/bflib/fhvint.h b/src/bflib/fhvint.h
index 000829c..73a78b6 100644
--- a/src/bflib/fhvint.h
+++ b/src/bflib/fhvint.h
@@ -73,6 +73,10 @@ double fhvint_estimate(FHVINT *fi);
void fhvint_delete(FHVINT *fi);
/* delete interface to FHV-factorization */
+#define fhvint_copy _glp_fhvint_copy
+void fhvint_copy(FHVINT *dst, FHVINT *src);
+/* copy interface to FHV-factorization */
+
#endif
/* eof */
diff --git a/src/bflib/lufint.c b/src/bflib/lufint.c
index 7cd0092..07b67f9 100644
--- a/src/bflib/lufint.c
+++ b/src/bflib/lufint.c
@@ -179,4 +179,82 @@ void lufint_delete(LUFINT *fi)
return;
}
+void lufint_copy(LUFINT *dst, LUFINT *src)
+{ /* copy interface to LU-factorization */
+ int n, n_max;
+ n = src->luf->n;
+ n_max = dst->n_max;
+ if (n > n_max)
+ { n_max = dst->n_max = src->n_max;
+ if (dst->luf != NULL)
+ { tfree(dst->luf->vr_piv);
+ tfree(dst->luf->pp_ind);
+ tfree(dst->luf->pp_inv);
+ tfree(dst->luf->qq_ind);
+ tfree(dst->luf->qq_inv);
+ }
+ else
+ dst->luf = talloc(1, LUF);
+ dst->luf->vr_piv = talloc(1+n_max, double);
+ dst->luf->pp_ind = talloc(1+n_max, int);
+ dst->luf->pp_inv = talloc(1+n_max, int);
+ dst->luf->qq_ind = talloc(1+n_max, int);
+ dst->luf->qq_inv = talloc(1+n_max, int);
+ if (dst->sgf != NULL)
+ { tfree(dst->sgf->rs_head);
+ tfree(dst->sgf->rs_prev);
+ tfree(dst->sgf->rs_next);
+ tfree(dst->sgf->cs_head);
+ tfree(dst->sgf->cs_prev);
+ tfree(dst->sgf->cs_next);
+ tfree(dst->sgf->vr_max);
+ tfree(dst->sgf->flag);
+ tfree(dst->sgf->work);
+ }
+ else
+ dst->sgf = talloc(1, SGF);
+ dst->sgf->rs_head = talloc(1+n_max, int);
+ dst->sgf->rs_prev = talloc(1+n_max, int);
+ dst->sgf->rs_next = talloc(1+n_max, int);
+ dst->sgf->cs_head = talloc(1+n_max, int);
+ dst->sgf->cs_prev = talloc(1+n_max, int);
+ dst->sgf->cs_next = talloc(1+n_max, int);
+ dst->sgf->vr_max = talloc(1+n_max, double);
+ dst->sgf->flag = talloc(1+n_max, char);
+ dst->sgf->work = talloc(1+n_max, double);
+ }
+ dst->valid = src->valid;
+ dst->sva_n_max = src->sva_n_max;
+ dst->sva_size = src->sva_size;
+ dst->delta_n0 = src->delta_n0;
+ dst->delta_n = src->delta_n;
+ dst->sgf_updat = src->sgf_updat;
+ dst->sgf_piv_tol = src->sgf_piv_tol;
+ dst->sgf_piv_lim = src->sgf_piv_lim;
+ dst->sgf_suhl = src->sgf_suhl;
+ dst->sgf_eps_tol = src->sgf_eps_tol;
+ if (dst->sva == NULL)
+ dst->sva = sva_create_area(src->sva->n_max, src->sva->size);
+ sva_copy_area(dst->sva, src->sva);
+ dst->luf->n = n;
+ dst->luf->fr_ref = src->luf->fr_ref;
+ dst->luf->fc_ref = src->luf->fc_ref;
+ dst->luf->vr_ref = src->luf->vr_ref;
+ dst->luf->vc_ref = src->luf->vc_ref;
+ memcpy(dst->luf->vr_piv, src->luf->vr_piv,
+ (1+n) * sizeof(double));
+ memcpy(dst->luf->pp_ind, src->luf->pp_ind, (1+n) * sizeof(int));
+ memcpy(dst->luf->pp_inv, src->luf->pp_inv, (1+n) * sizeof(int));
+ memcpy(dst->luf->qq_ind, src->luf->qq_ind, (1+n) * sizeof(int));
+ memcpy(dst->luf->qq_inv, src->luf->qq_inv, (1+n) * sizeof(int));
+ dst->luf->sva = dst->sva;
+ dst->sgf->luf = dst->luf;
+ dst->sgf->updat = src->sgf->updat;
+ dst->sgf->piv_tol = src->sgf->piv_tol;
+ dst->sgf->piv_lim = src->sgf->piv_lim;
+ dst->sgf->suhl = src->sgf->suhl;
+ dst->sgf->eps_tol = src->sgf->eps_tol;
+ return;
+}
+
/* eof */
diff --git a/src/bflib/lufint.h b/src/bflib/lufint.h
index b3ad5b6..f57caa8 100644
--- a/src/bflib/lufint.h
+++ b/src/bflib/lufint.h
@@ -68,6 +68,10 @@ int lufint_factorize(LUFINT *fi, int n, int (*col)(void *info, int j,
void lufint_delete(LUFINT *fi);
/* delete interface to LU-factorization */
+#define lufint_copy _glp_lufint_copy
+void lufint_copy(LUFINT *dst, LUFINT *src);
+/* copy interface to LU-factorization */
+
#endif
/* eof */
diff --git a/src/bflib/scfint.c b/src/bflib/scfint.c
index 06aa8f7..25aed12 100644
--- a/src/bflib/scfint.c
+++ b/src/bflib/scfint.c
@@ -252,4 +252,103 @@ void scfint_delete(SCFINT *fi)
return;
}
+void scfint_copy(SCFINT *dst, SCFINT *src)
+{ /* copy interface to SC-factorization */
+ int n0_max, old_n0_max, nn_max, n0, nn, k, n;
+ xassert(src->scf.type == dst->scf.type);
+ switch (src->scf.type)
+ { case 1:
+ old_n0_max = dst->u.lufi->n_max;
+ lufint_copy(dst->u.lufi, src->u.lufi);
+ n0_max = dst->u.lufi->n_max;
+ n0 = dst->u.lufi->luf->n;
+ dst->scf.sva = dst->u.lufi->sva;
+ dst->scf.a0.luf = dst->u.lufi->luf;
+ break;
+ case 2:
+ old_n0_max = dst->u.btfi->n_max;
+ btfint_copy(dst->u.btfi, src->u.btfi);
+ n0_max = dst->u.btfi->n_max;
+ n0 = dst->u.btfi->btf->n;
+ dst->scf.sva = dst->u.btfi->sva;
+ dst->scf.a0.btf = dst->u.btfi->btf;
+ break;
+ default:
+ xassert(dst != dst);
+ }
+ /* allocate/reallocate arrays, if necessary */
+ if (old_n0_max < n0_max)
+ { if (dst->w1 != NULL)
+ tfree(dst->w1);
+ if (dst->w2 != NULL)
+ tfree(dst->w2);
+ if (dst->w3 != NULL)
+ tfree(dst->w3);
+ dst->w1 = talloc(1+n0_max, double);
+ dst->w2 = talloc(1+n0_max, double);
+ dst->w3 = talloc(1+n0_max, double);
+ }
+ nn_max = dst->scf.nn_max;
+ nn = src->scf.nn;
+ if (nn > nn_max)
+ { nn_max = src->scf.nn_max;
+ if (dst->scf.ifu.f != NULL)
+ tfree(dst->scf.ifu.f);
+ if (dst->scf.ifu.u != NULL)
+ tfree(dst->scf.ifu.u);
+ dst->scf.ifu.f = talloc(nn_max * nn_max, double);
+ dst->scf.ifu.u = talloc(nn_max * nn_max, double);
+ }
+ n = src->scf.ifu.n;
+ if (src->scf.ifu.f != NULL)
+ for (k = 0; k < n; k++)
+ memcpy(dst->scf.ifu.f + k, src->scf.ifu.f + k,
+ n * sizeof(double));
+ if (src->scf.ifu.u != NULL)
+ for (k = 0; k < n; k++)
+ memcpy(dst->scf.ifu.u + k, src->scf.ifu.u + k,
+ n * sizeof(double));
+ if (old_n0_max < n0_max || dst->scf.nn_max != nn_max)
+ { if (dst->scf.pp_ind != NULL)
+ tfree(dst->scf.pp_ind);
+ if (dst->scf.pp_inv != NULL)
+ tfree(dst->scf.pp_inv);
+ if (dst->scf.qq_ind != NULL)
+ tfree(dst->scf.qq_ind);
+ if (dst->scf.qq_inv != NULL)
+ tfree(dst->scf.qq_inv);
+ if (dst->w4 != NULL)
+ tfree(dst->w4);
+ if (dst->w5 != NULL)
+ tfree(dst->w5);
+ dst->scf.pp_ind = talloc(1+n0_max+nn_max, int);
+ dst->scf.pp_inv = talloc(1+n0_max+nn_max, int);
+ dst->scf.qq_ind = talloc(1+n0_max+nn_max, int);
+ dst->scf.qq_inv = talloc(1+n0_max+nn_max, int);
+ dst->w4 = talloc(1+n0_max+nn_max, double);
+ dst->w5 = talloc(1+n0_max+nn_max, double);
+ }
+ k = src->scf.n0 + src->scf.nn;
+ if (src->scf.pp_ind != NULL)
+ memcpy(dst->scf.pp_ind, src->scf.pp_ind, (1+k) * sizeof(int));
+ if (src->scf.pp_inv != NULL)
+ memcpy(dst->scf.pp_inv, src->scf.pp_inv, (1+k) * sizeof(int));
+ if (src->scf.qq_ind != NULL)
+ memcpy(dst->scf.qq_ind, src->scf.qq_ind, (1+k) * sizeof(int));
+ if (src->scf.qq_inv != NULL)
+ memcpy(dst->scf.qq_inv, src->scf.qq_inv, (1+k) * sizeof(int));
+ /* copy SC-factorization */
+ dst->scf.n = src->scf.n;
+ dst->scf.n0 = src->scf.n0;
+ dst->scf.nn_max = nn_max;
+ dst->scf.nn = src->scf.nn;
+ dst->scf.rr_ref = src->scf.rr_ref;
+ dst->scf.ss_ref = src->scf.ss_ref;
+ dst->scf.ifu.n_max = nn_max;
+ dst->scf.ifu.n = src->scf.ifu.n;
+ dst->nn_max = src->nn_max;
+ dst->valid = src->valid;
+ return;
+}
+
/* eof */
diff --git a/src/bflib/scfint.h b/src/bflib/scfint.h
index 3e56355..67ca65d 100644
--- a/src/bflib/scfint.h
+++ b/src/bflib/scfint.h
@@ -84,6 +84,10 @@ double scfint_estimate(SCFINT *fi);
void scfint_delete(SCFINT *fi);
/* delete interface to SC-factorization */
+#define scfint_copy _glp_scfint_copy
+void scfint_copy(SCFINT *dst, SCFINT *src);
+/* copy interface to SC-factorization */
+
#endif
/* eof */
diff --git a/src/bflib/sva.c b/src/bflib/sva.c
index e6a675c..bcf8336 100644
--- a/src/bflib/sva.c
+++ b/src/bflib/sva.c
@@ -569,4 +569,73 @@ void sva_delete_area(SVA *sva)
return;
}
+/***********************************************************************
+* sva_copy_area - copy sparse vector area (SVA)
+*
+* This routine copies a sparse vector area (SVA) into another avoiding
+* new memory allocations if possible */
+
+void sva_copy_area(SVA *dst, SVA *src)
+{ int size, req, delta, k, n, n_max, ptr, len, r_ptr;
+ size = dst->size;
+ r_ptr = src->r_ptr;
+ req = src->m_ptr + src->size + 1 - r_ptr;
+ if (req >= size)
+ { size = dst->size = src->size;
+ tfree(dst->ind);
+ tfree(dst->val);
+ dst->ind = talloc(1+size, int);
+ dst->val = talloc(1+size, double);
+ }
+ delta = size - src->size;
+ n = src->n;
+ n_max = dst->n_max;
+ if (n >= n_max)
+ { n_max = dst->n_max = src->n_max;
+ tfree(dst->ptr);
+ tfree(dst->len);
+ tfree(dst->cap);
+ tfree(dst->prev);
+ tfree(dst->next);
+ dst->ptr = talloc(1+n_max, int);
+ dst->len = talloc(1+n_max, int);
+ dst->cap = talloc(1+n_max, int);
+ dst->prev = talloc(1+n_max, int);
+ dst->next = talloc(1+n_max, int);
+ }
+ dst->n = src->n;
+ dst->m_ptr = src->m_ptr;
+ dst->r_ptr = src->r_ptr + delta;
+ dst->head = src->head;
+ dst->tail = src->tail;
+ dst->talky = src->talky;
+ memcpy(dst->ptr, src->ptr, (1+n) * sizeof(int));
+ memcpy(dst->len, src->len, (1+n) * sizeof(int));
+ memcpy(dst->cap, src->cap, (1+n) * sizeof(int));
+ memcpy(dst->prev, src->prev, (1+n) * sizeof(int));
+ memcpy(dst->next, src->next, (1+n) * sizeof(int));
+ /* use linked list to copy the vectors in the left part */
+ for (k = src->head; k != 0; k = src->next[k])
+ { ptr = src->ptr[k];
+ len = src->len[k];
+ memcpy(dst->ind + ptr, src->ind + ptr, len * sizeof(int));
+ memcpy(dst->val + ptr, src->val + ptr, len * sizeof(double));
+ }
+ /* copy right part and adjust pointers for delta */
+ if (r_ptr <= src->size)
+ { len = src->size + 1 - r_ptr;
+ memcpy(dst->ind + r_ptr + delta, src->ind + r_ptr,
+ len * sizeof(int));
+ memcpy(dst->val + r_ptr + delta, src->val + r_ptr,
+ len * sizeof(double));
+ if (delta != 0)
+ { for (k = 1; k <= n; k++)
+ { if (dst->ptr[k] >= r_ptr)
+ dst->ptr[k] += delta;
+ }
+ }
+ }
+ return;
+}
+
/* eof */
diff --git a/src/bflib/sva.h b/src/bflib/sva.h
index 0eab317..f632a6d 100644
--- a/src/bflib/sva.h
+++ b/src/bflib/sva.h
@@ -156,6 +156,10 @@ void sva_check_area(SVA *sva);
void sva_delete_area(SVA *sva);
/* delete sparse vector area (SVA) */
+#define sva_copy_area _glp_sva_copy_area
+void sva_copy_area(SVA *dst, SVA *src);
+/* copy sparse vector area (SVA) */
+
#endif
/* eof */