void AmplTMINLP::write_solution(const std::string & message, const Number *x_sol) { ASL_pfgh* asl = ampl_tnlp_->AmplSolverObject(); DBG_ASSERT(asl); // DBG_ASSERT(x_sol); // We need to copy the message into a non-const char array to make // it work with the AMPL C function. char* cmessage = new char[message.length()+1]; strcpy(cmessage, message.c_str()); // In order to avoid casting into non-const, we copy the data here... double* x_sol_copy = NULL; if (x_sol) { x_sol_copy = new double[n_var]; for (int i=0; i<n_var; i++) { x_sol_copy[i] = x_sol[i]; } } write_sol(cmessage, x_sol_copy, NULL, NULL); delete [] x_sol_copy; delete [] cmessage; }
int con_branching() { CONSTRAINT *row0,*row1; double old_lowerb = lowerb; #ifdef STAMP std::cout << " >>>>>>>>>>>>> constraint branching " << std::endl; if(branchs==0) write_sol(fsolution); #endif if( upperb < ceil(lowerb-ZERO)+ZERO ) return(1); //// constraint_branching(nbetter,better,&row0,&row1); constraint_branching(nsupport,support,&row0,&row1); if( upperb < ceil(lowerb-ZERO)+ZERO ) return(1); if(row0==NULL && row1==NULL)return(-1); if(row0==NULL || row1==NULL)return(0); /*** to do not use the branch-cuts ***/ //// return(-1); branchs++; #ifdef STAMP std::cout << "branching " << branchs << " on constraint" << std::endl; #endif /* making the left child */ row0->stat = LP_BA; add_rows(1,&row0); lowerb = solve_lp(0); get_solution(); get_base(); write_prob(); deletelastrow(); row0->stat = FIX_LB; /* making the left child */ row1->stat = LP_BA; add_rows(1,&row1); lowerb = solve_lp(0); get_solution(); get_base(); write_prob(); deletelastrow(); row1->stat = FIX_LB; lowerb = old_lowerb; return(1); }
void AmplTNLP::write_solution_file(const std::string& message) const { ASL_pfgh* asl = asl_; DBG_ASSERT(asl); DBG_ASSERT(x_sol_ && lambda_sol_); // We need to copy the message into a non-const char array to make // it work with the AMPL C function. char* cmessage = new char[message.length()+1]; strcpy(cmessage, message.c_str()); write_sol(cmessage, x_sol_, lambda_sol_, (Option_Info*)Oinfo_ptr_); delete [] cmessage; }
void ampl_write_solution(double *varsX, double *Yelts,double *Zelts ) { double *dualWrk = (double*) malloc(n_con*sizeof(double)); int i; for( int iampl = 0; iampl < n_con; iampl++ ) { if( amplRowMap[iampl]<0 ) { i = - ( amplRowMap[iampl] + 1 ); // Recover i from the negative value if(Yelts) dualWrk[iampl] = Yelts[i]; else dualWrk[iampl] = 0; } else { i = amplRowMap[iampl]; if(Zelts) dualWrk[iampl] = Zelts[i]; else dualWrk[iampl] = 0; } } write_sol("\npipsnlp_serial:", varsX, dualWrk,NULL); free(dualWrk); }
int var_branching() { VARIABLE *col; double old_lowerb = lowerb; #ifdef STAMP std::cout << " >>>>>>>>>>>>> var branching " << std::endl; if(branchs==0) write_sol(fsolution); #endif if( upperb-ZERO < ceil(lowerb-ZERO) ) return(1); col = variable_branching(BETTERLP); if( upperb-ZERO < ceil(lowerb-ZERO) ) return(1); if(col==NULL) return(0); #ifdef STAMP std::cout << branchs << " on variable " << col->index << "=" << col->val << std::endl; #endif branchs++; /* making the left child */ if( ceil( solve_child_col( col , (double)0 , 1)-ZERO) < upperb-ZERO ) { col->stat = FIX_LB; write_prob(); } /* making the left child */ if( ceil( solve_child_col( col , (double)1 , 1)-ZERO) < upperb-ZERO ) { col->stat = FIX_UB; write_prob(); } lowerb = old_lowerb; return(1); }
void MAIN__(void) { FILE *nl; fint *iv, liv, lv; fint N, NZ, P; real *rhsLU, *v; int i, j; extern int xargc; extern char **xargv; char *stub; static fint L1 = 1; static char *rvmsg[9] = { "X-Convergence", /* 3 */ "Relative Function Convergence", "X- and Relative Function Convergence", "Absolute Function Convergence", "Singular Convergence", "False Convergence", "Function Evaluation Limit", "Iteration Limit", "Unexpected return code" }; char buf[256]; if (xargc < 2) { fprintf(Stderr, "usage: %s stub\n", xargv[0]); exit(1); } stub = xargv[1]; ASL_alloc(ASL_read_fg); amplflag = xargc >= 3 && !strncmp(xargv[2], "-AMPL", 5); nl = jac0dim(stub, (fint)strlen(stub)); if (n_obj) { fprintf(Stderr, "Ignoring %d objectives.\n", n_obj); fflush(Stderr); } N = n_con; P = n_var; NZ = nzc; liv = 82 + 4*P; lv = 105 + P*(N + 2*P + 21) + 2*N; v = (real *)Malloc((lv + P)*sizeof(real) + liv*sizeof(fint)); X0 = v + lv; iv = (fint *)(X0 + P); fg_read(nl,0); /* Check for valid problem: all equality constraints. */ for(i = j = 0, rhsLU = LUrhs; i++ < N; rhsLU += 2) if (rhsLU[0] != rhsLU[1]) { if (j++ > 4) { /* Stop chattering if > 4 errors. */ fprintf(Stderr, "...\n"); exit(2); } fprintf(Stderr, "Lrhs(%d) = %g < Urhs(%d) = %g\n", i, rhsLU[0], i, rhsLU[1]); } if (j) exit(2); dense_j(); /* Tell jacval_ we want a dense Jacobian. */ divset_(&L1, iv, &liv, &lv, v); /* set default iv and v values */ if (amplflag) iv[prunit] = 0; /* Turn off printing . */ dn2gb_(&N, &P, X0, LUv, (U_fp)calcr, (U_fp)calcj, iv, &liv, &lv, v, &NZ, LUrhs, (U_fp)calcr); j = iv[0] >= 3 && iv[0] <= 10 ? (int)iv[0] - 3 : 8; i = Sprintf(buf, "nl21: %s", rvmsg[j]); if (j == 8) i += Sprintf(buf+i, " %ld", iv[0]); i += Sprintf(buf+i, "\n%ld function, %ld gradient evaluations", iv[nfcall], iv[ngcall]); i += Sprintf(buf+i, "\nFinal sum of squares = "); g_fmtop(buf+i, 2*v[f]); write_sol(buf, X0, 0, 0); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { ASL_pfgh *asl = (ASL_pfgh*)cur_ASL; FILE *nl; Jmp_buf err_jmp0; cgrad *cg, **cgp; char *buf1, buf[512], *what, **whatp; fint *hcs, *hr, i, nerror; int *cs; mwIndex *Ir, *Jc; real *H, *He, *J1, *W, *c, *f, *g, *v, *t, *x; static fint n, nc, nhnz, nz; static real *Hsp; static char ignore_complementarity[] = "Warning: ignoring %d complementarity conditions.\n"; if (nrhs == 1 && mxIsChar(prhs[0])) { if (nlhs < 6 || nlhs > 7) usage(); if (mxGetString(prhs[0], buf1 = buf, sizeof(buf))) mexErrMsgTxt("Expected 'stub' as argument\n"); at_end(); mexAtExit(at_end); asl = (ASL_pfgh*)ASL_alloc(ASL_read_pfgh); return_nofile = 1; if (!(nl = jac0dim(buf1,strlen(buf)))) { sprintf(msgbuf, "Can't open %.*s\n", sizeof(msgbuf)-20, buf); mexErrMsgTxt(msgbuf); } if (n_obj <= 0) printf("Warning: objectve == 0\n"); n = n_var; nc = n_con; nz = nzc; X0 = mxGetPr(plhs[0] = mxCreateDoubleMatrix(n, 1, mxREAL)); LUv = mxGetPr(plhs[1] = mxCreateDoubleMatrix(n, 1, mxREAL)); Uvx = mxGetPr(plhs[2] = mxCreateDoubleMatrix(n, 1, mxREAL)); pi0 = mxGetPr(plhs[3] = mxCreateDoubleMatrix(nc, 1, mxREAL)); LUrhs = mxGetPr(plhs[4] = mxCreateDoubleMatrix(nc, 1, mxREAL)); Urhsx = mxGetPr(plhs[5] = mxCreateDoubleMatrix(nc, 1, mxREAL)); if (nlhs == 7) { cvar = (int*)M1alloc(nc*sizeof(int)); plhs[6] = mxCreateDoubleMatrix(nc, 1, mxREAL); x = mxGetPr(plhs[6]); } else if (n_cc) printf(ignore_complementarity, n_cc); pfgh_read(nl, ASL_findgroups); if (nlhs == 7) for(i = 0; i < nc; i++) x[i] = cvar[i]; /* Arrange to compute the whole sparese Hessian */ /* of the Lagrangian function (both triangles). */ nhnz = sphsetup(0, 0, nc > 0, 0); Hsp = (real *)M1alloc(nhnz*sizeof(real)); return; } if (!asl) mexErrMsgTxt("spamfunc(\"stub\") has not been called\n"); nerror = -1; err_jmp1 = &err_jmp0; what = "(?)"; whatp = &what; if (nlhs == 2) { if (nrhs != 2) usage(); x = sizechk(prhs[0],"x",n); t = sizechk(prhs[1],"0 or 1", 1); if (setjmp(err_jmp0.jb)) { sprintf(msgbuf, "Trouble evaluating %s\n", *whatp); mexErrMsgTxt(msgbuf); } if (t[0] == 0.) { f = mxGetPr(plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL)); c = mxGetPr(plhs[1] = mxCreateDoubleMatrix(nc, 1, mxREAL)); what = "f"; *f = n_obj > 0 ? objval(0, x, &nerror) : 0; what = "c"; conval(x, c, &nerror); return; } g = mxGetPr(plhs[0] = mxCreateDoubleMatrix(n, 1, mxREAL)); J1 = mxGetPr(plhs[1] = mxCreateSparse(nc, n, nz, mxREAL)); what = "g"; if (n_obj > 0) objgrd(0, x, g, &nerror); else memset(g, 0, n*sizeof(real)); if (nc) { what = "J"; jacval(x, J1, &nerror); Ir = mxGetIr(plhs[1]); /*memcpy(mxGetJc(plhs[1]), A_colstarts, (n+1)*sizeof(int));*/ for(Jc = mxGetJc(plhs[1]), cs = A_colstarts, i = 0; i <= n; ++i) Jc[i] = cs[i]; cgp = Cgrad; for(i = 0; i < nc; i++) for(cg = *cgp++; cg; cg = cg->next) Ir[cg->goff] = i; } return; } if (nlhs == 0 && (nrhs == 3 || nrhs == 4)) { /* eval2('solution message', x, v): x = primal, v = dual */ /* optional 4th arg = solve_result_num */ if (!mxIsChar(prhs[0])) usage(); x = sizechk(prhs[1],"x",n); v = sizechk(prhs[2],"v",nc); if (mxGetString(prhs[0], buf, sizeof(buf))) mexErrMsgTxt( "Expected 'solution message' as first argument\n"); solve_result_num = nrhs == 3 ? -1 /* unknown */ : (int)*sizechk(prhs[3],"solve_result_num",1); write_sol(buf, x, v, 0); return; } if (nlhs != 1 || nrhs != 1) usage(); v = sizechk(prhs[0],"v",nc); W = mxGetPr(plhs[0] = mxCreateSparse(n, n, nhnz, mxREAL)); what = "W"; sphes(H = Hsp, 0, 0, v); /* Expand the Hessian lower triangle into the full Hessian... */ Ir = mxGetIr(plhs[0]); Jc = mxGetJc(plhs[0]); hcs = sputinfo->hcolstarts; hr = sputinfo->hrownos; for(i = 0; i <= n; i++) Jc[i] = hcs[i]; He = H + hcs[n]; while(H < He) { *W++ = *H++; *Ir++ = *hr++; } }
static VARIABLE *variable_branching(int type) { int k,card; double val,val0,val1,lb0,lb1,minim; VARIABLE *col; VARIABLE **stack; int sort_var(const void*,const void*); col = NULL; card = 0; for(k=0;k<nsupport;k++) if( fabs( support[k]->val - 0.5 ) < FRAC-ZERO ) card++; if( card==0 ){ std::cout << "ERROR: no fractional variables (FRAC=" << FRAC << std::endl; write_sol(fsolution); CSPexit(EXIT_ERROR); //exit(1); } switch(type){ case NEAR05: minim = FRAC; for(k=0;k<nsupport;k++){ val = fabs( support[k]->val - 0.5 ); if( val < minim ){ minim = val; col = support[k]; } } return( col ); case BETTERLP: stack = (VARIABLE **)malloc( card * sizeof( VARIABLE * ) ); if( stack==NULL ){ std::cout << "ERROR: not memory for 'frac' in branching" << std::endl; CSPexit(EXIT_ERROR); //exit(1); } card = 0; for(k=0;k<nsupport;k++) if( fabs( support[k]->val - 0.5 ) < FRAC-ZERO ) stack[card++] = support[k]; qsort( (char *)stack , card , sizeof(VARIABLE *) , sort_var ); if(card > NUMB) card = NUMB; minim = lowerb - 1; for(k=0;k<card;k++){ activa_pricing(); val0 = solve_child_col( stack[k] , (double)0 , 0); lb0 = ceil( val0 -ZERO ) + ZERO; activa_pricing(); val1 = solve_child_col( stack[k] , (double)1 , 0); lb1 = ceil( val1 -ZERO ) + ZERO; if( lb0 > upperb && lb1 > upperb ) { lowerb = upperb; free( stack ); stack = NULL; /*PWOF*/ return(NULL); } if( lb0 > upperb ) { del_col( stack[k] , FIX_UB ); free( stack ); stack = NULL; /*PWOF*/ return(NULL); } if( lb1 > upperb ) { del_col( stack[k] , FIX_LB ); free( stack ); stack = NULL; /*PWOF*/ return(NULL); } val = PROP * val0 + (1-PROP) * val1; if( val > minim ){ minim = val; col = stack[k]; } } free( stack ); stack = NULL; /*PWOF*/ return( col ); default: std::cout << "ERROR: unknown type of branching" << std::endl; CSPexit(EXIT_ERROR); //exit(1); } return( NULL ); }
main(int argc, char **argv) #endif { char *stub; ASL *asl; FILE *nl; lprec *lp; ograd *og; int ct, i, intmin, *is, j, j0, j1, k, nalt, rc; short *basis, *lower; real *LU, *c, lb, objadj, *rshift, *shift, t, ub, *x, *x0, *x1; char buf[256]; typedef struct { char *msg; int code; } Sol_info; static Sol_info solinfo[] = { { "optimal", 0 }, { "integer programming failure", 502 }, { "infeasible", 200 }, { "unbounded", 300 }, { "failure", 501 }, { "bug", 500 } }; sprintf(lp_solve_version+9, "%.*s", (int)sizeof(lp_solve_version)-10, PATCHLEVEL); sprintf(lp_solve_vversion, "%s, driver(20001002)", lp_solve_version); asl = ASL_alloc(ASL_read_f); stub = getstub(&argv, &Oinfo); nl = jac0dim(stub, (fint)strlen(stub)); suf_declare(suftab, sizeof(suftab)/sizeof(SufDecl)); /* set A_vals to get the constraints column-wise */ A_vals = (real *)M1alloc(nzc*sizeof(real)); f_read(nl,0); lp = make_lp(n_con, 0); Oinfo.uinfo = (char *)lp; if (getopts(argv, &Oinfo)) return 1; i = n_var + n_con + 1; x = (real*)M1alloc(i*sizeof(real)); /* scratch vector */ memset(x, 0, i*sizeof(real)); x0 = x++; c = x + n_con; /* supply objective */ objadj = 0; if (--nobj >= 0 && nobj < n_obj) { for(og = Ograd[nobj]; og; og = og->next) c[og->varno] = og->coef; if (objtype[nobj]) set_maxim(lp); objadj = objconst(nobj); } /* supply columns and variable bounds */ LU = LUv; intmin = n_var - (nbv + niv); j1 = nalt = 0; rshift = shift = 0; for(i = 1; i <= n_var; i++, LU += 2) { lb = LU[0]; ub = LU[1]; j0 = j1; j1 = A_colstarts[i]; *x0 = *c++; /* cost coefficient */ if (lb <= negInfinity && ub < Infinity) { /* negate this variable */ nalt++; lb = -ub; ub = -LU[0]; for(j = j0; j < j1; j++) x[A_rownos[j]] = -A_vals[j]; *x0 = -*x0; add_column(lp, x0); if (lb) goto shift_check; } else { for(j = j0; j < j1; j++) x[A_rownos[j]] = A_vals[j]; add_column(lp, x0); if (lb <= negInfinity) { nalt++; if (i > intmin) set_int(lp, lp->columns, TRUE); /* split free variable */ *x0 = -*x0; for(j = j0; j < j1; j++) x[A_rownos[j]] *= -1.; add_column(lp,x0); } else if (lb) { shift_check: if (lb > 0) set_lowbo(lp, lp->columns, lb); else { if (!rshift) { rshift = (real*)M1zapalloc( (n_var+n_con)*sizeof(real)); shift = rshift + n_con - 1; } shift[i] = lb; for(j = j0; j < j1; j++) { k = A_rownos[j]; rshift[k] += lb*x[k]; } if (ub < Infinity) ub -= lb; objadj += lb**x0; } } if (ub < Infinity) set_upbo(lp, lp->columns, ub); } for(j = j0; j < j1; j++) x[A_rownos[j]] = 0; if (i > intmin) set_int(lp, lp->columns, TRUE); } if (objadj) { /* add a fixed variable to adjust the objective value */ *x0 = objadj; add_column(lp, x0); set_lowbo(lp, i, 1.); set_upbo(lp, i, 1.); } /* supply constraint rhs */ LU = LUrhs; for(i = 1; i <= n_con; i++, LU += 2) { t = LU[0]; if (t == LU[1]) ct = EQ; else if (t <= negInfinity) { t = LU[1]; if (t >= Infinity) { /* This is possible only with effort: */ /* one must turn presolve off and */ /* explicitly specify a constraint */ /* with infinite bounds. */ fprintf(Stderr, "Sorry, can't handle free rows.\n"); exit(1); } ct = LE; } else ct = GE; set_constr_type(lp, i, ct); set_rh(lp, i, rshift ? t - *rshift++ : t); if (ct == GE && LU[1] < Infinity) lp->orig_upbo[i] = LU[1] - t; } if (prlp) print_lp(lp); if (scaling) auto_scale(lp); /* Unfortunately, there seems to be no way to suggest */ /* a starting basis to lp_solve; thus we must ignore */ /* any incoming .sstatus values. */ rc = solve(lp); if (rc < 0 || rc > 5) rc = 5; solve_result_num = solinfo[rc].code; i = sprintf(buf, "%s: %s", Oinfo.bsname, solinfo[rc].msg); if (rc == OPTIMAL) i += sprintf(buf+i, ", objective %.*g", obj_prec(), lp->best_solution[0]); i += sprintf(buf+i,"\n%d simplex iterations", lp->total_iter); if (lp->max_level > 1 || lp->total_nodes > 1) sprintf(buf+i, "\n%d branch & bound nodes: depth %d", lp->total_nodes, lp->max_level); /* Prepare to report solution: deal with split free variables. */ x1 = lp->best_solution+lp->rows+1; if (nalt || shift) { x = x0; LU = LUv; for(i = 0; i < n_var; i++, LU += 2) { if (LU[0] > negInfinity) x[i] = *x1++; else if (LU[1] < Infinity) x[i] = -*x1++; else { x[i] = x1[0] - x1[1]; x1 += 2; } if (shift) x[i] += *++shift; } } else x = x1; if (solinfo[rc].code < 500 && !(nbv + niv)) { /* return .sstatus values */ basis = lp->basis; lower = lp->lower; is = M1alloc((n_var + n_con)*sizeof(int)); suf_iput("sstatus", ASL_Sufkind_con, is); for(i = 0; i < n_con; i++) { j = *++lower; *is++ = *++basis ? 1 : j ? 3 : 4; } suf_iput("sstatus", ASL_Sufkind_var, is); LU = LUv; for(i = 0; i < n_var; i++, LU += 2) { j0 = *++basis; j1 = *++lower; if (LU[0] > negInfinity) j = j0 ? 1 : j1 ? 3 : 4; else if (LU[1] < Infinity) j = j0 ? 1 : j1 ? 4 : 3; else { ++lower; j = *++basis || j0; } *is++ = j; } } write_sol(buf, x, lp->duals+1, &Oinfo); /* The following calls would only be needed */ /* if execution were to continue... */ delete_lp(lp); ASL_free(&asl); return 0; }
int main(int argc, char **argv) { FILE *nl; char *stub; fint nerror = (fint)0; int n_badvals = 0; real f; if( argc < 2 ) { fprintf(stderr, "Usage: %s stub\n", argv[0]); return 1; } // Read objectives and first derivative information. if( !(asl = ASL_alloc(ASL_read_fg)) ) exit(1); stub = getstub(&argv, &Oinfo); nl = jac0dim(stub, (fint)strlen(stub)); // Get command-line options. if (getopts(argv, &Oinfo)) exit(1); // Check command-line options. if( showgrad < 0 || showgrad > 1 ) { Printf("Invalid value for showgrad: %d\n", showgrad); n_badvals++; } if( showname < 0 || showname > 1 ) { Printf("Invalid value for showname: %d\n", showname); n_badvals++; } if(n_badvals) { Printf("Found %d errors in command-line options.\n", n_badvals); exit(1); } // Allocate memory for problem data. // The variables below must have precisely THESE names. X0 = (real*)Malloc(n_var * sizeof(real)); // Initial guess pi0 = (real*)Malloc(n_con * sizeof(real)); // Initial multipliers LUv = (real*)Malloc(n_var * sizeof(real)); // Lower bounds on variables Uvx = (real*)Malloc(n_var * sizeof(real)); // Upper bounds on variables LUrhs = (real*)Malloc(n_con * sizeof(real)); // Lower bounds on constraints Urhsx = (real*)Malloc(n_con * sizeof(real)); // Upper bounds on constraints want_xpi0 = 3; // Read in ASL structure - trap read errors if( fg_read(nl, 0) ) { fprintf(stderr, "Error fg-reading nl file\n"); goto bailout; } if(showname) { // Display objective name if requested. Printf("Objective name: %s\n", obj_name(0)); } // This "solver" outputs the objective function value at X0. f = objval(0, X0, &nerror); if(nerror) { fprintf(stderr, "Error while evaluating objective.\n"); goto bailout; } Printf("f(x0) = %21.15e\n", f); // Optionally also output objective gradient at X0. if(showgrad) { real *g = (real*)malloc(n_var * sizeof(real)); objgrd(0, X0, g, &nerror); Printf("g(x0) = [ "); for(int i=0; i<n_var; i++) Printf("%8.1e ", g[i]); Printf("]\n"); free(g); } // Write solution to file. Here we just write the initial guess. Oinfo.wantsol = 9; // Suppress message echo. Force .sol writing write_sol(CHR"And the winner is", X0, pi0, &Oinfo); bailout: // Free data structure. DO NOT use free() on X0, pi0, etc. ASL_free((ASL**)(&asl)); return 0; }
undo(char *s, int op) #endif { char *dve, *dvt, *dvtype, *msg; dvthead dvth; int i; fint L; double *x, *xi, *y, *yi, *yext; FILE *f; Option_Info Oinfo; L = strlen(s); filename = (char *)Malloc(L + 5); stub_end = filename + L; strcpy(filename, s); f = openfi(".duw", "rb"); fread1(&dvth, sizeof(dvthead), f, filename); yext = (real *)Malloc(dvth.m + dvth.nextra*sizeof(real)); dvtype = (char *)(yext + dvth.nextra); fread1(dvtype, dvth.m, f, filename); fclose(f); n_var = dvth.m + dvth.nextra; n_con = dvth.n; if (!(msg = read_soln(&y, &x))) return 1; dve = dvtype + dvth.m; yi = y; yext = y + dvth.m; for(dvt = dvtype; dvt < dve; dvt++, yi++) switch(*dvt) { case 1: *yi = -*yi; break; case 2: if (*yext > *yi) *yi = -*yext; yext++; } if (dvth.maxobj) { for(xi = y, dvt = dvtype; dvt < dve; xi++, dvt++) if (*dvt != 3) *xi = -*xi; } asl->i.n_var0 = n_var = dvth.n; asl->i.n_con0 = n_con = dvth.m; filename = outstub; stub_end = outstub_end; switch(op) { case 'b': binary_nl = 1; break; case 'g': binary_nl = 0; break; default: binary_nl = dvth.binary; } for(i = 0; i < 10; i++) ampl_options[i] = dvth.Options[i]; ampl_vbtol = dvth.vbtol; Oinfo.wantsol = 9; /* suppress message echo, force .sol writing */ i = solve_result_num; if (i >= 200 && i < 400) { /* interchange "infeasible" and "unbounded" */ if (i >= 300) i -= 100; else i += 100; solve_result_num = i; } write_sol(msg, x, y, &Oinfo); return 0; }
void mexFunction(int nlhs, Matrix **plhs, int nrhs, Matrix **prhs) { FILE *nl; char *buf1, buf[512], *what; static fint n, nc, nz; fint nerror; real *J1, *W, *c, *f, *g, *v, *t, *x; static real *J; cgrad *cg, **cgp; static size_t Jsize; Jmp_buf err_jmp0; ASL_pfgh *asl = (ASL_pfgh*)cur_ASL; static fint nhnz; static real *Hsp; real *H, *He; int *Ir, *Jc; fint *hcs, *hr, i; if (nrhs == 1 && mxIsString(prhs[0])) { if (nlhs != 6) usage(); if (mxGetString(prhs[0], buf1 = buf, sizeof(buf))) mexErrMsgTxt("Expected 'stub' as argument\n"); at_end(); mexAtExit(at_end); asl = (ASL_pfgh*)ASL_alloc(ASL_read_pfgh); return_nofile = 1; if (!(nl = jac0dim(buf1,strlen(buf)))) { sprintf(msgbuf, "Can't open %.*s\n", sizeof(msgbuf)-20, buf); mexErrMsgTxt(msgbuf); } if (n_obj <= 0) printf("Warning: objectve == 0\n"); n = n_var; nc = n_con; nz = nzc; J = (real *)M1alloc(nz*sizeof(real)); X0 = mxGetPr(plhs[0] = mxCreateFull(n, 1, REAL)); LUv = mxGetPr(plhs[1] = mxCreateFull(n, 1, REAL)); Uvx = mxGetPr(plhs[2] = mxCreateFull(n, 1, REAL)); pi0 = mxGetPr(plhs[3] = mxCreateFull(nc, 1, REAL)); LUrhs = mxGetPr(plhs[4] = mxCreateFull(nc, 1, REAL)); Urhsx = mxGetPr(plhs[5] = mxCreateFull(nc, 1, REAL)); pfgh_read(nl, ASL_findgroups); Jsize = nc*n*sizeof(real); /* Arrange to compute the whole sparese Hessian */ /* of the Lagrangian function (both triangles). */ nhnz = sphsetup(0, 0, nc > 0, 0); Hsp = (real *)M1alloc(nhnz*sizeof(real)); return; } if (!filename) mexErrMsgTxt("spamfunc(\"stub\") has not been called\n"); nerror = -1; err_jmp1 = &err_jmp0; if (nlhs == 2) { if (nrhs != 2) usage(); x = sizechk(prhs[0],"x",n); t = sizechk(prhs[1],"0 or 1", 1); if (t[0] == 0.) { f = mxGetPr(plhs[0] = mxCreateFull(1, 1, REAL)); c = mxGetPr(plhs[1] = mxCreateFull(nc, 1, REAL)); if (setjmp(err_jmp0.jb)) { sprintf(msgbuf, "Trouble evaluating %s\n", what); mexErrMsgTxt(msgbuf); } what = "f"; *f = objval(0, x, &nerror); what = "c"; conval(x, c, &nerror); return; } g = mxGetPr(plhs[0] = mxCreateFull(n, 1, REAL)); J1 = mxGetPr(plhs[1] = mxCreateSparse(nc, n, nz, REAL)); what = "g"; objgrd(0, x, g, &nerror); if (nc) { what = "J"; jacval(x, J1, &nerror); Ir = mxGetIr(plhs[1]); memcpy(mxGetJc(plhs[1]), A_colstarts, (n+1)*sizeof(int)); cgp = Cgrad; for(i = 0; i < nc; i++) for(cg = *cgp++; cg; cg = cg->next) Ir[cg->goff] = i; } return; } if (nlhs == 0 && nrhs == 3) { /* eval2('solution message', x, v): x = primal, v = dual */ if (!mxIsString(prhs[0])) usage(); x = sizechk(prhs[1],"x",n); v = sizechk(prhs[2],"v",nc); if (mxGetString(prhs[0], buf, sizeof(buf))) mexErrMsgTxt( "Expected 'solution message' as first argument\n"); write_sol(buf, x, v, 0); return; } if (nlhs != 1 || nrhs != 1) usage(); v = sizechk(prhs[0],"v",nc); W = mxGetPr(plhs[0] = mxCreateSparse(n, n, nhnz, REAL)); what = "W"; sphes(H = Hsp, 0, 0, v); /* Expand the Hessian lower triangle into the full Hessian... */ Ir = mxGetIr(plhs[0]); Jc = mxGetJc(plhs[0]); hcs = sputinfo->hcolstarts; hr = sputinfo->hrownos; for(i = 0; i <= n; i++) Jc[i] = hcs[i]; He = H + hcs[n]; while(H < He) { *W++ = *H++; *Ir++ = *hr++; } }
void ampl_write_solution(ASL_pfgh *asl_, double *varsX, double *dual) { ASL_pfgh *asl = asl_; write_sol("pipsnlp_parallel:", varsX, dual,NULL); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //Possible Inputs char fpath[FLEN]; char msg[FLEN]; char cmd[FLEN]; //user commmand int sp = 0; //Outputs const char *fnames[15] = {"H","f","lb","ub","A","cl","cu","Q","l","qcind","x0","v0","sense","objbias","conlin"}; double *sizes; //Internal Vars int ii; size_t i,j,k; //indexing vars char *what, **whatp; //error message vars static FILE *nl; //file handle ASL *asl = cur_ASL; //Current ASL instance int icmd = ASLCMD_ERROR; //Command Integer double *sense; //Objective sense double *objbias; //Objective bias int obj_lin; //linearity of the objectiuve (see ASL_DEGREE_ defines) double *con_lin; //linearity of the constraints (see ASL_DEGREE_ defines) double *isopen; //Is ASL open bool nlcon = false; //indicates whether any constraint is nonlinear double *x; //Evaluation point double *f, *g, *c = NULL; //Return pointers int nerror; //eval errors //Sparse Indexing mwIndex *Ir, *Jc; double *Pr; //QP Checking Vars int nqpz = 0; //number of nzs in quadratic objective int nqc_con = 0; //number of quadratic constraints int *QP_ir, *QP_jc; //Pointers used when calling nqpcheck double *QP_pr; double *pqi; //pointer to quadratic index vector ograd *og; //objective gradient structure //Jacobian Vars static double *J = NULL; //Memory to store intermediate Jacobian Values when using Dense Mode static double *J1 = NULL; //Memory to store Jacobian Values cgrad *cg, **cgp, **cgpe; //constraint gradient structures int *cs; //Column starts //Hessian Vars static double *Hsp = NULL; //Memory to store Hessian Values static int nhnz; //Number of Hessian nz double *s, *v; //Sigma, Lambda int *hcs, *hr; //Hessian column starts, row indexs double *H, *He, *W; //Error catching Jmp_buf err_jmp0; //If no inputs, just return info if(nrhs < 1) { if (nlhs >= 1) { sprintf(msgbuf,"%s %s",__TIME__,__DATE__); plhs[0] = mxCreateString(msgbuf); plhs[1] = mxCreateDoubleScalar(OPTI_VER); } else { printUtilityInfo(); } return; } //Get User Command icmd = getCommand(prhs[0]); //Switch Yard for Command switch(icmd) { case ASLCMD_ISOPEN: isopen = mxGetPr(plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL)); if(asl) *isopen = 1; else *isopen = 0; break; case ASLCMD_OPEN: //Check for Errors if(nrhs < 2) mexErrMsgTxt("Expected two arguments to open a file! [x0,v0,lb,ub,cl,cu,sense,sizes] = asl('open','file path')\n"); if(!mxIsChar(prhs[1])) mexErrMsgTxt("File path must be a char array!"); //Get String CHECK(mxGetString(prhs[1], fpath, FLEN) == 0,"error reading file path!"); //Clear any existing objects if (cur_ASL) ASL_free(&cur_ASL); //Set MEX exit function mexAtExit(mexExit); //Open file for LP/QP/QCQP checking asl = ASL_alloc(ASL_read_fg); //allocate for qp read return_nofile = 1; //return 0 if stub doesn't exist nl = jac0dim(fpath,(ftnlen)strlen(fpath)); //read in passed file //Check we got the file if(!nl) { sprintf(msgbuf, "Can't open (or error opening) %s\n", fpath); mexErrMsgTxt(msgbuf); } //Allocate Vector Memory pPROB = mxCreateStructMatrix(1,1,15,fnames); mxSetField(pPROB,0,fnames[eX0],mxCreateDoubleMatrix(n_var,1, mxREAL)); mxSetField(pPROB,0,fnames[eV0],mxCreateDoubleMatrix(n_con, 1, mxREAL)); mxSetField(pPROB,0,fnames[eLB],mxCreateDoubleMatrix(n_var, 1, mxREAL)); mxSetField(pPROB,0,fnames[eUB],mxCreateDoubleMatrix(n_var, 1, mxREAL)); mxSetField(pPROB,0,fnames[eCL],mxCreateDoubleMatrix(n_con, 1, mxREAL)); mxSetField(pPROB,0,fnames[eCU],mxCreateDoubleMatrix(n_con, 1, mxREAL)); mxSetField(pPROB,0,fnames[eSENSE],mxCreateDoubleMatrix(1, 1, mxREAL)); mxSetField(pPROB,0,fnames[eOBJBIAS],mxCreateDoubleMatrix(1, 1, mxREAL)); mxSetField(pPROB,0,fnames[eCONLIN],mxCreateDoubleMatrix(n_con, 1, mxREAL)); //Get Fields (ASL will fill) X0 = mxGetPr(mxGetField(pPROB,0,fnames[eX0])); pi0 = mxGetPr(mxGetField(pPROB,0,fnames[eV0])); LUv = mxGetPr(mxGetField(pPROB,0,fnames[eLB])); Uvx = mxGetPr(mxGetField(pPROB,0,fnames[eUB])); LUrhs = mxGetPr(mxGetField(pPROB,0,fnames[eCL])); Urhsx = mxGetPr(mxGetField(pPROB,0,fnames[eCU])); sense = mxGetPr(mxGetField(pPROB,0,fnames[eSENSE])); objbias = mxGetPr(mxGetField(pPROB,0,fnames[eOBJBIAS])); con_lin = mxGetPr(mxGetField(pPROB,0,fnames[eCONLIN])); //Other Output Args sizes = mxGetPr(pSIZE = mxCreateDoubleMatrix(16, 1, mxREAL)); //Check for complementarity problems if(n_cc) mexWarnMsgTxt("Ignoring Complementarity Constraints!"); //Assign asl problem sizes sizes[0] = (double)n_var; sizes[1] = (double)n_con; sizes[2] = (double)nzc; sizes[3] = (double)lnc; sizes[4] = (double)nbv; sizes[5] = (double)niv; sizes[6] = (double)nlc; sizes[7] = (double)nlnc; sizes[8] = (double)nlo; sizes[9] = (double)nlvb; sizes[10] = (double)nlvc; sizes[11] = (double)nlvo; sizes[12] = (double)nlvbi; sizes[13] = (double)nlvci; sizes[14] = (double)nlvoi; sizes[15] = (double)nwv; //Read In For QP Checking qp_read(nl,0); //Assign sense if(objtype[0] == 1) *sense = -1; //max else *sense = 1; //min //Determine Objective Linearity obj_lin = linCheck(asl, 0); //Determine Constraints Linearity for(ii = 0; ii < n_con; ii++) { con_lin[ii] = linCheck(asl, -(ii+1)); //Check if nonlinear or quadratic if(con_lin[ii] >= ASL_DEGREE_NLIN) nlcon = true; else if(con_lin[ii] == ASL_DEGREE_QUAD) { //con_lin indicates quadratic constraint, ensure is inequality if(LUrhs[ii] != Urhsx[ii]) nqc_con++; else nlcon = true; //quadratic equalities not currently handled by any explicit QCQP solver (I know of), make nl } } //Check to force to read as nonlinear problem if(nrhs > 2 && *mxGetPr(prhs[2])==1) nlcon = true; //If objective or any constraint is nonlinear, then we have to process as an NLP if(obj_lin == ASL_DEGREE_NLIN || nlcon) { //Free the QP read memory ASL_free(&asl); //Re-open for full NLP read asl = ASL_alloc(ASL_read_pfgh); //allocate memory for pfgh read nl = jac0dim(fpath,(ftnlen)strlen(fpath)); //read passed file (full nl read) //Allocate Jacobian Memory [note use M1alloc to let ASL clean it up if multiple instances opened] J = (double*)M1alloc(nzc*sizeof(double)); //Memory to store Jacobian nzs //Assign memory for saving obj + con x objx = (double*)M1alloc(n_var*sizeof(double)); conx = (double*)M1alloc(n_var*sizeof(double)); //Read File (f + g + H) pfgh_read(nl, ASL_findgroups); //Assign Hessian Memory nhnz = sphsetup(1, 1, n_con > 0, 0); //one obj, use sigma, optionally use lambda, full hessian Hsp = (double*)M1alloc(nhnz*sizeof(double)); //memory to store hessian nzs } //Otherwise we can process as a LP, QP or QCQP else { //Assign objective bias *objbias = objconst(0); //Check for quadratic objective if(obj_lin == ASL_DEGREE_QUAD) { //Capture Pointers nqpz = nqpcheck(0, &QP_ir, &QP_jc, &QP_pr); //check objective for qp //Create QP H mxSetField(pPROB,0,fnames[eH],mxCreateSparse(n_var,n_var,nqpz,mxREAL)); //Copy in Objective Quadratic Elements (copy-cast where appropriate) memcpy(mxGetPr(mxGetField(pPROB,0,fnames[eH])),QP_pr,nqpz*sizeof(double)); Jc = mxGetJc(mxGetField(pPROB,0,fnames[eH])); Ir = mxGetIr(mxGetField(pPROB,0,fnames[eH])); for(i = 0; i <= n_var; i++) Jc[i] = (mwIndex)QP_jc[i]; for(i = 0; i < nqpz; i++) Ir[i] = (mwIndex)QP_ir[i]; } else //create an empty sparse matrix mxSetField(pPROB,0,fnames[eH],mxCreateSparse(n_var,n_var,0,mxREAL)); //Create QP f mxSetField(pPROB,0,fnames[eF],mxCreateDoubleMatrix(n_var,1,mxREAL)); Pr = mxGetPr(mxGetField(pPROB,0,fnames[eF])); //Copy in Objective Linear Elements for( og = Ograd[0]; og; og = og->next ) Pr[og->varno] = og->coef; //Create A (linear constraints) mxSetField(pPROB,0,fnames[eA],mxCreateSparse(n_con, n_var, nzc, mxREAL)); if(n_con) { Pr = mxGetPr(mxGetField(pPROB,0,fnames[eA])); Ir = mxGetIr(mxGetField(pPROB,0,fnames[eA]));; //Fill in A (will double on quadratic linear sections, but easier to remove once in MATLAB) for(Jc = mxGetJc(mxGetField(pPROB,0,fnames[eA])), cs = A_colstarts, i = 0; i <= n_var; ++i) Jc[i] = (mwIndex)cs[i]; cgp = Cgrad; for(i = 0; i < n_con; i++) for(cg = *cgp++; cg; cg = cg->next) { Ir[cg->goff] = (mwIndex)i; Pr[cg->goff] = cg->coef; } } //Add quadratic constraints if present if(nqc_con) { //Allocate a Cell Array to store the quadratic constraint Qs, and vector to store indices mxSetField(pPROB,0,fnames[eQ],mxCreateCellMatrix(nqc_con,1)); //Q mxSetField(pPROB,0,fnames[eL],mxCreateDoubleMatrix(n_var, nqc_con,mxREAL)); //l mxSetField(pPROB,0,fnames[eQCIND],mxCreateDoubleMatrix(nqc_con,1,mxREAL)); //ind pqi = mxGetPr(mxGetField(pPROB,0,fnames[eQCIND])); //Fill In Constraints for(ii=0,j=0;ii<n_con;ii++) { //Quadratic Constraints if(con_lin[ii] == ASL_DEGREE_QUAD) { //Create index pqi[j] = ii+1; //increment for matlab index //Capture Pointers nqpz = nqpcheck(-(ii+1), &QP_ir, &QP_jc, &QP_pr); //check constraint for qp; if(nqpz <= 0) mexErrMsgTxt("Error reading quadratic constraints. Assumed constraint was quadratic based on prescan, now appears not?"); //Create QC Q mxSetCell(mxGetField(pPROB,0,fnames[eQ]),j,mxCreateSparse(n_var,n_var,nqpz,mxREAL)); //Copy in Constraint Quadratic Elements (copy-cast where appropriate) Pr = mxGetPr(mxGetCell(mxGetField(pPROB,0,fnames[eQ]),j)); Jc = mxGetJc(mxGetCell(mxGetField(pPROB,0,fnames[eQ]),j)); Ir = mxGetIr(mxGetCell(mxGetField(pPROB,0,fnames[eQ]),j)); for(k = 0; k <= n_var; k++) Jc[k] = (mwIndex)QP_jc[k]; for(k = 0; k < nqpz; k++) { Ir[k] = (mwIndex)QP_ir[k]; Pr[k] = 0.5*QP_pr[k]; //to QP form } //Create QC l (not sure why we can't extract this from Jacobian, values are wrong) Pr = mxGetPr(mxGetField(pPROB,0,fnames[eL])); for( cg = Cgrad[ii]; cg; cg = cg->next ) Pr[j*n_var + cg->varno] = cg->coef; //Increment for next cell / col j++; } } } //Put back into function eval mode (just in case) qp_opify(); } break; case ASLCMD_CLOSE: //Check for Errors CHECKASL(asl); //Call Exit Function mexExit(); break; case ASLCMD_FUN: //Check for Errors CHECKASL(asl); CHECKNRHS(nrhs,2); //Get x and check dimensions x = sizechk(prhs[1],"x",n_var); //Save x if(objx) memcpy(objx,x,n_var*sizeof(double)); //Create objective val memory and get it from ASL SETERRJMP(); what = "objective"; f = mxGetPr(plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL)); *f = objval(0, x, &nerror); break; case ASLCMD_GRAD: //Check for Errors CHECKASL(asl); CHECKNRHS(nrhs,2); //Get x and check dimensions x = sizechk(prhs[1],"x",n_var); //Save x if(objx) memcpy(objx,x,n_var*sizeof(double)); //Create objective grad memory and get it from ASL SETERRJMP(); what = "gradient"; g = mxGetPr(plhs[0] = mxCreateDoubleMatrix(1, n_var, mxREAL)); objgrd(0, x, g, &nerror); break; case ASLCMD_CON: //Check for Errors CHECKASL(asl); CHECKNRHS(nrhs,2); //Get x and check dimensions x = sizechk(prhs[1],"x",n_var); //Save x if(conx) memcpy(conx,x,n_var*sizeof(double)); //Create constraint memory and get it from ASL SETERRJMP(); what = "constraints"; c = mxGetPr(plhs[0] = mxCreateDoubleMatrix(n_con, 1, mxREAL)); if(n_con) conval(x, c, &nerror); break; case ASLCMD_JAC: //Check for Errors CHECKASL(asl); CHECKNRHS(nrhs,2); //Get x and check dimensions x = sizechk(prhs[1],"x",n_var); //Save x if(conx) memcpy(conx,x,n_var*sizeof(double)); //Create constraint jac memory and get it from ASL SETERRJMP(); what = "Jacobian"; //Check for sparsity if(nrhs > 2 && *mxGetPr(prhs[2])) { sp = 1; J1 = mxGetPr(plhs[0] = mxCreateSparse(n_con, n_var, nzc, mxREAL)); } else { sp = 0; J1 = mxGetPr(plhs[0] = mxCreateDoubleMatrix(n_con, n_var, mxREAL)); } //Evaluate if we have constraints if (n_con) { //Sparse if(sp) { jacval(x, J1, &nerror); Ir = mxGetIr(plhs[0]); for(Jc = mxGetJc(plhs[0]), cs = A_colstarts, i = 0; i <= n_var; ++i) Jc[i] = (mwIndex)cs[i]; cgp = Cgrad; for(i = 0; i < n_con; i++) for(cg = *cgp++; cg; cg = cg->next) Ir[cg->goff] = (mwIndex)i; } //Dense else { jacval(x, J, &nerror); cgp = Cgrad; for(cgpe = cgp + n_con; cgp < cgpe; J1++) for(cg = *cgp++; cg; cg = cg->next) J1[n_con*cg->varno] = J[cg->goff]; } } break; case ASLCMD_JACSTR: //Check for Errors CHECKASL(asl); CHECKNRHS(nrhs,1); //Create constraint jacstr memory and get it from ASL SETERRJMP(); what = "Jacobian Structure)"; J1 = mxGetPr(plhs[0] = mxCreateSparse(n_con, n_var, nzc, mxREAL)); //Fill In Structure for(i=0;i<nzc;i++) J1[i] = 1.0; for(Jc = mxGetJc(plhs[0]), cs = A_colstarts, i = 0; i <= n_var; ++i) Jc[i] = (mwIndex)cs[i]; cgp = Cgrad; Ir = mxGetIr(plhs[0]); for(i = 0; i < n_con; i++) for(cg = *cgp++; cg; cg = cg->next) Ir[cg->goff] = (mwIndex)i; break; case ASLCMD_HES: //Check for Errors CHECKASL(asl); CHECKNRHS(nrhs,4); //assume hess(x,sigma,lambda) and optionally sparse //Check dimensions & get args x = sizechk(prhs[1],"x",n_var); s = sizechk(prhs[2],"sigma",1); v = sizechk(prhs[3],"lambda",n_con); //Check for sparsity if(nrhs > 4 && *mxGetPr(prhs[4])) { sp = 1; W = mxGetPr(plhs[0] = mxCreateSparse(n_var, n_var, nhnz, mxREAL)); } else { sp = 0; W = mxGetPr(plhs[0] = mxCreateDoubleMatrix(n_var, n_var, mxREAL)); } //Check if we need to recalculate objective / constraints if(!comp_x(objx,x,n_var)) { //Setup Error Catching SETERRJMP(); what = "Objective for Hessian"; //Re-evaluate Objective objval(0, x, &nerror); } if(!comp_x(conx,x,n_var)){ if(!c) c = mxGetPr(mxCreateDoubleMatrix(n_con, 1, mxREAL)); //Setup Error Catching SETERRJMP(); what = "Constraints for Hessian"; //Re-evaluate Constraints conval(x, c, &nerror); } //Setup Error Catching SETERRJMP(); what = "Hessian"; //Sparse if(sp) { //This function returns the full (symmetric) Hessian as setup above sphes(H = Hsp, 1, s, v); Ir = mxGetIr(plhs[0]); Jc = mxGetJc(plhs[0]); hcs = sputinfo->hcolstarts; hr = sputinfo->hrownos; for(i = 0; i <= n_var; i++) Jc[i] = (mwIndex)hcs[i]; He = H + hcs[n_var]; while(H < He) { *W++ = *H++; *Ir++ = (mwIndex)*hr++; } } //Dense else fullhes(W, n_var, 1, s, v); break; case ASLCMD_HESSTR: //mexPrintf("CMD: Get Hessian Structure\n"); //Check for Errors CHECKASL(asl); CHECKNRHS(nrhs,1); //Create hessianstr memory and get it from ASL SETERRJMP(); what = "Hessian Structure"; W = mxGetPr(plhs[0] = mxCreateSparse(n_var, n_var, nhnz, mxREAL)); Ir = mxGetIr(plhs[0]); Jc = mxGetJc(plhs[0]); //Get Sparse Info hcs = sputinfo->hcolstarts; hr = sputinfo->hrownos; //Assign col starts for(i = 0; i <= n_var; i++) Jc[i] = (mwIndex)hcs[i]; //Assign rows + 1.0 for nz positions H = Hsp; //Start of nz Hsp elements He = H + hcs[n_var]; //End of nz Hsp elements while(H < He) { *W++ = 1.0; *Ir++ = (mwIndex)*hr++; *H++; //increment nz element position } break; case ASLCMD_WRITESOL: //Check for Errors CHECKASL(asl); CHECKNRHS(nrhs,2); //asl('writesol',msg,x) //Get Input Args CHECK(mxGetString(prhs[1], msg, FLEN) == 0,"error reading message!"); x = sizechk(prhs[2],"x",n_var); //Write to solution stub file write_sol(msg,x,NULL,NULL); break; default: mexExit(); //clean up mxGetString(prhs[0], cmd, FLEN); sprintf(msgbuf, "ASL Command Error! Unknown Command: '%s'\n", cmd); mexErrMsgTxt(msgbuf); break; } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { FILE *nl; char *buf1, buf[512], *what, **whatp; static fint n, nc, nz; fint i, nerror; real *J1, *W, *c, *f, *g, *v, *t, *x; static real *J; cgrad *cg, **cgp, **cgpe; static size_t Jsize; Jmp_buf err_jmp0; ASL *asl = cur_ASL; static char ignore_complementarity[] = "Warning: ignoring %d complementarity conditions.\n"; if (nrhs == 1 && mxIsChar(prhs[0])) { if (nlhs < 6 || nlhs > 7) usage(); if (mxGetString(prhs[0], buf1 = buf, sizeof(buf))) mexErrMsgTxt("Expected 'stub' as argument\n"); at_end(); mexAtExit(at_end); asl = ASL_alloc(ASL_read_pfgh); return_nofile = 1; if (!(nl = jac0dim(buf1,strlen(buf)))) { sprintf(msgbuf, "Can't open %.*s\n", sizeof(msgbuf)-20, buf); mexErrMsgTxt(msgbuf); } if (n_obj <= 0) printf("Warning: objectve == 0\n"); n = n_var; nc = n_con; nz = nzc; J = (real *)M1alloc(nz*sizeof(real)); X0 = mxGetPr(plhs[0] = mxCreateDoubleMatrix(n, 1, mxREAL)); LUv = mxGetPr(plhs[1] = mxCreateDoubleMatrix(n, 1, mxREAL)); Uvx = mxGetPr(plhs[2] = mxCreateDoubleMatrix(n, 1, mxREAL)); pi0 = mxGetPr(plhs[3] = mxCreateDoubleMatrix(nc, 1, mxREAL)); LUrhs = mxGetPr(plhs[4] = mxCreateDoubleMatrix(nc, 1, mxREAL)); Urhsx = mxGetPr(plhs[5] = mxCreateDoubleMatrix(nc, 1, mxREAL)); if (nlhs == 7) { cvar = (int*)M1alloc(nc*sizeof(int)); plhs[6] = mxCreateDoubleMatrix(nc, 1, mxREAL); x = mxGetPr(plhs[6]); } else if (n_cc) printf(ignore_complementarity, n_cc); pfgh_read(nl, ASL_findgroups); Jsize = nc*n*sizeof(real); if (nlhs == 7) for(i = 0; i < nc; i++) x[i] = cvar[i]; return; } if (!asl) mexErrMsgTxt("amplfunc(\"stub\") has not been called\n"); nerror = -1; err_jmp1 = &err_jmp0; what = "(?)"; whatp = &what; if (nlhs == 2) { if (nrhs != 2) usage(); x = sizechk(prhs[0],"x",n); t = sizechk(prhs[1],"0 or 1", 1); if (setjmp(err_jmp0.jb)) { sprintf(msgbuf, "Trouble evaluating %s\n", *whatp); mexErrMsgTxt(msgbuf); } if (t[0] == 0.) { f = mxGetPr(plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL)); c = mxGetPr(plhs[1] = mxCreateDoubleMatrix(nc, 1, mxREAL)); what = "f"; *f = objval(0, x, &nerror); what = "c"; conval(x, c, &nerror); return; } g = mxGetPr(plhs[0] = mxCreateDoubleMatrix(n, 1, mxREAL)); J1 = mxGetPr(plhs[1] = mxCreateDoubleMatrix(nc, n, mxREAL)); what = "g"; objgrd(0, x, g, &nerror); if (nc) { memset(J1, 0, Jsize); what = "J"; jacval(x, J, &nerror); cgp = Cgrad; for(cgpe = cgp + nc; cgp < cgpe; J1++) for(cg = *cgp++; cg; cg = cg->next) J1[nc*cg->varno] = J[cg->goff]; } return; } if (nlhs == 0 && (nrhs == 3 || nrhs == 4)) { /* eval2('solution message', x, v): x = primal, v = dual */ /* optional 4th arg = solve_result_num */ if (!mxIsChar(prhs[0])) usage(); x = sizechk(prhs[1],"x",n); v = sizechk(prhs[2],"v",nc); if (mxGetString(prhs[0], buf, sizeof(buf))) mexErrMsgTxt( "Expected 'solution message' as first argument\n"); solve_result_num = nrhs == 3 ? -1 /* unknown */ : (int)*sizechk(prhs[3],"solve_result_num",1); write_sol(buf, x, v, 0); return; } if (nlhs != 1 || nrhs != 1) usage(); v = sizechk(prhs[0],"v",nc); W = mxGetPr(plhs[0] = mxCreateDoubleMatrix(n, n, mxREAL)); what = "W"; fullhes(W, n, 0, 0, v); }
//Main Function void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[]) { //Input Args double *f, *blin = NULL, *lb = NULL, *ub = NULL, *y0 = NULL; //Return Args double *x, *pval, *dval, *exitflag, *iter, *pinf, *dinf, *realgap, *xzgap; //Options (most get defaults written in) int maxiter = 1500; //Internal Vars size_t ndec = 0, nlincon = 0, lincon_nz = 0, total_dim = 0, ncones = 0; size_t i, j; const char *onames[2] = {"pval","dval"}; const char *fnames[5] = {"iter","pinf","dinf","realgap","xzgap"}; double evaltime; int status = -1, nb = 0, linoffset = 0, indlb = 1, indub = 1, nLB = 0, nUB = 0; mwIndex *jc; //CSDP Problem Data struct blockmatrix C; double *b, *y, *xx, objconstant = 0.0; struct constraintmatrix *constraints; struct blockmatrix X, Z; struct sparseblock *blockptr; struct paramstruc params; //Version Return if(nrhs < 1) { if(nlhs < 1) printSolverInfo(); else plhs[0] = mxCreateString(CSDP_VERSION); return; } //Check Inputs checkInputs(prhs,nrhs); //Get pointers to Input variables f = mxGetPr(pF); ndec = mxGetNumberOfElements(pF); if(!mxIsEmpty(pA)) { blin = mxGetPr(pB); nlincon = mxGetM(pA); jc = mxGetJc(pA); lincon_nz = jc[ndec]; } if(nrhs > eLB && !mxIsEmpty(pLB)) { lb = mxGetPr(pLB); //Ensure we have at least one finite bound for(i=0,j=0;i<ndec;i++) if(mxIsInf(lb[i])) j++; if(j==ndec) lb = NULL; } if(nrhs > eUB && !mxIsEmpty(pUB)) { ub = mxGetPr(pUB); //Ensure we have at least one finite bound for(i=0,j=0;i<ndec;i++) if(mxIsInf(ub[i])) j++; if(j==ndec) ub = NULL; } if(nrhs > eSDP && !mxIsEmpty(pSDP)) { if(mxIsCell(pSDP)) ncones = mxGetNumberOfElements(pSDP); else ncones = 1; } if(nrhs > eY0 && !mxIsEmpty(pY0)) y0 = mxGetPr(pY0); //Create Outputs plhs[0] = mxCreateDoubleMatrix(ndec,1, mxREAL); plhs[1] = mxCreateStructMatrix(1,1,2,onames); mxSetField(plhs[1],0,onames[0],mxCreateDoubleMatrix(1,1, mxREAL)); mxSetField(plhs[1],0,onames[1],mxCreateDoubleMatrix(1,1, mxREAL)); plhs[2] = mxCreateDoubleMatrix(1,1, mxREAL); x = mxGetPr(plhs[0]); pval = mxGetPr(mxGetField(plhs[1],0,onames[0])); dval = mxGetPr(mxGetField(plhs[1],0,onames[1])); exitflag = mxGetPr(plhs[2]); //Info Output plhs[3] = mxCreateStructMatrix(1,1,5,fnames); mxSetField(plhs[3],0,fnames[0],mxCreateDoubleMatrix(1,1, mxREAL)); mxSetField(plhs[3],0,fnames[1],mxCreateDoubleMatrix(1,1, mxREAL)); mxSetField(plhs[3],0,fnames[2],mxCreateDoubleMatrix(1,1, mxREAL)); mxSetField(plhs[3],0,fnames[3],mxCreateDoubleMatrix(1,1, mxREAL)); mxSetField(plhs[3],0,fnames[4],mxCreateDoubleMatrix(1,1, mxREAL)); iter = mxGetPr(mxGetField(plhs[3],0,fnames[0])); pinf = mxGetPr(mxGetField(plhs[3],0,fnames[1])); dinf = mxGetPr(mxGetField(plhs[3],0,fnames[2])); realgap = mxGetPr(mxGetField(plhs[3],0,fnames[3])); xzgap = mxGetPr(mxGetField(plhs[3],0,fnames[4])); //Set Defaults citer = 0; maxtime = 1000; printLevel = 0; //Allocate Initial Storage for the Problem b = (double*)malloc((ndec+1)*sizeof(double)); //objective vector //C matrices [LB UB LIN SD] nb = (int)ncones+(int)(nlincon>0)+(int)(lb!=NULL)+(int)(ub!=NULL); #ifdef DEBUG mexPrintf("Number of blocks (including bounds, linear and sdcones): %d\n",nb); #endif C.nblocks = nb; C.blocks = (struct blockrec*)malloc((nb+1)*sizeof(struct blockrec)); //+1 due to fortran index if(C.blocks == NULL) mexErrMsgTxt("Error allocating memory for C matrices"); //Constraints (i.e. 1 per decision variable) constraints = (struct constraintmatrix*)malloc((ndec+1)*sizeof(struct constraintmatrix)); //+1 due to fortran index if(constraints == NULL) { free(C.blocks); mexErrMsgTxt("Error allocating memory for A matrices"); } for(i=1;i<=ndec;i++) constraints[i].blocks=NULL; //initially set as NULL //Copy in and negate objective vector for(i=0;i<ndec;i++) b[i+1] = -f[i]; //Create Bounds if Present if(lb || ub) linoffset += addBounds(C,lb,ub,ndec,&nLB,&nUB); //Create Linear Cone (diagonal) if present if(nlincon) { //Initialize C C.blocks[linoffset+1].blockcategory = DIAG; C.blocks[linoffset+1].blocksize = (int)nlincon; C.blocks[linoffset+1].data.vec = (double*)malloc((nlincon+1)*sizeof(double)); if(C.blocks[linoffset+1].data.vec == NULL) mexErrMsgTxt("Error allocating memory for LP C diagonal"); #ifdef DEBUG mexPrintf("LP C[%d] Vector size: %d\n",linoffset+1,nlincon); #endif //Copy Elements for(i=0;i<nlincon;i++) { C.blocks[linoffset+1].data.vec[i+1] = -blin[i]; #ifdef DEBUG mexPrintf(" C vec[%d] = %f\n",i+1,-blin[i]); #endif } linoffset++; } #ifdef DEBUG mexPrintf("\nBlock offset after bounds + linear con: %d\n\n",linoffset); #endif //Setup Semidefinite C matrices (note all full matrices, dense, in order from 1) for(i=1;i<=ncones;i++) { //Single Cone if(ncones == 1 && !mxIsCell(pSDP)) total_dim += addCMatrix(C,pSDP,(int)i+linoffset); //Multiple Cones else total_dim += addCMatrix(C,mxGetCell(pSDP,i-1),(int)i+linoffset); } //Add Linear Dims total_dim += nLB+nUB+nlincon; #ifdef DEBUG mexPrintf("\nTotal dimension of all cones: %d\n\n",total_dim); #endif //Setup Each Constraint (for each decision var) (in order from 1) indlb = 1; indub = 1; for(i=1;i<=ndec;i++) { //For each Semidefinte A matrix (sparse triu, in reverse order, i.e. [SD, LP, UB, LB]) for(j=ncones;j>0;j--) { //Create an A matrix blockptr=(struct sparseblock*)malloc(sizeof(struct sparseblock)); if(blockptr==NULL) { sprintf(msgbuf,"Error allocating memory for Semidefinite A[%d,%d]",i,j+linoffset); mexErrMsgTxt(msgbuf); } //Single Cone if(ncones == 1 && !mxIsCell(pSDP)) addAMatrix(blockptr,pSDP,(int)i,(int)j+linoffset); //Multiple Cones else addAMatrix(blockptr,mxGetCell(pSDP,j-1),(int)i,(int)j+linoffset); //Insert A matrix into constraint list blockptr->next=constraints[i].blocks; constraints[i].blocks=blockptr; } //Linear Inequality Constraints if(nlincon) { //Create an A matrix blockptr=(struct sparseblock*)malloc(sizeof(struct sparseblock)); if(blockptr==NULL) { sprintf(msgbuf,"Error allocating memory for LP A[%d]",i); mexErrMsgTxt(msgbuf); } //Insert LP A entries j = 1 + (int)(nUB > 0) + (int)(nLB > 0); insertLPVector(blockptr, pA, (int)i, (int)j); //Insert A matrix into constraint list blockptr->next=constraints[i].blocks; constraints[i].blocks=blockptr; } //Upper Bounds if(nUB) { //Create an A matrix blockptr=(struct sparseblock*)malloc(sizeof(struct sparseblock)); if(blockptr==NULL) { sprintf(msgbuf,"Error allocating memory for UB A[%d]",i); mexErrMsgTxt(msgbuf); } //Insert Bound A matrix entries if(nLB > 0) indub += insertBound(blockptr,ub,nUB,(int)i,2,indub,1.0); //block 2 ([LB,UB,..] 1.0 for ub) else indub += insertBound(blockptr,ub,nUB,(int)i,1,indub,1.0); //block 1 (first block, 1.0 for ub) //Insert A matrix into constraint list blockptr->next=constraints[i].blocks; constraints[i].blocks=blockptr; } //Lower Bounds if(nLB) { //Create an A matrix blockptr=(struct sparseblock*)malloc(sizeof(struct sparseblock)); if(blockptr==NULL) { sprintf(msgbuf,"Error allocating memory for LB A[%d]",i); mexErrMsgTxt(msgbuf); } //Insert Bound A matrix entries indlb += insertBound(blockptr,lb,nLB,(int)i,1,indlb,-1.0); //block 1 (always first block, -1.0 for lb) //Insert A matrix into constraint list blockptr->next=constraints[i].blocks; constraints[i].blocks=blockptr; } } // //Set y0 // if (y0) // for (i=0;i<ndec;i++) { // DSDP_ERR( DSDPSetY0(dsdp,(int)i+1,y0[i]), "Error setting Y0"); // } // //Get CSDP Default Options initparams(¶ms,&printLevel); //Set OPTI default printLevel (none) printLevel = 0; //Get User Options (overwrites defaults above) if(nrhs > eOPTS && !mxIsEmpty(pOPTS)) { //OPTI Options GetIntegerOption(pOPTS,"maxiter",¶ms.maxiter); GetDoubleOption(pOPTS,"maxtime",&maxtime); GetIntegerOption(pOPTS,"display",&printLevel); GetDoubleOption(pOPTS,"objconstant",&objconstant); //CSDP Options GetDoubleOption(pOPTS,"axtol",¶ms.axtol); GetDoubleOption(pOPTS,"atytol",¶ms.atytol); GetDoubleOption(pOPTS,"objtol",¶ms.objtol); GetDoubleOption(pOPTS,"pinftol",¶ms.pinftol); GetDoubleOption(pOPTS,"dinftol",¶ms.dinftol); GetDoubleOption(pOPTS,"minstepfrac",¶ms.minstepfrac); GetDoubleOption(pOPTS,"maxstepfrac",¶ms.maxstepfrac); GetDoubleOption(pOPTS,"minstepp",¶ms.minstepp); GetDoubleOption(pOPTS,"minstepd",¶ms.minstepd); GetIntegerOption(pOPTS,"usexzgap",¶ms.usexzgap); GetIntegerOption(pOPTS,"tweakgap",¶ms.tweakgap); GetIntegerOption(pOPTS,"affine",¶ms.affine); GetDoubleOption(pOPTS,"perturbobj",¶ms.perturbobj); //Optionally write problem to a SDPA sparse file if(mxGetField(pOPTS,0,"writeprob") && !mxIsEmpty(mxGetField(pOPTS,0,"writeprob")) && mxIsChar(mxGetField(pOPTS,0,"writeprob"))) { mxGetString(mxGetField(pOPTS,0,"writeprob"),msgbuf,1024); write_prob(msgbuf,(int)total_dim,(int)ndec,C,b,constraints); } } //Print Header if(printLevel) { mexPrintf("\n------------------------------------------------------------------\n"); mexPrintf(" This is CSDP v%s\n",CSDP_VERSION); mexPrintf(" Author: Brian Borchers\n MEX Interface J. Currie 2013\n\n"); mexPrintf(" Problem Properties:\n"); mexPrintf(" # Decision Variables: %4d\n",ndec); mexPrintf(" # Linear Inequalities: %4d ",nlincon); if(nlincon) mexPrintf("[%d nz]\n",lincon_nz); else mexPrintf("\n"); mexPrintf(" # Semidefinite Cones: %4d\n",ncones); mexPrintf("------------------------------------------------------------------\n"); } //Start timer start = clock(); //Find Initial Solution initsoln((int)total_dim,(int)ndec,C,b,constraints,&X,&y,&Z); //Solve the problem status=easy_sdp((int)total_dim,(int)ndec,C,b,constraints,objconstant,params,&X,&y,&Z,pval,dval,pinf,dinf,realgap,xzgap); //Stop Timer end = clock(); evaltime = ((double)(end-start))/CLOCKS_PER_SEC; //Copy and negate solution for(i=0;i<ndec;i++) x[i] = -y[i+1]; //Assign other MATLAB outputs *iter = (double)citer-1; *exitflag = (double)status; //Print Header if(printLevel){ //Detail termination reason switch(status) { //Success case 0: mexPrintf("\n *** CSDP CONVERGED ***\n"); break; //Infeasible case 1: mexPrintf("\n *** TERMINATION: Primal Infeasible ***\n"); break; case 2: mexPrintf("\n *** TERMINATION: Dual Infeasible ***\n"); break; //Partial Success case 3: mexPrintf("\n *** TERMINATION: PARTIAL SUCESS ***\n *** A Solution is found but full accuracy was not achieved ***\n"); break; //Error case 4: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Maximum Iterations Reached ***\n"); break; case CSDP_MAX_TIME: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Maximum Time Reached ***\n"); break; case 5: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Stuck at edge of primal feasibility ***\n"); break; case 6: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Stuck at edge of dual infeasibility ***\n"); break; case 7: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Lack of progress ***\n"); break; case 8: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: X, Z, or O was singular ***\n"); break; case 9: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Detected NaN or Inf values ***\n"); break; case 10: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Easy-SDP General Failure ***\n"); break; case 11: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Failed C Check - Check Symmetry! ***\n"); break; case 12: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Failed Constraints Check ***\n"); break; case CSDP_USER_TERMINATION: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: User Exited ***\n"); break; //Here is ok too? default: mexPrintf("\n *** CSDP FINISHED ***\n"); break; } if(status==0 || status==3) mexPrintf("\n Final Primal Objective: %2.5g\n Final Dual Objective: %2.5g\n In %5d iterations\n %5.2f seconds\n",*pval,*dval,citer-1,evaltime); mexPrintf("------------------------------------------------------------------\n\n"); } //Optionally write solution to a SDPA sparse file if(nrhs > eOPTS && !mxIsEmpty(pOPTS) && mxGetField(pOPTS,0,"writesol") && !mxIsEmpty(mxGetField(pOPTS,0,"writesol")) && mxIsChar(mxGetField(pOPTS,0,"writesol"))) { mxGetString(mxGetField(pOPTS,0,"writesol"),msgbuf,1024); write_sol(msgbuf,(int)total_dim,(int)ndec,X,y,Z); } //Optionally retrieve X if(nlhs > 4) { plhs[4] = mxCreateCellMatrix(X.nblocks,1); for(i=0;i<X.nblocks;i++) { //Set Block Values if(X.blocks[i+1].blockcategory == DIAG) { mxSetCell(plhs[4],i,mxCreateDoubleMatrix(X.blocks[i+1].blocksize,1,mxREAL)); //create vector xx = mxGetPr(mxGetCell(plhs[4],i)); for(j=0;j<X.blocks[i+1].blocksize;j++) xx[j] = X.blocks[i+1].data.vec[j+1]; } else { mxSetCell(plhs[4],i,mxCreateDoubleMatrix(X.blocks[i+1].blocksize,X.blocks[i+1].blocksize,mxREAL)); //create matrix xx = mxGetPr(mxGetCell(plhs[4],i)); for(j=0;j<(X.blocks[i+1].blocksize*X.blocks[i+1].blocksize);j++) xx[j] = X.blocks[i+1].data.mat[j]; } } } //Free CSDP Problem (including all allocated memory) free_prob((int)total_dim,(int)ndec,C,b,constraints,X,y,Z); }