/* nag_opt_sparse_convex_qp_option_set_file (e04nrc) Example Program. * * Copyright 2004 Numerical Algorithms Group. * * Mark 8, 2004. */ #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif static void NAG_CALL qphx(Integer ncolh, const double x[], double hx[], Integer nstate, Nag_Comm *comm); #ifdef __cplusplus } #endif int main(int argc, char *argv[]) { FILE *fpin, *fpout; char *optionsfile; char *outfile; Integer exit_status = 0; /* Scalars */ double bndinf, featol, obj, objadd, sinf; Integer elmode, i, icol, iobj, j, jcol, lenc, m, n, ncolh, ne; Integer ninf, nname, ns; /* Arrays */ char nag_enum_arg[40]; char *cuser = 0, *prob = 0; char **names; double *acol = 0, *bl = 0, *bu = 0, *c = 0, *pi = 0, *rc = 0; double *ruser = 0, *x = 0; Integer *helast = 0, *hs = 0, *inda = 0, *iuser = 0, *loca = 0; /*Nag Types*/ Nag_E04State state; Nag_Start start; Nag_Comm comm; Nag_FileID fileidout; Nag_FileID fileidin; NagError fail; INIT_FAIL(fail); /* Check for command-line IO options */ fpin = nag_example_file_io(argc, argv, "-data", NULL); fpout = nag_example_file_io(argc, argv, "-results", NULL); (void) nag_example_file_io(argc, argv, "-nag_write", &outfile); (void) nag_example_file_io(argc, argv, "-options", &optionsfile); fprintf( fpout, "%s", "nag_opt_sparse_convex_qp_option_set_file (e04nrc) Example" " Program Results"); fprintf(fpout, "\n"); /* This program demonstrates the use of routines to set and * get values of optional parameters associated with * nag_opt_sparse_convex_qp_solve (e04nqc). */ /* Skip heading in data file. */ fscanf(fpin, "%*[^\n] "); fscanf(fpin, "%ld %ld ", &n, &m); fscanf(fpin, "%*[^\n] "); if (n >= 1 && m >= 1) { /* Read ne, iobj, ncolh, start and nname from data file. */ fscanf(fpin, "%ld %ld %ld %s %ld", &ne, &iobj, &ncolh, nag_enum_arg, &nname); fscanf(fpin, "%*[^\n] "); /* nag_enum_name_to_value(x04nac). * Converts NAG enum member name to value */ start = (Nag_Start) nag_enum_name_to_value(nag_enum_arg); /* Allocate memory */ if (!(names = NAG_ALLOC(n+m, char *)) || !(prob = NAG_ALLOC(9, 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)) || !(iuser = NAG_ALLOC(1, Integer)) || !(loca = NAG_ALLOC(n+1, Integer))) { fprintf(fpout, "Allocation failure\n"); exit_status = -1; goto END; } } else { fprintf(fpout, "Invalid n or nf or nea or neg\n"); exit_status = 1; goto END; } /* Read names from data file. */ for (i = 1; i <= nname; ++i) { names[i-1] = NAG_ALLOC(9, char); fscanf(fpin, " ' %8s '", names[i-1]); } fscanf(fpin, "%*[^\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]. */ fscanf(fpin, "%lf %ld %ld", &acol[i - 1], &inda[i - 1], &icol); fscanf(fpin, "%*[^\n] "); if (icol < jcol) { /* Elements not ordered by increasing column index. */ fprintf(fpout, "%s %5ld %s %5ld", "Element in column", icol, " found after element in column", jcol); fprintf(fpout, "%s\n\n", ". 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) { fscanf(fpin, "%lf", &bl[i - 1]); } fscanf(fpin, "%*[^\n] "); for (i = 1; i <= n + m; ++i) { fscanf(fpin, "%lf", &bu[i - 1]); } fscanf(fpin, "%*[^\n] "); if (start == Nag_Cold) { for (i = 1; i <= n; ++i) { fscanf(fpin, "%ld", &hs[i - 1]); } fscanf(fpin, "%*[^\n] "); } else if (start == Nag_Warm) { for (i = 1; i <= n + m; ++i) { fscanf(fpin, "%ld", &hs[i - 1]); } fscanf(fpin, "%*[^\n] "); } for (i = 1; i <= n; ++i) { fscanf(fpin, "%lf", &x[i - 1]); } fscanf(fpin, "%*[^\n] "); /* 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, ""); /* 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) { fprintf( fpout, "Initialisation of nag_opt_sparse_convex_qp_solve (e04nqc)" " failed.\n%s\n", fail.message); 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 * fileidout */ /* nag_open_file (x04acc). * Open unit number for reading, writing or appending, and * associate unit with named file */ if (outfile) { fclose(fpout); /* Close application output */ fpout = 0; } nag_open_file(outfile, 2, &fileidout, &fail); if (fail.code != NE_NOERROR) { exit_status = 2; 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", fileidout, &state, &fail); if (fail.code != NE_NOERROR) { exit_status = 1; goto END; } /* Set input to options file to read. */ /* nag_open_file (x04acc), see above. */ nag_open_file(optionsfile, 0, &fileidin, &fail); if (fail.code != NE_NOERROR) { exit_status = 1; goto END; } /* nag_opt_sparse_convex_qp_option_set_file (e04nrc). * Supply optional parameter values for * nag_opt_sparse_convex_qp_solve (e04nqc) from external * file */ nag_opt_sparse_convex_qp_option_set_file(fileidin, &state, &fail); if (fail.code != NE_NOERROR) { exit_status = 1; goto END; } nag_close_file(fileidin, &fail); /* Close Library output */ if (outfile && !(fpout = fopen(outfile, "a"))) /* Open application output */ { exit_status = 2; goto END; } /* Use nag_opt_sparse_convex_qp_option_get_integer (e04nxc) to find the value * of Integer-valued option 'Elastic mode'. */ /* nag_opt_sparse_convex_qp_option_get_integer (e04nxc). * Get the setting of an integer valued option of * nag_opt_sparse_convex_qp_solve (e04nqc) */ nag_opt_sparse_convex_qp_option_get_integer("Elastic mode", &elmode, &state, &fail); if (fail.code != NE_NOERROR) { exit_status = 1; goto END; } nag_close_file(fileidout, &fail); if (outfile && !(fpout = fopen(outfile, "a"))) { exit_status = 2; goto END; } fprintf(fpout, "Option 'Elastic mode' has the value %3ld.\n", elmode); /* Use nag_opt_sparse_convex_qp_option_set_double (e04nuc) to set the value of * real-valued option 'Infinite bound size'. */ bndinf = 1e10; /* nag_opt_sparse_convex_qp_option_set_double (e04nuc). * Set a single option for nag_opt_sparse_convex_qp_solve * (e04nqc) from a double argument */ nag_opt_sparse_convex_qp_option_set_double("Infinite bound size", bndinf, &state, &fail); if (fail.code != NE_NOERROR) { exit_status = 1; goto END; } /* Use nag_opt_sparse_convex_qp_option_get_double (e04nyc) to find the value * of real-valued option 'Feasibility tolerance'. */ /* nag_opt_sparse_convex_qp_option_get_double (e04nyc). * Get the setting of a double valued option of * nag_opt_sparse_convex_qp_solve (e04nqc) */ nag_opt_sparse_convex_qp_option_get_double("Feasibility tolerance", &featol, &state, &fail); if (fail.code != NE_NOERROR) { exit_status = 1; goto END; } fprintf(fpout, "Option 'Feasibility tolerance' has the value %14.5e.\n", featol); /* Use nag_opt_sparse_convex_qp_option_set_string (e04nsc) to set the option * 'Iterations limit'. */ /* nag_opt_sparse_convex_qp_option_set_string (e04nsc). * Set a single option for nag_opt_sparse_convex_qp_solve * (e04nqc) from a character string */ nag_opt_sparse_convex_qp_option_set_string("Iterations limit 50", &state, &fail); if (fail.code != NE_NOERROR) { exit_status = 1; goto END; } /* Solve the QP problem. */ /* nag_opt_sparse_convex_qp_solve (e04nqc). * LP or QP problem (suitable for sparse problems) */ if (outfile) fclose(fpout); /* Close application output */ nag_open_file(outfile, 2, &fileidout, &fail); 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); if (outfile && !(fpout = fopen(outfile, "a"))) { exit_status = 2; goto END; } if (fail.code == NE_NOERROR) { fprintf(fpout, "Final objective value = %12.3e\n", obj); fprintf(fpout, "Optimal X = "); for (i = 1; i <= n; ++i) { fprintf(fpout, "%9.2f%s", x[i - 1], i%7 == 0 || i == n?"\n":" "); } } else { fprintf(fpout, "Error from nag_opt_sparse_convex_qp_solve (e04nqc).\n%s\n", fail.message); exit_status = 1; goto END; } nag_close_file(fileidout, &fail); if (fail.code != NE_NOERROR) { exit_status = 2; } END: if (fpin != stdin) fclose(fpin); if (fpout != stdout) fclose(fpout); if (cuser) NAG_FREE(cuser); for (i = 1; i <= nname; ++i) { if (names[i-1]) NAG_FREE(names[i-1]); } if (names) NAG_FREE(names); if (prob) NAG_FREE(prob); 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 (ruser) NAG_FREE(ruser); if (x) NAG_FREE(x); if (helast) NAG_FREE(helast); if (hs) NAG_FREE(hs); if (inda) NAG_FREE(inda); if (iuser) NAG_FREE(iuser); if (loca) NAG_FREE(loca); if (optionsfile) NAG_FREE(optionsfile); return exit_status; } static void NAG_CALL 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 */