/*
Copyright 2002-2008 Greg Kochanski. 
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

This program may be downloaded from http://www.sourceforge.org from the "speechresearch" project.
*/
#include "gpk_std.h"
#include "romberg.h"

/* trapezoidal rule on a closed interval */

method_fr trapzd(integrand_function func, double a, double b,
				int n, void *c, int nc)
{
 method_fr rv;
 long tnm, j;
 int i;

 if(n == 0)     {
	C double tmp1 = (*func)(a, c, nc);
	C double tmp2 = (*func)(b, c, nc);
	rv.s = 0.5*(tmp1 + tmp2);
	rv.ss = 0.5*(tmp1*tmp1 + tmp2*tmp2);
	rv.h = rv.hext = 1.0;
	return rv;
	}
 for(tnm=1,i=0; i<n-1; i++)
	tnm *= 2;
 C double del = (b-a)/tnm;
 double ss = 0.0, s = 0.0;
 OPENMP(omp parallel for private(j) reduction(+: s,ss) schedule(dynamic, 16))
 for(j=0; j<tnm; j++)  {
	C double tmp = (*func)(a + del*(0.5+j), c, nc);
	s += tmp;
	ss += tmp*tmp;
	}
 rv.ss = ss;
 rv.s = s;
 rv.h = 1.0/(2*tnm);
 rv.hext = rv.h * rv.h;
 return rv;
}
