/* RECIP_NOWTS.C */
/*-
VERSION OF XXXXFIT, for:
  
nonlinear least squares fit by simplex minimizaton (Nelder-Mead algorithm).
  
test:
	Lineweaver-Burke equation, with wrong weighting (all wts equal)
 */
/*-
contents of the XXXXFIT module  =  
declarations and routines for simplex fitting special to function to be fit
(no other functions/files need to be rewritten or adapted for a new model):
  
	mnemonic defines for members of data and parameter structures
  
	function for calculation of dependent variable and
		weighted sum of residuals squared		= func()
  
	print of <data> records					= fdatprint()
  
	additional display called by fdatprint(), 
		specially written for this model 		= fpointprint()
  
	customizable display called by <simpfit()>, 
		following the output tracking each cycle
		of minimization					= fspecial()
  
J.A. Rupley, Tucson, Arizona
rupley!local@megaron.arizona.edu
*/

#define XXXXFIT

#include "simpdefs.h"		/* externals are read from <simpdefs> */

/* DEFINES SPECIAL TO FITTING FUNCTION */

#define Y	0		/* defines for elements of struct dat */
#define YC	1		/* (mnemonic) */
#define W	2
#define X	3

#define A	0		/* defines for elements of struct pstruct */
#define B	1		/* (mnemonic) */

/*-
FUNC
	CALCULATION OF LEAST SQUARES FUNCTION
	CODED ACCORDING TO MODEL BEING FIT
	IT SHOULD BE EFFICIENT
	DURING THE FIT, TIME IS MOSTLY SPENT HERE
*/

int	firstflag;

int
func(pnam)
	struct pstruct *pnam;
{
	register int    n;

	extern struct dat data[];
	extern int      nparm;
	extern int      ndata;

	/*
	 * execute some changes in input data for first pass through func 
	 */

	if (!firstflag) {
		firstflag = 1;
		for (n = 0; n < ndata; n++) {
			data[n].datval[Y] = 1 / data[n].datval[Y];
			data[n].datval[X] = 1 / data[n].datval[X];
/* 			data[n].datval[W] = 1 / data[n].datval[Y] * */
/* 						1 / data[n].datval[Y]; */
		}
	}

	/*
	 * here set/test bounds on parms...may not be needed
	 */

	pnam->val = 0;
	for (n = 0; n < ndata; n++) {
		/* evaluation of dependent variable */
		data[n].datval[YC] =  pnam->parm[A] * data[n].datval[X]
			+ pnam->parm[B] ;
		/* evaluation of weighted sum of residuals squared */
		pnam->val = pnam->val
			+ (data[n].datval[Y] - data[n].datval[YC])
			* (data[n].datval[Y] - data[n].datval[YC])
			* data[n].datval[W]
			* data[n].datval[W];
	}
	return (OK);
}				/* END OF FUNC        			 */

/*-
FDATPRINT
	PRINT DATA AND COMPARE WITH CALCULATED VALUES
	CODED ACCORDING TO MODEL AND DATA
*/

void
fdatprint(fptr)
	FILE           *fptr;
{
	register int    j;

	extern void     fpointprint();

	extern int      iter, ndata, maxiter;
	extern struct dat data[];
	extern char     title[];

	fprintf(fptr, "\1\f\n%-s\n\niteration number %d\n\n", title, iter);
	fprintf(fptr,
		"        yobs   ycalc   del-y  weight       x\n");
	for (j = 0; j < ndata; j++)
		fprintf(fptr,
			"%4d %7.3f %7.3f %7.3f %7.3f %10.5f\n",
			(j + 1), data[j].datval[Y], data[j].datval[YC],
			(data[j].datval[Y] - data[j].datval[YC]),
			data[j].datval[W], data[j].datval[X]);

	if (maxiter != 0)
		fpointprint(fptr);
}				/* END OF FDATPRINT			 */

/*-
FPOINTPRINT
	CODE FOR SPECIAL OUTPUT, IF ANY
*/

void
fpointprint(fptr)
	FILE           *fptr;
{
}				/* END OF FPOINTPRINT			 */


/*-
FSPECIAL
	DISPLAY ADDITIONAL INFORMATION DURING
	TRACKING OF MINIMIZATION, IN SIMPFIT()
*/

void
fspecial(fptr)
	FILE           *fptr;
{
	register        j;

	extern int      maxiter;
	extern double   ypmin, yzero, quad_test;

	if (ypmin > 0.99E38) {
		fprintf(fptr, "y-pmin error");
		for (j = 0; j < nvert; j++)
			if (pmin.parm[j] < 0)
				fprintf(fptr, " (parm(%d) < 0)", j);
	} else if (ypmin > yzero)
		fprintf(fptr, "y-pmin > yzero");

	fprintf(fptr, "    next_prt= %d  next_quad= %7.2e\n",
		maxiter, quad_test);

	return;
}				/* END OF FSPECIAL			 */
