/* returns a vecpair of NaNs if a parabolic approximation is non useful. */
LOCAL vecpair fit_dir_parab(C sortedstuff& s,
							double dely, double T,
							maybe_s *maybe)
{
 boom(1800);
 double m[6][6], beta[6];
 if(s.n() < 6)	{
	D fprintf(stderr, "\tNot 6 points!!! n=%d\n", s.n());
	return vecpair();
	}
 C int count = count_not_in_line(s);
 if(count < 0)	{
	D fprintf(stderr, "\tNot 6 good!!!: %d\n", count);
	return vecpair();
	}

 int i;
 {
 int j;
 for(j=0; j<6; j++)	{
	int k;
	for(k=0; k<6; k++)
		m[j][k] = 0;
	beta[j] = 0;
	}
 }
 int used = 0;
 double big = -infinity();
 for(i=0; i<s.n(); i++)	{
	if(!finite(s[i].y))
		continue;
	if(i>=count && used>6 && !(s[i].y<big+T*logrand()))
		continue;
	if(s[i].y > big)
		big = s[i].y;

	double x[6];
	x[0] = xx(s[i].v(0)-s[0].v(0));
	x[1] = 2*(s[i].v(0)-s[0].v(0))*(s[i].v(1)-s[0].v(1));
	x[2] = xx(s[i].v(1)-s[0].v(1));
	x[3] = (s[i].v(0)-s[0].v(0));
	x[4] = (s[i].v(1)-s[0].v(1));
	x[5] = 1/dely;
	int j;
	for(j=0; j<6; j++)	{
		int k;
		for(k=0; k<6; k++)
			m[j][k] += x[j]*x[k];
		beta[j] += x[j]*(s[i].y-s[0].y);
		}
	used++;
	}
 if(used < 6)	{
	fprintf(stderr, "Not 6 good!  Used=%d, count=%d, s.n()=%d\n",
		used, count, s.n());
	return vecpair();
	}

 if(!invert(m, 6))	{
	fprintf(stderr, "\tInvert fails!.   Points follow:\n");
	return vecpair();
	}

 double abcdef[6];
 for(i=0;i<6;i++)	{
	int k;
	abcdef[i] = 0;
	for(k=0;k<6;k++)
		abcdef[i] += m[i][k]*beta[k];
	}
 D fprintf(stderr, "\tsolution (%g, %g, %g)^2 + (%g,%g) + %g + %g\n",
					abcdef[0], abcdef[1], abcdef[2],
					abcdef[3], abcdef[4], abcdef[5],
					s[0].y);

 matrix22 curv(abcdef[0], abcdef[1], abcdef[1], abcdef[2]);


 vector2 evec1, evec2;
 jacobi_step(curv, &evec1, &evec2);
 C double eval1 = sandwitch(evec1, curv);
 C double eval2 = sandwitch(evec2, curv);

 vector2 downhill(-abcdef[3], -abcdef[4]);

 if(eval1+2*eval2<0 || eval2+2*eval1<0)	{
	/* The eigenvalues are far from positive definite.  We cannot
		trust any parabolic approximation. */
	return vecpair();
	}

 if(dot(downhill, evec1) < 0)
	evec1 *= -1;

 if(dot(downhill, evec2) < 0)
	evec2 *= -1;

 evec1 *= sqrt(fabs(dely/eval1));	/* vectors have length to change chi-squared by about dely. */
 evec2 *= sqrt(fabs(dely/eval2));


 /* Down here, there is some reason to believe that the
 eigenvalues mean *something*... */
 matrix22 invc;
 {
 C double min_eval = min(eval1, eval2);
 if(min_eval < 0)	{		/* Force the matrix to be positive definite, in an arbitrary manner. */
	curv += 2*min_eval*matrix22::identity();
	/* The minimum is probably wrong, so beware... */
	maybe->trustworthy = FALSE;
	}
 else	maybe->trustworthy = TRUE;

 double det = quiet_nan(0);
 invc = inverse(curv, &det);

	/* Strong cancellations - minimum is doubtful: */
 if(det < 0.1*curv(0,0)*curv(1,1))
	maybe->trustworthy = FALSE;
 }

 C vector2 randvec = evec1 * normalrand() * sqrt(T/dely)
				+ evec2 * normalrand() * sqrt(T/dely);
 /* Calculate where the minimum ought to be, if the surface were
		truly parabolic. Add in a random jiggle (r1&r2) so
	that we explore the region with temperature T. */
 maybe->x = invc*downhill*0.5 + s[0].v + randvec;
 maybe->slope = vector2(abcdef[3], abcdef[4]);
 maybe->y0 = abcdef[5] + s[0].y;
 maybe->setcurv(curv);
 maybe->x0 = s[0].v;


 return vecpair(evec1, evec2);
}



matrices_t linear_matrix(C sortedstuff& ss, double e)
{
???
}

