/*
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.
*/
#ifndef ROMBERG_H
# define ROMBERG_H
# ifdef __cplusplus
extern "C"	{
# endif



struct method_fr { double h, hext; double s, ss;};

typedef double (*integrand_function)(double x, void *c, int nc);
typedef method_fr (*method_fcn)(integrand_function func,
					double a, double b,
					int n,
					void *c, int nc);


double qromo(integrand_function f, double a, double b,
			 method_fcn how, void *c, int nc, double eps, double size);
double qromox(integrand_function f, double a, double b,
			 method_fcn how, void *c, int nc,
			 double eps, double size, int Kmax,
			 BOOL rational_interpolation);




/* For exp(-x) asymptotic behavior (both limits positive): */
method_fr midexp(integrand_function func, double a, double b,
				int n, void *c, int nc);
/* For exp(-x)(?) behavior, integrated out to b=infinity (a positive): */
method_fr mid2exp(integrand_function func, double a, double b,
				int n, void *c, int nc);

method_fr midpnt(integrand_function func, double a, double b,
				int n, void *c, int nc);
method_fr trapzd(integrand_function func, double a, double b,
				int n, void *c, int nc);

/* for sqrt(x-a) singularity: */
method_fr midsqrt(integrand_function func, double a, double b,
				int n, void *c, int nc);
/* for sqrt((b-x)) singularity: */
method_fr mid2sqrt(integrand_function func, double a, double b,
				int n, void *c, int nc);
/* For 1/x^2 behavior, (a, b positive): */
method_fr mid_inv2(integrand_function func, double a, double b,
				int n, void *c, int nc);
/* For 1/x behavior, (a, b positive): */
method_fr mid_inv1(integrand_function func, double a, double b,
				int n, void *c, int nc);
/* For 1/sqrt(x) behavior, (a, b positive): */
method_fr mid_inv_half(integrand_function func, double a, double b,
				int n, void *c, int nc);
/* For proportional to x behavior, (a, b positive): */
method_fr mid_prop(integrand_function func, double a, double b,
				int n, void *c, int nc);


/* For functions which are exp(something). Uses endpoints. */
double romexp(integrand_function func, double a, double b, void *c,
			 int nc, double eps, double size);

/* For functions which are exp(something). No endpoints. */
double rom_mid_exp(integrand_function func, double a, double b, void *c,
			 int nc, double eps, double size);

#ifdef __cplusplus
 }
# include "gpklib/doublet.h"

double qromo(integrand_function f, C doublet<double>& ab,
			 method_fcn how, void *c, int nc, double eps, double size);

typedef double (*dbl_integrand_function)(double x, double y, C void *c);

/* Inner integral is over x, outer is over y */
/* for double integrals of two-parameter functions */
/*	over arbitrary areas: */
double
qromo_xy(dbl_integrand_function f,
			C doublet<double> (*inner)(double y, C doublet<double>& outer, C void *p),
			C doublet<double>& outer,
			method_fcn how, void *c, double eps_o, double size_o,
			double eps_i=0.0, double size_i=0.0, method_fcn how_i=0);
/* 	over rectangular areas: */
double
qromo_xy(dbl_integrand_function f,
			C doublet<double>& inner, C doublet<double>& outer,
			method_fcn how, void *c, double eps_o, double size_o,
			double eps_i=0.0, double size_i=0.0, method_fcn how_i=0);

/* for double integrals of the same variable */
double
qromo2(integrand_function f, C doublet<double>& outer,
			C doublet<double> (*inner)(double x, C doublet<double>& outer, C void *p),
			method_fcn how, void *c, int nc, double eps_o, double size_o,
			double eps_i=0.0, double size_i=0.0, method_fcn how_i=0);
#endif
#endif
