static void setSolution(Data * d, Work * w, Sol * sol, Info * info) { idxint l = d->n + d->m + 1; setx(d, w, sol); sety(d, w, sol); sets(d, w, sol); if (info->statusVal == 0 || info->statusVal == SOLVED) { pfloat tau = w->u[l - 1]; pfloat kap = ABS(w->v[l - 1]); if (tau > INDETERMINATE_TOL && tau > kap) { info->statusVal = solved(d, sol, info, tau); } else { if (calcNorm(w->u, l) < INDETERMINATE_TOL * SQRTF((pfloat) l)) { info->statusVal = indeterminate(d, sol, info); } else { pfloat bTy = innerProd(d->b, sol->y, d->m); pfloat cTx = innerProd(d->c, sol->x, d->n); if (bTy < cTx) { info->statusVal = infeasible(d, sol, info); } else { info->statusVal = unbounded(d, sol, info); } } } } else if (info->statusVal == INFEASIBLE) { info->statusVal = infeasible(d, sol, info); } else { info->statusVal = unbounded(d, sol, info); } }
static idxint converged(Data * d, Work * w, struct residuals * r, idxint iter) { pfloat nmpr, nmdr, tau, kap, *x, *y, cTx, nmAxs, bTy, nmATy, rpri, rdua, gap; idxint n = d->n, m = d->m; if (iter % CONVERGED_INTERVAL != 0) { return 0; } x = w->u; y = &(w->u[n]); tau = ABS(w->u[n + m]); kap = ABS(w->v[n + m]) / (d->NORMALIZE ? (d->SCALE * w->sc_c * w->sc_b) : 1); r->tau = tau; r->kap = kap; /* requires mult by A: nmpr = calcPrimalResid(d, w, w->u, &(w->v[n]), ABS(w->u[n + m]), &nmAxs); */ /* does not require mult by A: */ nmpr = fastCalcPrimalResid(d, w, &nmAxs); cTx = innerProd(x, d->c, n) / (d->NORMALIZE ? (d->SCALE * w->sc_c * w->sc_b) : 1); r->resPri = cTx < 0 ? w->nm_c * nmAxs / -cTx : NAN; if (r->resPri < d->EPS) { return UNBOUNDED; } nmdr = calcDualResid(d, w, y, tau, &nmATy); bTy = innerProd(y, d->b, m) / (d->NORMALIZE ? (d->SCALE * w->sc_c * w->sc_b) : 1); r->resDual = bTy < 0 ? w->nm_b * nmATy / -bTy : NAN; if (r->resDual < d->EPS) { return INFEASIBLE; } r->cTx = cTx / tau; r->bTy = bTy / tau; r->relGap = NAN; rpri = nmpr / (1 + w->nm_b) / tau; rdua = nmdr / (1 + w->nm_c) / tau; gap = ABS(cTx + bTy) / (tau + ABS(cTx) + ABS(bTy)); if (tau > kap) { r->resPri = rpri; r->resDual = rdua; r->relGap = gap; } return (MAX(MAX(rpri,rdua),gap) < d->EPS ? SOLVED : 0); }
// Feature transformation to PCA, whitening or Fisher subspace void MQDFTEST::featureTrans( unsigned char* ftr, int dim, float* input ) { float *shx; shx = new float [dim]; powerTrans( ftr, dim, power, shx ); int i; for( i=0; i<dim; i++ ) shx[i] -= gmean[i]; // shift with respect to gross mean int j; float proj, euclid; if( residual ) { euclid = 0; for( i=0; i<dim; i++ ) euclid += shx[i]*shx[i]; } for( j=0; j<redDim; j++ ) { proj = innerProd( shx, trbasis+j*dim, dim ); if( residual ) euclid -= proj*proj; input[j] = proj*dscale1 ; } if( residual ) input[redDim] = euclid*dscale1*dscale1 ; delete []shx; }
static void updateWork(Data * d, Work * w, Sol * sol) { /* before normalization */ idxint n = d->n; idxint m = d->m; w->nm_b = calcNorm(d->b, m); w->nm_c = calcNorm(d->c, n); #ifdef EXTRAVERBOSE printArray(d->b, d->m, "b"); scs_printf("pre-normalized norm b = %4f\n", calcNorm(d->b, d->m)); printArray(d->c, d->n, "c"); scs_printf("pre-normalized norm c = %4f\n", calcNorm(d->c, d->n)); #endif if (d->NORMALIZE) { normalizeBC(d, w); #ifdef EXTRAVERBOSE printArray(d->b, d->m, "bn"); scs_printf("sc_b = %4f\n", w->sc_b); scs_printf("post-normalized norm b = %4f\n", calcNorm(d->b, d->m)); printArray(d->c, d->n, "cn"); scs_printf("sc_c = %4f\n", w->sc_c); scs_printf("post-normalized norm c = %4f\n", calcNorm(d->c, d->n)); #endif } if (d->WARM_START) { warmStartVars(d, w, sol); } else { coldStartVars(d, w); } memcpy(w->h, d->c, n * sizeof(pfloat)); memcpy(&(w->h[d->n]), d->b, m * sizeof(pfloat)); memcpy(w->g, w->h, (n + m) * sizeof(pfloat)); solveLinSys(d, w->p, w->g, NULL, -1); scaleArray(&(w->g[d->n]), -1, m); w->gTh = innerProd(w->h, w->g, n + m); }
/* status < 0 indicates failure */ static idxint projectLinSys(Data * d, Work * w, idxint iter) { /* ut = u + v */ idxint n = d->n, m = d->m, l = n + m + 1, status; memcpy(w->u_t, w->u, l * sizeof(pfloat)); addScaledArray(w->u_t, w->v, l, 1.0); scaleArray(w->u_t, d->RHO_X, n); addScaledArray(w->u_t, w->h, l - 1, -w->u_t[l - 1]); addScaledArray(w->u_t, w->h, l - 1, -innerProd(w->u_t, w->g, l - 1) / (w->gTh + 1)); scaleArray(&(w->u_t[n]), -1, m); status = solveLinSys(d, w->p, w->u_t, w->u, iter); w->u_t[l - 1] += innerProd(w->u_t, w->h, l - 1); return status; }
static void getInfo(Data * d, Work * w, Sol * sol, Info * info) { pfloat cTx, bTy, nmAxs, nmATy, nmpr, nmdr; pfloat * x = sol->x, *y = sol->y, *s = sol->s; /* unNomalized */ nmpr = calcPrimalResid(d, w, x, s, 1, &nmAxs); /* pr = Ax + s - b */ nmdr = calcDualResid(d, w, y, 1, &nmATy); /* dr = A'y + c */ cTx = innerProd(x, d->c, d->n); bTy = innerProd(y, d->b, d->m); if (d->NORMALIZE) { cTx /= (d->SCALE * w->sc_c * w->sc_b); bTy /= (d->SCALE * w->sc_c * w->sc_b); } info->pobj = cTx; info->dobj = -bTy; if (info->statusVal == SOLVED) { info->relGap = ABS(cTx + bTy) / (1 + ABS(cTx) + ABS(bTy)); info->resPri = nmpr / (1 + w->nm_b); info->resDual = nmdr / (1 + w->nm_c); } else { if (info->statusVal == UNBOUNDED) { info->dobj = NAN; info->relGap = NAN; info->resPri = w->nm_c * nmAxs / -cTx; info->resDual = NAN; scaleArray(x, -1 / cTx, d->n); scaleArray(s, -1 / cTx, d->m); info->pobj = -1; } else { info->pobj = NAN; info->relGap = NAN; info->resPri = NAN; info->resDual = w->nm_b * nmATy / -bTy; scaleArray(y, -1 / bTy, d->m); info->dobj = -1; } } }
static void cgCustom(Data *d, Work *w, const double * s, int max_its, double tol) { /* solves (I+A'A)x = b */ /* warm start cg with s */ int i = 0, n = d->n; double *x = w->p->x; double *p = w->p->p; // cg direction double *Ap = w->p->Ap; // updated CG direction double *r = w->p->r; // cg residual double *G = w->p->G; // Gram matrix double alpha, beta, rsnew=0; if (s==NULL) { memset(x,0,n*sizeof(double)); } else { memcpy(x,s,n*sizeof(double)); cblas_dsymv(CblasColMajor, CblasUpper,n, -1, G, n, x,1, 1, r, 1); //b_dsymv('U', n, -1, G, n, x,1, 1, r, 1); } memcpy(p, r, n*sizeof(double)); //double rsold=cblas_dnrm2(n,r,1); double rsold=calcNorm(r,n); for (i=0; i< max_its; i++) { cblas_dsymv(CblasColMajor, CblasUpper,n, 1, G, n, p, 1, 0, Ap, 1); //b_dsymv('U', n, 1, G, n, p, 1, 0, Ap, 1); //beta = cblas_ddot(n, p, 1, Ap, 1); beta = innerProd(p,Ap,n); alpha=(rsold*rsold)/beta; addScaledArray(x,p,n,alpha); //cblas_daxpy(n,alpha,p,1,x,1); addScaledArray(r,Ap,n,-alpha); //cblas_daxpy(n,-alpha,Ap,1,r,1); //rsnew=cblas_dnrm2(n,r,1); rsnew=calcNorm(r,n); if (rsnew<tol) { break; } scaleArray(p,(rsnew*rsnew)/(rsold*rsold),n); //cblas_dscal(n,(rsnew*rsnew)/(rsold*rsold),p,1); addScaledArray(p,r,n,1); //cblas_daxpy(n,1,r,1,p,1); rsold=rsnew; } //printf("terminating cg residual = %4f, took %i itns\n",rsnew,i); }
static scs_int pcg(const AMatrix * A, const Settings * stgs, Priv * pr, const scs_float * s, scs_float * b, scs_int max_its, scs_float tol) { scs_int i, n = A->n; scs_float ipzr, ipzrOld, alpha; scs_float *p = pr->p; /* cg direction */ scs_float *Gp = pr->Gp; /* updated CG direction */ scs_float *r = pr->r; /* cg residual */ scs_float *z = pr->z; /* for preconditioning */ scs_float *M = pr->M; /* inverse diagonal preconditioner */ if (s == NULL) { memcpy(r, b, n * sizeof(scs_float)); memset(b, 0, n * sizeof(scs_float)); } else { matVec(A, stgs, pr, s, r); addScaledArray(r, b, n, -1); scaleArray(r, -1, n); memcpy(b, s, n * sizeof(scs_float)); } /* check to see if we need to run CG at all */ if (calcNorm(r, n) < MIN(tol, 1e-18)) { return 0; } applyPreConditioner(M, z, r, n, &ipzr); memcpy(p, z, n * sizeof(scs_float)); for (i = 0; i < max_its; ++i) { matVec(A, stgs, pr, p, Gp); alpha = ipzr / innerProd(p, Gp, n); addScaledArray(b, p, n, alpha); addScaledArray(r, Gp, n, -alpha); if (calcNorm(r, n) < tol) { #if EXTRAVERBOSE > 0 scs_printf("tol: %.4e, resid: %.4e, iters: %li\n", tol, calcNorm(r, n), (long) i+1); #endif return i + 1; } ipzrOld = ipzr; applyPreConditioner(M, z, r, n, &ipzr); scaleArray(p, ipzr / ipzrOld, n); addScaledArray(p, z, n, 1); } return i; }
void MQDFTEST::MQDF( float* ftr, int dim, float* eudist, short* preIdx, int rank1, float* qdmin, short* index, int rankNum ) { int k; for( k=0; k<rankNum; k++ ) qdmin[k] = (float)1E12+k; float euclid; float* shx; shx = new float [dim]; int cls, i, m; float proj; float qdist, tdist; int pos, kt; for( int ri=0; ri<rankN1; ri++ ) { if( preIdx ) cls = preIdx[ri]; else cls = ri; for( i=0; i<dim; i++ ) shx[i] = (float)ftr[i]-means[cls*dim+i]; if( preIdx ) euclid = eudist[ri]; else { euclid = 0; for( i=0; i<dim; i++ ) euclid += shx[i]*shx[i]; } qdist = loglambda[cls]; kt = knum[cls]; // truncated knum if( kt==dim ) kt -= 1; for( m=0; m<kt; m++ ) { proj = innerProd( shx, phi[cls]+m*dim, dim ); euclid -= proj*proj; qdist += proj*proj/lambda[cls][m]; tdist = qdist+euclid/lambda[cls][m+1]; // increasing sequence if( tdist>=qdmin[rankNum-1] ) break; } qdist = tdist; if( qdist<qdmin[rankNum-1] ) { pos = posAscd( qdist, qdmin, rankNum ); for( k=rankNum-1; k>pos; k-- ) { qdmin[k] = qdmin[k-1]; index[k] = index[k-1]; } qdmin[pos] = qdist; index[pos] = cls; } } delete shx; }
int main(int argc, char **argv) { scs_int n, m, col_nnz, nnz, i, q_total, q_num_rows, max_q; Cone * k; Data * d; Sol * sol, * opt_sol; Info info = { 0 }; scs_float p_f, p_l; int seed = 0; /* default parameters */ p_f = 0.1; p_l = 0.3; seed = time(SCS_NULL); switch (argc) { case 5: seed = atoi(argv[4]); /* no break */ case 4: p_f = atof(argv[2]); p_l = atof(argv[3]); /* no break */ case 2: n = atoi(argv[1]); break; default: scs_printf("usage:\t%s n p_f p_l s\n" "\tcreates an SOCP with n variables where p_f fraction of rows correspond\n" "\tto equality constraints, p_l fraction of rows correspond to LP constraints,\n" "\tand the remaining percentage of rows are involved in second-order\n" "\tcone constraints. the random number generator is seeded with s.\n" "\tnote that p_f + p_l should be less than or equal to 1, and that\n" "\tp_f should be less than .33, since that corresponds to as many equality\n" "\tconstraints as variables.\n", argv[0]); scs_printf("\nusage:\t%s n p_f p_l\n" "\tdefaults the seed to the system time\n", argv[0]); scs_printf("\nusage:\t%s n\n" "\tdefaults to using p_f = 0.1 and p_l = 0.3\n", argv[0]); return 0; } srand(seed); scs_printf("seed : %i\n", seed); k = scs_calloc(1, sizeof(Cone)); d = scs_calloc(1, sizeof(Data)); d->stgs = scs_calloc(1, sizeof(Settings)); sol = scs_calloc(1, sizeof(Sol)); opt_sol = scs_calloc(1, sizeof(Sol)); m = 3 * n; col_nnz = (int) ceil(sqrt(n)); nnz = n * col_nnz; max_q = (scs_int) ceil(3 * n / log(3 * n)); if (p_f + p_l > 1.0) { printf("error: p_f + p_l > 1.0!\n"); return 1; } k->f = (scs_int) floor(3 * n * p_f); k->l = (scs_int) floor(3 * n * p_l); k->qsize = 0; q_num_rows = 3 * n - k->f - k->l; k->q = scs_malloc(q_num_rows * sizeof(scs_int)); while (q_num_rows > max_q) { int size; size = (rand() % max_q) + 1; k->q[k->qsize] = size; k->qsize++; q_num_rows -= size; } if (q_num_rows > 0) { k->q[k->qsize] = q_num_rows; k->qsize++; } q_total = 0; for (i = 0; i < k->qsize; i++) { q_total += k->q[i]; } k->s = SCS_NULL; k->ssize = 0; k->ep = 0; k->ed = 0; scs_printf("\nA is %ld by %ld, with %ld nonzeros per column.\n", (long) m, (long) n, (long) col_nnz); scs_printf("A has %ld nonzeros (%f%% dense).\n", (long) nnz, 100 * (scs_float) col_nnz / m); scs_printf("Nonzeros of A take %f GB of storage.\n", ((scs_float) nnz * sizeof(scs_float)) / POWF(2, 30)); scs_printf("Row idxs of A take %f GB of storage.\n", ((scs_float) nnz * sizeof(scs_int)) / POWF(2, 30)); scs_printf("Col ptrs of A take %f GB of storage.\n\n", ((scs_float) n * sizeof(scs_int)) / POWF(2, 30)); printf("Cone information:\n"); printf("Zero cone rows: %ld\n", (long) k->f); printf("LP cone rows: %ld\n", (long) k->l); printf("Number of second-order cones: %ld, covering %ld rows, with sizes\n[", (long) k->qsize, (long) q_total); for (i = 0; i < k->qsize; i++) { printf("%ld, ", (long) k->q[i]); } printf("]\n"); printf("Number of rows covered is %ld out of %ld.\n\n", (long) (q_total + k->f + k->l), (long) m); /* set up SCS structures */ d->m = m; d->n = n; genRandomProbData(nnz, col_nnz, d, k, opt_sol); setDefaultSettings(d); scs_printf("true pri opt = %4f\n", innerProd(d->c, opt_sol->x, d->n)); scs_printf("true dua opt = %4f\n", -innerProd(d->b, opt_sol->y, d->m)); /* solve! */ scs(d, k, sol, &info); scs_printf("true pri opt = %4f\n", innerProd(d->c, opt_sol->x, d->n)); scs_printf("true dua opt = %4f\n", -innerProd(d->b, opt_sol->y, d->m)); if (sol->x) { scs_printf("scs pri obj= %4f\n", innerProd(d->c, sol->x, d->n)); } if (sol->y) { scs_printf("scs dua obj = %4f\n", -innerProd(d->b, sol->y, d->m)); } freeData(d, k); freeSol(sol); freeSol(opt_sol); return 0; }