/* SIMPFRONT.C */
/*-
standalone front end for simplex minimizer:
read data file from stdin and stuff values into externals
setup for call of <simpmain()>
some initial and final output

J.A. Rupley, Tucson, Arizona
rupley!local@cs.arizona.edu
*/

#define STANDALONE

#include "simpdefs.h"

/* used only by standalone version; declare as external in <func()> */
struct dat      data[NDATA];
double          bounds[2][NPARM];
int             ndatval;
char            title[BUFSIZ];

/*-
READ_DATA
	READ TITLE, CONTROL VARIABLES, STARTING SIMPLEX, AND DATA FROM INPUT
	MANIPULATION OF INPUT PRIOR TO FITTING SHOULD BE DONE HERE
	INPUT IS FREE-FORM (IE, WITHOUT FIELD WIDTHS),
		BUT THE SEQUENCE OF ENTRIES MUST BE EXACTLY AS BELOW
	MNEMONIC IDENTIFIERS IN THE INPUT ARE DISCARDED BUT MUST BE PRESENT
	THE TITLE SHOULD BE ONE-LINE
*/


/*-
set externals for <simpmain()>:
struct pstruct p[nvert] = the starting simplex
double exit_test, quad_test
double ratio_exit_test
int prt_cycle, maxquad_skip
int iter, nparm, nvert, nfree, ndata
int verbose
int ndatval		unused
*/

main(argc, argv)
	int             argc;
	char          **argv;
{
	FILE           *fp_in;
	FILE           *fp_out;

	int             i, j;
	int             input_count;
	char            dummy[200];

	extern          simpmain();
	extern void     fsprint();
	extern void     fdatprint();
	extern void     enditall();

	fp_in = stdin;
	fp_out = stdout;

	/*
	 * read title, nvert, nparm, ndata, ndatval, iter, maxquad_skip,
	 * exit_test, prt_cycle, quad_test
	 */
	fgets(title, sizeof(title) - 1, fp_in);
	input_count = 0;
	input_count += fscanf(fp_in, "%*s %d", &nvert);
	input_count += fscanf(fp_in, "%*s %d", &nparm);
	input_count += fscanf(fp_in, "%*s %d", &ndata);
	input_count += fscanf(fp_in, "%*s %d", &ndatval);
	input_count += fscanf(fp_in, "%*s %d", &iter);
	input_count += fscanf(fp_in, "%*s %d", &maxquad_skip);
	input_count += fscanf(fp_in, "%*s %lg", &exit_test);
	input_count += fscanf(fp_in, "%*s %d", &prt_cycle);
	input_count += fscanf(fp_in, "%*s %lg", &quad_test);

	nfree = nvert - 1;

	if (input_count != 9) {
		fprintf(fp_out, "simpinput: error in format of input file control values\n");
		enditall();
	}
	if ((nvert <= 0) || (nvert > (NPARM + 1)) ||
	    (nparm <= 0) || (nparm > NPARM) ||
	    (ndata > NDATA) ||
	    (ndatval > NDATVAL) ||
	    (iter < 0) ||
	    (maxquad_skip < 0) ||
	    (exit_test == 0) ||
	    (prt_cycle < 0) ||
	    (quad_test < 0)) {
		fprintf(fp_out, "simpinput: error in value of input file control variable\n");
		enditall();
	}
	/*
	 * read simplex
	 */
	input_count = 0;
	fscanf(fp_in, "%*s");
	for (j = 0; j < nvert; j++) {
		for (i = 0; i < nparm; i++) {
			input_count += fscanf(fp_in, "%lg", &(p[j].parm[i]));
		}
	}

	if (input_count != nvert * nparm) {
		fprintf(fp_out, "simpinput: error in format of input file simplex values\n");
		enditall();
	}
	/*
	 * read bounds, if present
	 */
	input_count = 0;
	fscanf(fp_in, "%s", dummy);
	if (strncmp(dummy, "parm-bounds", 11) == 0) {
		for (j = 0; j < 2; j++) {
			for (i = 0; i < nparm; i++) {
				input_count += fscanf(fp_in, "%lg", &(bounds[j][i]));
			}
		}
		fscanf(fp_in, "%*s");	/* discard next mnemonic */
		if (input_count != 2 * nparm) {
			fprintf(fp_out, "simpinput: error in format of input file bounds values\n");
			enditall();
		}
	}
	/*
	 * read data array
	 */
	input_count = 0;
	for (j = 0; j < ndata; j++) {
		for (i = 0; i < ndatval; i++) {
			input_count += fscanf(fp_in, "%lg", &(data[j].datval[i]));
		}
	}


	if (input_count != ndata * ndatval) {
		fprintf(fp_out, "simpinput: error in format of input file bounds values\n");
		enditall();
	}
	/*
	 * read verbose
	 */
	input_count = 0;
	fscanf(fp_in, "%s", dummy);
	if (strncmp(dummy, "verbose", 7) == 0) {
		fscanf(fp_in, "%d", &verbose);
	} else {
		verbose = SLIGHTLY;
	}

	maxiter = 0;		/* to suppress some output from fdatprint() */

	if (ndata == 0)
		ndata = nvert;	/* to handle dataless function minimization */

	if (exit_test > 0) {
		ratio_exit_test = TRUE;
	} else {
		ratio_exit_test = FALSE;
		exit_test = -exit_test;
	}

	if (verbose >= VERY) {
		fprintf(fp_out, "verbose = %d\n", verbose);
		fprintf(fp_out, "ndata = %d\n", ndata);
		fprintf(fp_out, "ndatval = %d\n", ndatval);
		fprintf(fp_out, "nvert = %d\n", nvert);
		fprintf(fp_out, "nparm = %d\n", nparm);
		fprintf(fp_out, "iter = %d\n", iter);
		fprintf(fp_out, "maxquad_skip = %d\n", maxquad_skip);
		fprintf(fp_out, "exit_test = %20.14e\n", exit_test);
		fprintf(fp_out, "ratio_exit_test = %d\n", ratio_exit_test);
		fprintf(fp_out, "prt_cycle = %d\n", prt_cycle);
		fprintf(fp_out, "quad_test = %20.14e\n", quad_test);
		fsprint(fp_out, "\n\nsimplex:\n");
		fdatprint(fp_out);
	}
	/*
	 * calculate starting function values for simplex
	 */
	for (j = 0; j < nvert; j++) {
		func(&p[j]);
	}

	simpmain(fp_out);

	if (verbose >= SLIGHTLY) {
		fdatprint(fp_out);
	}
	enditall();
	/* NOT REACHED */

	return (OK);
}				/* END OF READ_DATA			 */
