/* nag_nag_opt_sparse_convex_qp_solve (e04nqc) Example Program. * * Copyright 2004 Numerical Algorithms Group. * * Mark 8, 2004. */ #include #include #include #include #include #include static void qphx(Integer ncolh, const double x[], double hx[], Integer nstate, Nag_Comm *comm); int main(void) { /* Scalars */ double obj, objadd, sinf; Integer exit_status, i, icol, iobj, j, jcol, lenc, m, n, ncolh, ne, ninf; Integer nname, ns; /* Arrays */ char prob[9], start_char[2]; char **names; double *acol=0, *bl=0, *bu=0, *c=0, *pi=0, *rc=0, *x=0; Integer *helast=0, *hs=0, *inda=0, *loca=0; /*Nag Types*/ Nag_E04State state; NagError fail; Nag_Start start; Nag_Comm comm; Nag_FileID fileid; exit_status = 0; INIT_FAIL(fail); Vprintf("nag_opt_sparse_convex_qp_solve (e04nqc) Example Program Results\n"); /* Skip heading in data file. */ Vscanf("%*[^\n] "); /* Read ne, iobj, ncolh, start and nname from data file. */ Vscanf("%ld%ld%*[^\n] ", &n, &m); Vscanf("%ld%ld%ld ' %1s '%ld%*[^\n] ", &ne, &iobj, &ncolh, start_char, &nname); if (n>=1 && m >= 1) { /* Allocate memory */ if ( !(names = NAG_ALLOC(n+m, char *)) || !(acol = NAG_ALLOC(ne, double)) || !(bl = NAG_ALLOC(m+n, double)) || !(bu = NAG_ALLOC(m+n, double)) || !(c = NAG_ALLOC(1, double)) || !(pi = NAG_ALLOC(m, double)) || !(rc = NAG_ALLOC(n+m, double)) || !(x = NAG_ALLOC(n+m, double)) || !(helast = NAG_ALLOC(n+m, Integer)) || !(hs = NAG_ALLOC(n+m, Integer)) || !(inda = NAG_ALLOC(ne, Integer)) || !(loca = NAG_ALLOC(n+1, Integer)) ) { Vprintf("Allocation failure\n"); exit_status = -1; goto END; } } else { Vprintf("%s", "Either m or n invalid\n"); exit_status = 1; return exit_status; } /* Read names from data file. */ for (i = 1; i <= nname; ++i) { names[i-1] = NAG_ALLOC(9, char); Vscanf(" ' %8s '", names[i-1]); } Vscanf("%*[^\n] "); /* Read the matrix acol from data file. Set up LOCA. */ jcol = 1; loca[jcol - 1] = 1; for (i = 1; i <= ne; ++i) { /* Element (inda[i-1], icol) is stored in acol[i-1]. */ Vscanf("%lf%ld%ld%*[^\n] ", &acol[i - 1], &inda[i - 1], &icol); if (icol < jcol) { /* Elements not ordered by increasing column index. */ Vprintf("%s%5ld%s%5ld%s%s\n", "Element in column", icol, " found after element in column", jcol, ". Problem", " abandoned."); } else if (icol == jcol + 1) { /* Index in ACOL of the start of the ICOL-th column equals I. */ loca[icol - 1] = i; jcol = icol; } else if (icol > jcol + 1) { /* Index in acol of the start of the icol-th column equals i, */ /* but columns jcol+1,jcol+2,...,icol-1 are empty. Set the */ /* corresponding elements of loca to i. */ for (j = jcol + 1; j <= icol - 1; ++j) { loca[j - 1] = i; } loca[icol - 1] = i; jcol = icol; } } loca[n] = ne + 1; if (n > icol) { /* Columns n,n-1,...,icol+1 are empty. Set the corresponding */ /* elements of loca accordingly. */ for (i = n; i >= icol + 1; --i) { loca[i - 1] = loca[i]; } } /* Read bl, bu, hs and x from data file. */ for (i = 1; i <= n + m; ++i) { Vscanf("%lf", &bl[i - 1]); } Vscanf("%*[^\n] "); for (i = 1; i <= n + m; ++i) { Vscanf("%lf", &bu[i - 1]); } Vscanf("%*[^\n] "); if (*(unsigned char *)start_char == 'C') { start = Nag_Cold; for (i = 1; i <= n; ++i) { Vscanf("%ld", &hs[i - 1]); } Vscanf("%*[^\n] "); } else if (*(unsigned char *)start_char == 'W') { start = Nag_Warm; for (i = 1; i <= n + m; ++i) { Vscanf("%ld", &hs[i - 1]); } Vscanf("%*[^\n] "); } for (i = 1; i <= n; ++i) { Vscanf("%lf", &x[i - 1]); } Vscanf("%*[^\n] "); /* Call nag_opt_sparse_convex_qp_init (e04npc) to initialise e04nqc. */ /* nag_opt_sparse_convex_qp_init (e04npc). * Initialization function for * nag_opt_sparse_convex_qp_solve (e04nqc) */ nag_opt_sparse_convex_qp_init(&state, &fail); if (fail.code != NE_NOERROR) { Vprintf("Initialisation of nag_opt_sparse_convex_qp_solve (e04nqc)" " failed.\n"); exit_status = 1; goto END; } /* By default nag_opt_sparse_convex_qp_solve (e04nqc) does not print * monitoring information. Call nag_open_file (x04acc) to set the print file * fileid */ /* nag_open_file (x04acc). * Open unit number for reading, writing or appending, and * associate unit with named file */ nag_open_file("", 2, &fileid, &fail); if (fail.code != NE_NOERROR) { Vprintf("Fileid could not be obtained.\n"); exit_status = 1; goto END; } /* nag_opt_sparse_convex_qp_option_set_integer (e04ntc). * Set a single option for nag_opt_sparse_convex_qp_solve * (e04nqc) from an integer argument */ nag_opt_sparse_convex_qp_option_set_integer("Print file", fileid, &state, &fail); if (fail.code != NE_NOERROR) { Vprintf("Files stream could not be set.\n"); exit_status = 1; goto END; } /* We have no explicit objective vector so set lenc = 0; the * objective vector is stored in row iobj of acol. */ lenc = 0; objadd = 0.; strcpy(prob, ""); /* Do not allow any elastic variables (i.e. they cannot be */ /* infeasible). If we'd set optional argument "Elastic mode" to 0, */ /* we wouldn't need to set the individual elements of array helast. */ for (i = 1; i <= n + m; ++i) { helast[i - 1] = 0; } /* Solve the QP problem. */ /* nag_opt_sparse_convex_qp_solve (e04nqc). * LP or QP problem (suitable for sparse problems) */ nag_opt_sparse_convex_qp_solve(start, qphx, m, n, ne, nname, lenc, ncolh, iobj, objadd, prob, acol, inda, loca, bl, bu, c, names, helast, hs, x, pi, rc, &ns, &ninf, &sinf, &obj, &state, &comm, &fail); Vprintf("\n"); Vprintf("On exit from e04nqc, fail.message = %s\n", fail.message); if (fail.code == NE_NOERROR) { Vprintf("Final objective value = %11.3e\n", obj); Vprintf("Optimal X = "); for (i = 1; i <= n; ++i) { Vprintf("%9.2f%s", x[i - 1], i%7 == 0 || i == n ?"\n":" "); } } END: for (i = 0; i < n+m; i++) { if (names[i]) NAG_FREE(names[i]); } if (names) NAG_FREE(names); if (acol) NAG_FREE(acol); if (bl) NAG_FREE(bl); if (bu) NAG_FREE(bu); if (c) NAG_FREE(c); if (pi) NAG_FREE(pi); if (rc) NAG_FREE(rc); if (x) NAG_FREE(x); if (helast) NAG_FREE(helast); if (hs) NAG_FREE(hs); if (inda) NAG_FREE(inda); if (loca) NAG_FREE(loca); return exit_status; } static void qphx(Integer ncolh, const double x[], double hx[], Integer nstate, Nag_Comm *comm) { /* Routine to compute H*x. (In this version of qphx, the Hessian * matrix H is not referenced explicitly.) */ /* Parameter adjustments */ #define HX(I) hx[(I)-1] #define X(I) x[(I)-1] /* Function Body */ HX(1) = X(1) * 2; HX(2) = X(2) * 2; HX(3) = (X(3) + X(4)) * 2; HX(4) = HX(3); HX(5) = X(5) * 2; HX(6) = (X(6) + X(7)) * 2; HX(7) = HX(6); return; } /* qphx */