/* SIMPMAIN.C */
/*-
control of simplex fitting
and of quadratic fit for var-covar matrix and std dev

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

#define XXXXFIT

#include "simpdefs.h"
/*-
set externals before enter <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 

on entering <simpmain()>:
set iterlimit to iter if iter != 0, else to MANYITER
set iter to 0
zero nquad_skip
set quad_cycle = quad_test for use if quad_test >1

in loop calling <simpfit()> and <simpdev()>:
set maxiter to iter+prt_cycle
test and reset as appropriate nquad_skip and quad_test

on return from <simpfit()>:
the structure <p[nvert]> has the current simplex and <pcent> the centroid,
the variables mean_func, rms_func, test, mse, and rms_data contain the 
mnemonically indicated information.

on return from <simpdev()>:
the array <qmat[nfree][nfree]> contains the variance-covariance matrix,
scaled by the factor mse;
the elements of structures <q> and <pmin> and variables yzero, ymin, ypmin,
and mse contain the mnemonically indicated information.
*/


int
simpmain(fp_out)
	FILE           *fp_out;
{
	int             quad_cycle, nquad_skip;
	int             iterlimit;


	extern          simpfit();
	extern          simpdev();
	extern void     ffitprint();
	extern void     fmatprint();
	extern void     fquadprint();
	extern void     pcopy();

	quad_cycle = (int) quad_test;
	nquad_skip = 0;
	prog_done = FALSE;
	if (iter > 0) {
		iterlimit = iter;
		iter = 0;
	} else {
		iterlimit = iter = 0;
	}

	/* If nvert == 1, then print simplex and calculated values, */
	/* and exit */
	if (nvert == 1) {
		pcopy(&pcent, &p[0]);
		if (verbose >= NEAR_SILENT)
			ffitprint(fp_out);
		return (0);
	}
	/* BEGIN LOOP */
	/* simplex minimization alternates with quadratic fit */
	while (TRUE) {
		maxiter = iter + prt_cycle;

		/* carry out simplex minimization */
		fflush(fp_out);
		simpfit();

		if (iterlimit > 0 && iter >= iterlimit)
			prog_done = TRUE;

		if (verbose >= VERY || verbose == SLIGHTLY && prog_done)
			ffitprint(fp_out);
		else if (verbose >= NEAR_SILENT)
			fprintf(fp_out, "iter=%d, mean=%16.10e test=%16.10e rmse=%12.6e\n", iter, mean_func, test, rms_data);

		/* if test vs quad_test false, */
		/* loop back to simpfit ; */
		if (iter == maxiter && !prog_done) {
			if (quad_test >= 1) {
				if (iter < (int) quad_test)
					continue;
			} else if (test >= quad_test)
				continue;
		}
		/* carry out quadratic fit */
		if (quad_test > 0)
			if (simpdev(fp_out) == ERROR) {
				if (verbose >= NEAR_SILENT)
					fprintf(fp_out, "simpmain: error return from <simpdev()>\n");
			}
		/* exit if done = return on exit test true */
		if (prog_done) {
			break;
		}
		/* increment nquad_skip if ypmin >= yzero */
		if (ypmin < yzero)
			nquad_skip = 0;
		else if (nquad_skip < maxquad_skip)
			nquad_skip++;

		/* alter quad_test for next set of */
		/* fitting cycles according to */
		/* nquad_skip = the number of */
		/* quadratic fit failures and quad_test */
		/* greater or less than unity */
		if (quad_test >= 1) {
			if (iter >= (int) quad_test)
				quad_test = (double) (iter +
					     (nquad_skip + 1) * quad_cycle);
		} else if (test <= quad_test)
			quad_test = quad_test / 10;

	}			/* END OF LOOP */

	if (verbose >= SLIGHTLY) {
		fquadprint(fp_out);
		fprintf(fp_out, "\nscaled variance-covariance matrix:\n");
		fmatprint(fp_out, qmat);
	}
	fflush(fp_out);
	return (0);
}				/* END OF MAIN */
