/* nag_glopt_bnd_mcs_solve (e05jbc) Example Program. * * Copyright 2006 Numerical Algorithms Group. * * Mark 9, 2009. */ #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif static void NAG_CALL objfun(Integer n, const double x[], double *f, Integer nstate, Nag_Comm *comm, Integer *inform); static void NAG_CALL monit(Integer n, Integer ncall, const double xbest[], const Integer icount[], Integer sdlist, const double list[], const Integer numpts[], const Integer initpt[], Integer nbaskt, const double xbaskt[], const double boxl[], const double boxu[], Integer nstate, Nag_Comm *comm, Integer *inform); static void NAG_CALL output_current_box(Integer n, const double boxl[], const double boxu[], FILE *fpout); #ifdef __cplusplus } #endif int main(int argc, char *argv[]) { FILE *fpin, *fpout; /* Scalars */ double obj; Integer exit_status, i, n, plot, sdlist; Nag_BoundType boundenum; Nag_MCSInitMethod initmethodenum; /* Arrays */ char bound[16], initmethod[18]; double *bl = 0, *bu = 0, *list = 0, *x = 0; Integer *initpt = 0, *numpts = 0; Integer iuser[1]; /*Nag Types*/ Nag_E05State state; NagError fail; Nag_Comm comm; comm.iuser = iuser; exit_status = 0; 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); fprintf(fpout, "nag_glopt_bnd_mcs_solve (e05jbc) Example Program Results\n"); comm.p = (Pointer) fpout; /* Skip heading in data file */ fscanf(fpin, "%*[^\n] "); /* Read n and sdlist from data file */ fscanf(fpin, "%ld%ld%*[^\n] ", &n, &sdlist); if (n > 0 && sdlist > 0) { /* Allocate memory */ if (!(bl = NAG_ALLOC(n, double)) || !(bu = NAG_ALLOC(n, double)) || !(list = NAG_ALLOC(n*sdlist, double)) || !(x = NAG_ALLOC(n, double)) || !(initpt = NAG_ALLOC(n, Integer)) || !(numpts = NAG_ALLOC(n, Integer))) { fprintf(fpout, "Allocation failure\n"); exit_status = -1; goto END; } /* Read in bound (and bl and bu if necessary) */ fscanf(fpin, "%s%*[^\n] ", bound); /* * nag_enum_name_to_value (x04nac). * Converts NAG enum member name to value */ boundenum = (Nag_BoundType) nag_enum_name_to_value(bound); if (boundenum == Nag_Bounds) /* Read in the whole of each bound */ { for (i = 0; i < n; ++i) fscanf(fpin, "%lf", &bl[i]); fscanf(fpin, "%*[^\n] "); for (i = 0; i < n; ++i) fscanf(fpin, "%lf", &bu[i]); fscanf(fpin, "%*[^\n] "); } else if (boundenum == Nag_BoundsEqual) /* Bounds are uniform: read in only the first entry of each */ { fscanf(fpin, "%lf%*[^\n] ", &bl[0]); fscanf(fpin, "%lf%*[^\n] ", &bu[0]); } /* Read in initmethod */ fscanf(fpin, "%s%*[^\n] ", initmethod); /* * nag_enum_name_to_value (x04nac). * Converts NAG enum member name to value */ initmethodenum = (Nag_MCSInitMethod) nag_enum_name_to_value(initmethod); /* Read in plot. Its value determines whether monit displays information on the current search box */ fscanf(fpin, "%ld%*[^\n] ", &plot); /* Communicate plot through to monit */ iuser[0] = plot; /* Call nag_glopt_bnd_mcs_init (e05jac) to initialize * nag_glopt_bnd_mcs_solve (e05jbc). */ nag_glopt_bnd_mcs_init(n, &state, &fail); if (fail.code != NE_NOERROR) { fprintf(fpout, "Initialization of nag_glopt_bnd_mcs_init (e05jac) " "failed.\n%s\n", fail.message); exit_status = 1; goto END; } /* Solve the problem. */ /* nag_glopt_bnd_mcs_solve (e05jbc). * Global optimization by multilevel coordinate search, simple bounds. */ nag_glopt_bnd_mcs_solve(n, objfun, boundenum, initmethodenum, bl, bu, sdlist, list, numpts, initpt, monit, x, &obj, &state, &comm, &fail); if (fail.code == NE_NOERROR) { fprintf(fpout, "Final objective value = %11.5f\n", obj); fprintf(fpout, "Global optimum X = "); for (i = 0; i < n; ++i) fprintf(fpout, "%9.5f", x[i]); fprintf(fpout, "\n"); } else { fprintf(fpout, "Error message from nag_glopt_bnd_mcs_solve (e05jbc).\n%s\n", fail.message); exit_status = 1; } } END: if (fpin != stdin) fclose(fpin); if (fpout != stdout) fclose(fpout); if (bl) NAG_FREE(bl); if (bu) NAG_FREE(bu); if (list) NAG_FREE(list); if (x) NAG_FREE(x); if (initpt) NAG_FREE(initpt); if (numpts) NAG_FREE(numpts); return exit_status; } static void NAG_CALL objfun(Integer n, const double x[], double *f, Integer nstate, Nag_Comm *comm, Integer *inform) { /* Routine to evaluate objective function */ FILE *fpout = (FILE *) comm->p; *inform = 0; if (*inform >= 0) /* Here we're prepared to evaluate objfun at the current x */ { if (nstate == 1) /* This is the first call to objfun */ { fprintf(fpout, "\n(objfun was just called for the first time)\n"); } *f = ( 3.0*pow((1.0-x[0]), 2)*exp(-pow(x[0], 2)-pow((x[1]+1), 2)) - (10.0*(x[0]/5.0-pow(x[0], 3)-pow(x[1], 5))* exp(-pow(x[0], 2)-pow(x[1], 2))) - 1.0/3.0*exp(-pow((x[0]+1.0), 2)-pow(x[1], 2)) ); } } static void NAG_CALL monit(Integer n, Integer ncall, const double xbest[], const Integer icount[], Integer sdlist, const double list[], const Integer numpts[], const Integer initpt[], Integer nbaskt, const double xbaskt[], const double boxl[], const double boxu[], Integer nstate, Nag_Comm *comm, Integer *inform) { /* Scalars */ Integer i, j; Integer plot; #define XBASKT(I, J) xbaskt[(I-1)*nbaskt + (J-1)] FILE *fpout = (FILE *) comm->p; *inform = 0; if (*inform >= 0) /* We are going to allow the iterations to continue */ { /* Extract plot from the communication structure */ plot = comm->iuser[0]; if (nstate == 0 || nstate == 1) /* When nstate == 1, monit is called for the first time. * When nstate == 0, monit is called for the first AND last time. * Display a welcome message */ { fprintf(fpout, "\n*** Begin monitoring information ***\n\n"); if (plot != 0 && n == 2) fprintf(fpout, "\n\n"); } if (plot != 0 && n == 2) { /* Display the coordinates of the edges of the current search box */ output_current_box(n, boxl, boxu, fpout); } if (nstate <= 0) /* monit is called for the last time */ { if (plot != 0 && n == 2) fprintf(fpout, "\n\n"); fprintf(fpout, "Total sub-boxes = %5ld\n", icount[0]); fprintf(fpout, "Total function evaluations = %5ld\n", ncall); fprintf(fpout, "Total function evaluations used in local search = %5ld\n", icount[1]); fprintf(fpout, "Total points used in local search = %5ld\n", icount[2]); fprintf(fpout, "Total sweeps through levels = %5ld\n", icount[3]); fprintf(fpout, "Total splits by init. list = %5ld\n", icount[4]); fprintf(fpout, "Lowest level with nonsplit boxes = %5ld\n", icount[5]); fprintf(fpout, "Number of candidate minima in the 'shopping basket'" " = %5ld\n", nbaskt); fprintf(fpout, "Shopping basket:\n"); for (i = 1; i <= n; ++i) { fprintf(fpout, "xbaskt(%3ld,:) =", i); for (j = 1; j <= nbaskt; ++j) fprintf(fpout, "%9.5f", XBASKT(i, j)); fprintf(fpout, "\n"); } fprintf(fpout, "\n"); fprintf(fpout, "*** End monitoring information ***\n"); fprintf(fpout, "\n"); } } } static void NAG_CALL output_current_box(Integer n, const double boxl[], const double boxu[], FILE *fpout) { fprintf(fpout, "%20.15f %20.15f\n", boxl[0], boxl[1]); fprintf(fpout, "%20.15f %20.15f\n\n", boxl[0], boxu[1]); fprintf(fpout, "%20.15f %20.15f\n", boxl[0], boxl[1]); fprintf(fpout, "%20.15f %20.15f\n\n", boxu[0], boxl[1]); fprintf(fpout, "%20.15f %20.15f\n", boxl[0], boxu[1]); fprintf(fpout, "%20.15f %20.15f\n\n", boxu[0], boxu[1]); fprintf(fpout, "%20.15f %20.15f\n", boxu[0], boxl[1]); fprintf(fpout, "%20.15f %20.15f\n\n", boxu[0], boxu[1]); }