Package: lintegrate
lintegrateA numerical integration library for when you want/need to work with the natural logarithm of the function requiring integration.This library provides three numerical integration functions, heavily based onGSLfunctions, to integrate a function when only its natural logarithm is given, and return the natural logarithm of that integral. The three functions:lintegrate_qaglintegrate_qnglintegrate_cquadare equivalents of the GSL functions:gsl_integration_qaggsl_integration_qnggsl_integration_cquadrespectively. These can be useful when, e.g., you can calculate the natural logarithm of a Gaussian likelihood function (in cases where the exponentiation of the Gaussian function would lead to zeros or infinities) and you want to numerically find the integral of the Gaussian function itself.The functionslintegrate_qag,lintegrate_qng, andlintegrate_cquad, all have wrappers functions (with_splitappended to their names) that allow the user to specify a set of intervals that the integrals will be split into when performing the calculation. The intervals could, for example, be spaced evenly in log-space, for cases where the integral function has a very pronounced peak as it approaches zero.The full API documentation and examples can be foundhere.ExampleAnexampleof the use the functions is:/* example using lintegrate functionality */#include<stdio.h>#include<stdlib.h>#include<math.h>#include<gsl/gsl_math.h>#include<gsl/gsl_integration.h>#include<lintegrate.h>/* create function for integration */doublelintegrand(doublex,void*params);structintparams{doublemu;doublesig;};doublelintegrand(doublex,void*params){structintparams*p=(structintparams*)params;doublemu=p->mu;doublesig=p->sig;return-0.5*(mu-x)*(mu-x)/(sig*sig);}doubleintegrand(doublex,void*params){structintparams*p=(structintparams*)params;doublemu=p->mu;doublesig=p->sig;returnexp(-0.5*(mu-x)*(mu-x)/(sig*sig));}intmain(intargv,char**argc){gsl_functionF;structintparamsparams;gsl_integration_workspace*w=gsl_integration_workspace_alloc(100);gsl_integration_cquad_workspace*cw=gsl_integration_cquad_workspace_alloc(50);doubleqaganswer=0.,qnganswer=0.,cquadanswer=0.,answer=0.;doubleabserr=0.;size_tneval=0;doubleminlim=-6.;/* minimum for integration range */doublemaxlim=6.;/* maximum for integration range */doubleabstol=1e-10;/* absolute tolerance */doublereltol=1e-10;/* relative tolerance */params.mu=0.;params.sig=1.;F.function=&lintegrand;F.params=&params;/* integrate log of function using QAG */lintegration_qag(&F,minlim,maxlim,abstol,reltol,100,GSL_INTEG_GAUSS31,w,&qaganswer,&abserr);/* integrate log of function using QNG */lintegration_qng(&F,minlim,maxlim,abstol,reltol,&qnganswer,&abserr,&neval);/* integrate log of function using CQUAD */lintegration_cquad(&F,minlim,maxlim,abstol,reltol,cw,&cquadanswer,&abserr,&neval);/* integrate function using GSL QAG */F.function=&integrand;gsl_integration_qag(&F,minlim,maxlim,abstol,reltol,100,GSL_INTEG_GAUSS31,w,&answer,&abserr);gsl_integration_workspace_free(w);gsl_integration_cquad_workspace_free(cw);fprintf(stdout,"Answer\"lintegrate QAG\"= %.8lf\n",qaganswer);fprintf(stdout,"Answer\"lintegrate QNG\"= %.8lf\n",qnganswer);fprintf(stdout,"Answer\"lintegrate CQUAD\"= %.8lf\n",cquadanswer);fprintf(stdout,"Answer\"gsl_integrate_qag\"= %.8lf\n",log(answer));fprintf(stdout,"Analytical answer = %.8lf\n",log(sqrt(2.*M_PI)));return0;}RequirementsGSL- on Debian/Ubuntu (16.04) install with e.g.sudo apt-get install libgsl-devInstallationThe library can be built usingsconsby just typingsudo sconsin the base directory. To install
the library system-wide (in/usr/local/libby default) run:sudo scons
sudo scons installA Python module containing wrappers to the functions can be built and installed from source for the user by running, e.g.:pipinstall.from within the repository directory.The Python module can also be installed fromPyPIusing pip with:pipinstalllintegrateor in a Conda environment with:condainstall-cconda-forgelintegratePythonIf the Python module has been installed it has the following functions:lqng- a wrapper tolintegration_qnglqag- a wrapper tolintegration_qaglcquad- a wrapper tolintegration_cquadlogtrapz- using the trapezium rule for integration on a grid of valuesThelqng,lqag, andlcquadfunctions are used in a similar way to the scipyquadfunction.An example of their use would be:fromlintegrateimportlqag,lqng,lcquad,logtrapzimportnumpyasnp# define the log of the function to be integrateddefintegrand(x,args):mu,sig=args# unpack extra argumentsreturn-0.5*((x-mu)/sig)**2# set integration limitsxmin=-6.xmax=6.# set additional argumentsmu=0.sig=1.resqag=lqag(integrand,xmin,xmax,args=(mu,sig))resqng=lqng(integrand,xmin,xmax,args=(mu,sig))rescquad=lcquad(integrand,xmin,xmax,args=(mu,sig))restrapz=logtrapz(integrand,np.linspace(xmin,xmax,100),args=(mu,sig))RInRone can use thereticulatepackage to call the functions inlintegrate.
The above example would be:library(reticulate)py_install("lintegrate",pip=TRUE)## run once to make sure lintegrate is installed and visible to reticulate.lint<-import("lintegrate",convert=FALSE)integrand<-function(x,args){mu=args[1]sig=args[2]return(-.5*((x-mu)/sig)^2)}integrand<-Vectorize(integrand)mu<-0sig<-1mmin<--10mmax<-10lint$lqag(py_func(integrand),r_to_py(mmin),r_to_py(mmax),c(mu,sig))CitationIf usinglintegratein your research, I would be grateful if you cite the associatedJOSS paperfor the software. The following BibTeX citation can be used:@article{Pitkin2022,doi={10.21105/joss.04231},url={https://doi.org/10.21105/joss.04231},year={2022},publisher={The Open Journal},volume={7},number={73},pages={4231},author={Matthew Pitkin},title={lintegrate: A C/Python numerical integration library for working in log-space},journal={Journal of Open Source Software}}You may also want to cite theGSLreference "M. Galassi et al, GNU Scientific Library Reference Manual (3rd Ed.), ISBN 0954612078" and the URLhttp://www.gnu.org/software/gsl/.© 2017 Matthew Pitkin