static scs_int factorize(const ScsMatrix *A, const ScsSettings *stgs, ScsLinSysWork *p) { scs_float *info; scs_int *Pinv, amd_status, ldl_status; cs *C, *K = form_kkt(A, stgs); if (!K) { return -1; } amd_status = _ldl_init(K, p->P, &info); if (amd_status < 0) { return (amd_status); } #if EXTRA_VERBOSE > 0 if (stgs->verbose) { scs_printf("Matrix factorization info:\n"); #ifdef DLONG amd_l_info(info); #else amd_info(info); #endif } #endif Pinv = SCS(cs_pinv)(p->P, A->n + A->m); C = SCS(cs_symperm)(K, Pinv, 1); ldl_status = _ldl_factor(C, SCS_NULL, SCS_NULL, &p->L, &p->D); SCS(cs_spfree)(C); SCS(cs_spfree)(K); scs_free(Pinv); scs_free(info); return (ldl_status); }
static void printInitHeader(Data * d, Work * w, Cone * k) { idxint i; char * coneStr = getConeHeader(k); char * linSysMethod = getLinSysMethod(d, w->p); _lineLen_ = -1; for (i = 0; i < HEADER_LEN; ++i) { _lineLen_ += (idxint) strlen(HEADER[i]) + 1; } for (i = 0; i < _lineLen_; ++i) { scs_printf("-"); } scs_printf("\n\tSCS v%s - Splitting Conic Solver\n\t(c) Brendan O'Donoghue, Stanford University, 2012\n", SCS_VERSION); for (i = 0; i < _lineLen_; ++i) { scs_printf("-"); } scs_printf("\n"); if (linSysMethod) { scs_printf("Lin-sys: %s\n", linSysMethod); scs_free(linSysMethod); } if (d->NORMALIZE) { scs_printf("EPS = %.2e, ALPHA = %.2f, MAX_ITERS = %i, NORMALIZE = %i, SCALE = %2.2f\n", d->EPS, d->ALPHA, (int) d->MAX_ITERS, (int) d->NORMALIZE, d->SCALE); } else { scs_printf("EPS = %.2e, ALPHA = %.2f, MAX_ITERS = %i, NORMALIZE = %i\n", d->EPS, d->ALPHA, (int) d->MAX_ITERS, (int) d->NORMALIZE); } scs_printf("Variables n = %i, constraints m = %i\n", (int) d->n, (int) d->m); scs_printf("%s", coneStr); scs_free(coneStr); #ifdef MATLAB_MEX_FILE mexEvalString("drawnow;"); #endif }
scs_int factorize(const AMatrix * A, const Settings * stgs, Priv * p) { scs_float *info; scs_int *Pinv, amd_status, ldl_status; cs *C, *K = formKKT(A, stgs); if (!K) { return -1; } amd_status = LDLInit(K, p->P, &info); if (amd_status < 0) return (amd_status); #if EXTRAVERBOSE > 0 if(stgs->verbose) { scs_printf("Matrix factorization info:\n"); #ifdef DLONG amd_l_info(info); #else amd_info(info); #endif } #endif Pinv = cs_pinv(p->P, A->n + A->m); C = cs_symperm(K, Pinv, 1); ldl_status = LDLFactor(C, NULL, NULL, &p->L, &p->D); cs_spfree(C); cs_spfree(K); scs_free(Pinv); scs_free(info); return (ldl_status); }
static void printFooter(Data * d, Work * w, Info * info) { idxint i; char * linSysStr = getLinSysSummary(w->p, info); char * coneStr = getConeSummary(info); for (i = 0; i < _lineLen_; ++i) { scs_printf("-"); } scs_printf("\nStatus: %s\n", info->status); if (info->iter == d->MAX_ITERS) { scs_printf("Hit MAX_ITERS, solution may be inaccurate\n"); } scs_printf("Timing: Total solve time: %1.2es\n", info->solveTime / 1e3); if (linSysStr) { scs_printf("%s", linSysStr); scs_free(linSysStr); } if (coneStr) { scs_printf("%s", coneStr); scs_free(coneStr); } for (i = 0; i < _lineLen_; ++i) { scs_printf("-"); } scs_printf("\n"); if (info->statusVal == INFEASIBLE) { scs_printf("Certificate of primal infeasibility:\n"); scs_printf("|A'y|_2 * |b|_2 = %.4e\n", info->resDual); scs_printf("dist(y, K*) = 0\n"); scs_printf("b'y = %.4f\n", info->dobj); } else if (info->statusVal == UNBOUNDED) { scs_printf("Certificate of dual infeasibility:\n"); scs_printf("|Ax + s|_2 * |c|_2 = %.4e\n", info->resPri); scs_printf("dist(s, K) = 0\n"); scs_printf("c'x = %.4f\n", info->pobj); } else { scs_printf("Error metrics:\n"); scs_printf("|Ax + s - b|_2 / (1 + |b|_2) = %.4e\n", info->resPri); scs_printf("|A'y + c|_2 / (1 + |c|_2) = %.4e\n", info->resDual); scs_printf("|c'x + b'y| / (1 + |c'x| + |b'y|) = %.4e\n", info->relGap); scs_printf("dist(s, K) = 0, dist(y, K*) = 0, s'y = 0\n"); for (i = 0; i < _lineLen_; ++i) { scs_printf("-"); } scs_printf("\n"); scs_printf("c'x = %.4f, -b'y = %.4f\n", info->pobj, info->dobj); } for (i = 0; i < _lineLen_; ++i) { scs_printf("="); } scs_printf("\n"); #ifdef MATLAB_MEX_FILE mexEvalString("drawnow;"); #endif }
void freePriv(Priv * p) { if (p) { if (p->L) cs_spfree(p->L); if (p->P) scs_free(p->P); if (p->D) scs_free(p->D); if (p->bp) scs_free(p->bp); scs_free(p); } }
void SCS(free_lin_sys_work)(ScsLinSysWork *p) { if (p) { if (p->L) { SCS(cs_spfree)(p->L); } if (p->P) { scs_free(p->P); } if (p->D) { scs_free(p->D); } if (p->bp) { scs_free(p->bp); } scs_free(p); } }
static void freePyData(Data *d, Cone *k, struct ScsPyData *ps) { if (ps->Ax) { Py_DECREF(ps->Ax); } if (ps->Ai) { Py_DECREF(ps->Ai); } if (ps->Ap) { Py_DECREF(ps->Ap); } if (ps->b) { Py_DECREF(ps->b); } if (ps->c) { Py_DECREF(ps->c); } if (k) { if (k->q) scs_free(k->q); if (k->s) scs_free(k->s); if (k->p) scs_free(k->p); scs_free(k); } if (d) { if (d->A) scs_free(d->A); if (d->stgs) scs_free(d->stgs); scs_free(d); } }
static scs_int _ldl_factor(cs *A, scs_int P[], scs_int Pinv[], cs **L, scs_float **D) { scs_int kk, n = A->n; scs_int *Parent = (scs_int *)scs_malloc(n * sizeof(scs_int)); scs_int *Lnz = (scs_int *)scs_malloc(n * sizeof(scs_int)); scs_int *Flag = (scs_int *)scs_malloc(n * sizeof(scs_int)); scs_int *Pattern = (scs_int *)scs_malloc(n * sizeof(scs_int)); scs_float *Y = (scs_float *)scs_malloc(n * sizeof(scs_float)); (*L)->p = (scs_int *)scs_malloc((1 + n) * sizeof(scs_int)); /*scs_int Parent[n], Lnz[n], Flag[n], Pattern[n]; */ /*scs_float Y[n]; */ LDL_symbolic(n, A->p, A->i, (*L)->p, Parent, Lnz, Flag, P, Pinv); (*L)->nzmax = *((*L)->p + n); (*L)->x = (scs_float *)scs_malloc((*L)->nzmax * sizeof(scs_float)); (*L)->i = (scs_int *)scs_malloc((*L)->nzmax * sizeof(scs_int)); *D = (scs_float *)scs_malloc(n * sizeof(scs_float)); if (!(*D) || !(*L)->i || !(*L)->x || !Y || !Pattern || !Flag || !Lnz || !Parent) { return -1; } #if EXTRA_VERBOSE > 0 scs_printf("numeric factorization\n"); #endif kk = LDL_numeric(n, A->p, A->i, A->x, (*L)->p, Parent, Lnz, (*L)->i, (*L)->x, *D, Y, Pattern, Flag, P, Pinv); #if EXTRA_VERBOSE > 0 scs_printf("finished numeric factorization\n"); #endif scs_free(Parent); scs_free(Lnz); scs_free(Flag); scs_free(Pattern); scs_free(Y); return (kk - n); }
static void transpose(const AMatrix * A, Priv * p) { scs_int * Ci = p->At->i; scs_int * Cp = p->At->p; scs_float * Cx = p->At->x; scs_int m = A->m; scs_int n = A->n; scs_int * Ap = A->p; scs_int * Ai = A->i; scs_float * Ax = A->x; scs_int i, j, q, *z, c1, c2; #if EXTRAVERBOSE > 0 timer transposeTimer; scs_printf("transposing A\n"); tic(&transposeTimer); #endif z = scs_calloc(m, sizeof(scs_int)); for (i = 0; i < Ap[n]; i++) z[Ai[i]]++; /* row counts */ cs_cumsum(Cp, z, m); /* row pointers */ for (j = 0; j < n; j++) { c1 = Ap[j]; c2 = Ap[j + 1]; for (i = c1; i < c2; i++) { q = z[Ai[i]]; Ci[q] = j; /* place A(i,j) as entry C(j,i) */ Cx[q] = Ax[i]; z[Ai[i]]++; } } scs_free(z); #if EXTRAVERBOSE > 0 scs_printf("finished transposing A, time: %1.2es\n", tocq(&transposeTimer) / 1e3); #endif }
SEXP scsr(SEXP data, SEXP cone, SEXP params) { scs_int len, num_protected = 0; SEXP ret, retnames, infor, xr, yr, sr; /* allocate memory */ Data *d = scs_malloc(sizeof(Data)); Cone *k = scs_malloc(sizeof(Cone)); Settings *stgs = scs_malloc(sizeof(Settings)); AMatrix *A = scs_malloc(sizeof(AMatrix)); Info *info = scs_calloc(1, sizeof(Info)); Sol *sol = scs_calloc(1, sizeof(Sol)); d->b = getFloatVectorFromList(data, "b", &len); d->c = getFloatVectorFromList(data, "c", &len); d->n = getIntFromListWithDefault(data, "n", 0); d->m = getIntFromListWithDefault(data, "m", 0); A->m = d->m; A->n = d->n; A->x = getFloatVectorFromList(data, "Ax", &len); A->i = getIntVectorFromList(data, "Ai", &len); A->p = getIntVectorFromList(data, "Ap", &len); d->A = A; stgs->max_iters = getIntFromListWithDefault(params, "max_iters", MAX_ITERS); stgs->normalize = getIntFromListWithDefault(params, "normalize", NORMALIZE); stgs->verbose = getIntFromListWithDefault(params, "verbose", VERBOSE); stgs->cg_rate = getFloatFromListWithDefault(params, "cg_rate", CG_RATE); stgs->scale = getFloatFromListWithDefault(params, "scale", SCALE); stgs->rho_x = getFloatFromListWithDefault(params, "rho_x", RHO_X); stgs->alpha = getFloatFromListWithDefault(params, "alpha", ALPHA); stgs->eps = getFloatFromListWithDefault(params, "eps", EPS); /* TODO add warm starting */ stgs->warm_start = getIntFromListWithDefault(params, "warm_start", WARM_START); d->stgs = stgs; k->f = getIntFromListWithDefault(cone, "f", 0); k->l = getIntFromListWithDefault(cone, "l", 0); k->ep = getIntFromListWithDefault(cone, "ep", 0); k->ed = getIntFromListWithDefault(cone, "ed", 0); k->q = getIntVectorFromList(cone, "q", &(k->qsize)); k->s = getIntVectorFromList(cone, "s", &(k->ssize)); k->p = getFloatVectorFromList(cone, "p", &(k->psize)); /* solve! */ scs(d, k, sol, info); infor = populateInfoR(info, &num_protected); PROTECT(ret = NEW_LIST(4)); num_protected++; PROTECT(retnames = NEW_CHARACTER(4)); num_protected++; SET_NAMES(ret, retnames); xr = floatVec2R(d->n, sol->x); num_protected++; yr = floatVec2R(d->m, sol->y); num_protected++; sr = floatVec2R(d->m, sol->s); num_protected++; SET_STRING_ELT(retnames, 0, mkChar("x")); SET_VECTOR_ELT(ret, 0, xr); SET_STRING_ELT(retnames, 1, mkChar("y")); SET_VECTOR_ELT(ret, 1, yr); SET_STRING_ELT(retnames, 2, mkChar("s")); SET_VECTOR_ELT(ret, 2, sr); SET_STRING_ELT(retnames, 3, mkChar("info")); SET_VECTOR_ELT(ret, 3, infor); /* free memory */ scs_free(info); scs_free(d); scs_free(k); scs_free(stgs); scs_free(A); freeSol(sol); UNPROTECT(num_protected); return ret; }
/* wrapper for free */ static void *cs_free(void *p) { if (p) { scs_free(p); } /* free p if it is not already SCS_NULL */ return (SCS_NULL); /* return SCS_NULL to simplify the use of cs_free */ }
static void freeWork(Work * w) { if (w) { if (w->u) scs_free(w->u); if (w->v) scs_free(w->v); if (w->u_t) scs_free(w->u_t); if (w->u_prev) scs_free(w->u_prev); if (w->h) scs_free(w->h); if (w->g) scs_free(w->g); if (w->D) scs_free(w->D); if (w->E) scs_free(w->E); if (w->pr) scs_free(w->pr); if (w->dr) scs_free(w->dr); scs_free(w); } }
/* wrapper for free */ static void *cs_free(void *p) { if (p) scs_free(p); /* free p if it is not already NULL */ return (NULL); /* return NULL to simplify the use of cs_free */ }
void freePriv(Priv * p) { if (p) { if (p->p) scs_free(p->p); if (p->r) scs_free(p->r); if (p->Gp) scs_free(p->Gp); if (p->tmp) scs_free(p->tmp); if (p->At) { AMatrix * At = p->At; if (At->i) scs_free(At->i); if (At->x) scs_free(At->x); if (At->p) scs_free(At->p); scs_free(At); } if (p->z) scs_free(p->z); if (p->M) scs_free(p->M); scs_free(p); } }