Updated the built-in version of the cuba library to version 2.1 within the BMWlibs.

Also the cuba-compiler-check for gcc-versions containing a certain bug (4.2, 4.4.3) has been adopted.
This still needs to be tested on systems having such a gcc.

If this new version of the built-in library should be installed,
first make sure that the old version is completely deinstalled (including headers, pkg-config-files, etc.).
This commit is contained in:
Bastian M. Wojek
2011-01-27 13:46:51 +00:00
parent a89c70ae84
commit 55071fb754
41 changed files with 1577 additions and 1276 deletions

View File

@ -20,6 +20,7 @@ FIXED fixes the inadequate attempt to use log max likelihood fit for asymmetry/n
CHANGED less strict handling of empty FUNCTION block CHANGED less strict handling of empty FUNCTION block
CHANGED cosmetics in the y-labelling (MUSR-154) CHANGED cosmetics in the y-labelling (MUSR-154)
CHANGED maximum possible run number for the use in msr2data to numeric_limits<unsigned int>::max() (MUSR-155) CHANGED maximum possible run number for the use in msr2data to numeric_limits<unsigned int>::max() (MUSR-155)
UPDATED built-in cuba-library to version 2.1 in BMWlibs
musrfit 0.8.0 - changes since 0.7.0 musrfit 0.8.0 - changes since 0.7.0
=================================== ===================================

View File

@ -1,18 +1,22 @@
#--------------------------------------------------------------------- #---------------------------------------------------------------------
# INSTALL # INSTALL
# Andreas Suter, 2009/06/21 # BMW, 2011/01/27
# $Id: INSTALL 4013 2009-06-21 # $Id: INSTALL 4013 2009-06-21
#--------------------------------------------------------------------- #---------------------------------------------------------------------
To get it all build: To get it all build:
./autogen.sh sh autogen.sh
./configure --prefix=/apps/cern/root (or whereever musrfit should be installed) ./configure --prefix=/apps/cern/root (or whereever musrfit should be installed)
make make
make install (as superuser -- maybe) make install (as superuser -- maybe)
In the optimal case, everything is set up ;-) In the optimal case, everything is set up ;-)
More information about the software requirements and the installation can be found at:
https://intranet.psi.ch/MUSR/MusrFitSetup
http://lmu.web.psi.ch/facilities/software/musrfit/user/intranet.psi.ch/MUSR/MusrFitSetup.html
#--------------------------------------------------------------------- #---------------------------------------------------------------------
# this is the end ... # this is the end ...
#--------------------------------------------------------------------- #---------------------------------------------------------------------

17
NEWS
View File

@ -1,23 +1,10 @@
#--------------------------------------------------------------------- #---------------------------------------------------------------------
# NEWS # NEWS
# Andreas Suter, 2010/06/15 # BMW, 2011/01/27
# $Id: NEWS 4013 2009-06-21 # $Id: NEWS 4013 2009-06-21
#--------------------------------------------------------------------- #---------------------------------------------------------------------
musrfit 0.6.0 Please check the ChangeLog to see what is new!
+ Added grouping of histograms
+ Added global mode to msr2data
+
+
+
+
musrfit 0.5.0
+ Initial release supporting building by autotools
on Linux, MS Windows (Cygwin), Mac OS X
#--------------------------------------------------------------------- #---------------------------------------------------------------------
# this is the end ... # this is the end ...

4
README
View File

@ -1,6 +1,6 @@
#--------------------------------------------------------------------- #---------------------------------------------------------------------
# README # README
# Andreas Suter, 2010/06/20 # BMW, 2011/01/27
# $Id: README 4013 2009-06-21 # $Id: README 4013 2009-06-21
#--------------------------------------------------------------------- #---------------------------------------------------------------------
@ -8,9 +8,11 @@ musrfit - muSR data analysis package
Installation instructions can be found in INSTALL and at Installation instructions can be found in INSTALL and at
https://intranet.psi.ch/MUSR/MusrFitSetup https://intranet.psi.ch/MUSR/MusrFitSetup
http://lmu.web.psi.ch/facilities/software/musrfit/user/intranet.psi.ch/MUSR/MusrFitSetup.html
For further documentation, please visit For further documentation, please visit
https://intranet.psi.ch/MUSR/MusrFit https://intranet.psi.ch/MUSR/MusrFit
http://lmu.web.psi.ch/facilities/software/musrfit/user/intranet.psi.ch/MUSR/MusrFit.html
#--------------------------------------------------------------------- #---------------------------------------------------------------------
# this is the end ... # this is the end ...

View File

@ -52,36 +52,39 @@ PLUGIN_MINOR_VERSION=0
PLUGIN_MICRO_VERSION=0 PLUGIN_MICRO_VERSION=0
#release versioning #release versioning
CUBA_MAJOR_VERSION=1 CUBA_MAJOR_VERSION=2
CUBA_MINOR_VERSION=6 CUBA_MINOR_VERSION=1
CUBA_MICRO_VERSION=0 CUBA_MICRO_VERSION=0
#API version #API version
MUSR_API_VERSION=MUSR_MAJOR_VERSION.MUSR_MINOR_VERSION MUSR_API_VERSION=$MUSR_MAJOR_VERSION.$MUSR_MINOR_VERSION
AC_SUBST(MUSR_API_VERSION) AC_SUBST(MUSR_API_VERSION)
LEM_API_VERSION=LEM_MAJOR_VERSION.LEM_MINOR_VERSION LEM_API_VERSION=$LEM_MAJOR_VERSION.$LEM_MINOR_VERSION
AC_SUBST(LEM_API_VERSION) AC_SUBST(LEM_API_VERSION)
PSIBIN_API_VERSION=PSIBIN_MAJOR_VERSION.PSIBIN_MINOR_VERSION PSIBIN_API_VERSION=$PSIBIN_MAJOR_VERSION.$PSIBIN_MINOR_VERSION
AC_SUBST(PSIBIN_API_VERSION) AC_SUBST(PSIBIN_API_VERSION)
MUD_API_VERSION=MUD_MAJOR_VERSION.MUD_MINOR_VERSION MUD_API_VERSION=$MUD_MAJOR_VERSION.$MUD_MINOR_VERSION
AC_SUBST(MUD_API_VERSION) AC_SUBST(MUD_API_VERSION)
PLUGIN_API_VERSION=PLUGIN_MAJOR_VERSION.PLUGIN_MINOR_VERSION PLUGIN_API_VERSION=$PLUGIN_MAJOR_VERSION.$PLUGIN_MINOR_VERSION
AC_SUBST(PLUGIN_API_VERSION) AC_SUBST(PLUGIN_API_VERSION)
CUBA_API_VERSION=CUBA_MAJOR_VERSION.CUBA_MINOR_VERSION CUBA_API_VERSION=$CUBA_MAJOR_VERSION.$CUBA_MINOR_VERSION
AC_SUBST(CUBA_API_VERSION) AC_SUBST(CUBA_API_VERSION)
#shared library versioning #shared library versioning
CUBA_LIBRARY_VERSION=1:6:0 CUBA_LIBRARY_VERSION=$CUBA_MAJOR_VERSION:$CUBA_MINOR_VERSION:$CUBA_MICRO_VERSION
PLUGIN_LIBRARY_VERSION=1:0:0 PLUGIN_LIBRARY_VERSION=$PLUGIN_MAJOR_VERSION:$PLUGIN_MINOR_VERSION:$PLUGIN_MICRO_VERSION
LEM_LIBRARY_VERSION=1:5:0 LEM_LIBRARY_VERSION=$LEM_MAJOR_VERSION:$LEM_MINOR_VERSION:$LEM_MICRO_VERSION
PSIBIN_LIBRARY_VERSION=0:1:0 PSIBIN_LIBRARY_VERSION=$PSIBIN_MAJOR_VERSION:$PSIBIN_MINOR_VERSION:$PSIBIN_MICRO_VERSION
MUD_LIBRARY_VERSION=0:0:0 MUD_LIBRARY_VERSION=$MUD_MAJOR_VERSION:$MUD_MINOR_VERSION:$MUD_MICRO_VERSION
MUSR_LIBRARY_VERSION=0:8:0 MUSR_LIBRARY_VERSION=$MUSR_MAJOR_VERSION:$MUSR_MINOR_VERSION:$MUSR_MICRO_VERSION
# This is definitely handled wrongly at the moment and needs to be fixed...
#XXX_LIBRARY_VERSION=X:Y:Z
# | | | # | | |
# +------+ | +---+ # +------+ | +---+
# | | | # | | |
@ -371,11 +374,17 @@ AC_ARG_ENABLE([BMWlibs], [AC_HELP_STRING([--enable-BMWlibs],[build optional BMW
) )
if test "${BUILD_CUBA}" = "1"; then if test "${BUILD_CUBA}" = "1"; then
if test "x$GCC" = "xyes" ; then AS_IF([test "x$GCC" = "xyes"],
CUBA_BUILD_CFLAGS=${USER_CFLAGS:--O3 -fomit-frame-pointer -ffast-math} [case "$($CC --version 2>&1 < /dev/null)" in
else gcc*4.2* | gcc*4.4.3*)
CUBA_BUILD_CFLAGS=${USER_CFLAGS:--O} opt=-O0
fi ;;
*)
opt=-O3
;;
esac
CUBA_BUILD_CFLAGS=${USER_CFLAGS:-$opt -fomit-frame-pointer -ffast-math}],
[CUBA_BUILD_CFLAGS=${USER_CFLAGS:--O}])
AC_LANG_PUSH([C]) AC_LANG_PUSH([C])

View File

@ -29,9 +29,12 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
# include "BMWIntegrator.h" #include "BMWIntegrator.h"
# include "cuba.h" #include "cuba.h"
#define USERDATA NULL
#define SEED 0
std::vector<double> TDWaveGapIntegralCuhre::fPar; std::vector<double> TDWaveGapIntegralCuhre::fPar;
@ -50,7 +53,7 @@ double TDWaveGapIntegralCuhre::IntegrateFunc()
int nregions, neval, fail; int nregions, neval, fail;
double integral[NCOMP], error[NCOMP], prob[NCOMP]; double integral[NCOMP], error[NCOMP], prob[NCOMP];
Cuhre(fNDim, NCOMP, Integrand, Cuhre(fNDim, NCOMP, Integrand, USERDATA,
EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL, EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL,
KEY, KEY,
&nregions, &neval, &fail, integral, error, prob); &nregions, &neval, &fail, integral, error, prob);
@ -58,12 +61,12 @@ double TDWaveGapIntegralCuhre::IntegrateFunc()
return integral[0]; return integral[0];
} }
void TDWaveGapIntegralCuhre::Integrand(const int *ndim, const double x[], int TDWaveGapIntegralCuhre::Integrand(const int *ndim, const double x[],
const int *ncomp, double f[]) // x = {E, phi}, fPar = {twokBT, Delta(T), Ec, phic} const int *ncomp, double f[], void *userdata) // x = {E, phi}, fPar = {twokBT, Delta(T), Ec, phic}
{ {
double deltasq(TMath::Power(fPar[1]*TMath::Cos(2.0*x[1]*fPar[3]),2.0)); double deltasq(TMath::Power(fPar[1]*TMath::Cos(2.0*x[1]*fPar[3]),2.0));
f[0] = 1.0/TMath::Power(TMath::CosH(TMath::Sqrt(x[0]*x[0]*fPar[2]*fPar[2]+deltasq)/fPar[0]),2.0); f[0] = 1.0/TMath::Power(TMath::CosH(TMath::Sqrt(x[0]*x[0]*fPar[2]*fPar[2]+deltasq)/fPar[0]),2.0);
return; return 0;
} }
std::vector<double> TCosSqDWaveGapIntegralCuhre::fPar; std::vector<double> TCosSqDWaveGapIntegralCuhre::fPar;
@ -83,7 +86,7 @@ double TCosSqDWaveGapIntegralCuhre::IntegrateFunc()
int nregions, neval, fail; int nregions, neval, fail;
double integral[NCOMP], error[NCOMP], prob[NCOMP]; double integral[NCOMP], error[NCOMP], prob[NCOMP];
Cuhre(fNDim, NCOMP, Integrand, Cuhre(fNDim, NCOMP, Integrand, USERDATA,
EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL, EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL,
KEY, KEY,
&nregions, &neval, &fail, integral, error, prob); &nregions, &neval, &fail, integral, error, prob);
@ -91,12 +94,12 @@ double TCosSqDWaveGapIntegralCuhre::IntegrateFunc()
return integral[0]; return integral[0];
} }
void TCosSqDWaveGapIntegralCuhre::Integrand(const int *ndim, const double x[], int TCosSqDWaveGapIntegralCuhre::Integrand(const int *ndim, const double x[],
const int *ncomp, double f[]) // x = {E, phi}, fPar = {twokBT, DeltaD(T), Ec, phic, DeltaS(T)} const int *ncomp, double f[], void *userdata) // x = {E, phi}, fPar = {twokBT, DeltaD(T), Ec, phic, DeltaS(T)}
{ {
double deltasq(TMath::Power(fPar[1]*TMath::Cos(2.0*x[1]*fPar[3]) + fPar[4], 2.0)); double deltasq(TMath::Power(fPar[1]*TMath::Cos(2.0*x[1]*fPar[3]) + fPar[4], 2.0));
f[0] = TMath::Power(TMath::Cos(x[1]*fPar[3])/TMath::CosH(TMath::Sqrt(x[0]*x[0]*fPar[2]*fPar[2]+deltasq)/fPar[0]),2.0); f[0] = TMath::Power(TMath::Cos(x[1]*fPar[3])/TMath::CosH(TMath::Sqrt(x[0]*x[0]*fPar[2]*fPar[2]+deltasq)/fPar[0]),2.0);
return; return 0;
} }
std::vector<double> TSinSqDWaveGapIntegralCuhre::fPar; std::vector<double> TSinSqDWaveGapIntegralCuhre::fPar;
@ -116,7 +119,7 @@ double TSinSqDWaveGapIntegralCuhre::IntegrateFunc()
int nregions, neval, fail; int nregions, neval, fail;
double integral[NCOMP], error[NCOMP], prob[NCOMP]; double integral[NCOMP], error[NCOMP], prob[NCOMP];
Cuhre(fNDim, NCOMP, Integrand, Cuhre(fNDim, NCOMP, Integrand, USERDATA,
EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL, EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL,
KEY, KEY,
&nregions, &neval, &fail, integral, error, prob); &nregions, &neval, &fail, integral, error, prob);
@ -124,12 +127,12 @@ double TSinSqDWaveGapIntegralCuhre::IntegrateFunc()
return integral[0]; return integral[0];
} }
void TSinSqDWaveGapIntegralCuhre::Integrand(const int *ndim, const double x[], int TSinSqDWaveGapIntegralCuhre::Integrand(const int *ndim, const double x[],
const int *ncomp, double f[]) // x = {E, phi}, fPar = {twokBT, DeltaD(T), Ec, phic, DeltaS(T)} const int *ncomp, double f[], void *userdata) // x = {E, phi}, fPar = {twokBT, DeltaD(T), Ec, phic, DeltaS(T)}
{ {
double deltasq(TMath::Power(fPar[1]*TMath::Cos(2.0*x[1]*fPar[3]) + fPar[4],2.0)); double deltasq(TMath::Power(fPar[1]*TMath::Cos(2.0*x[1]*fPar[3]) + fPar[4],2.0));
f[0] = TMath::Power(TMath::Sin(x[1]*fPar[3]),2.0)/TMath::Power(TMath::CosH(TMath::Sqrt(x[0]*x[0]*fPar[2]*fPar[2]+deltasq)/fPar[0]),2.0); f[0] = TMath::Power(TMath::Sin(x[1]*fPar[3]),2.0)/TMath::Power(TMath::CosH(TMath::Sqrt(x[0]*x[0]*fPar[2]*fPar[2]+deltasq)/fPar[0]),2.0);
return; return 0;
} }
@ -150,7 +153,7 @@ double TAnSWaveGapIntegralCuhre::IntegrateFunc()
int nregions, neval, fail; int nregions, neval, fail;
double integral[NCOMP], error[NCOMP], prob[NCOMP]; double integral[NCOMP], error[NCOMP], prob[NCOMP];
Cuhre(fNDim, NCOMP, Integrand, Cuhre(fNDim, NCOMP, Integrand, USERDATA,
EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL, EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL,
KEY, KEY,
&nregions, &neval, &fail, integral, error, prob); &nregions, &neval, &fail, integral, error, prob);
@ -158,12 +161,12 @@ double TAnSWaveGapIntegralCuhre::IntegrateFunc()
return integral[0]; return integral[0];
} }
void TAnSWaveGapIntegralCuhre::Integrand(const int *ndim, const double x[], int TAnSWaveGapIntegralCuhre::Integrand(const int *ndim, const double x[],
const int *ncomp, double f[]) // x = {E, phi}, fPar = {twokBT, Delta(T),a, Ec, phic} const int *ncomp, double f[], void *userdata) // x = {E, phi}, fPar = {twokBT, Delta(T),a, Ec, phic}
{ {
double deltasq(TMath::Power(fPar[1]*(1.0+fPar[2]*TMath::Cos(4.0*x[1]*fPar[4])),2.0)); double deltasq(TMath::Power(fPar[1]*(1.0+fPar[2]*TMath::Cos(4.0*x[1]*fPar[4])),2.0));
f[0] = 1.0/TMath::Power(TMath::CosH(TMath::Sqrt(x[0]*x[0]*fPar[3]*fPar[3]+deltasq)/fPar[0]),2.0); f[0] = 1.0/TMath::Power(TMath::CosH(TMath::Sqrt(x[0]*x[0]*fPar[3]*fPar[3]+deltasq)/fPar[0]),2.0);
return; return 0;
} }
std::vector<double> TAnSWaveGapIntegralDivonne::fPar; std::vector<double> TAnSWaveGapIntegralDivonne::fPar;
@ -190,8 +193,8 @@ double TAnSWaveGapIntegralDivonne::IntegrateFunc()
int nregions, neval, fail; int nregions, neval, fail;
double integral[NCOMP], error[NCOMP], prob[NCOMP]; double integral[NCOMP], error[NCOMP], prob[NCOMP];
Divonne(fNDim, NCOMP, Integrand, Divonne(fNDim, NCOMP, Integrand, USERDATA,
EPSREL, EPSABS, VERBOSE, MINEVAL, MAXEVAL, EPSREL, EPSABS, VERBOSE, SEED, MINEVAL, MAXEVAL,
KEY1, KEY2, KEY3, MAXPASS, BORDER, MAXCHISQ, MINDEVIATION, KEY1, KEY2, KEY3, MAXPASS, BORDER, MAXCHISQ, MINDEVIATION,
NGIVEN, LDXGIVEN, NULL, NEXTRA, NULL, NGIVEN, LDXGIVEN, NULL, NEXTRA, NULL,
&nregions, &neval, &fail, integral, error, prob); &nregions, &neval, &fail, integral, error, prob);
@ -199,12 +202,12 @@ double TAnSWaveGapIntegralDivonne::IntegrateFunc()
return integral[0]; return integral[0];
} }
void TAnSWaveGapIntegralDivonne::Integrand(const int *ndim, const double x[], int TAnSWaveGapIntegralDivonne::Integrand(const int *ndim, const double x[],
const int *ncomp, double f[]) // x = {E, phi}, fPar = {twokBT, Delta(T),a, Ec, phic} const int *ncomp, double f[], void *userdata) // x = {E, phi}, fPar = {twokBT, Delta(T),a, Ec, phic}
{ {
double deltasq(TMath::Power(fPar[1]*(1.0+fPar[2]*TMath::Cos(4.0*x[1]*fPar[4])),2.0)); double deltasq(TMath::Power(fPar[1]*(1.0+fPar[2]*TMath::Cos(4.0*x[1]*fPar[4])),2.0));
f[0] = 1.0/TMath::Power(TMath::CosH(TMath::Sqrt(x[0]*x[0]*fPar[3]*fPar[3]+deltasq)/fPar[0]),2.0); f[0] = 1.0/TMath::Power(TMath::CosH(TMath::Sqrt(x[0]*x[0]*fPar[3]*fPar[3]+deltasq)/fPar[0]),2.0);
return; return 0;
} }
std::vector<double> TAnSWaveGapIntegralSuave::fPar; std::vector<double> TAnSWaveGapIntegralSuave::fPar;
@ -225,20 +228,20 @@ double TAnSWaveGapIntegralSuave::IntegrateFunc()
int nregions, neval, fail; int nregions, neval, fail;
double integral[NCOMP], error[NCOMP], prob[NCOMP]; double integral[NCOMP], error[NCOMP], prob[NCOMP];
Suave(fNDim, NCOMP, Integrand, Suave(fNDim, NCOMP, Integrand, USERDATA,
EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL, EPSREL, EPSABS, VERBOSE | LAST, SEED, MINEVAL, MAXEVAL,
NNEW, FLATNESS, NNEW, FLATNESS,
&nregions, &neval, &fail, integral, error, prob); &nregions, &neval, &fail, integral, error, prob);
return integral[0]; return integral[0];
} }
void TAnSWaveGapIntegralSuave::Integrand(const int *ndim, const double x[], int TAnSWaveGapIntegralSuave::Integrand(const int *ndim, const double x[],
const int *ncomp, double f[]) // x = {E, phi}, fPar = {twokBT, Delta(T),a, Ec, phic} const int *ncomp, double f[], void *userdata) // x = {E, phi}, fPar = {twokBT, Delta(T),a, Ec, phic}
{ {
double deltasq(TMath::Power(fPar[1]*(1.0+fPar[2]*TMath::Cos(4.0*x[1]*fPar[4])),2.0)); double deltasq(TMath::Power(fPar[1]*(1.0+fPar[2]*TMath::Cos(4.0*x[1]*fPar[4])),2.0));
f[0] = 1.0/TMath::Power(TMath::CosH(TMath::Sqrt(x[0]*x[0]*fPar[3]*fPar[3]+deltasq)/fPar[0]),2.0); f[0] = 1.0/TMath::Power(TMath::CosH(TMath::Sqrt(x[0]*x[0]*fPar[3]*fPar[3]+deltasq)/fPar[0]),2.0);
return; return 0;
} }
std::vector<double> TNonMonDWave1GapIntegralCuhre::fPar; std::vector<double> TNonMonDWave1GapIntegralCuhre::fPar;
@ -258,7 +261,7 @@ double TNonMonDWave1GapIntegralCuhre::IntegrateFunc()
int nregions, neval, fail; int nregions, neval, fail;
double integral[NCOMP], error[NCOMP], prob[NCOMP]; double integral[NCOMP], error[NCOMP], prob[NCOMP];
Cuhre(fNDim, NCOMP, Integrand, Cuhre(fNDim, NCOMP, Integrand, USERDATA,
EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL, EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL,
KEY, KEY,
&nregions, &neval, &fail, integral, error, prob); &nregions, &neval, &fail, integral, error, prob);
@ -266,12 +269,12 @@ double TNonMonDWave1GapIntegralCuhre::IntegrateFunc()
return integral[0]; return integral[0];
} }
void TNonMonDWave1GapIntegralCuhre::Integrand(const int *ndim, const double x[], int TNonMonDWave1GapIntegralCuhre::Integrand(const int *ndim, const double x[],
const int *ncomp, double f[]) // x = {E, phi}, fPar = {twokBT, Delta(T),a, Ec, phic} const int *ncomp, double f[], void *userdata) // x = {E, phi}, fPar = {twokBT, Delta(T),a, Ec, phic}
{ {
double deltasq(TMath::Power(fPar[1]*(fPar[2]*TMath::Cos(2.0*x[1]*fPar[4])+(1.0-fPar[2])*TMath::Cos(6.0*x[1]*fPar[4])),2.0)); double deltasq(TMath::Power(fPar[1]*(fPar[2]*TMath::Cos(2.0*x[1]*fPar[4])+(1.0-fPar[2])*TMath::Cos(6.0*x[1]*fPar[4])),2.0));
f[0] = 1.0/TMath::Power(TMath::CosH(TMath::Sqrt(x[0]*x[0]*fPar[3]*fPar[3]+deltasq)/fPar[0]),2.0); f[0] = 1.0/TMath::Power(TMath::CosH(TMath::Sqrt(x[0]*x[0]*fPar[3]*fPar[3]+deltasq)/fPar[0]),2.0);
return; return 0;
} }
std::vector<double> TNonMonDWave2GapIntegralCuhre::fPar; std::vector<double> TNonMonDWave2GapIntegralCuhre::fPar;
@ -291,7 +294,7 @@ double TNonMonDWave2GapIntegralCuhre::IntegrateFunc()
int nregions, neval, fail; int nregions, neval, fail;
double integral[NCOMP], error[NCOMP], prob[NCOMP]; double integral[NCOMP], error[NCOMP], prob[NCOMP];
Cuhre(fNDim, NCOMP, Integrand, Cuhre(fNDim, NCOMP, Integrand, USERDATA,
EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL, EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL,
KEY, KEY,
&nregions, &neval, &fail, integral, error, prob); &nregions, &neval, &fail, integral, error, prob);
@ -299,11 +302,11 @@ double TNonMonDWave2GapIntegralCuhre::IntegrateFunc()
return integral[0]; return integral[0];
} }
void TNonMonDWave2GapIntegralCuhre::Integrand(const int *ndim, const double x[], int TNonMonDWave2GapIntegralCuhre::Integrand(const int *ndim, const double x[],
const int *ncomp, double f[]) // x = {E, phi}, fPar = {twokBT, Delta(T),a, Ec, phic} const int *ncomp, double f[], void *userdata) // x = {E, phi}, fPar = {twokBT, Delta(T),a, Ec, phic}
{ {
double deltasq(4.0*fPar[2]/27.0*TMath::Power(fPar[1]*TMath::Cos(2.0*x[1]*fPar[4]), 2.0) \ double deltasq(4.0*fPar[2]/27.0*TMath::Power(fPar[1]*TMath::Cos(2.0*x[1]*fPar[4]), 2.0) \
/ TMath::Power(1.0 + fPar[2]*TMath::Cos(2.0*x[1]*fPar[4])*TMath::Cos(2.0*x[1]*fPar[4]), 3.0)); / TMath::Power(1.0 + fPar[2]*TMath::Cos(2.0*x[1]*fPar[4])*TMath::Cos(2.0*x[1]*fPar[4]), 3.0));
f[0] = 1.0/TMath::Power(TMath::CosH(TMath::Sqrt(x[0]*x[0]*fPar[3]*fPar[3]+deltasq)/fPar[0]),2.0); f[0] = 1.0/TMath::Power(TMath::CosH(TMath::Sqrt(x[0]*x[0]*fPar[3]*fPar[3]+deltasq)/fPar[0]),2.0);
return; return 0;
} }

View File

@ -128,7 +128,7 @@ class TDWaveGapIntegralCuhre {
TDWaveGapIntegralCuhre() : fNDim(2) {} TDWaveGapIntegralCuhre() : fNDim(2) {}
~TDWaveGapIntegralCuhre() { fPar.clear(); } ~TDWaveGapIntegralCuhre() { fPar.clear(); }
void SetParameters(const std::vector<double> &par) { fPar=par; } void SetParameters(const std::vector<double> &par) { fPar=par; }
static void Integrand(const int*, const double[], const int*, double[]); static int Integrand(const int*, const double[], const int*, double[], void*);
double IntegrateFunc(); double IntegrateFunc();
protected: protected:
@ -142,7 +142,7 @@ class TCosSqDWaveGapIntegralCuhre {
TCosSqDWaveGapIntegralCuhre() : fNDim(2) {} TCosSqDWaveGapIntegralCuhre() : fNDim(2) {}
~TCosSqDWaveGapIntegralCuhre() { fPar.clear(); } ~TCosSqDWaveGapIntegralCuhre() { fPar.clear(); }
void SetParameters(const std::vector<double> &par) { fPar=par; } void SetParameters(const std::vector<double> &par) { fPar=par; }
static void Integrand(const int*, const double[], const int*, double[]); static int Integrand(const int*, const double[], const int*, double[], void*);
double IntegrateFunc(); double IntegrateFunc();
protected: protected:
@ -156,7 +156,7 @@ class TSinSqDWaveGapIntegralCuhre {
TSinSqDWaveGapIntegralCuhre() : fNDim(2) {} TSinSqDWaveGapIntegralCuhre() : fNDim(2) {}
~TSinSqDWaveGapIntegralCuhre() { fPar.clear(); } ~TSinSqDWaveGapIntegralCuhre() { fPar.clear(); }
void SetParameters(const std::vector<double> &par) { fPar=par; } void SetParameters(const std::vector<double> &par) { fPar=par; }
static void Integrand(const int*, const double[], const int*, double[]); static int Integrand(const int*, const double[], const int*, double[], void*);
double IntegrateFunc(); double IntegrateFunc();
protected: protected:
@ -170,7 +170,7 @@ class TAnSWaveGapIntegralCuhre {
TAnSWaveGapIntegralCuhre() : fNDim(2) {} TAnSWaveGapIntegralCuhre() : fNDim(2) {}
~TAnSWaveGapIntegralCuhre() { fPar.clear(); } ~TAnSWaveGapIntegralCuhre() { fPar.clear(); }
void SetParameters(const std::vector<double> &par) { fPar=par; } void SetParameters(const std::vector<double> &par) { fPar=par; }
static void Integrand(const int*, const double[], const int*, double[]); static int Integrand(const int*, const double[], const int*, double[], void*);
double IntegrateFunc(); double IntegrateFunc();
protected: protected:
@ -184,7 +184,7 @@ class TAnSWaveGapIntegralDivonne {
TAnSWaveGapIntegralDivonne() : fNDim(2) {} TAnSWaveGapIntegralDivonne() : fNDim(2) {}
~TAnSWaveGapIntegralDivonne() { fPar.clear(); } ~TAnSWaveGapIntegralDivonne() { fPar.clear(); }
void SetParameters(const std::vector<double> &par) { fPar=par; } void SetParameters(const std::vector<double> &par) { fPar=par; }
static void Integrand(const int*, const double[], const int*, double[]); static int Integrand(const int*, const double[], const int*, double[], void*);
double IntegrateFunc(); double IntegrateFunc();
protected: protected:
@ -198,7 +198,7 @@ class TAnSWaveGapIntegralSuave {
TAnSWaveGapIntegralSuave() : fNDim(2) {} TAnSWaveGapIntegralSuave() : fNDim(2) {}
~TAnSWaveGapIntegralSuave() { fPar.clear(); } ~TAnSWaveGapIntegralSuave() { fPar.clear(); }
void SetParameters(const std::vector<double> &par) { fPar=par; } void SetParameters(const std::vector<double> &par) { fPar=par; }
static void Integrand(const int*, const double[], const int*, double[]); static int Integrand(const int*, const double[], const int*, double[], void*);
double IntegrateFunc(); double IntegrateFunc();
protected: protected:
@ -212,7 +212,7 @@ class TNonMonDWave1GapIntegralCuhre {
TNonMonDWave1GapIntegralCuhre() : fNDim(2) {} TNonMonDWave1GapIntegralCuhre() : fNDim(2) {}
~TNonMonDWave1GapIntegralCuhre() { fPar.clear(); } ~TNonMonDWave1GapIntegralCuhre() { fPar.clear(); }
void SetParameters(const std::vector<double> &par) { fPar=par; } void SetParameters(const std::vector<double> &par) { fPar=par; }
static void Integrand(const int*, const double[], const int*, double[]); static int Integrand(const int*, const double[], const int*, double[], void*);
double IntegrateFunc(); double IntegrateFunc();
protected: protected:
@ -226,7 +226,7 @@ class TNonMonDWave2GapIntegralCuhre {
TNonMonDWave2GapIntegralCuhre() : fNDim(2) {} TNonMonDWave2GapIntegralCuhre() : fNDim(2) {}
~TNonMonDWave2GapIntegralCuhre() { fPar.clear(); } ~TNonMonDWave2GapIntegralCuhre() { fPar.clear(); }
void SetParameters(const std::vector<double> &par) { fPar=par; } void SetParameters(const std::vector<double> &par) { fPar=par; }
static void Integrand(const int*, const double[], const int*, double[]); static int Integrand(const int*, const double[], const int*, double[], void*);
double IntegrateFunc(); double IntegrateFunc();
protected: protected:

View File

@ -1,7 +1,7 @@
#--------------------------------------------------------------------- #---------------------------------------------------------------------
# README # README
# Bastian M. Wojek, 2010/01/05 # Bastian M. Wojek, 2011/01/27
# $Id: # $Id$
#--------------------------------------------------------------------- #---------------------------------------------------------------------
This directory contains a subset of the code This directory contains a subset of the code

View File

@ -13,7 +13,7 @@ INCLUDES = -I. -Icommon
AM_CFLAGS = $(LOCAL_CUBA_LIB_CFLAGS) AM_CFLAGS = $(LOCAL_CUBA_LIB_CFLAGS)
AM_LDFLAGS = $(LOCAL_LIB_LDFLAGS) AM_LDFLAGS = $(LOCAL_LIB_LDFLAGS)
CLEANFILES = *~ core CLEANFILES = common/*~ cuhre/*~ divonne/*~ suave/*~ vegas/*~ *~ core
lib_LTLIBRARIES = libcuba.la lib_LTLIBRARIES = libcuba.la

View File

@ -7,7 +7,7 @@
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *

View File

@ -8,7 +8,7 @@
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -27,6 +27,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
static real Erfc(creal x) static real Erfc(creal x)
{ {
static creal c[] = { static creal c[] = {

View File

@ -1,11 +1,11 @@
/* /*
Random.c Random.c
quasi- and pseudo-random-number generation quasi- and pseudo-random-number generation
last modified 2 Apr 09 th last modified 8 Jun 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -24,22 +24,47 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
/* /*
PART 1: Sobol quasi-random-number generator PART 1: Sobol quasi-random-number generator
adapted from ACM TOMS algorithm 659 adapted from ACM TOMS algorithm 659
*/ */
#define SOBOL_MINDIM 1 static void SobolGet(This *t, real *x)
#define SOBOL_MAXDIM 40 {
number seq = t->rng.sobol.seq++;
count zerobit = 0, dim;
static struct { while( seq & 1 ) {
real norm; ++zerobit;
number v[SOBOL_MAXDIM][30], prev[SOBOL_MAXDIM]; seq >>= 1;
number seq; }
} sobol_;
for( dim = 0; dim < t->ndim; ++dim ) {
t->rng.sobol.prev[dim] ^= t->rng.sobol.v[dim][zerobit];
x[dim] = t->rng.sobol.prev[dim]*t->rng.sobol.norm;
}
}
static inline void SobolIni(cnumber n) static void SobolSkip(This *t, number n)
{
while( n-- ) {
number seq = t->rng.sobol.seq++;
count zerobit = 0, dim;
while( seq & 1 ) {
++zerobit;
seq >>= 1;
}
for( dim = 0; dim < t->ndim; ++dim )
t->rng.sobol.prev[dim] ^= t->rng.sobol.v[dim][zerobit];
}
}
static inline void SobolIni(This *t)
{ {
static number ini[9*40] = { static number ini[9*40] = {
3, 1, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0,
@ -84,15 +109,16 @@ static inline void SobolIni(cnumber n)
count dim, bit, nbits; count dim, bit, nbits;
number max, *pini = ini; number max, *pini = ini;
cnumber nmax = 2*t->maxeval;
for( nbits = 0, max = 1; max <= n; max <<= 1 ) ++nbits; for( nbits = 0, max = 1; max <= nmax; max <<= 1 ) ++nbits;
sobol_.norm = 1./max; t->rng.sobol.norm = 1./max;
for( bit = 0; bit < nbits; ++bit ) for( bit = 0; bit < nbits; ++bit )
sobol_.v[0][bit] = (max >>= 1); t->rng.sobol.v[0][bit] = (max >>= 1);
for( dim = 1; dim < ndim_; ++dim ) { for( dim = 1; dim < t->ndim; ++dim ) {
number *pv = sobol_.v[dim], *pvv = pv; number *pv = t->rng.sobol.v[dim], *pvv = pv;
number powers = *pini++, j; number powers = *pini++, j;
int inibits = -1, bit; int inibits = -1, bit;
for( j = powers; j; j >>= 1 ) ++inibits; for( j = powers; j; j >>= 1 ) ++inibits;
@ -115,42 +141,11 @@ static inline void SobolIni(cnumber n)
pv[bit] <<= nbits - bit - 1; pv[bit] <<= nbits - bit - 1;
} }
sobol_.seq = 0; t->rng.sobol.seq = 0;
VecClear(sobol_.prev); VecClear(t->rng.sobol.prev);
}
t->rng.getrandom = SobolGet;
static inline void SobolGet(real *x) t->rng.skiprandom = SobolSkip;
{
number seq = sobol_.seq++;
count zerobit = 0, dim;
while( seq & 1 ) {
++zerobit;
seq >>= 1;
}
for( dim = 0; dim < ndim_; ++dim ) {
sobol_.prev[dim] ^= sobol_.v[dim][zerobit];
x[dim] = sobol_.prev[dim]*sobol_.norm;
}
}
static inline void SobolSkip(number n)
{
while( n-- ) {
number seq = sobol_.seq++;
count zerobit = 0, dim;
while( seq & 1 ) {
++zerobit;
seq >>= 1;
}
for( dim = 0; dim < ndim_; ++dim )
sobol_.prev[dim] ^= sobol_.v[dim][zerobit];
}
} }
@ -160,24 +155,9 @@ static inline void SobolSkip(number n)
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
*/ */
/* length of state vector */
#define MERSENNE_N 624
/* period parameter */
#define MERSENNE_M 397
/* 32 or 53 random bits */ /* 32 or 53 random bits */
#define RANDOM_BITS 32 #define RANDOM_BITS 32
typedef unsigned int state_t;
static struct {
state_t state[MERSENNE_N];
count next;
} mersenne_;
unsigned int SUFFIX(mersenneseed);
static inline state_t Twist(state_t a, state_t b) static inline state_t Twist(state_t a, state_t b)
{ {
@ -187,41 +167,21 @@ static inline state_t Twist(state_t a, state_t b)
} }
static inline void MersenneReload() static inline void MersenneReload(state_t *state)
{ {
state_t *s = mersenne_.state; state_t *s = state;
int j; int j;
for( j = MERSENNE_N - MERSENNE_M + 1; --j; ++s ) for( j = MERSENNE_N - MERSENNE_M + 1; --j; ++s )
*s = s[MERSENNE_M] ^ Twist(s[0], s[1]); *s = s[MERSENNE_M] ^ Twist(s[0], s[1]);
for( j = MERSENNE_M; --j; ++s ) for( j = MERSENNE_M; --j; ++s )
*s = s[MERSENNE_M - MERSENNE_N] ^ Twist(s[0], s[1]); *s = s[MERSENNE_M - MERSENNE_N] ^ Twist(s[0], s[1]);
*s = s[MERSENNE_M - MERSENNE_N] ^ Twist(s[0], mersenne_.state[0]); *s = s[MERSENNE_M - MERSENNE_N] ^ Twist(s[0], state[0]);
} }
static inline void MersenneIni() static inline state_t MersenneInt(state_t s)
{ {
state_t seed = SUFFIX(mersenneseed);
state_t *next = mersenne_.state;
int j;
if( seed == 0 ) seed = 5489;
for( j = 1; j <= MERSENNE_N; ++j ) {
*next++ = seed;
seed = 0x6c078965*(seed ^ (seed >> 30)) + j;
/* see Knuth TAOCP Vol 2, 3rd Ed, p. 106 for multiplier */
}
MersenneReload();
mersenne_.next = 0;
}
static inline state_t MersenneInt(count next)
{
state_t s = mersenne_.state[next];
s ^= s >> 11; s ^= s >> 11;
s ^= (s << 7) & 0x9d2c5680; s ^= (s << 7) & 0x9d2c5680;
s ^= (s << 15) & 0xefc60000; s ^= (s << 15) & 0xefc60000;
@ -229,75 +189,177 @@ static inline state_t MersenneInt(count next)
} }
static inline void MersenneGet(real *x) static void MersenneGet(This *t, real *x)
{ {
count next = mersenne_.next, dim; count next = t->rng.mersenne.next, dim;
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
#if RANDOM_BITS == 53 #if RANDOM_BITS == 53
state_t a, b; state_t a, b;
#endif #endif
if( next >= MERSENNE_N ) { if( next >= MERSENNE_N ) {
MersenneReload(); MersenneReload(t->rng.mersenne.state);
next = 0; next = 0;
} }
#if RANDOM_BITS == 53 #if RANDOM_BITS == 53
a = MersenneInt(next++) >> 5; a = MersenneInt(t->rng.mersenne.state[next++]) >> 5;
b = MersenneInt(next++) >> 6; b = MersenneInt(t->rng.mersenne.state[next++]) >> 6;
x[dim] = (67108864.*a + b)/9007199254740992.; x[dim] = (67108864.*a + b)/9007199254740992.;
#else #else
x[dim] = MersenneInt(next++)/4294967296.; x[dim] = MersenneInt(t->rng.mersenne.state[next++])/4294967296.;
#endif #endif
} }
mersenne_.next = next; t->rng.mersenne.next = next;
} }
static inline void MersenneSkip(number n) static void MersenneSkip(This *t, number n)
{ {
#if RANDOM_BITS == 53 #if RANDOM_BITS == 53
n = 2*n*ndim_ + mersenne_.next; n = 2*n*t->ndim + t->rng.mersenne.next;
#else #else
n = n*ndim_ + mersenne_.next; n = n*t->ndim + t->rng.mersenne.next;
#endif #endif
mersenne_.next = n % MERSENNE_N; t->rng.mersenne.next = n % MERSENNE_N;
n /= MERSENNE_N; n /= MERSENNE_N;
while( n-- ) MersenneReload(); while( n-- ) MersenneReload(t->rng.mersenne.state);
}
static inline void MersenneIni(This *t)
{
state_t seed = t->seed;
state_t *next = t->rng.mersenne.state;
count j;
for( j = 1; j <= MERSENNE_N; ++j ) {
*next++ = seed;
seed = 0x6c078965*(seed ^ (seed >> 30)) + j;
/* see Knuth TAOCP Vol 2, 3rd Ed, p. 106 for multiplier */
}
MersenneReload(t->rng.mersenne.state);
t->rng.mersenne.next = 0;
t->rng.getrandom = MersenneGet;
t->rng.skiprandom = MersenneSkip;
} }
/* /*
PART 3: User routines: PART 3: Ranlux subtract-and-borrow random-number generator
proposed by Marsaglia and Zaman, implemented by F. James with
the name RCARRY in 1991, and later improved by Martin Luescher
in 1993 to produce "Luxury Pseudorandom Numbers".
Adapted from the CERNlib Fortran 77 code by F. James, 1993.
The available luxury levels are:
level 0 (p = 24): equivalent to the original RCARRY of Marsaglia
and Zaman, very long period, but fails many tests.
level 1 (p = 48): considerable improvement in quality over level 0,
now passes the gap test, but still fails spectral test.
level 2 (p = 97): passes all known tests, but theoretically still
defective.
level 3 (p = 223): DEFAULT VALUE. Any theoretically possible
correlations have very small chance of being observed.
level 4 (p = 389): highest possible luxury, all 24 bits chaotic.
*/
static inline int RanluxInt(This *t, count n)
{
int s = 0;
while( n-- ) {
s = t->rng.ranlux.state[t->rng.ranlux.j24] -
t->rng.ranlux.state[t->rng.ranlux.i24] + t->rng.ranlux.carry;
s += (t->rng.ranlux.carry = NegQ(s)) & (1 << 24);
t->rng.ranlux.state[t->rng.ranlux.i24] = s;
--t->rng.ranlux.i24;
t->rng.ranlux.i24 += NegQ(t->rng.ranlux.i24) & 24;
--t->rng.ranlux.j24;
t->rng.ranlux.j24 += NegQ(t->rng.ranlux.j24) & 24;
}
return s;
}
static void RanluxGet(This *t, real *x)
{
/* The Generator proper: "Subtract-with-borrow",
as proposed by Marsaglia and Zaman, FSU, March 1989 */
count dim;
for( dim = 0; dim < t->ndim; ++dim ) {
cint nskip = (--t->rng.ranlux.n24 >= 0) ? 0 :
(t->rng.ranlux.n24 = 24, t->rng.ranlux.nskip);
cint s = RanluxInt(t, 1 + nskip);
x[dim] = s*0x1p-24;
/* small numbers (with less than 12 significant bits) are "padded" */
if( s < (1 << 12) )
x[dim] += t->rng.ranlux.state[t->rng.ranlux.j24]*0x1p-48;
}
}
static void RanluxSkip(This *t, cnumber n)
{
RanluxInt(t, n + t->rng.ranlux.nskip*(n/24));
t->rng.ranlux.n24 = 24 - n % 24;
}
static inline void RanluxIni(This *t)
{
cint skip[] = {24, 48, 97, 223, 389,
223, 223, 223, 223, 223, 223, 223, 223, 223, 223,
223, 223, 223, 223, 223, 223, 223, 223, 223, 223};
state_t seed = t->seed;
state_t level = RNG;
count i;
if( level < sizeof skip ) level = skip[level];
t->rng.ranlux.nskip = level - 24;
t->rng.ranlux.i24 = 23;
t->rng.ranlux.j24 = 9;
t->rng.ranlux.n24 = 24;
for( i = 0; i < 24; ++i ) {
cint k = seed/53668;
seed = 40014*(seed - k*53668) - k*12211;
seed += NegQ(seed) & 2147483563;
t->rng.ranlux.state[i] = seed & ((1 << 24) - 1);
}
t->rng.ranlux.carry = ~TrueQ(t->rng.ranlux.state[23]) & (1 << 24);
t->rng.getrandom = RanluxGet;
t->rng.skiprandom = RanluxSkip;
}
/*
PART 4: User routines:
- IniRandom sets up the random-number generator to produce a - IniRandom sets up the random-number generator to produce a
sequence of at least n ndim_-dimensional random vectors. sequence of at least n ndim-dimensional random vectors.
- GetRandom retrieves one random vector. - GetRandom retrieves one random vector.
- SkipRandom skips over n random vectors. - SkipRandom skips over n random vectors.
*/ */
static void IniRandom(cnumber n, cint flags) static inline void IniRandom(This *t)
{ {
if( PSEUDORNG ) { if( t->seed == 0 ) SobolIni(t);
sobol_.seq = -1; else if( RNG == 0 ) MersenneIni(t);
MersenneIni(); else RanluxIni(t);
}
else SobolIni(n);
}
static inline void GetRandom(real *x)
{
if( sobol_.seq == -1 ) MersenneGet(x);
else SobolGet(x);
}
static inline void SkipRandom(cnumber n)
{
if( sobol_.seq == -1 ) MersenneSkip(n);
else SobolSkip(n);
} }

View File

@ -1,11 +1,11 @@
/* /*
stddecl.h stddecl.h
Type declarations common to all Cuba routines Type declarations common to all Cuba routines
last modified 29 May 09 th last modified 16 Jun 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -24,6 +24,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
#ifndef __stddecl_h__ #ifndef __stddecl_h__
#define __stddecl_h__ #define __stddecl_h__
@ -39,45 +40,47 @@
#include <limits.h> #include <limits.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <setjmp.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifndef NDIM #ifndef NDIM
#define NDIM ndim_ #define NDIM t->ndim
#endif #endif
#ifndef NCOMP #ifndef NCOMP
#define NCOMP ncomp_ #define NCOMP t->ncomp
#endif #endif
#define VERBOSE (flags & 3) #define VERBOSE (t->flags & 3)
#define LAST (flags & 4) #define LAST (t->flags & 4)
#define PSEUDORNG (flags & 8) #define SHARPEDGES (t->flags & 8)
#define SHARPEDGES (flags & 16) #define REGIONS (t->flags & 128)
#define REGIONS (flags & 256) #define RNG (t->flags >> 8)
#define INFTY DBL_MAX #define INFTY DBL_MAX
#define NOTZERO 0x1p-104 #define NOTZERO 0x1p-104
#define ABORT -999
#define Elements(x) (sizeof(x)/sizeof(*x)) #define Elements(x) (sizeof(x)/sizeof(*x))
#define Copy(d, s, n) memcpy(d, s, (n)*sizeof(*(d))) #define Copy(d, s, n) memcpy(d, s, (n)*sizeof(*(d)))
#define VecCopy(d, s) Copy(d, s, ndim_) #define VecCopy(d, s) Copy(d, s, t->ndim)
#define ResCopy(d, s) Copy(d, s, ncomp_) #define ResCopy(d, s) Copy(d, s, t->ncomp)
#define Clear(d, n) memset(d, 0, (n)*sizeof(*(d))) #define Clear(d, n) memset(d, 0, (n)*sizeof(*(d)))
#define VecClear(d) Clear(d, ndim_) #define VecClear(d) Clear(d, t->ndim)
#define ResClear(d) Clear(d, ncomp_) #define ResClear(d) Clear(d, t->ncomp)
#define Zap(d) memset(d, 0, sizeof(d)) #define Zap(d) memset(d, 0, sizeof(d))
#define MaxErr(avg) Max(epsrel*fabs(avg), epsabs) #define MaxErr(avg) Max(t->epsrel*fabs(avg), t->epsabs)
#ifdef __cplusplus #ifdef __cplusplus
#define mallocset(p, n) (*(void **)&p = malloc(n)) #define mallocset(p, n) (*(void **)&p = malloc(n))
@ -104,6 +107,8 @@
typedef enum { false, true } bool; typedef enum { false, true } bool;
#endif #endif
typedef const char cchar;
typedef const bool cbool; typedef const bool cbool;
typedef const int cint; typedef const int cint;
@ -140,6 +145,40 @@ typedef /*long*/ double real;
typedef const real creal; typedef const real creal;
struct _this;
typedef unsigned int state_t;
#define SOBOL_MINDIM 1
#define SOBOL_MAXDIM 40
/* length of state vector */
#define MERSENNE_N 624
/* period parameter */
#define MERSENNE_M 397
typedef struct {
void (*getrandom)(struct _this *t, real *x);
void (*skiprandom)(struct _this *t, cnumber n);
union {
struct {
real norm;
number v[SOBOL_MAXDIM][30], prev[SOBOL_MAXDIM];
number seq;
} sobol;
struct {
state_t state[MERSENNE_N];
count next;
} mersenne;
struct {
count n24, i24, j24, nskip;
int carry, state[24];
} ranlux;
};
} RNGState;
#ifdef UNDERSCORE #ifdef UNDERSCORE
#define SUFFIX(s) s##_ #define SUFFIX(s) s##_
#else #else
@ -175,6 +214,9 @@ static inline real Weight(creal sum, creal sqsum, cnumber n)
/* (a < 0) ? -1 : 0 */ /* (a < 0) ? -1 : 0 */
#define NegQ(a) ((a) >> (sizeof(a)*8 - 1)) #define NegQ(a) ((a) >> (sizeof(a)*8 - 1))
/* (a < 0) ? -1 : 1 */
#define Sign(a) (1 + 2*NegQ(a))
/* (a < 0) ? 0 : a */ /* (a < 0) ? 0 : a */
#define IDim(a) ((a) & NegQ(-(a))) #define IDim(a) ((a) & NegQ(-(a)))

View File

@ -2,11 +2,11 @@
cuba.h cuba.h
Prototypes for the Cuba library Prototypes for the Cuba library
this file is part of Cuba this file is part of Cuba
last modified 5 Dec 08 th last modified 16 Jun 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -29,59 +29,74 @@
extern "C" { extern "C" {
#endif #endif
typedef void (*integrand_t)(const int *, const double [], /* NB: Divonne actually passes a fifth argument, a const int *
const int *, double []); which points to the integration phase. This is used only
rarely and most users are confused by the warnings the
compiler emits if the `correct' prototype is used. Thus,
if you need to access this argument, use an explicit cast
to integrand_t when invoking Divonne. */
typedef int (*integrand_t)(const int *ndim, const double x[],
const int *ncomp, double f[], void *userdata);
/* Note: Divonne actually passes a fifth argument, a const int * typedef void (*peakfinder_t)(const int *ndim, const double b[],
which points to the integration phase. This is used only rarely int *n, double x[]);
and most users are confused by the warnings the compiler emits
if the `correct' prototype is used. Thus, if you need to access
this argument, use an explicit cast to integrand_t when invoking
Divonne. */
void Vegas(const int ndim, const int ncomp,
void Vegas(const int ndim, const int ncomp, integrand_t integrand, integrand_t integrand, void *userdata,
const double epsrel, const double epsabs, const double epsrel, const double epsabs,
const int flags, const int mineval, const int maxeval, const int flags, const int seed,
const int nstart, const int nincrease, const int mineval, const int maxeval,
const int nstart, const int nincrease, const int nbatch,
const int gridno, const char *statefile,
int *neval, int *fail, int *neval, int *fail,
double integral[], double error[], double prob[]); double integral[], double error[], double prob[]);
void llVegas(const int ndim, const int ncomp, integrand_t integrand, void llVegas(const int ndim, const int ncomp,
integrand_t integrand, void *userdata,
const double epsrel, const double epsabs, const double epsrel, const double epsabs,
const int flags, const long long int mineval, const long long int maxeval, const int flags, const int seed,
const long long int mineval, const long long int maxeval,
const long long int nstart, const long long int nincrease, const long long int nstart, const long long int nincrease,
const long long int nbatch,
const int gridno, const char *statefile,
long long int *neval, int *fail, long long int *neval, int *fail,
double integral[], double error[], double prob[]); double integral[], double error[], double prob[]);
void Suave(const int ndim, const int ncomp, integrand_t integrand, void Suave(const int ndim, const int ncomp,
integrand_t integrand, void *userdata,
const double epsrel, const double epsabs, const double epsrel, const double epsabs,
const int flags, const int mineval, const int maxeval, const int flags, const int seed,
const int mineval, const int maxeval,
const int nnew, const double flatness, const int nnew, const double flatness,
int *nregions, int *neval, int *fail, int *nregions, int *neval, int *fail,
double integral[], double error[], double prob[]); double integral[], double error[], double prob[]);
void llSuave(const int ndim, const int ncomp, integrand_t integrand, void llSuave(const int ndim, const int ncomp,
integrand_t integrand, void *userdata,
const double epsrel, const double epsabs, const double epsrel, const double epsabs,
const int flags, const long long int mineval, const long long int maxeval, const int flags, const int seed,
const long long int mineval, const long long int maxeval,
const long long int nnew, const double flatness, const long long int nnew, const double flatness,
int *nregions, long long int *neval, int *fail, int *nregions, long long int *neval, int *fail,
double integral[], double error[], double prob[]); double integral[], double error[], double prob[]);
void Divonne(const int ndim, const int ncomp, integrand_t integrand, void Divonne(const int ndim, const int ncomp,
integrand_t integrand, void *userdata,
const double epsrel, const double epsabs, const double epsrel, const double epsabs,
const int flags, const int mineval, const int maxeval, const int flags, const int seed,
const int mineval, const int maxeval,
const int key1, const int key2, const int key3, const int maxpass, const int key1, const int key2, const int key3, const int maxpass,
const double border, const double maxchisq, const double mindeviation, const double border, const double maxchisq, const double mindeviation,
const int ngiven, const int ldxgiven, double xgiven[], const int ngiven, const int ldxgiven, double xgiven[],
const int nextra, const int nextra, peakfinder_t peakfinder,
void (*peakfinder)(const int *, const double [], int *, double []),
int *nregions, int *neval, int *fail, int *nregions, int *neval, int *fail,
double integral[], double error[], double prob[]); double integral[], double error[], double prob[]);
void llDivonne(const int ndim, const int ncomp, integrand_t integrand, void llDivonne(const int ndim, const int ncomp,
integrand_t integrand, void *userdata,
const double epsrel, const double epsabs, const double epsrel, const double epsabs,
const int flags, const long long int mineval, const long long int maxeval, const int flags, const int seed,
const long long int mineval, const long long int maxeval,
const int key1, const int key2, const int key3, const int maxpass, const int key1, const int key2, const int key3, const int maxpass,
const double border, const double maxchisq, const double mindeviation, const double border, const double maxchisq, const double mindeviation,
const long long int ngiven, const int ldxgiven, double xgiven[], const long long int ngiven, const int ldxgiven, double xgiven[],
@ -90,30 +105,23 @@ void llDivonne(const int ndim, const int ncomp, integrand_t integrand,
int *nregions, long long int *neval, int *fail, int *nregions, long long int *neval, int *fail,
double integral[], double error[], double prob[]); double integral[], double error[], double prob[]);
void Cuhre(const int ndim, const int ncomp, integrand_t integrand, void Cuhre(const int ndim, const int ncomp,
integrand_t integrand, void *userdata,
const double epsrel, const double epsabs, const double epsrel, const double epsabs,
const int flags, const int mineval, const int maxeval, const int flags, const int mineval, const int maxeval,
const int key, const int key,
int *nregions, int *neval, int *fail, int *nregions, int *neval, int *fail,
double integral[], double error[], double prob[]); double integral[], double error[], double prob[]);
void llCuhre(const int ndim, const int ncomp, integrand_t integrand, void llCuhre(const int ndim, const int ncomp,
integrand_t integrand, void *userdata,
const double epsrel, const double epsabs, const double epsrel, const double epsabs,
const int flags, const long long int mineval, const long long int maxeval, const int flags,
const long long int mineval, const long long int maxeval,
const int key, const int key,
int *nregions, long long int *neval, int *fail, int *nregions, long long int *neval, int *fail,
double integral[], double error[], double prob[]); double integral[], double error[], double prob[]);
extern int vegasnbatch;
extern int vegasgridno;
extern char vegasstate[128];
extern int llvegasnbatch;
extern int llvegasgridno;
extern char llvegasstate[128];
extern unsigned int mersenneseed;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -2,11 +2,11 @@
Cuhre.c Cuhre.c
Adaptive integration using cubature rules Adaptive integration using cubature rules
by Thomas Hahn by Thomas Hahn
last modified 2 Mar 06 th last modified 16 Jun 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -25,21 +25,21 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
#include "util.c"
#include "decl.h"
#define Print(s) puts(s); fflush(stdout) #define Print(s) puts(s); fflush(stdout)
static Integrand integrand_;
/*********************************************************************/ /*********************************************************************/
static inline void DoSample(count n, creal *x, real *f) static inline void DoSample(This *t, count n, creal *x, real *f)
{ {
neval_ += n; t->neval += n;
while( n-- ) { while( n-- ) {
integrand_(&ndim_, x, &ncomp_, f); if( t->integrand(&t->ndim, x, &t->ncomp, f, t->userdata) == ABORT )
x += ndim_; longjmp(t->abort, 1);
f += ncomp_; x += t->ndim;
f += t->ncomp;
} }
} }
@ -48,44 +48,58 @@ static inline void DoSample(count n, creal *x, real *f)
#include "common.c" #include "common.c"
Extern void EXPORT(Cuhre)(ccount ndim, ccount ncomp, Extern void EXPORT(Cuhre)(ccount ndim, ccount ncomp,
Integrand integrand, Integrand integrand, void *userdata,
creal epsrel, creal epsabs, creal epsrel, creal epsabs,
cint flags, cnumber mineval, cnumber maxeval, cint flags, cnumber mineval, cnumber maxeval,
ccount key, ccount key,
count *pnregions, number *pneval, int *pfail, count *pnregions, number *pneval, int *pfail,
real *integral, real *error, real *prob) real *integral, real *error, real *prob)
{ {
ndim_ = ndim; This t;
ncomp_ = ncomp; t.ndim = ndim;
t.ncomp = ncomp;
t.integrand = integrand;
t.userdata = userdata;
t.epsrel = epsrel;
t.epsabs = epsabs;
t.flags = flags;
t.mineval = mineval;
t.maxeval = maxeval;
t.key = key;
t.nregions = 0;
t.neval = 0;
if( BadComponent(ncomp) || BadDimension(ndim) ) *pfail = -1; *pfail = Integrate(&t, integral, error, prob);
else { *pnregions = t.nregions;
neval_ = 0; *pneval = t.neval;
integrand_ = integrand;
*pfail = Integrate(epsrel, Max(epsabs, NOTZERO),
flags, mineval, maxeval, key,
integral, error, prob);
*pnregions = nregions_;
*pneval = neval_;
}
} }
/*********************************************************************/ /*********************************************************************/
Extern void EXPORT(cuhre)(ccount *pndim, ccount *pncomp, Extern void EXPORT(cuhre)(ccount *pndim, ccount *pncomp,
Integrand integrand, Integrand integrand, void *userdata,
creal *pepsrel, creal *pepsabs, creal *pepsrel, creal *pepsabs,
cint *pflags, cnumber *pmineval, cnumber *pmaxeval, cint *pflags, cnumber *pmineval, cnumber *pmaxeval,
ccount *pkey, ccount *pkey,
count *pnregions, number *pneval, int *pfail, count *pnregions, number *pneval, int *pfail,
real *integral, real *error, real *prob) real *integral, real *error, real *prob)
{ {
EXPORT(Cuhre)(*pndim, *pncomp, integrand, This t;
*pepsrel, *pepsabs, t.ndim = *pndim;
*pflags, *pmineval, *pmaxeval, t.ncomp = *pncomp;
*pkey, t.integrand = integrand;
pnregions, pneval, pfail, t.userdata = userdata;
integral, error, prob); t.epsrel = *pepsrel;
t.epsabs = *pepsabs;
t.flags = *pflags;
t.mineval = *pmineval;
t.maxeval = *pmaxeval;
t.key = *pkey;
t.nregions = 0;
t.neval = 0;
*pfail = Integrate(&t, integral, error, prob);
*pnregions = t.nregions;
*pneval = t.neval;
} }

View File

@ -2,11 +2,11 @@
Integrate.c Integrate.c
integrate over the unit hypercube integrate over the unit hypercube
this file is part of Cuhre this file is part of Cuhre
last modified 8 Apr 09 th last modified 7 Jun 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -25,11 +25,10 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
#define POOLSIZE 1024 #define POOLSIZE 1024
static int Integrate(creal epsrel, creal epsabs, static int Integrate(This *t, real *integral, real *error, real *prob)
cint flags, number mineval, cnumber maxeval, ccount key,
real *integral, real *error, real *prob)
{ {
TYPEDEFREGION; TYPEDEFREGION;
typedef struct pool { typedef struct pool {
@ -37,9 +36,8 @@ static int Integrate(creal epsrel, creal epsabs,
Region region[POOLSIZE]; Region region[POOLSIZE];
} Pool; } Pool;
count dim, comp, ncur, nregions, ipool, npool; count dim, comp, ncur, ipool, npool;
int fail = 1; int fail = -99;
Rule rule;
Totals totals[NCOMP]; Totals totals[NCOMP];
Pool *cur = NULL, *pool; Pool *cur = NULL, *pool;
Region *region; Region *region;
@ -51,31 +49,21 @@ static int Integrate(creal epsrel, creal epsabs,
" epsrel " REAL "\n epsabs " REAL "\n" " epsrel " REAL "\n epsabs " REAL "\n"
" flags %d\n mineval " NUMBER "\n maxeval " NUMBER "\n" " flags %d\n mineval " NUMBER "\n maxeval " NUMBER "\n"
" key " COUNT, " key " COUNT,
ndim_, ncomp_, t->ndim, t->ncomp,
epsrel, epsabs, t->epsrel, t->epsabs,
flags, mineval, maxeval, t->flags, t->mineval, t->maxeval,
key); t->key);
Print(s); Print(s);
} }
#ifdef MLVERSION if( BadComponent(t) ) return -2;
if( setjmp(abort_) ) goto abort; if( BadDimension(t) ) return -1;
#endif
if( key == 13 && ndim_ == 2 ) Rule13Alloc(&rule); RuleAlloc(t);
else if( key == 11 && ndim_ == 3 ) Rule11Alloc(&rule); t->epsabs = Max(t->epsabs, NOTZERO);
else if( key == 9 ) Rule9Alloc(&rule); t->mineval = IMax(t->mineval, t->rule.n + 1);
else if( key == 7 ) Rule7Alloc(&rule);
else {
if( ndim_ == 2 ) Rule13Alloc(&rule);
else if( ndim_ == 3 ) Rule11Alloc(&rule);
else Rule9Alloc(&rule);
}
Alloc(rule.x, rule.n*(ndim_ + ncomp_)); if( setjmp(t->abort) ) goto abort;
rule.f = rule.x + rule.n*ndim_;
mineval = IMax(mineval, rule.n + 1);
Alloc(cur, 1); Alloc(cur, 1);
cur->next = NULL; cur->next = NULL;
@ -83,15 +71,15 @@ static int Integrate(creal epsrel, creal epsabs,
region = cur->region; region = cur->region;
region->div = 0; region->div = 0;
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
Bounds *b = &region->bounds[dim]; Bounds *b = &region->bounds[dim];
b->lower = 0; b->lower = 0;
b->upper = 1; b->upper = 1;
} }
Sample(&rule, region, flags); Sample(t, region);
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
Totals *tot = &totals[comp]; Totals *tot = &totals[comp];
Result *r = &region->result[comp]; Result *r = &region->result[comp];
tot->avg = tot->lastavg = tot->guess = r->avg; tot->avg = tot->lastavg = tot->guess = r->avg;
@ -101,7 +89,7 @@ static int Integrate(creal epsrel, creal epsabs,
tot->chisq = tot->chisqsum = tot->chisum = 0; tot->chisq = tot->chisqsum = tot->chisum = 0;
} }
for( nregions = 1; ; ++nregions ) { for( t->nregions = 1; ; ++t->nregions ) {
count maxcomp, bisectdim; count maxcomp, bisectdim;
real maxratio, maxerr; real maxratio, maxerr;
Result result[NCOMP]; Result result[NCOMP];
@ -113,13 +101,13 @@ static int Integrate(creal epsrel, creal epsabs,
p += sprintf(p, "\n" p += sprintf(p, "\n"
"Iteration " COUNT ": " NUMBER " integrand evaluations so far", "Iteration " COUNT ": " NUMBER " integrand evaluations so far",
nregions, neval_); t->nregions, t->neval);
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
cTotals *tot = &totals[comp]; cTotals *tot = &totals[comp];
p += sprintf(p, "\n[" COUNT "] " p += sprintf(p, "\n[" COUNT "] "
REAL " +- " REAL " \tchisq " REAL " (" COUNT " df)", REAL " +- " REAL " \tchisq " REAL " (" COUNT " df)",
comp + 1, tot->avg, tot->err, tot->chisq, nregions - 1); comp + 1, tot->avg, tot->err, tot->chisq, t->nregions - 1);
} }
Print(s); Print(s);
@ -127,7 +115,7 @@ static int Integrate(creal epsrel, creal epsabs,
maxratio = -INFTY; maxratio = -INFTY;
maxcomp = 0; maxcomp = 0;
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
creal ratio = totals[comp].err/MaxErr(totals[comp].avg); creal ratio = totals[comp].err/MaxErr(totals[comp].avg);
if( ratio > maxratio ) { if( ratio > maxratio ) {
maxratio = ratio; maxratio = ratio;
@ -135,12 +123,12 @@ static int Integrate(creal epsrel, creal epsabs,
} }
} }
if( maxratio <= 1 && neval_ >= mineval ) { if( maxratio <= 1 && t->neval >= t->mineval ) {
fail = 0; fail = 0;
break; break;
} }
if( neval_ >= maxeval ) break; if( t->neval >= t->maxeval ) break;
maxerr = -INFTY; maxerr = -INFTY;
regionL = cur->region; regionL = cur->region;
@ -172,10 +160,10 @@ static int Integrate(creal epsrel, creal epsabs,
bR = &regionR->bounds[bisectdim]; bR = &regionR->bounds[bisectdim];
bL->upper = bR->lower = .5*(bL->upper + bL->lower); bL->upper = bR->lower = .5*(bL->upper + bL->lower);
Sample(&rule, regionL, flags); Sample(t, regionL);
Sample(&rule, regionR, flags); Sample(t, regionR);
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
cResult *r = &result[comp]; cResult *r = &result[comp];
Result *rL = &regionL->result[comp]; Result *rL = &regionL->result[comp];
Result *rR = &regionR->result[comp]; Result *rR = &regionR->result[comp];
@ -214,17 +202,17 @@ static int Integrate(creal epsrel, creal epsabs,
} }
} }
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
cTotals *tot = &totals[comp]; cTotals *tot = &totals[comp];
integral[comp] = tot->avg; integral[comp] = tot->avg;
error[comp] = tot->err; error[comp] = tot->err;
prob[comp] = ChiSquare(tot->chisq, nregions - 1); prob[comp] = ChiSquare(tot->chisq, t->nregions - 1);
} }
#ifdef MLVERSION #ifdef MLVERSION
if( REGIONS ) { if( REGIONS ) {
MLPutFunction(stdlink, "List", 2); MLPutFunction(stdlink, "List", 2);
MLPutFunction(stdlink, "List", nregions); MLPutFunction(stdlink, "List", t->nregions);
npool = ncur; npool = ncur;
for( pool = cur; pool; npool = POOLSIZE, pool = pool->next ) for( pool = cur; pool; npool = POOLSIZE, pool = pool->next )
@ -232,18 +220,18 @@ static int Integrate(creal epsrel, creal epsabs,
Region const *region = &pool->region[ipool]; Region const *region = &pool->region[ipool];
real lower[NDIM], upper[NDIM]; real lower[NDIM], upper[NDIM];
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
cBounds *b = &region->bounds[dim]; cBounds *b = &region->bounds[dim];
lower[dim] = b->lower; lower[dim] = b->lower;
upper[dim] = b->upper; upper[dim] = b->upper;
} }
MLPutFunction(stdlink, "Cuba`Cuhre`region", 3); MLPutFunction(stdlink, "Cuba`Cuhre`region", 3);
MLPutRealList(stdlink, lower, ndim_); MLPutRealList(stdlink, lower, t->ndim);
MLPutRealList(stdlink, upper, ndim_); MLPutRealList(stdlink, upper, t->ndim);
MLPutFunction(stdlink, "List", ncomp_); MLPutFunction(stdlink, "List", t->ncomp);
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
cResult *r = &region->result[comp]; cResult *r = &region->result[comp];
real res[] = {r->avg, r->err}; real res[] = {r->avg, r->err};
MLPutRealList(stdlink, res, Elements(res)); MLPutRealList(stdlink, res, Elements(res));
@ -252,19 +240,13 @@ static int Integrate(creal epsrel, creal epsabs,
} }
#endif #endif
#ifdef MLVERSION
abort: abort:
#endif
while( (pool = cur) ) { while( (pool = cur) ) {
cur = cur->next; cur = cur->next;
free(pool); free(pool);
} }
free(rule.x); RuleFree(t);
RuleFree(&rule);
nregions_ = nregions;
return fail; return fail;
} }

View File

@ -4,11 +4,11 @@
code lifted with minor modifications from DCUHRE code lifted with minor modifications from DCUHRE
by J. Berntsen, T. Espelid, and A. Genz by J. Berntsen, T. Espelid, and A. Genz
this file is part of Divonne this file is part of Divonne
last modified 9 Feb 05 th last modified 8 Jun 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -38,14 +38,7 @@ enum { nrules = 5 };
/*********************************************************************/ /*********************************************************************/
static inline void RuleFree(Rule *rule) static void Rule13Alloc(This *t)
{
free(rule->first);
}
/*********************************************************************/
static void Rule13Alloc(Rule *rule)
{ {
static creal w[][nrules] = { static creal w[][nrules] = {
{ .00844923090033615, .3213775489050763, .3372900883288987, { .00844923090033615, .3213775489050763, .3372900883288987,
@ -93,7 +86,7 @@ static void Rule13Alloc(Rule *rule)
TYPEDEFSET; TYPEDEFSET;
count n, r; count n, r;
Set *first, *last, *s, *t; Set *first, *last, *s, *x;
Alloc(first, nsets); Alloc(first, nsets);
Clear(first, nsets); Clear(first, nsets);
@ -175,20 +168,20 @@ static void Rule13Alloc(Rule *rule)
last->gen[0] = g[14]; last->gen[0] = g[14];
last->gen[1] = g[15]; last->gen[1] = g[15];
rule->first = first; t->rule.first = first;
rule->last = last; t->rule.last = last;
rule->errcoeff[0] = 10; t->rule.errcoeff[0] = 10;
rule->errcoeff[1] = 1; t->rule.errcoeff[1] = 1;
rule->errcoeff[2] = 5; t->rule.errcoeff[2] = 5;
rule->n = n; t->rule.n = n;
for( s = first; s <= last; ++s ) for( s = first; s <= last; ++s )
for( r = 1; r < nrules - 1; ++r ) { for( r = 1; r < nrules - 1; ++r ) {
creal scale = (s->weight[r] == 0) ? 100 : creal scale = (s->weight[r] == 0) ? 100 :
-s->weight[r + 1]/s->weight[r]; -s->weight[r + 1]/s->weight[r];
real sum = 0; real sum = 0;
for( t = first; t <= last; ++t ) for( x = first; x <= last; ++x )
sum += t->n*fabs(t->weight[r + 1] + scale*t->weight[r]); sum += x->n*fabs(x->weight[r + 1] + scale*x->weight[r]);
s->scale[r] = scale; s->scale[r] = scale;
s->norm[r] = 1/sum; s->norm[r] = 1/sum;
} }
@ -196,7 +189,7 @@ static void Rule13Alloc(Rule *rule)
/*********************************************************************/ /*********************************************************************/
static void Rule11Alloc(Rule *rule) static void Rule11Alloc(This *t)
{ {
static creal w[][nrules] = { static creal w[][nrules] = {
{ .0009903847688882167, 1.715006248224684, 1.936014978949526, { .0009903847688882167, 1.715006248224684, 1.936014978949526,
@ -241,7 +234,7 @@ static void Rule11Alloc(Rule *rule)
TYPEDEFSET; TYPEDEFSET;
count n, r; count n, r;
Set *first, *last, *s, *t; Set *first, *last, *s, *x;
Alloc(first, nsets); Alloc(first, nsets);
Clear(first, nsets); Clear(first, nsets);
@ -322,20 +315,20 @@ static void Rule11Alloc(Rule *rule)
last->gen[1] = g[12]; last->gen[1] = g[12];
last->gen[2] = g[13]; last->gen[2] = g[13];
rule->first = first; t->rule.first = first;
rule->last = last; t->rule.last = last;
rule->errcoeff[0] = 4; t->rule.errcoeff[0] = 4;
rule->errcoeff[1] = .5; t->rule.errcoeff[1] = .5;
rule->errcoeff[2] = 3; t->rule.errcoeff[2] = 3;
rule->n = n; t->rule.n = n;
for( s = first; s <= last; ++s ) for( s = first; s <= last; ++s )
for( r = 1; r < nrules - 1; ++r ) { for( r = 1; r < nrules - 1; ++r ) {
creal scale = (s->weight[r] == 0) ? 100 : creal scale = (s->weight[r] == 0) ? 100 :
-s->weight[r + 1]/s->weight[r]; -s->weight[r + 1]/s->weight[r];
real sum = 0; real sum = 0;
for( t = first; t <= last; ++t ) for( x = first; x <= last; ++x )
sum += t->n*fabs(t->weight[r + 1] + scale*t->weight[r]); sum += x->n*fabs(x->weight[r + 1] + scale*x->weight[r]);
s->scale[r] = scale; s->scale[r] = scale;
s->norm[r] = 1/sum; s->norm[r] = 1/sum;
} }
@ -343,7 +336,7 @@ static void Rule11Alloc(Rule *rule)
/*********************************************************************/ /*********************************************************************/
static void Rule9Alloc(Rule *rule) static void Rule9Alloc(This *t)
{ {
static creal w[] = { static creal w[] = {
-.0023611709677855117884, .11415390023857325268, -.0023611709677855117884, .11415390023857325268,
@ -377,10 +370,10 @@ static void Rule9Alloc(Rule *rule)
TYPEDEFSET; TYPEDEFSET;
ccount ndim = ndim_; ccount ndim = t->ndim;
ccount twondim = 1 << ndim; ccount twondim = 1 << ndim;
count dim, n, r; count dim, n, r;
Set *first, *last, *s, *t; Set *first, *last, *s, *x;
Alloc(first, nsets); Alloc(first, nsets);
Clear(first, nsets); Clear(first, nsets);
@ -466,20 +459,20 @@ static void Rule9Alloc(Rule *rule)
for( dim = 0; dim < ndim; ++dim ) for( dim = 0; dim < ndim; ++dim )
last->gen[dim] = g[4]; last->gen[dim] = g[4];
rule->first = first; t->rule.first = first;
rule->last = last; t->rule.last = last;
rule->errcoeff[0] = 5; t->rule.errcoeff[0] = 5;
rule->errcoeff[1] = 1; t->rule.errcoeff[1] = 1;
rule->errcoeff[2] = 5; t->rule.errcoeff[2] = 5;
rule->n = n; t->rule.n = n;
for( s = first; s <= last; ++s ) for( s = first; s <= last; ++s )
for( r = 1; r < nrules - 1; ++r ) { for( r = 1; r < nrules - 1; ++r ) {
creal scale = (s->weight[r] == 0) ? 100 : creal scale = (s->weight[r] == 0) ? 100 :
-s->weight[r + 1]/s->weight[r]; -s->weight[r + 1]/s->weight[r];
real sum = 0; real sum = 0;
for( t = first; t <= last; ++t ) for( x = first; x <= last; ++x )
sum += t->n*fabs(t->weight[r + 1] + scale*t->weight[r]); sum += x->n*fabs(x->weight[r + 1] + scale*x->weight[r]);
s->scale[r] = scale; s->scale[r] = scale;
s->norm[r] = 1/sum; s->norm[r] = 1/sum;
} }
@ -487,7 +480,7 @@ static void Rule9Alloc(Rule *rule)
/*********************************************************************/ /*********************************************************************/
static void Rule7Alloc(Rule *rule) static void Rule7Alloc(This *t)
{ {
static creal w[] = { static creal w[] = {
.019417866674748388428, -.40385257701150182546, .019417866674748388428, -.40385257701150182546,
@ -510,10 +503,10 @@ static void Rule7Alloc(Rule *rule)
TYPEDEFSET; TYPEDEFSET;
ccount ndim = ndim_; ccount ndim = t->ndim;
ccount twondim = 1 << ndim; ccount twondim = 1 << ndim;
count dim, n, r; count dim, n, r;
Set *first, *last, *s, *t; Set *first, *last, *s, *x;
Alloc(first, nsets); Alloc(first, nsets);
Clear(first, nsets); Clear(first, nsets);
@ -569,20 +562,20 @@ static void Rule7Alloc(Rule *rule)
for( dim = 0; dim < ndim; ++dim ) for( dim = 0; dim < ndim; ++dim )
last->gen[dim] = g[3]; last->gen[dim] = g[3];
rule->first = first; t->rule.first = first;
rule->last = last; t->rule.last = last;
rule->errcoeff[0] = 5; t->rule.errcoeff[0] = 5;
rule->errcoeff[1] = 1; t->rule.errcoeff[1] = 1;
rule->errcoeff[2] = 5; t->rule.errcoeff[2] = 5;
rule->n = n; t->rule.n = n;
for( s = first; s <= last; ++s ) for( s = first; s <= last; ++s )
for( r = 1; r < nrules - 1; ++r ) { for( r = 1; r < nrules - 1; ++r ) {
creal scale = (s->weight[r] == 0) ? 100 : creal scale = (s->weight[r] == 0) ? 100 :
-s->weight[r + 1]/s->weight[r]; -s->weight[r + 1]/s->weight[r];
real sum = 0; real sum = 0;
for( t = first; t <= last; ++t ) for( x = first; x <= last; ++x )
sum += t->n*fabs(t->weight[r + 1] + scale*t->weight[r]); sum += x->n*fabs(x->weight[r + 1] + scale*x->weight[r]);
s->scale[r] = scale; s->scale[r] = scale;
s->norm[r] = 1/sum; s->norm[r] = 1/sum;
} }
@ -590,9 +583,34 @@ static void Rule7Alloc(Rule *rule)
/*********************************************************************/ /*********************************************************************/
static real *ExpandFS(cBounds *b, real *g, real *x) static inline void RuleAlloc(This *t)
{ {
count dim, ndim = ndim_; if( t->key == 13 && t->ndim == 2 ) Rule13Alloc(t);
else if( t->key == 11 && t->ndim == 3 ) Rule11Alloc(t);
else if( t->key == 9 ) Rule9Alloc(t);
else if( t->key == 7 ) Rule7Alloc(t);
else {
if( t->ndim == 2 ) Rule13Alloc(t);
else if( t->ndim == 3 ) Rule11Alloc(t);
else Rule9Alloc(t);
}
Alloc(t->rule.x, t->rule.n*(t->ndim + t->ncomp));
t->rule.f = t->rule.x + t->rule.n*t->ndim;
}
/*********************************************************************/
static inline void RuleFree(cThis *t)
{
free(t->rule.x);
free(t->rule.first);
}
/*********************************************************************/
static real *ExpandFS(cThis *t, cBounds *b, real *g, real *x)
{
count dim, ndim = t->ndim;
next: next:
/* Compute centrally symmetric sum for permutation of G */ /* Compute centrally symmetric sum for permutation of G */
@ -611,7 +629,7 @@ next:
for( dim = 1; dim < ndim; ++dim ) { for( dim = 1; dim < ndim; ++dim ) {
creal gd = g[dim]; creal gd = g[dim];
if( g[dim - 1] > gd ) { if( g[dim - 1] > gd ) {
count i, ix, j = dim, dx = dim - 1; count i, j = dim, ix = dim, dx = dim - 1;
for( i = 0; i < --j; ++i ) { for( i = 0; i < --j; ++i ) {
creal tmp = g[i]; creal tmp = g[i];
g[i] = g[j]; g[i] = g[j];
@ -639,7 +657,7 @@ next:
/*********************************************************************/ /*********************************************************************/
static void Sample(cRule *rule, void *voidregion, cint flags) static void Sample(This *t, void *voidregion)
{ {
TYPEDEFREGION; TYPEDEFREGION;
TYPEDEFSET; TYPEDEFSET;
@ -647,16 +665,16 @@ static void Sample(cRule *rule, void *voidregion, cint flags)
Region *const region = (Region *)voidregion; Region *const region = (Region *)voidregion;
creal vol = ldexp(1., -region->div); creal vol = ldexp(1., -region->div);
real *x = rule->x, *f = rule->f; real *x = t->rule.x, *f = t->rule.f;
Set *first = (Set *)rule->first, *last = (Set *)rule->last, *s; Set *first = (Set *)t->rule.first, *last = (Set *)t->rule.last, *s;
creal *errcoeff = rule->errcoeff; creal *errcoeff = t->rule.errcoeff;
creal ratio = Sq(first[2].gen[0]/first[1].gen[0]); creal ratio = Sq(first[2].gen[0]/first[1].gen[0]);
ccount offset = 2*ndim_*ncomp_; ccount offset = 2*t->ndim*t->ncomp;
count dim, comp, rul, n, maxdim = 0; count dim, comp, rul, n, maxdim = 0;
real maxrange = 0; real maxrange = 0;
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
cBounds *b = &region->bounds[dim]; cBounds *b = &region->bounds[dim];
creal range = b->upper - b->lower; creal range = b->upper - b->lower;
if( range > maxrange ) { if( range > maxrange ) {
@ -666,11 +684,11 @@ static void Sample(cRule *rule, void *voidregion, cint flags)
} }
for( s = first; s <= last; ++s ) for( s = first; s <= last; ++s )
if( s->n ) x = ExpandFS(region->bounds, s->gen, x); if( s->n ) x = ExpandFS(t, region->bounds, s->gen, x);
DoSample(rule->n, rule->x, f); DoSample(t, t->rule.n, t->rule.x, f);
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
Result *r = &region->result[comp]; Result *r = &region->result[comp];
real sum[nrules]; real sum[nrules];
creal *f1 = f; creal *f1 = f;
@ -678,9 +696,9 @@ static void Sample(cRule *rule, void *voidregion, cint flags)
real maxdiff = 0; real maxdiff = 0;
count bisectdim = maxdim; count bisectdim = maxdim;
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
creal *fp = f1 + ncomp_; creal *fp = f1 + t->ncomp;
creal *fm = fp + ncomp_; creal *fm = fp + t->ncomp;
creal fourthdiff = fabs(base + creal fourthdiff = fabs(base +
ratio*(fp[0] + fm[0]) - (fp[offset] + fm[offset])); ratio*(fp[0] + fm[0]) - (fp[offset] + fm[offset]));
f1 = fm; f1 = fm;
@ -696,7 +714,7 @@ static void Sample(cRule *rule, void *voidregion, cint flags)
for( s = first; s <= last; ++s ) for( s = first; s <= last; ++s )
for( n = s->n; n; --n ) { for( n = s->n; n; --n ) {
creal fun = *f1; creal fun = *f1;
f1 += ncomp_; f1 += t->ncomp;
for( rul = 0; rul < nrules; ++rul ) for( rul = 0; rul < nrules; ++rul )
sum[rul] += fun*s->weight[rul]; sum[rul] += fun*s->weight[rul];
} }
@ -724,7 +742,7 @@ static void Sample(cRule *rule, void *voidregion, cint flags)
if( VERBOSE > 2 ) { if( VERBOSE > 2 ) {
char s[64*NDIM + 128*NCOMP], *p = s; char s[64*NDIM + 128*NCOMP], *p = s;
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
cBounds *b = &region->bounds[dim]; cBounds *b = &region->bounds[dim];
p += sprintf(p, p += sprintf(p,
(dim == 0) ? "\nRegion (" REALF ") - (" REALF ")" : (dim == 0) ? "\nRegion (" REALF ") - (" REALF ")" :
@ -732,7 +750,7 @@ static void Sample(cRule *rule, void *voidregion, cint flags)
b->lower, b->upper); b->lower, b->upper);
} }
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
cResult *r = &region->result[comp]; cResult *r = &region->result[comp];
p += sprintf(p, "\n[" COUNT "] " p += sprintf(p, "\n[" COUNT "] "
REAL " +- " REAL, comp + 1, r->avg, r->err); REAL " +- " REAL, comp + 1, r->avg, r->err);

View File

@ -2,11 +2,11 @@
common.c common.c
includes most of the modules includes most of the modules
this file is part of Cuhre this file is part of Cuhre
last modified 14 Feb 05 th last modified 7 Jun 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -25,25 +25,21 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
#include "ChiSquare.c" #include "ChiSquare.c"
#include "Rule.c" #include "Rule.c"
static inline bool BadDimension(cThis *t)
{
if( t->ndim > NDIM ) return true;
return t->ndim < 2;
}
static inline bool BadComponent(cThis *t)
{
if( t->ncomp > NCOMP ) return true;
return t->ncomp < 1;
}
#include "Integrate.c" #include "Integrate.c"
static inline bool BadDimension(ccount ndim)
{
#if NDIM > 0
if( ndim > NDIM ) return true;
#endif
return ndim < 2;
}
static inline bool BadComponent(cint ncomp)
{
#if NCOMP > 0
if( ncomp > NCOMP ) return true;
#endif
return ncomp < 1;
}

View File

@ -2,11 +2,10 @@
decl.h decl.h
Type declarations Type declarations
this file is part of Cuhre this file is part of Cuhre
last modified 8 Apr 09 th last modified 7 Jun 10 th */
*/
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -27,7 +26,6 @@
#include "stddecl.h" #include "stddecl.h"
typedef struct { typedef struct {
real avg, err; real avg, err;
count bisectdim; count bisectdim;
@ -35,7 +33,6 @@ typedef struct {
typedef const Result cResult; typedef const Result cResult;
typedef struct { typedef struct {
real avg, err, lastavg, lasterr; real avg, err, lastavg, lasterr;
real weightsum, avgsum; real weightsum, avgsum;
@ -44,14 +41,12 @@ typedef struct {
typedef const Totals cTotals; typedef const Totals cTotals;
typedef struct { typedef struct {
real lower, upper; real lower, upper;
} Bounds; } Bounds;
typedef const Bounds cBounds; typedef const Bounds cBounds;
typedef struct { typedef struct {
real *x, *f; real *x, *f;
void *first, *last; void *first, *last;
@ -61,6 +56,24 @@ typedef struct {
typedef const Rule cRule; typedef const Rule cRule;
typedef int (*Integrand)(ccount *, creal *, ccount *, real *, void *);
typedef struct _this {
count ndim, ncomp;
#ifndef MLVERSION
Integrand integrand;
void *userdata;
#endif
real epsrel, epsabs;
int flags;
number mineval, maxeval;
count key, nregions;
number neval;
Rule rule;
jmp_buf abort;
} This;
typedef const This cThis;
#define TYPEDEFREGION \ #define TYPEDEFREGION \
typedef struct region { \ typedef struct region { \
@ -69,6 +82,3 @@ typedef const Rule cRule;
Bounds bounds[NDIM]; \ Bounds bounds[NDIM]; \
} Region } Region
typedef void (*Integrand)(ccount *, creal *, ccount *, real *);

View File

@ -4,11 +4,11 @@
originally by J.H. Friedman and M.H. Wright originally by J.H. Friedman and M.H. Wright
(CERNLIB subroutine D151) (CERNLIB subroutine D151)
this version by Thomas Hahn this version by Thomas Hahn
last modified 2 Mar 06 th last modified 16 Jun 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -27,119 +27,153 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
#include "util.c" #include "decl.h"
#define Print(s) puts(s); fflush(stdout) #define Print(s) puts(s); fflush(stdout)
static Integrand integrand_;
static PeakFinder peakfinder_;
/*********************************************************************/ /*********************************************************************/
static inline void DoSample(number n, ccount ldx, creal *x, real *f) static inline void DoSample(This *t, number n, ccount ldx, creal *x, real *f)
{ {
neval_ += n; t->neval += n;
while( n-- ) { while( n-- ) {
integrand_(&ndim_, x, &ncomp_, f, &phase_); if( t->integrand(&t->ndim, x, &t->ncomp, f, t->userdata, &t->phase) == ABORT )
longjmp(t->abort, 1);
x += ldx; x += ldx;
f += ncomp_; f += t->ncomp;
} }
} }
/*********************************************************************/ /*********************************************************************/
static inline count SampleExtra(cBounds *b) static inline count SampleExtra(This *t, cBounds *b)
{ {
number n = nextra_; number n = t->nextra;
peakfinder_(&ndim_, b, &n, xextra_); t->peakfinder(&t->ndim, b, &n, t->xextra);
DoSample(n, ldxgiven_, xextra_, fextra_); DoSample(t, n, t->ldxgiven, t->xextra, t->fextra);
return n; return n;
} }
/*********************************************************************/ /*********************************************************************/
static inline void AllocGiven(This *t, creal *xgiven)
{
if( t->ngiven | t->nextra ) {
cnumber nxgiven = t->ngiven*(t->ldxgiven = IMax(t->ldxgiven, t->ndim));
cnumber nxextra = t->nextra*t->ldxgiven;
cnumber nfgiven = t->ngiven*t->ncomp;
cnumber nfextra = t->nextra*t->ncomp;
Alloc(t->xgiven, nxgiven + nxextra + nfgiven + nfextra);
t->xextra = t->xgiven + nxgiven;
t->fgiven = t->xextra + nxextra;
t->fextra = t->fgiven + nfgiven;
if( nxgiven ) {
t->phase = 0;
Copy(t->xgiven, xgiven, nxgiven);
DoSample(t, t->ngiven, t->ldxgiven, t->xgiven, t->fgiven);
}
}
}
/*********************************************************************/
#include "common.c" #include "common.c"
Extern void EXPORT(Divonne)(ccount ndim, ccount ncomp, Extern void EXPORT(Divonne)(ccount ndim, ccount ncomp,
Integrand integrand, Integrand integrand, void *userdata,
creal epsrel, creal epsabs, creal epsrel, creal epsabs,
cint flags, cnumber mineval, cnumber maxeval, cint flags, cint seed,
cnumber mineval, cnumber maxeval,
cint key1, cint key2, cint key3, ccount maxpass, cint key1, cint key2, cint key3, ccount maxpass,
creal border, creal maxchisq, creal mindeviation, creal border, creal maxchisq, creal mindeviation,
cnumber ngiven, ccount ldxgiven, real *xgiven, cnumber ngiven, ccount ldxgiven, creal *xgiven,
cnumber nextra, PeakFinder peakfinder, cnumber nextra, PeakFinder peakfinder,
int *pnregions, number *pneval, int *pfail, int *pnregions, number *pneval, int *pfail,
real *integral, real *error, real *prob) real *integral, real *error, real *prob)
{ {
ndim_ = ndim; This t;
ncomp_ = ncomp; t.ndim = ndim;
t.ncomp = ncomp;
t.integrand = integrand;
t.userdata = userdata;
t.epsrel = epsrel;
t.epsabs = epsabs;
t.flags = flags;
t.seed = seed;
t.mineval = mineval;
t.maxeval = maxeval;
t.key1 = key1;
t.key2 = key2;
t.key3 = key3;
t.maxpass = maxpass;
t.border.upper = 1 - (t.border.lower = border);
t.maxchisq = maxchisq;
t.mindeviation = mindeviation;
t.ngiven = ngiven;
t.xgiven = NULL;
t.ldxgiven = ldxgiven;
t.nextra = nextra;
t.peakfinder = peakfinder;
t.nregions = 0;
t.neval = 0;
if( BadComponent(ncomp) || AllocGiven(&t, xgiven);
BadDimension(ndim, flags, key1) ||
BadDimension(ndim, flags, key2) ||
((key3 & -2) && BadDimension(ndim, flags, key3)) ) *pfail = -1;
else {
neval_ = neval_opt_ = neval_cut_ = 0;
integrand_ = integrand;
peakfinder_ = peakfinder;
border_.lower = border;
border_.upper = 1 - border_.lower;
ngiven_ = ngiven;
xgiven_ = NULL;
ldxgiven_ = IMax(ldxgiven, ndim_);
nextra_ = nextra;
if( ngiven + nextra ) { *pfail = Integrate(&t, integral, error, prob);
cnumber nxgiven = ngiven*ldxgiven; *pnregions = t.nregions;
cnumber nxextra = nextra*ldxgiven; *pneval = t.neval;
cnumber nfgiven = ngiven*ncomp;
cnumber nfextra = nextra*ncomp;
Alloc(xgiven_, nxgiven + nxextra + nfgiven + nfextra); free(t.xgiven);
xextra_ = xgiven_ + nxgiven;
fgiven_ = xextra_ + nxextra;
fextra_ = fgiven_ + nfgiven;
if( nxgiven ) {
phase_ = 0;
Copy(xgiven_, xgiven, nxgiven);
DoSample(ngiven_, ldxgiven_, xgiven_, fgiven_);
}
}
*pfail = Integrate(epsrel, Max(epsabs, NOTZERO),
flags, mineval, maxeval, key1, key2, key3, maxpass,
maxchisq, mindeviation,
integral, error, prob);
*pnregions = nregions_;
*pneval = neval_;
if( xgiven_ ) free(xgiven_);
}
} }
/*********************************************************************/ /*********************************************************************/
Extern void EXPORT(divonne)(ccount *pndim, ccount *pncomp, Extern void EXPORT(divonne)(ccount *pndim, ccount *pncomp,
Integrand integrand, Integrand integrand, void *userdata,
creal *pepsrel, creal *pepsabs, creal *pepsrel, creal *pepsabs,
cint *pflags, cnumber *pmineval, cnumber *pmaxeval, cint *pflags, cint *pseed,
cnumber *pmineval, cnumber *pmaxeval,
cint *pkey1, cint *pkey2, cint *pkey3, ccount *pmaxpass, cint *pkey1, cint *pkey2, cint *pkey3, ccount *pmaxpass,
creal *pborder, creal *pmaxchisq, creal *pmindeviation, creal *pborder, creal *pmaxchisq, creal *pmindeviation,
cnumber *pngiven, ccount *pldxgiven, real *xgiven, cnumber *pngiven, ccount *pldxgiven, creal *xgiven,
cnumber *pnextra, PeakFinder peakfinder, cnumber *pnextra, PeakFinder peakfinder,
int *pnregions, number *pneval, int *pfail, int *pnregions, number *pneval, int *pfail,
real *integral, real *error, real *prob) real *integral, real *error, real *prob)
{ {
EXPORT(Divonne)(*pndim, *pncomp, This t;
integrand, t.ndim = *pndim;
*pepsrel, *pepsabs, t.ncomp = *pncomp;
*pflags, *pmineval, *pmaxeval, t.integrand = integrand;
*pkey1, *pkey2, *pkey3, *pmaxpass, t.userdata = userdata;
*pborder, *pmaxchisq, *pmindeviation, t.epsrel = *pepsrel;
*pngiven, *pldxgiven, xgiven, t.epsabs = *pepsabs;
*pnextra, peakfinder, t.flags = *pflags;
pnregions, pneval, pfail, t.seed = *pseed;
integral, error, prob); t.mineval = *pmineval;
t.maxeval = *pmaxeval;
t.key1 = *pkey1;
t.key2 = *pkey2;
t.key3 = *pkey3;
t.maxpass = *pmaxpass;
t.border.upper = 1 - (t.border.lower = *pborder);
t.maxchisq = *pmaxchisq;
t.mindeviation = *pmindeviation;
t.ngiven = *pngiven;
t.xgiven = NULL;
t.ldxgiven = *pldxgiven;
t.nextra = *pnextra;
t.peakfinder = peakfinder;
t.nregions = 0;
t.neval = 0;
AllocGiven(&t, xgiven);
*pfail = Integrate(&t, integral, error, prob);
*pnregions = t.nregions;
*pneval = t.neval;
free(t.xgiven);
} }

View File

@ -2,11 +2,11 @@
Explore.c Explore.c
sample region, determine min and max, split if necessary sample region, determine min and max, split if necessary
this file is part of Divonne this file is part of Divonne
last modified 25 May 09 th last modified 8 Jun 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -25,14 +25,16 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
typedef struct { typedef struct {
real fmin, fmax; real fmin, fmax;
real *xmin, *xmax; creal *xmin, *xmax;
} Extrema; } Extrema;
/*********************************************************************/ /*********************************************************************/
static bool Explore(count iregion, cSamples *samples, cint depth, cint flags) static bool Explore(This *t, count iregion, cSamples *samples,
cint depth, cint flags)
{ {
#define SPLICE (flags & 1) #define SPLICE (flags & 1)
#define HAVESAMPLES (flags & 2) #define HAVESAMPLES (flags & 2)
@ -42,7 +44,8 @@ static bool Explore(count iregion, cSamples *samples, cint depth, cint flags)
count n, dim, comp, maxcomp; count n, dim, comp, maxcomp;
Extrema extrema[NCOMP]; Extrema extrema[NCOMP];
Result *r; Result *r;
real *x, *f; creal *x;
real *f;
real halfvol, maxerr; real halfvol, maxerr;
Region *region; Region *region;
Bounds *bounds; Bounds *bounds;
@ -52,18 +55,18 @@ static bool Explore(count iregion, cSamples *samples, cint depth, cint flags)
sizeof(*region); sizeof(*region);
if( SPLICE ) { if( SPLICE ) {
if( nregions_ == size_ ) { if( t->nregions == t->size ) {
size_ += CHUNKSIZE; t->size += CHUNKSIZE;
ReAlloc(voidregion_, size_*sizeof(Region)); ReAlloc(t->voidregion, t->size*sizeof(Region));
} }
VecCopy(region_[nregions_].bounds, region_[iregion].bounds); VecCopy(RegionPtr(t->nregions)->bounds, RegionPtr(iregion)->bounds);
iregion = nregions_++; iregion = t->nregions++;
} }
region = &region_[iregion]; region = RegionPtr(iregion);
bounds = region->bounds; bounds = region->bounds;
result = region->result; result = region->result;
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
Extrema *e = &extrema[comp]; Extrema *e = &extrema[comp];
e->fmin = INFTY; e->fmin = INFTY;
e->fmax = -INFTY; e->fmax = -INFTY;
@ -72,78 +75,76 @@ static bool Explore(count iregion, cSamples *samples, cint depth, cint flags)
if( !HAVESAMPLES ) { if( !HAVESAMPLES ) {
real vol = 1; real vol = 1;
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
cBounds *b = &bounds[dim]; cBounds *b = &bounds[dim];
vol *= b->upper - b->lower; vol *= b->upper - b->lower;
} }
region->vol = vol; region->vol = vol;
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
Result *r = &result[comp]; Result *r = &result[comp];
r->fmin = INFTY; r->fmin = INFTY;
r->fmax = -INFTY; r->fmax = -INFTY;
} }
x = xgiven_; x = t->xgiven;
f = fgiven_; f = t->fgiven;
n = ngiven_; n = t->ngiven;
if( nextra_ ) n += SampleExtra(bounds); if( t->nextra ) n += SampleExtra(t, bounds);
for( ; n; --n ) { for( ; n; --n ) {
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
cBounds *b = &bounds[dim]; cBounds *b = &bounds[dim];
if( x[dim] < b->lower || x[dim] > b->upper ) goto skip; if( x[dim] < b->lower || x[dim] > b->upper ) goto skip;
} }
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
Extrema *e = &extrema[comp]; Extrema *e = &extrema[comp];
creal y = f[comp]; creal y = f[comp];
if( y < e->fmin ) e->fmin = y, e->xmin = x; if( y < e->fmin ) e->fmin = y, e->xmin = x;
if( y > e->fmax ) e->fmax = y, e->xmax = x; if( y > e->fmax ) e->fmax = y, e->xmax = x;
} }
skip: skip:
x += ldxgiven_; x += t->ldxgiven;
f += ncomp_; f += t->ncomp;
} }
samples->sampler(samples, bounds, vol); samples->sampler(t, samples, bounds, vol);
} }
x = samples->x; x = samples->x;
f = samples->f; f = samples->f;
for( n = samples->n; n; --n ) { for( n = samples->n; n; --n ) {
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
Extrema *e = &extrema[comp]; Extrema *e = &extrema[comp];
creal y = *f++; creal y = *f++;
if( y < e->fmin ) e->fmin = y, e->xmin = x; if( y < e->fmin ) e->fmin = y, e->xmin = x;
if( y > e->fmax ) e->fmax = y, e->xmax = x; if( y > e->fmax ) e->fmax = y, e->xmax = x;
} }
x += ndim_; x += t->ndim;
} }
neval_opt_ -= neval_; t->neval_opt -= t->neval;
halfvol = .5*region->vol; halfvol = .5*region->vol;
maxerr = -INFTY; maxerr = -INFTY;
maxcomp = -1; maxcomp = -1;
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
Extrema *e = &extrema[comp]; Extrema *e = &extrema[comp];
Result *r = &result[comp]; Result *r = &result[comp];
real xtmp[NDIM], ftmp, err; real xtmp[NDIM], ftmp, err;
if( e->xmin ) { /* not all NaNs */ if( e->xmin ) { /* not all NaNs */
selectedcomp_ = comp; t->selectedcomp = comp;
sign_ = 1;
VecCopy(xtmp, e->xmin); VecCopy(xtmp, e->xmin);
ftmp = FindMinimum(bounds, xtmp, e->fmin); ftmp = FindMinimum(t, bounds, xtmp, e->fmin);
if( ftmp < r->fmin ) { if( ftmp < r->fmin ) {
r->fmin = ftmp; r->fmin = ftmp;
VecCopy(r->xmin, xtmp); VecCopy(r->xmin, xtmp);
} }
sign_ = -1; t->selectedcomp = Tag(comp);
VecCopy(xtmp, e->xmax); VecCopy(xtmp, e->xmax);
ftmp = -FindMinimum(bounds, xtmp, -e->fmax); ftmp = -FindMinimum(t, bounds, xtmp, -e->fmax);
if( ftmp > r->fmax ) { if( ftmp > r->fmax ) {
r->fmax = ftmp; r->fmax = ftmp;
VecCopy(r->xmax, xtmp); VecCopy(r->xmax, xtmp);
@ -161,7 +162,7 @@ skip:
} }
} }
neval_opt_ += neval_; t->neval_opt += t->neval;
if( maxcomp == -1 ) { /* all NaNs */ if( maxcomp == -1 ) { /* all NaNs */
region->depth = 0; region->depth = 0;
@ -185,14 +186,14 @@ skip:
if( !HAVESAMPLES ) { if( !HAVESAMPLES ) {
if( samples->weight*r->spread < r->err || if( samples->weight*r->spread < r->err ||
r->spread < totals_[maxcomp].secondspread ) region->depth = 0; r->spread < t->totals[maxcomp].secondspread ) region->depth = 0;
if( region->depth == 0 ) if( region->depth == 0 )
for( comp = 0; comp < ncomp_; ++comp ) for( comp = 0; comp < t->ncomp; ++comp )
totals_[comp].secondspread = t->totals[comp].secondspread =
Max(totals_[comp].secondspread, result[comp].spread); Max(t->totals[comp].secondspread, result[comp].spread);
} }
if( region->depth ) Split(iregion, region->depth); if( region->depth ) Split(t, iregion, region->depth);
return true; return true;
} }

View File

@ -2,11 +2,11 @@
FindMinimum.c FindMinimum.c
find minimum (maximum) of hyperrectangular region find minimum (maximum) of hyperrectangular region
this file is part of Divonne this file is part of Divonne
last modified 7 Mar 05 th last modified 8 Jun 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -25,6 +25,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
#define EPS 0x1p-52 #define EPS 0x1p-52
#define RTEPS 0x1p-26 #define RTEPS 0x1p-26
#define QEPS 0x1p-13 #define QEPS 0x1p-13
@ -43,23 +44,12 @@
#define FTOL 5e-2 #define FTOL 5e-2
#define GTOL 1e-2 #define GTOL 1e-2
#define Hessian(i, j) hessian[(i)*ndim_ + j] #define Hessian(i, j) hessian[(i)*t->ndim + j]
#define Tag(x) ((x) | 0x8000)
#define Untag(x) ((x) & 0x7fff)
#define TaggedQ(x) ((x) & 0x8000)
typedef struct { real dx, f; } Point; typedef struct { real dx, f; } Point;
/*********************************************************************/ /*********************************************************************/
static inline real SignSample(real *x)
{
return sign_*Sample(x);
}
/*********************************************************************/
static inline real Dot(ccount n, creal *a, creal *b) static inline real Dot(ccount n, creal *a, creal *b)
{ {
real sum = 0; real sum = 0;
@ -77,7 +67,7 @@ static inline real Length(ccount n, creal *vec)
/*********************************************************************/ /*********************************************************************/
static inline void LinearSolve(ccount n, creal *hessian, static inline void LinearSolve(cThis *t, ccount n, creal *hessian,
creal *grad, real *p) creal *grad, real *p)
{ {
int i, j; int i, j;
@ -101,7 +91,7 @@ static inline void LinearSolve(ccount n, creal *hessian,
/*********************************************************************/ /*********************************************************************/
static void RenormalizeCholesky(ccount n, real *hessian, static void RenormalizeCholesky(cThis *t, ccount n, real *hessian,
real *z, real alpha) real *z, real alpha)
{ {
count i, j; count i, j;
@ -137,7 +127,7 @@ static void RenormalizeCholesky(ccount n, real *hessian,
/*********************************************************************/ /*********************************************************************/
static void UpdateCholesky(ccount n, real *hessian, static void UpdateCholesky(cThis *t, ccount n, real *hessian,
real *z, real *p) real *z, real *p)
{ {
int i, j; int i, j;
@ -169,7 +159,7 @@ static void UpdateCholesky(ccount n, real *hessian,
/*********************************************************************/ /*********************************************************************/
static inline void BFGS(ccount n, real *hessian, static inline void BFGS(cThis *t, ccount n, real *hessian,
creal *gnew, creal *g, real *p, creal dx) creal *gnew, creal *g, real *p, creal dx)
{ {
real y[NDIM], c; real y[NDIM], c;
@ -179,14 +169,14 @@ static inline void BFGS(ccount n, real *hessian,
y[i] = gnew[i] - g[i]; y[i] = gnew[i] - g[i];
c = dx*Dot(n, y, p); c = dx*Dot(n, y, p);
if( c < 1e-10 ) return; if( c < 1e-10 ) return;
RenormalizeCholesky(n, hessian, y, 1/c); RenormalizeCholesky(t, n, hessian, y, 1/c);
c = Dot(n, g, p); c = Dot(n, g, p);
if( c >= 0 ) return; if( c >= 0 ) return;
c = 1/sqrt(-c); c = 1/sqrt(-c);
for( i = 0; i < n; ++i ) for( i = 0; i < n; ++i )
y[i] = c*g[i]; y[i] = c*g[i];
UpdateCholesky(n, hessian, y, p); UpdateCholesky(t, n, hessian, y, p);
for( i = 0; i < n - 1; ++i ) for( i = 0; i < n - 1; ++i )
for( j = i + 1; j < n; ++j ) for( j = i + 1; j < n; ++j )
@ -195,7 +185,7 @@ static inline void BFGS(ccount n, real *hessian,
/*********************************************************************/ /*********************************************************************/
static void Gradient(ccount nfree, ccount *ifree, static void Gradient(This *t, ccount nfree, ccount *ifree,
cBounds *b, real *x, creal y, real *grad) cBounds *b, real *x, creal y, real *grad)
{ {
count i; count i;
@ -205,14 +195,14 @@ static void Gradient(ccount nfree, ccount *ifree,
creal xd = x[dim]; creal xd = x[dim];
creal delta = (b[dim].upper - xd < DELTA) ? -DELTA : DELTA; creal delta = (b[dim].upper - xd < DELTA) ? -DELTA : DELTA;
x[dim] += delta; x[dim] += delta;
grad[i] = (SignSample(x) - y)/delta; grad[i] = (Sample(t, x) - y)/delta;
x[dim] = xd; x[dim] = xd;
} }
} }
/*********************************************************************/ /*********************************************************************/
static Point LineSearch(ccount nfree, ccount *ifree, static Point LineSearch(This *t, ccount nfree, ccount *ifree,
creal *p, creal *xini, real fini, real *x, creal *p, creal *xini, real fini, real *x,
real step, creal range, creal grad, real step, creal range, creal grad,
creal ftol, creal xtol, creal gtol) creal ftol, creal xtol, creal gtol)
@ -260,7 +250,7 @@ static Point LineSearch(ccount nfree, ccount *ifree,
ccount dim = ifree[i]; ccount dim = ifree[i];
x[dim] = xini[dim] + dist*p[i]; x[dim] = xini[dim] + dist*p[i];
} }
cur.f = SignSample(x); cur.f = Sample(t, x);
if( cur.f <= min.f ) { if( cur.f <= min.f ) {
v = w; v = w;
@ -347,7 +337,7 @@ static Point LineSearch(ccount nfree, ccount *ifree,
ccount dim = ifree[i]; ccount dim = ifree[i];
x[dim] = xini[dim] + cur.dx*p[i]; x[dim] = xini[dim] + cur.dx*p[i];
} }
if( !first ) cur.f = SignSample(x); if( !first ) cur.f = Sample(t, x);
if( cur.dx + b.dx <= xtol ) { if( cur.dx + b.dx <= xtol ) {
cur.dx = 0; cur.dx = 0;
@ -367,8 +357,8 @@ static Point LineSearch(ccount nfree, ccount *ifree,
/*********************************************************************/ /*********************************************************************/
static real LocalSearch(ccount nfree, ccount *ifree, cBounds *b, static real LocalSearch(This *t, ccount nfree, ccount *ifree,
creal *x, creal fx, real *z) cBounds *b, creal *x, creal fx, real *z)
{ {
real delta, smax, sopp, spmax, snmax; real delta, smax, sopp, spmax, snmax;
real y[NDIM], fy, fz, ftest; real y[NDIM], fy, fz, ftest;
@ -408,7 +398,7 @@ static real LocalSearch(ccount nfree, ccount *ifree, cBounds *b,
ccount dim = ifree[i]; ccount dim = ifree[i];
y[dim] = x[dim] + delta*p[i]; y[dim] = x[dim] + delta*p[i];
} }
fy = SignSample(y); fy = Sample(t, y);
if( fabs(fy - fx) > ftest ) break; if( fabs(fy - fx) > ftest ) break;
} while( delta != smax ); } while( delta != smax );
@ -461,7 +451,7 @@ static real LocalSearch(ccount nfree, ccount *ifree, cBounds *b,
ccount dim = ifree[i]; ccount dim = ifree[i];
z[dim] = y[dim] + delta*p[i]; z[dim] = y[dim] + delta*p[i];
} }
fz = SignSample(z); fz = Sample(t, z);
if( fabs(fz - fy) > ftest ) break; if( fabs(fz - fy) > ftest ) break;
} while( delta != smax ); } while( delta != smax );
@ -485,7 +475,7 @@ static real LocalSearch(ccount nfree, ccount *ifree, cBounds *b,
} }
pleneps = Length(nfree, p) + RTEPS; pleneps = Length(nfree, p) + RTEPS;
low = LineSearch(nfree, ifree, p, y, fy, z, step, range, grad, low = LineSearch(t, nfree, ifree, p, y, fy, z, step, range, grad,
RTEPS/pleneps, 0., RTEPS); RTEPS/pleneps, 0., RTEPS);
fz = low.f; fz = low.f;
} }
@ -522,7 +512,7 @@ static real LocalSearch(ccount nfree, ccount *ifree, cBounds *b,
ccount dim = ifree[i]; ccount dim = ifree[i];
z[dim] = x[dim] - delta*p[i]; z[dim] = x[dim] - delta*p[i];
} }
fz = SignSample(z); fz = Sample(t, z);
if( fz < fx ) { if( fz < fx ) {
grad = (fz - fx)/delta; grad = (fz - fx)/delta;
range = snmax; range = snmax;
@ -533,7 +523,7 @@ static real LocalSearch(ccount nfree, ccount *ifree, cBounds *b,
else if( delta < 1 ) grad = (fx - fz)/delta; else if( delta < 1 ) grad = (fx - fz)/delta;
} }
low = LineSearch(nfree, ifree, p, x, fx, z, step, range, grad, low = LineSearch(t, nfree, ifree, p, x, fx, z, step, range, grad,
RTEPS/pleneps, 0., RTEPS); RTEPS/pleneps, 0., RTEPS);
fz = low.f; fz = low.f;
} }
@ -543,18 +533,18 @@ static real LocalSearch(ccount nfree, ccount *ifree, cBounds *b,
/*********************************************************************/ /*********************************************************************/
static real FindMinimum(cBounds *b, real *xmin, real fmin) static real FindMinimum(This *t, cBounds *b, real *xmin, real fmin)
{ {
real hessian[NDIM*NDIM]; real hessian[NDIM*NDIM];
real gfree[NDIM], p[NDIM]; real gfree[NDIM], p[NDIM];
real tmp[NDIM], ftmp, fini = fmin; real tmp[NDIM], ftmp, fini = fmin;
ccount maxeval = neval_ + 50*ndim_; ccount maxeval = t->neval + 50*t->ndim;
count nfree, nfix; count nfree, nfix;
count ifree[NDIM], ifix[NDIM]; count ifree[NDIM], ifix[NDIM];
count dim, local; count dim, local;
Zap(hessian); Zap(hessian);
for( dim = 0; dim < ndim_; ++dim ) for( dim = 0; dim < t->ndim; ++dim )
Hessian(dim, dim) = 1; Hessian(dim, dim) = 1;
/* Step 1: - classify the variables as "fixed" (sufficiently close /* Step 1: - classify the variables as "fixed" (sufficiently close
@ -565,7 +555,7 @@ static real FindMinimum(cBounds *b, real *xmin, real fmin)
for( local = 0; local < 2; ++local ) { for( local = 0; local < 2; ++local ) {
bool resample = false; bool resample = false;
nfree = nfix = 0; nfree = nfix = 0;
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
if( xmin[dim] < b[dim].lower + (1 + fabs(b[dim].lower))*QEPS ) { if( xmin[dim] < b[dim].lower + (1 + fabs(b[dim].lower))*QEPS ) {
xmin[dim] = b[dim].lower; xmin[dim] = b[dim].lower;
ifix[nfix++] = dim; ifix[nfix++] = dim;
@ -579,21 +569,21 @@ static real FindMinimum(cBounds *b, real *xmin, real fmin)
else ifree[nfree++] = dim; else ifree[nfree++] = dim;
} }
if( resample ) fini = fmin = SignSample(xmin); if( resample ) fini = fmin = Sample(t, xmin);
if( nfree == 0 ) goto releasebounds; if( nfree == 0 ) goto releasebounds;
Gradient(nfree, ifree, b, xmin, fmin, gfree); Gradient(t, nfree, ifree, b, xmin, fmin, gfree);
if( local || Length(nfree, gfree) > GTOL ) break; if( local || Length(nfree, gfree) > GTOL ) break;
ftmp = LocalSearch(nfree, ifree, b, xmin, fmin, tmp); ftmp = LocalSearch(t, nfree, ifree, b, xmin, fmin, tmp);
if( ftmp > fmin - (1 + fabs(fmin))*RTEPS ) if( ftmp > fmin - (1 + fabs(fmin))*RTEPS )
goto releasebounds; goto releasebounds;
fmin = ftmp; fmin = ftmp;
VecCopy(xmin, tmp); VecCopy(xmin, tmp);
} }
while( neval_ <= maxeval ) { while( t->neval <= maxeval ) {
/* Step 2a: perform a quasi-Newton iteration on the free /* Step 2a: perform a quasi-Newton iteration on the free
variables only. */ variables only. */
@ -601,10 +591,10 @@ static real FindMinimum(cBounds *b, real *xmin, real fmin)
if( nfree > 0 ) { if( nfree > 0 ) {
real plen, pleneps; real plen, pleneps;
real minstep; real minstep;
count i, mini, minfix; count i, mini = 0, minfix = 0;
Point low; Point low;
LinearSolve(nfree, hessian, gfree, p); LinearSolve(t, nfree, hessian, gfree, p);
plen = Length(nfree, p); plen = Length(nfree, p);
pleneps = plen + RTEPS; pleneps = plen + RTEPS;
@ -645,7 +635,7 @@ fixbound:
Copy(&Hessian(i, 0), &Hessian(i + 1, 0), i); Copy(&Hessian(i, 0), &Hessian(i + 1, 0), i);
Hessian(i, i) = Hessian(i + 1, i + 1); Hessian(i, i) = Hessian(i + 1, i + 1);
} }
RenormalizeCholesky(nfree, hessian, tmp, diag); RenormalizeCholesky(t, nfree, hessian, tmp, diag);
Copy(&ifree[mini], &ifree[mini + 1], nfree - mini); Copy(&ifree[mini], &ifree[mini + 1], nfree - mini);
Copy(&gfree[mini], &gfree[mini + 1], nfree - mini); Copy(&gfree[mini], &gfree[mini + 1], nfree - mini);
@ -653,7 +643,7 @@ fixbound:
continue; continue;
} }
low = LineSearch(nfree, ifree, p, xmin, fmin, tmp, low = LineSearch(t, nfree, ifree, p, xmin, fmin, tmp,
Min(minstep, 1.), Min(minstep, 100.), Dot(nfree, gfree, p), Min(minstep, 1.), Min(minstep, 100.), Dot(nfree, gfree, p),
RTEPS/pleneps, DELTA/pleneps, .2); RTEPS/pleneps, DELTA/pleneps, .2);
@ -663,8 +653,8 @@ fixbound:
fmin = low.f; fmin = low.f;
VecCopy(xmin, tmp); VecCopy(xmin, tmp);
Gradient(nfree, ifree, b, xmin, fmin, tmp); Gradient(t, nfree, ifree, b, xmin, fmin, tmp);
BFGS(nfree, hessian, tmp, gfree, p, low.dx); BFGS(t, nfree, hessian, tmp, gfree, p, low.dx);
VecCopy(gfree, tmp); VecCopy(gfree, tmp);
if( fabs(low.dx - minstep) < QEPS*minstep ) goto fixbound; if( fabs(low.dx - minstep) < QEPS*minstep ) goto fixbound;
@ -672,7 +662,7 @@ fixbound:
fdiff = fini - fmin; fdiff = fini - fmin;
fini = fmin; fini = fmin;
if( fdiff > (1 + fabs(fmin))*FTOL || if( fdiff > (1 + fabs(fmin))*FTOL ||
low.dx*plen > (1 + Length(ndim_, xmin))*FTOL ) continue; low.dx*plen > (1 + Length(t->ndim, xmin))*FTOL ) continue;
} }
} }
@ -685,10 +675,10 @@ releasebounds:
count i, mini = 0; count i, mini = 0;
bool repeat = false; bool repeat = false;
Gradient(nfix, ifix, b, xmin, fmin, tmp); Gradient(t, nfix, ifix, b, xmin, fmin, tmp);
for( i = 0; i < nfix; ++i ) { for( i = 0; i < nfix; ++i ) {
creal grad = TaggedQ(ifix[i]) ? -tmp[i] : tmp[i]; creal grad = Sign(ifix[i])*tmp[i];
if( grad < -RTEPS ) { if( grad < -RTEPS ) {
repeat = true; repeat = true;
if( grad < mingrad ) { if( grad < mingrad ) {

View File

@ -4,11 +4,11 @@
has approximately equal spread = 1/2 vol (max - min), has approximately equal spread = 1/2 vol (max - min),
then do a main integration over all regions then do a main integration over all regions
this file is part of Divonne this file is part of Divonne
last modified 8 May 09 th last modified 8 Jun 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -27,17 +27,14 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
#define INIDEPTH 3 #define INIDEPTH 3
#define DEPTH 5 #define DEPTH 5
#define POSTDEPTH 15 #define POSTDEPTH 15
/*********************************************************************/ /*********************************************************************/
static int Integrate(creal epsrel, creal epsabs, static int Integrate(This *t, real *integral, real *error, real *prob)
cint flags, cnumber mineval, cnumber maxeval,
int key1, int key2, int key3, ccount maxpass,
creal maxchisq, creal mindeviation,
real *integral, real *error, real *prob)
{ {
TYPEDEFREGION; TYPEDEFREGION;
@ -45,77 +42,85 @@ static int Integrate(creal epsrel, creal epsabs,
real nneed, weight; real nneed, weight;
count dim, comp, iter, pass = 0, err, iregion; count dim, comp, iter, pass = 0, err, iregion;
number nwant, nmin = INT_MAX; number nwant, nmin = INT_MAX;
int fail = -1; int fail = -99;
if( VERBOSE > 1 ) { if( VERBOSE > 1 ) {
char s[512]; char s[512];
sprintf(s, "Divonne input parameters:\n" sprintf(s, "Divonne input parameters:\n"
" ndim " COUNT "\n ncomp " COUNT "\n" " ndim " COUNT "\n ncomp " COUNT "\n"
" epsrel " REAL "\n epsabs " REAL "\n" " epsrel " REAL "\n epsabs " REAL "\n"
" flags %d\n mineval " NUMBER "\n maxeval " NUMBER "\n" " flags %d\n seed %d\n"
" mineval " NUMBER "\n maxeval " NUMBER "\n"
" key1 %d\n key2 %d\n key3 %d\n maxpass " COUNT "\n" " key1 %d\n key2 %d\n key3 %d\n maxpass " COUNT "\n"
" border " REAL "\n maxchisq " REAL "\n mindeviation " REAL "\n" " border " REAL "\n maxchisq " REAL "\n mindeviation " REAL "\n"
" ngiven " NUMBER "\n nextra " NUMBER "\n", " ngiven " NUMBER "\n nextra " NUMBER "\n",
ndim_, ncomp_, t->ndim, t->ncomp,
epsrel, epsabs, t->epsrel, t->epsabs,
flags, mineval, maxeval, t->flags, t->seed,
key1, key2, key3, maxpass, t->mineval, t->maxeval,
border_.lower, maxchisq, mindeviation, t->key1, t->key2, t->key3, t->maxpass,
ngiven_, nextra_); t->border.lower, t->maxchisq, t->mindeviation,
t->ngiven, t->nextra);
Print(s); Print(s);
} }
size_ = CHUNKSIZE; if( BadComponent(t) ) return -2;
MemAlloc(voidregion_, size_*sizeof(Region)); if( BadDimension(t, t->key1) ||
for( dim = 0; dim < ndim_; ++dim ) { BadDimension(t, t->key2) ||
Bounds *b = &region_->bounds[dim]; ((t->key3 & -2) && BadDimension(t, t->key3)) ) return -1;
t->neval_opt = t->neval_cut = 0;
t->size = CHUNKSIZE;
MemAlloc(t->voidregion, t->size*sizeof(Region));
for( dim = 0; dim < t->ndim; ++dim ) {
Bounds *b = &RegionPtr(0)->bounds[dim];
b->lower = 0; b->lower = 0;
b->upper = 1; b->upper = 1;
} }
nregions_ = 0;
RuleIni(&rule7_); RuleIni(&t->rule7);
RuleIni(&rule9_); RuleIni(&t->rule9);
RuleIni(&rule11_); RuleIni(&t->rule11);
RuleIni(&rule13_); RuleIni(&t->rule13);
SamplesIni(&samples_[0]); SamplesIni(&t->samples[0]);
SamplesIni(&samples_[1]); SamplesIni(&t->samples[1]);
SamplesIni(&samples_[2]); SamplesIni(&t->samples[2]);
#ifdef MLVERSION if( setjmp(t->abort) ) goto abort;
if( setjmp(abort_) ) goto abort;
#endif t->epsabs = Max(t->epsabs, NOTZERO);
/* Step 1: partition the integration region */ /* Step 1: partition the integration region */
if( VERBOSE ) Print("Partitioning phase:"); if( VERBOSE ) Print("Partitioning phase:");
if( IsSobol(key1) || IsSobol(key2) || IsSobol(key3) ) if( IsSobol(t->key1) || IsSobol(t->key2) || IsSobol(t->key3) )
IniRandom(2*maxeval, flags); IniRandom(t);
SamplesLookup(&samples_[0], key1, SamplesLookup(t, &t->samples[0], t->key1,
(number)47, (number)INT_MAX, (number)0); (number)47, (number)INT_MAX, (number)0);
SamplesAlloc(&samples_[0]); SamplesAlloc(t, &t->samples[0]);
totals_ = totals; t->totals = totals;
Zap(totals); Zap(totals);
phase_ = 1; t->phase = 1;
Explore(0, &samples_[0], INIDEPTH, 1); Explore(t, 0, &t->samples[0], INIDEPTH, 1);
for( iter = 1; ; ++iter ) { for( iter = 1; ; ++iter ) {
Totals *maxtot; Totals *maxtot;
count valid; count valid;
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
Totals *tot = &totals[comp]; Totals *tot = &totals[comp];
tot->avg = tot->spreadsq = 0; tot->avg = tot->spreadsq = 0;
tot->spread = tot->secondspread = -INFTY; tot->spread = tot->secondspread = -INFTY;
} }
for( iregion = 0; iregion < nregions_; ++iregion ) { for( iregion = 0; iregion < t->nregions; ++iregion ) {
Region *region = &region_[iregion]; Region *region = RegionPtr(iregion);
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
cResult *r = &region->result[comp]; cResult *r = &region->result[comp];
Totals *tot = &totals[comp]; Totals *tot = &totals[comp];
tot->avg += r->avg; tot->avg += r->avg;
@ -132,13 +137,13 @@ static int Integrate(creal epsrel, creal epsabs,
maxtot = totals; maxtot = totals;
valid = 0; valid = 0;
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
Totals *tot = &totals[comp]; Totals *tot = &totals[comp];
integral[comp] = tot->avg; integral[comp] = tot->avg;
valid += tot->avg == tot->avg; valid += tot->avg == tot->avg;
if( tot->spreadsq > maxtot->spreadsq ) maxtot = tot; if( tot->spreadsq > maxtot->spreadsq ) maxtot = tot;
tot->spread = sqrt(tot->spreadsq); tot->spread = sqrt(tot->spreadsq);
error[comp] = tot->spread*samples_[0].weight; error[comp] = tot->spread*t->samples[0].weight;
} }
if( VERBOSE ) { if( VERBOSE ) {
@ -149,9 +154,9 @@ static int Integrate(creal epsrel, creal epsabs,
NUMBER7 " integrand evaluations so far,\n" NUMBER7 " integrand evaluations so far,\n"
NUMBER7 " in optimizing regions,\n" NUMBER7 " in optimizing regions,\n"
NUMBER7 " in finding cuts", NUMBER7 " in finding cuts",
iter, pass, nregions_, neval_, neval_opt_, neval_cut_); iter, pass, t->nregions, t->neval, t->neval_opt, t->neval_cut);
for( comp = 0; comp < ncomp_; ++comp ) for( comp = 0; comp < t->ncomp; ++comp )
p += sprintf(p, "\n[" COUNT "] " p += sprintf(p, "\n[" COUNT "] "
REAL " +- " REAL, REAL " +- " REAL,
comp + 1, integral[comp], error[comp]); comp + 1, integral[comp], error[comp]);
@ -161,59 +166,59 @@ static int Integrate(creal epsrel, creal epsabs,
if( valid == 0 ) goto abort; /* all NaNs */ if( valid == 0 ) goto abort; /* all NaNs */
if( neval_ > maxeval ) break; if( t->neval > t->maxeval ) break;
nneed = maxtot->spread/MaxErr(maxtot->avg); nneed = maxtot->spread/MaxErr(maxtot->avg);
if( nneed < MAXPRIME ) { if( nneed < MAXPRIME ) {
cnumber n = neval_ + nregions_*(number)ceil(nneed); cnumber n = t->neval + t->nregions*(number)ceil(nneed);
if( n < nmin ) { if( n < nmin ) {
nmin = n; nmin = n;
pass = 0; pass = 0;
} }
else if( ++pass > maxpass && n >= mineval ) break; else if( ++pass > t->maxpass && n >= t->mineval ) break;
} }
Split(maxtot->iregion, DEPTH); Split(t, maxtot->iregion, DEPTH);
} }
/* Step 2: do a "full" integration on each region */ /* Step 2: do a "full" integration on each region */
/* nneed = samples_[0].neff + 1; */ /* nneed = t->samples[0].neff + 1; */
nneed = 2*samples_[0].neff; nneed = 2*t->samples[0].neff;
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
Totals *tot = &totals[comp]; Totals *tot = &totals[comp];
creal maxerr = MaxErr(tot->avg); creal maxerr = MaxErr(tot->avg);
tot->nneed = tot->spread/maxerr; tot->nneed = tot->spread/maxerr;
nneed = Max(nneed, tot->nneed); nneed = Max(nneed, tot->nneed);
tot->maxerrsq = Sq(maxerr); tot->maxerrsq = Sq(maxerr);
tot->mindevsq = tot->maxerrsq*Sq(mindeviation); tot->mindevsq = tot->maxerrsq*Sq(t->mindeviation);
} }
nwant = (number)Min(ceil(nneed), MARKMASK/40.); nwant = (number)Min(ceil(nneed), MARKMASK/40.);
err = SamplesLookup(&samples_[1], key2, nwant, err = SamplesLookup(t, &t->samples[1], t->key2, nwant,
(maxeval - neval_)/nregions_ + 1, samples_[0].n + 1); (t->maxeval - t->neval)/t->nregions + 1, t->samples[0].n + 1);
/* the number of points needed to reach the desired accuracy */ /* the number of points needed to reach the desired accuracy */
fail = Unmark(err)*nregions_; fail = Unmark(err)*t->nregions;
if( Marked(err) ) { if( Marked(err) ) {
if( VERBOSE ) Print("\nNot enough samples left for main integration."); if( VERBOSE ) Print("\nNot enough samples left for main integration.");
for( comp = 0; comp < ncomp_; ++comp ) for( comp = 0; comp < t->ncomp; ++comp )
prob[comp] = -999; prob[comp] = -999;
weight = samples_[0].weight; weight = t->samples[0].weight;
} }
else { else {
bool can_adjust = (key3 == 1 && samples_[1].sampler != SampleRule && bool can_adjust = (t->key3 == 1 && t->samples[1].sampler != SampleRule &&
(key2 < 0 || samples_[1].neff < MAXPRIME)); (t->key2 < 0 || t->samples[1].neff < MAXPRIME));
count df, nlimit; count df, nlimit;
SamplesAlloc(&samples_[1]); SamplesAlloc(t, &t->samples[1]);
if( VERBOSE ) { if( VERBOSE ) {
char s[128]; char s[128];
sprintf(s, "\nMain integration on " COUNT sprintf(s, "\nMain integration on " COUNT
" regions with " NUMBER " samples per region.", " regions with " NUMBER " samples per region.",
nregions_, samples_[1].neff); t->nregions, t->samples[1].neff);
Print(s); Print(s);
} }
@ -221,60 +226,60 @@ static int Integrate(creal epsrel, creal epsabs,
ResClear(error); ResClear(error);
ResClear(prob); ResClear(prob);
nlimit = maxeval - nregions_*samples_[1].n; nlimit = t->maxeval - t->nregions*t->samples[1].n;
df = 0; df = 0;
for( iregion = 0; iregion < nregions_; ++iregion ) { for( iregion = 0; iregion < t->nregions; ++iregion ) {
Region *region = &region_[iregion]; Region *region = RegionPtr(iregion);
char s[64*NDIM + 256*NCOMP], *p = s; char s[64*NDIM + 256*NCOMP], *p = s;
int todo; int todo;
refine: refine:
phase_ = 2; t->phase = 2;
samples_[1].sampler(&samples_[1], region->bounds, region->vol); t->samples[1].sampler(t, &t->samples[1], region->bounds, region->vol);
if( can_adjust ) if( can_adjust )
for( comp = 0; comp < ncomp_; ++comp ) for( comp = 0; comp < t->ncomp; ++comp )
totals[comp].spreadsq -= Sq(region->result[comp].spread); totals[comp].spreadsq -= Sq(region->result[comp].spread);
nlimit += samples_[1].n; nlimit += t->samples[1].n;
todo = 0; todo = 0;
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
cResult *r = &region->result[comp]; cResult *r = &region->result[comp];
Totals *tot = &totals[comp]; Totals *tot = &totals[comp];
samples_[0].avg[comp] = r->avg; t->samples[0].avg[comp] = r->avg;
samples_[0].err[comp] = r->err; t->samples[0].err[comp] = r->err;
if( neval_ < nlimit ) { if( t->neval < nlimit ) {
creal avg2 = samples_[1].avg[comp]; creal avg2 = t->samples[1].avg[comp];
creal err2 = samples_[1].err[comp]; creal err2 = t->samples[1].err[comp];
creal diffsq = Sq(avg2 - r->avg); creal diffsq = Sq(avg2 - r->avg);
#define Var(s) Sq((s.err[comp] == 0) ? r->spread*s.weight : s.err[comp]) #define Var(s) Sq((s.err[comp] == 0) ? r->spread*s.weight : s.err[comp])
if( err2*tot->nneed > r->spread || if( err2*tot->nneed > r->spread ||
diffsq > Max(maxchisq*(Var(samples_[0]) + Var(samples_[1])), diffsq > Max(t->maxchisq*(Var(t->samples[0]) + Var(t->samples[1])),
EPS*Sq(avg2)) ) { EPS*Sq(avg2)) ) {
if( key3 && diffsq > tot->mindevsq ) { if( t->key3 && diffsq > tot->mindevsq ) {
if( key3 == 1 ) { if( t->key3 == 1 ) {
ccount xregion = nregions_; ccount xregion = t->nregions;
if( VERBOSE > 2 ) Print("\nSplit"); if( VERBOSE > 2 ) Print("\nSplit");
phase_ = 1; t->phase = 1;
Explore(iregion, &samples_[1], POSTDEPTH, 2); Explore(t, iregion, &t->samples[1], POSTDEPTH, 2);
if( can_adjust ) { if( can_adjust ) {
number nnew; number nnew;
count ireg, xreg; count ireg, xreg;
for( ireg = iregion, xreg = xregion; for( ireg = iregion, xreg = xregion;
ireg < nregions_; ireg = xreg++ ) { ireg < t->nregions; ireg = xreg++ ) {
cResult *result = region_[ireg].result; cResult *result = RegionPtr(ireg)->result;
count c; count c;
for( c = 0; c < ncomp_; ++c ) for( c = 0; c < t->ncomp; ++c )
totals[c].spreadsq += Sq(result[c].spread); totals[c].spreadsq += Sq(result[c].spread);
} }
@ -282,21 +287,21 @@ refine:
MARKMASK : MARKMASK :
(number)ceil(sqrt(tot->spreadsq/tot->maxerrsq)); (number)ceil(sqrt(tot->spreadsq/tot->maxerrsq));
if( nnew > nwant + nwant/64 ) { if( nnew > nwant + nwant/64 ) {
ccount err = SamplesLookup(&samples_[1], key2, nnew, ccount err = SamplesLookup(t, &t->samples[1], t->key2, nnew,
(maxeval - neval_)/nregions_ + 1, samples_[1].n); (t->maxeval - t->neval)/t->nregions + 1, t->samples[1].n);
fail += Unmark(err)*nregions_; fail += Unmark(err)*t->nregions;
nwant = nnew; nwant = nnew;
SamplesFree(&samples_[1]); SamplesFree(&t->samples[1]);
SamplesAlloc(&samples_[1]); SamplesAlloc(t, &t->samples[1]);
if( key2 > 0 && samples_[1].neff >= MAXPRIME ) if( t->key2 > 0 && t->samples[1].neff >= MAXPRIME )
can_adjust = false; can_adjust = false;
if( VERBOSE > 2 ) { if( VERBOSE > 2 ) {
char s[128]; char s[128];
sprintf(s, "Sampling remaining " COUNT sprintf(s, "Sampling remaining " COUNT
" regions with " NUMBER " points per region.", " regions with " NUMBER " points per region.",
nregions_, samples_[1].neff); t->nregions, t->samples[1].neff);
Print(s); Print(s);
} }
} }
@ -312,25 +317,25 @@ refine:
} }
if( can_adjust ) { if( can_adjust ) {
for( comp = 0; comp < ncomp_; ++comp ) for( comp = 0; comp < t->ncomp; ++comp )
totals[comp].maxerrsq -= totals[comp].maxerrsq -=
Sq(region->result[comp].spread*samples_[1].weight); Sq(region->result[comp].spread*t->samples[1].weight);
} }
switch( todo ) { switch( todo ) {
case 1: /* get spread right */ case 1: /* get spread right */
Explore(iregion, &samples_[1], 0, 2); Explore(t, iregion, &t->samples[1], 0, 2);
break; break;
case 3: /* sample region again with more points */ case 3: /* sample region again with more points */
if( MEM(&samples_[2]) == NULL ) { if( SamplesIniQ(&t->samples[2]) ) {
SamplesLookup(&samples_[2], key3, SamplesLookup(t, &t->samples[2], t->key3,
nwant, (number)INT_MAX, (number)0); nwant, (number)INT_MAX, (number)0);
SamplesAlloc(&samples_[2]); SamplesAlloc(t, &t->samples[2]);
} }
phase_ = 3; t->phase = 3;
samples_[2].sampler(&samples_[2], region->bounds, region->vol); t->samples[2].sampler(t, &t->samples[2], region->bounds, region->vol);
Explore(iregion, &samples_[2], 0, 2); Explore(t, iregion, &t->samples[2], 0, 2);
++region->depth; /* misused for df here */ ++region->depth; /* misused for df here */
++df; ++df;
} }
@ -338,7 +343,7 @@ refine:
++region->depth; /* misused for df here */ ++region->depth; /* misused for df here */
if( VERBOSE > 2 ) { if( VERBOSE > 2 ) {
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
cBounds *b = &region->bounds[dim]; cBounds *b = &region->bounds[dim];
p += sprintf(p, p += sprintf(p,
(dim == 0) ? "\nRegion (" REALF ") - (" REALF ")" : (dim == 0) ? "\nRegion (" REALF ") - (" REALF ")" :
@ -347,14 +352,14 @@ refine:
} }
} }
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
Result *r = &region->result[comp]; Result *r = &region->result[comp];
creal x1 = samples_[0].avg[comp]; creal x1 = t->samples[0].avg[comp];
creal s1 = Var(samples_[0]); creal s1 = Var(t->samples[0]);
creal x2 = samples_[1].avg[comp]; creal x2 = t->samples[1].avg[comp];
creal s2 = Var(samples_[1]); creal s2 = Var(t->samples[1]);
creal r2 = (s1 == 0) ? Sq(samples_[1].neff*samples_[0].weight) : s2/s1; creal r2 = (s1 == 0) ? Sq(t->samples[1].neff*t->samples[0].weight) : s2/s1;
real norm = 1 + r2; real norm = 1 + r2;
real avg = x2 + r2*x1; real avg = x2 + r2*x1;
@ -363,9 +368,9 @@ refine:
real chiden = s1 + s2; real chiden = s1 + s2;
if( todo == 3 ) { if( todo == 3 ) {
creal x3 = samples_[2].avg[comp]; creal x3 = t->samples[2].avg[comp];
creal s3 = Var(samples_[2]); creal s3 = Var(t->samples[2]);
creal r3 = (s2 == 0) ? Sq(samples_[2].neff*samples_[1].weight) : s3/s2; creal r3 = (s2 == 0) ? Sq(t->samples[2].neff*t->samples[1].weight) : s3/s2;
norm = 1 + r3*norm; norm = 1 + r3*norm;
avg = x3 + r3*avg; avg = x3 + r3*avg;
@ -383,10 +388,10 @@ refine:
p += sprintf(p, "\n[" COUNT "] " p += sprintf(p, "\n[" COUNT "] "
REAL " +- " REAL "(" REAL ")\n " REAL " +- " REAL "(" REAL ")\n "
REAL " +- " REAL "(" REAL ")", REAL " +- " REAL "(" REAL ")",
comp + 1, Out(samples_[0]), Out(samples_[1])); comp + 1, Out(t->samples[0]), Out(t->samples[1]));
if( todo == 3 ) p += sprintf(p, "\n " if( todo == 3 ) p += sprintf(p, "\n "
REAL " +- " REAL "(" REAL ")", REAL " +- " REAL "(" REAL ")",
Out(samples_[2])); Out(t->samples[2]));
p += sprintf(p, " \tchisq " REAL, chisq); p += sprintf(p, " \tchisq " REAL, chisq);
} }
@ -402,17 +407,17 @@ refine:
if( VERBOSE > 2 ) Print(s); if( VERBOSE > 2 ) Print(s);
} }
for( comp = 0; comp < ncomp_; ++comp ) for( comp = 0; comp < t->ncomp; ++comp )
error[comp] = sqrt(error[comp]); error[comp] = sqrt(error[comp]);
df += nregions_; df += t->nregions;
if( VERBOSE > 2 ) { if( VERBOSE > 2 ) {
char s[16 + 128*NCOMP], *p = s; char s[16 + 128*NCOMP], *p = s;
p += sprintf(p, "\nTotals:"); p += sprintf(p, "\nTotals:");
for( comp = 0; comp < ncomp_; ++comp ) for( comp = 0; comp < t->ncomp; ++comp )
p += sprintf(p, "\n[" COUNT "] " p += sprintf(p, "\n[" COUNT "] "
REAL " +- " REAL " \tchisq " REAL " (" COUNT " df)", REAL " +- " REAL " \tchisq " REAL " (" COUNT " df)",
comp + 1, integral[comp], error[comp], prob[comp], df); comp + 1, integral[comp], error[comp], prob[comp], df);
@ -420,7 +425,7 @@ refine:
Print(s); Print(s);
} }
for( comp = 0; comp < ncomp_; ++comp ) for( comp = 0; comp < t->ncomp; ++comp )
prob[comp] = ChiSquare(prob[comp], df); prob[comp] = ChiSquare(prob[comp], df);
weight = 1; weight = 1;
@ -429,24 +434,24 @@ refine:
#ifdef MLVERSION #ifdef MLVERSION
if( REGIONS ) { if( REGIONS ) {
MLPutFunction(stdlink, "List", 2); MLPutFunction(stdlink, "List", 2);
MLPutFunction(stdlink, "List", nregions_); MLPutFunction(stdlink, "List", t->nregions);
for( iregion = 0; iregion < nregions_; ++iregion ) { for( iregion = 0; iregion < t->nregions; ++iregion ) {
Region *region = &region_[iregion]; Region *region = RegionPtr(iregion);
cBounds *b = region->bounds; cBounds *b = region->bounds;
real lower[NDIM], upper[NDIM]; real lower[NDIM], upper[NDIM];
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
lower[dim] = b[dim].lower; lower[dim] = b[dim].lower;
upper[dim] = b[dim].upper; upper[dim] = b[dim].upper;
} }
MLPutFunction(stdlink, "Cuba`Divonne`region", 4); MLPutFunction(stdlink, "Cuba`Divonne`region", 4);
MLPutRealList(stdlink, lower, ndim_); MLPutRealList(stdlink, lower, t->ndim);
MLPutRealList(stdlink, upper, ndim_); MLPutRealList(stdlink, upper, t->ndim);
MLPutFunction(stdlink, "List", ncomp_); MLPutFunction(stdlink, "List", t->ncomp);
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
cResult *r = &region->result[comp]; cResult *r = &region->result[comp];
real res[] = {r->avg, r->spread*weight, r->chisq}; real res[] = {r->avg, r->spread*weight, r->chisq};
MLPutRealList(stdlink, res, Elements(res)); MLPutRealList(stdlink, res, Elements(res));
@ -458,16 +463,15 @@ refine:
#endif #endif
abort: abort:
SamplesFree(&t->samples[2]);
SamplesFree(&t->samples[1]);
SamplesFree(&t->samples[0]);
RuleFree(&t->rule13);
RuleFree(&t->rule11);
RuleFree(&t->rule9);
RuleFree(&t->rule7);
SamplesFree(&samples_[2]); free(t->voidregion);
SamplesFree(&samples_[1]);
SamplesFree(&samples_[0]);
RuleFree(&rule13_);
RuleFree(&rule11_);
RuleFree(&rule9_);
RuleFree(&rule7_);
free(region_);
return fail; return fail;
} }

View File

@ -1,5 +1,5 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *

View File

@ -4,11 +4,11 @@
code lifted with minor modifications from DCUHRE code lifted with minor modifications from DCUHRE
by J. Berntsen, T. Espelid, and A. Genz by J. Berntsen, T. Espelid, and A. Genz
this file is part of Divonne this file is part of Divonne
last modified 9 Feb 05 th last modified 16 Jun 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -38,21 +38,7 @@ enum { nrules = 5 };
/*********************************************************************/ /*********************************************************************/
static inline void RuleIni(Rule *rule) static void Rule13Alloc(This *t)
{
rule->first = NULL;
}
/*********************************************************************/
static inline void RuleFree(Rule *rule)
{
if( rule->first ) free(rule->first);
}
/*********************************************************************/
static void Rule13Alloc(Rule *rule)
{ {
static creal w[][nrules] = { static creal w[][nrules] = {
{ .00844923090033615, .3213775489050763, .3372900883288987, { .00844923090033615, .3213775489050763, .3372900883288987,
@ -100,7 +86,7 @@ static void Rule13Alloc(Rule *rule)
TYPEDEFSET; TYPEDEFSET;
count n, r; count n, r;
Set *first, *last, *s, *t; Set *first, *last, *s, *x;
Alloc(first, nsets); Alloc(first, nsets);
Clear(first, nsets); Clear(first, nsets);
@ -182,20 +168,20 @@ static void Rule13Alloc(Rule *rule)
last->gen[0] = g[14]; last->gen[0] = g[14];
last->gen[1] = g[15]; last->gen[1] = g[15];
rule->first = first; t->rule13.first = first;
rule->last = last; t->rule13.last = last;
rule->errcoeff[0] = 10; t->rule13.errcoeff[0] = 10;
rule->errcoeff[1] = 1; t->rule13.errcoeff[1] = 1;
rule->errcoeff[2] = 5; t->rule13.errcoeff[2] = 5;
rule->n = n; t->rule13.n = n;
for( s = first; s <= last; ++s ) for( s = first; s <= last; ++s )
for( r = 1; r < nrules - 1; ++r ) { for( r = 1; r < nrules - 1; ++r ) {
creal scale = (s->weight[r] == 0) ? 100 : creal scale = (s->weight[r] == 0) ? 100 :
-s->weight[r + 1]/s->weight[r]; -s->weight[r + 1]/s->weight[r];
real sum = 0; real sum = 0;
for( t = first; t <= last; ++t ) for( x = first; x <= last; ++x )
sum += t->n*fabs(t->weight[r + 1] + scale*t->weight[r]); sum += x->n*fabs(x->weight[r + 1] + scale*x->weight[r]);
s->scale[r] = scale; s->scale[r] = scale;
s->norm[r] = 1/sum; s->norm[r] = 1/sum;
} }
@ -203,7 +189,7 @@ static void Rule13Alloc(Rule *rule)
/*********************************************************************/ /*********************************************************************/
static void Rule11Alloc(Rule *rule) static void Rule11Alloc(This *t)
{ {
static creal w[][nrules] = { static creal w[][nrules] = {
{ .0009903847688882167, 1.715006248224684, 1.936014978949526, { .0009903847688882167, 1.715006248224684, 1.936014978949526,
@ -248,7 +234,7 @@ static void Rule11Alloc(Rule *rule)
TYPEDEFSET; TYPEDEFSET;
count n, r; count n, r;
Set *first, *last, *s, *t; Set *first, *last, *s, *x;
Alloc(first, nsets); Alloc(first, nsets);
Clear(first, nsets); Clear(first, nsets);
@ -329,20 +315,20 @@ static void Rule11Alloc(Rule *rule)
last->gen[1] = g[12]; last->gen[1] = g[12];
last->gen[2] = g[13]; last->gen[2] = g[13];
rule->first = first; t->rule11.first = first;
rule->last = last; t->rule11.last = last;
rule->errcoeff[0] = 4; t->rule11.errcoeff[0] = 4;
rule->errcoeff[1] = .5; t->rule11.errcoeff[1] = .5;
rule->errcoeff[2] = 3; t->rule11.errcoeff[2] = 3;
rule->n = n; t->rule11.n = n;
for( s = first; s <= last; ++s ) for( s = first; s <= last; ++s )
for( r = 1; r < nrules - 1; ++r ) { for( r = 1; r < nrules - 1; ++r ) {
creal scale = (s->weight[r] == 0) ? 100 : creal scale = (s->weight[r] == 0) ? 100 :
-s->weight[r + 1]/s->weight[r]; -s->weight[r + 1]/s->weight[r];
real sum = 0; real sum = 0;
for( t = first; t <= last; ++t ) for( x = first; x <= last; ++x )
sum += t->n*fabs(t->weight[r + 1] + scale*t->weight[r]); sum += x->n*fabs(x->weight[r + 1] + scale*x->weight[r]);
s->scale[r] = scale; s->scale[r] = scale;
s->norm[r] = 1/sum; s->norm[r] = 1/sum;
} }
@ -350,7 +336,7 @@ static void Rule11Alloc(Rule *rule)
/*********************************************************************/ /*********************************************************************/
static void Rule9Alloc(Rule *rule) static void Rule9Alloc(This *t)
{ {
static creal w[] = { static creal w[] = {
-.0023611709677855117884, .11415390023857325268, -.0023611709677855117884, .11415390023857325268,
@ -384,10 +370,10 @@ static void Rule9Alloc(Rule *rule)
TYPEDEFSET; TYPEDEFSET;
ccount ndim = ndim_; ccount ndim = t->ndim;
ccount twondim = 1 << ndim; ccount twondim = 1 << ndim;
count dim, n, r; count dim, n, r;
Set *first, *last, *s, *t; Set *first, *last, *s, *x;
Alloc(first, nsets); Alloc(first, nsets);
Clear(first, nsets); Clear(first, nsets);
@ -473,20 +459,20 @@ static void Rule9Alloc(Rule *rule)
for( dim = 0; dim < ndim; ++dim ) for( dim = 0; dim < ndim; ++dim )
last->gen[dim] = g[4]; last->gen[dim] = g[4];
rule->first = first; t->rule9.first = first;
rule->last = last; t->rule9.last = last;
rule->errcoeff[0] = 5; t->rule9.errcoeff[0] = 5;
rule->errcoeff[1] = 1; t->rule9.errcoeff[1] = 1;
rule->errcoeff[2] = 5; t->rule9.errcoeff[2] = 5;
rule->n = n; t->rule9.n = n;
for( s = first; s <= last; ++s ) for( s = first; s <= last; ++s )
for( r = 1; r < nrules - 1; ++r ) { for( r = 1; r < nrules - 1; ++r ) {
creal scale = (s->weight[r] == 0) ? 100 : creal scale = (s->weight[r] == 0) ? 100 :
-s->weight[r + 1]/s->weight[r]; -s->weight[r + 1]/s->weight[r];
real sum = 0; real sum = 0;
for( t = first; t <= last; ++t ) for( x = first; x <= last; ++x )
sum += t->n*fabs(t->weight[r + 1] + scale*t->weight[r]); sum += x->n*fabs(x->weight[r + 1] + scale*x->weight[r]);
s->scale[r] = scale; s->scale[r] = scale;
s->norm[r] = 1/sum; s->norm[r] = 1/sum;
} }
@ -494,7 +480,7 @@ static void Rule9Alloc(Rule *rule)
/*********************************************************************/ /*********************************************************************/
static void Rule7Alloc(Rule *rule) static void Rule7Alloc(This *t)
{ {
static creal w[] = { static creal w[] = {
.019417866674748388428, -.40385257701150182546, .019417866674748388428, -.40385257701150182546,
@ -517,10 +503,10 @@ static void Rule7Alloc(Rule *rule)
TYPEDEFSET; TYPEDEFSET;
ccount ndim = ndim_; ccount ndim = t->ndim;
ccount twondim = 1 << ndim; ccount twondim = 1 << ndim;
count dim, n, r; count dim, n, r;
Set *first, *last, *s, *t; Set *first, *last, *s, *x;
Alloc(first, nsets); Alloc(first, nsets);
Clear(first, nsets); Clear(first, nsets);
@ -576,20 +562,20 @@ static void Rule7Alloc(Rule *rule)
for( dim = 0; dim < ndim; ++dim ) for( dim = 0; dim < ndim; ++dim )
last->gen[dim] = g[3]; last->gen[dim] = g[3];
rule->first = first; t->rule7.first = first;
rule->last = last; t->rule7.last = last;
rule->errcoeff[0] = 5; t->rule7.errcoeff[0] = 5;
rule->errcoeff[1] = 1; t->rule7.errcoeff[1] = 1;
rule->errcoeff[2] = 5; t->rule7.errcoeff[2] = 5;
rule->n = n; t->rule7.n = n;
for( s = first; s <= last; ++s ) for( s = first; s <= last; ++s )
for( r = 1; r < nrules - 1; ++r ) { for( r = 1; r < nrules - 1; ++r ) {
creal scale = (s->weight[r] == 0) ? 100 : creal scale = (s->weight[r] == 0) ? 100 :
-s->weight[r + 1]/s->weight[r]; -s->weight[r + 1]/s->weight[r];
real sum = 0; real sum = 0;
for( t = first; t <= last; ++t ) for( x = first; x <= last; ++x )
sum += t->n*fabs(t->weight[r + 1] + scale*t->weight[r]); sum += x->n*fabs(x->weight[r + 1] + scale*x->weight[r]);
s->scale[r] = scale; s->scale[r] = scale;
s->norm[r] = 1/sum; s->norm[r] = 1/sum;
} }
@ -597,9 +583,30 @@ static void Rule7Alloc(Rule *rule)
/*********************************************************************/ /*********************************************************************/
static real *ExpandFS(cBounds *b, real *g, real *x) static inline void RuleIni(Rule *rule)
{ {
count dim, ndim = ndim_; rule->first = NULL;
}
/*********************************************************************/
static inline bool RuleIniQ(Rule *rule)
{
return rule->first == NULL;
}
/*********************************************************************/
static inline void RuleFree(Rule *rule)
{
free(rule->first);
}
/*********************************************************************/
static real *ExpandFS(cThis *t, cBounds *b, real *g, real *x)
{
count dim, ndim = t->ndim;
next: next:
/* Compute centrally symmetric sum for permutation of G */ /* Compute centrally symmetric sum for permutation of G */
@ -617,19 +624,18 @@ next:
for( dim = 1; dim < ndim; ++dim ) { for( dim = 1; dim < ndim; ++dim ) {
creal gd = g[dim]; creal gd = g[dim];
count big = dim - 1; if( g[dim - 1] > gd ) {
if( g[big] > gd ) { count i, j = dim, ix = dim, dx = dim - 1;
count i, j = dim, lastbig = big;
for( i = 0; i < --j; ++i ) { for( i = 0; i < --j; ++i ) {
creal tmp = g[i]; creal tmp = g[i];
g[i] = g[j]; g[i] = g[j];
g[j] = tmp; g[j] = tmp;
if( tmp <= gd ) --big; if( tmp <= gd ) --dx;
if( g[i] > gd ) lastbig = i; if( g[i] > gd ) ix = i;
} }
if( g[big] <= gd ) big = lastbig; if( g[dx] <= gd ) dx = ix;
g[dim] = g[big]; g[dim] = g[dx];
g[big] = gd; g[dx] = gd;
goto next; goto next;
} }
} }
@ -647,7 +653,7 @@ next:
/*********************************************************************/ /*********************************************************************/
static void SampleRule(cSamples *samples, cBounds *b, creal vol) static void SampleRule(This *t, cSamples *samples, cBounds *b, creal vol)
{ {
TYPEDEFSET; TYPEDEFSET;
@ -659,11 +665,11 @@ static void SampleRule(cSamples *samples, cBounds *b, creal vol)
count comp, rul, n; count comp, rul, n;
for( s = first; s <= last; ++s ) for( s = first; s <= last; ++s )
if( s->n ) x = ExpandFS(b, s->gen, x); if( s->n ) x = ExpandFS(t, b, s->gen, x);
DoSample(samples->n, ndim_, samples->x, f); DoSample(t, samples->n, t->ndim, samples->x, f);
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
real sum[nrules]; real sum[nrules];
creal *f1 = f++; creal *f1 = f++;
@ -671,7 +677,7 @@ static void SampleRule(cSamples *samples, cBounds *b, creal vol)
for( s = first; s <= last; ++s ) for( s = first; s <= last; ++s )
for( n = s->n; n; --n ) { for( n = s->n; n; --n ) {
creal fun = *f1; creal fun = *f1;
f1 += ncomp_; f1 += t->ncomp;
for( rul = 0; rul < nrules; ++rul ) for( rul = 0; rul < nrules; ++rul )
sum[rul] += fun*s->weight[rul]; sum[rul] += fun*s->weight[rul];
} }

View File

@ -2,11 +2,11 @@
Sample.c Sample.c
most of what is related to sampling most of what is related to sampling
this file is part of Divonne this file is part of Divonne
last modified 4 Mar 05 th last modified 16 Jun 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -25,29 +25,38 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
#define MARKMASK 0xfffffff #define MARKMASK 0xfffffff
#define Marked(x) ((x) & ~MARKMASK) #define Marked(x) ((x) & ~MARKMASK)
#define Unmark(x) ((x) & MARKMASK) #define Unmark(x) ((x) & MARKMASK)
#define MEM(samples) (samples)->x #define EXTRAPOLATE_EPS (.25*t->border.lower)
/*#define EXTRAPOLATE_EPS 0x1p-26*/
/*********************************************************************/ /*********************************************************************/
static inline void SamplesIni(Samples *samples) static inline void SamplesIni(Samples *samples)
{ {
MEM(samples) = NULL; samples->x = NULL;
}
/*********************************************************************/
static inline bool SamplesIniQ(cSamples *samples)
{
return samples->x == NULL;
} }
/*********************************************************************/ /*********************************************************************/
static inline void SamplesFree(cSamples *samples) static inline void SamplesFree(cSamples *samples)
{ {
if( MEM(samples) ) free(MEM(samples)); free(samples->x);
} }
/*********************************************************************/ /*********************************************************************/
static void SampleSobol(cSamples *samples, cBounds *b, creal vol) static void SampleSobol(This *t, cSamples *samples, cBounds *b, creal vol)
{ {
creal norm = vol*samples->weight; creal norm = vol*samples->weight;
real *x = samples->x, *f = samples->f, *avg = samples->avg; real *x = samples->x, *f = samples->f, *avg = samples->avg;
@ -56,30 +65,30 @@ static void SampleSobol(cSamples *samples, cBounds *b, creal vol)
count dim, comp; count dim, comp;
for( i = 0; i < n; ++i ) { for( i = 0; i < n; ++i ) {
GetRandom(x); t->rng.getrandom(t, x);
for( dim = 0; dim < ndim_; ++x, ++dim ) for( dim = 0; dim < t->ndim; ++x, ++dim )
*x = b[dim].lower + *x*(b[dim].upper - b[dim].lower); *x = b[dim].lower + *x*(b[dim].upper - b[dim].lower);
} }
DoSample(n, ndim_, samples->x, f); DoSample(t, n, t->ndim, samples->x, f);
ResCopy(avg, f); ResCopy(avg, f);
f += ncomp_; f += t->ncomp;
for( i = 1; i < n; ++i ) for( i = 1; i < n; ++i )
for( comp = 0; comp < ncomp_; ++comp ) for( comp = 0; comp < t->ncomp; ++comp )
avg[comp] += *f++; avg[comp] += *f++;
for( comp = 0; comp < ncomp_; ++comp ) for( comp = 0; comp < t->ncomp; ++comp )
avg[comp] *= norm; avg[comp] *= norm;
} }
/*********************************************************************/ /*********************************************************************/
static void SampleKorobov(cSamples *samples, cBounds *b, creal vol) static void SampleKorobov(This *t, cSamples *samples, cBounds *b, creal vol)
{ {
creal norm = vol*samples->weight; creal norm = vol*samples->weight;
real *x = samples->x, *xlast = x + ndim_; real *x = samples->x, *xlast = x + t->ndim;
real *f = samples->f, *flast = f + ncomp_; real *f = samples->f, *flast = f + t->ncomp;
real *avg = samples->avg; real *avg = samples->avg;
cnumber n = samples->n, neff = samples->neff; cnumber n = samples->n, neff = samples->neff;
number nextra = n, i; number nextra = n, i;
@ -88,47 +97,47 @@ static void SampleKorobov(cSamples *samples, cBounds *b, creal vol)
for( i = 1; i < n; ++i ) { for( i = 1; i < n; ++i ) {
number c = i; number c = i;
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
creal dx = abs(2*c - neff)*samples->weight; creal dx = abs(2*c - neff)*samples->weight;
*xlast++ = b[dim].lower + dx*(b[dim].upper - b[dim].lower); *xlast++ = b[dim].lower + dx*(b[dim].upper - b[dim].lower);
c = c*samples->coeff % neff; c = c*samples->coeff % neff;
} }
} }
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
creal dx = (x[dim] = b[dim].upper) - border_.upper; creal dx = (x[dim] = b[dim].upper) - t->border.upper;
if( dx > 0 ) dist += Sq(dx); if( dx > 0 ) dist += Sq(dx);
} }
if( dist > 0 ) { if( dist > 0 ) {
dist = sqrt(dist)/EXTRAPOLATE_EPS; dist = sqrt(dist)/EXTRAPOLATE_EPS;
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
real x2 = x[dim], dx = x2 - border_.upper; real x2 = x[dim], dx = x2 - t->border.upper;
if( dx > 0 ) { if( dx > 0 ) {
x[dim] = border_.upper; x[dim] = t->border.upper;
x2 = border_.upper - dx/dist; x2 = t->border.upper - dx/dist;
} }
xlast[dim] = x2; xlast[dim] = x2;
} }
++nextra; ++nextra;
} }
DoSample(nextra, ndim_, x, f); DoSample(t, nextra, t->ndim, x, f);
ResCopy(avg, flast); ResCopy(avg, flast);
flast += ncomp_; flast += t->ncomp;
for( i = 2; i < n; ++i ) for( i = 2; i < n; ++i )
for( comp = 0; comp < ncomp_; ++comp ) for( comp = 0; comp < t->ncomp; ++comp )
avg[comp] += *flast++; avg[comp] += *flast++;
if( nextra > n ) { if( nextra > n ) {
for( comp = 0; comp < ncomp_; ++comp ) for( comp = 0; comp < t->ncomp; ++comp )
f[comp] += dist*(f[comp] - flast[comp]); f[comp] += dist*(f[comp] - flast[comp]);
for( dim = 0; dim < ndim_; ++dim ) for( dim = 0; dim < t->ndim; ++dim )
x[dim] = b[dim].upper; x[dim] = b[dim].upper;
} }
for( comp = 0; comp < ncomp_; ++comp ) for( comp = 0; comp < t->ncomp; ++comp )
avg[comp] = (avg[comp] + avg[comp] + f[comp])*norm; avg[comp] = (avg[comp] + avg[comp] + f[comp])*norm;
} }
@ -150,33 +159,33 @@ static void SampleKorobov(cSamples *samples, cBounds *b, creal vol)
1..39 = multiplicator, Korobov numbers, 1..39 = multiplicator, Korobov numbers,
40..inf = absolute # of points, Korobov numbers. */ 40..inf = absolute # of points, Korobov numbers. */
static count SamplesLookup(Samples *samples, cint key, static count SamplesLookup(This *t, Samples *samples, cint key,
cnumber nwant, cnumber nmax, number nmin) cnumber nwant, cnumber nmax, number nmin)
{ {
number n; number n;
if( key == 13 && ndim_ == 2 ) { if( key == 13 && t->ndim == 2 ) {
if( rule13_.first == NULL ) Rule13Alloc(&rule13_); if( RuleIniQ(&t->rule13) ) Rule13Alloc(t);
samples->rule = &rule13_; samples->rule = &t->rule13;
samples->n = n = nmin = rule13_.n; samples->n = n = nmin = t->rule13.n;
samples->sampler = SampleRule; samples->sampler = SampleRule;
} }
else if( key == 11 && ndim_ == 3 ) { else if( key == 11 && t->ndim == 3 ) {
if( rule11_.first == NULL ) Rule11Alloc(&rule11_); if( RuleIniQ(&t->rule11) ) Rule11Alloc(t);
samples->rule = &rule11_; samples->rule = &t->rule11;
samples->n = n = nmin = rule11_.n; samples->n = n = nmin = t->rule11.n;
samples->sampler = SampleRule; samples->sampler = SampleRule;
} }
else if( key == 9 ) { else if( key == 9 ) {
if( rule9_.first == NULL ) Rule9Alloc(&rule9_); if( RuleIniQ(&t->rule9) ) Rule9Alloc(t);
samples->rule = &rule9_; samples->rule = &t->rule9;
samples->n = n = nmin = rule9_.n; samples->n = n = nmin = t->rule9.n;
samples->sampler = SampleRule; samples->sampler = SampleRule;
} }
else if( key == 7 ) { else if( key == 7 ) {
if( rule7_.first == NULL ) Rule7Alloc(&rule7_); if( RuleIniQ(&t->rule7) ) Rule7Alloc(t);
samples->rule = &rule7_; samples->rule = &t->rule7;
samples->n = n = nmin = rule7_.n; samples->n = n = nmin = t->rule7.n;
samples->sampler = SampleRule; samples->sampler = SampleRule;
} }
else { else {
@ -194,7 +203,7 @@ static count SamplesLookup(Samples *samples, cint key,
/*********************************************************************/ /*********************************************************************/
static void SamplesAlloc(Samples *samples) static void SamplesAlloc(cThis *t, Samples *samples)
{ {
#define FIRST -INT_MAX #define FIRST -INT_MAX
#define MarkLast(x) (x | Marked(INT_MAX)) #define MarkLast(x) (x | Marked(INT_MAX))
@ -215,18 +224,18 @@ static void SamplesAlloc(Samples *samples)
i += Min1(d); i += Min1(d);
} }
samples->coeff = coeff[i][ndim_ - KOROBOV_MINDIM]; samples->coeff = coeff[i][t->ndim - KOROBOV_MINDIM];
samples->neff = p = Unmark(p); samples->neff = p = Unmark(p);
samples->n = p/2 + 1; samples->n = p/2 + 1;
} }
nx = ndim_*(samples->n + 1); /* need 1 for extrapolation */ nx = t->ndim*(samples->n + 1); /* need 1 for extrapolation */
nf = ncomp_*(samples->n + 1); nf = t->ncomp*(samples->n + 1);
Alloc(samples->x, nx + nf + ncomp_ + ncomp_); Alloc(samples->x, nx + nf + t->ncomp + t->ncomp);
samples->f = samples->x + nx; samples->f = samples->x + nx;
samples->avg = samples->f + nf; samples->avg = samples->f + nf;
samples->err = samples->avg + ncomp_; samples->err = samples->avg + t->ncomp;
ResClear(samples->err); ResClear(samples->err);
samples->weight = 1./samples->neff; samples->weight = 1./samples->neff;
@ -234,26 +243,26 @@ static void SamplesAlloc(Samples *samples)
/*********************************************************************/ /*********************************************************************/
static real Sample(creal *x0) static real Sample(This *t, creal *x0)
{ {
real xtmp[2*NDIM], ftmp[2*NCOMP], *xlast = xtmp, f; real xtmp[2*NDIM], ftmp[2*NCOMP], *xlast = xtmp, f;
real dist = 0; real dist = 0;
count dim; count dim, comp;
number nextra = 1; number nextra = 1;
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
creal x1 = *xlast++ = Min(Max(*x0++, 0.), 1.); creal x1 = *xlast++ = Min(Max(*x0++, 0.), 1.);
real dx; real dx;
if( (dx = x1 - border_.lower) < 0 || if( (dx = x1 - t->border.lower) < 0 ||
(dx = x1 - border_.upper) > 0 ) dist += Sq(dx); (dx = x1 - t->border.upper) > 0 ) dist += Sq(dx);
} }
if( dist > 0 ) { if( dist > 0 ) {
dist = sqrt(dist)/EXTRAPOLATE_EPS; dist = sqrt(dist)/EXTRAPOLATE_EPS;
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
real x2 = xtmp[dim], dx, b; real x2 = xtmp[dim], dx, b;
if( (dx = x2 - (b = border_.lower)) < 0 || if( (dx = x2 - (b = t->border.lower)) < 0 ||
(dx = x2 - (b = border_.upper)) > 0 ) { (dx = x2 - (b = t->border.upper)) > 0 ) {
xtmp[dim] = b; xtmp[dim] = b;
x2 = b - dx/dist; x2 = b - dx/dist;
} }
@ -262,11 +271,12 @@ static real Sample(creal *x0)
nextra = 2; nextra = 2;
} }
DoSample(nextra, ndim_, xtmp, ftmp); DoSample(t, nextra, t->ndim, xtmp, ftmp);
f = ftmp[selectedcomp_]; comp = Untag(t->selectedcomp);
if( nextra > 1 ) f += dist*(f - ftmp[selectedcomp_ + ncomp_]); f = ftmp[comp];
if( nextra > 1 ) f += dist*(f - ftmp[comp + t->ncomp]);
return f; return Sign(t->selectedcomp)*f;
} }

View File

@ -2,11 +2,11 @@
Split.c Split.c
determine optimal cuts for splitting a region determine optimal cuts for splitting a region
this file is part of Divonne this file is part of Divonne
last modified 22 Jul 09 th last modified 20 Jul 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -25,6 +25,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
#define BNDTOL .05 #define BNDTOL .05
#define FRACT .5 #define FRACT .5
#define BIG 1e10 #define BIG 1e10
@ -37,7 +38,7 @@
#define Lower(d) (2*d) #define Lower(d) (2*d)
#define Upper(d) (2*d + 1) #define Upper(d) (2*d + 1)
#define Dim(i) ((i) >> 1) #define Dim(i) ((i) >> 1)
#define SignedDelta(i) ((i & 1) ? delta[i] : -delta[i]) #define SignedDelta(i) (2*(i & 1) - 1)*delta[i]
typedef struct { typedef struct {
count i; count i;
@ -61,25 +62,25 @@ static inline real Div(creal a, creal b)
/*********************************************************************/ /*********************************************************************/
static void SomeCut(Cut *cut, Bounds *b) static void SomeCut(This *t, Cut *cut, Bounds *b)
{ {
count dim, maxdim; count dim, maxdim;
static count nextdim = 0; static count nextdim = 0;
real xmid[NDIM], ymid, maxdev; real xmid[NDIM], ymid, maxdev;
for( dim = 0; dim < ndim_; ++dim ) for( dim = 0; dim < t->ndim; ++dim )
xmid[dim] = .5*(b[dim].upper + b[dim].lower); xmid[dim] = .5*(b[dim].upper + b[dim].lower);
ymid = Sample(xmid); ymid = Sample(t, xmid);
maxdev = 0; maxdev = 0;
maxdim = 0; maxdim = 0;
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
real ylower, yupper, dev; real ylower, yupper, dev;
creal x = xmid[dim]; creal x = xmid[dim];
xmid[dim] = b[dim].lower; xmid[dim] = b[dim].lower;
ylower = Sample(xmid); ylower = Sample(t, xmid);
xmid[dim] = b[dim].upper; xmid[dim] = b[dim].upper;
yupper = Sample(xmid); yupper = Sample(t, xmid);
xmid[dim] = x; xmid[dim] = x;
dev = fabs(ymid - .5*(ylower + yupper)); dev = fabs(ymid - .5*(ylower + yupper));
@ -90,7 +91,7 @@ static void SomeCut(Cut *cut, Bounds *b)
} }
if( maxdev > 0 ) nextdim = 0; if( maxdev > 0 ) nextdim = 0;
else maxdim = nextdim++ % ndim_; else maxdim = nextdim++ % t->ndim;
cut->i = Upper(maxdim); cut->i = Upper(maxdim);
cut->save = b[maxdim].upper; cut->save = b[maxdim].upper;
@ -99,11 +100,11 @@ static void SomeCut(Cut *cut, Bounds *b)
/*********************************************************************/ /*********************************************************************/
static inline real Volume(creal *delta) static inline real Volume(cThis *t, creal *delta)
{ {
real vol = 1; real vol = 1;
count dim; count dim;
for( dim = 0; dim < ndim_; ++dim ) for( dim = 0; dim < t->ndim; ++dim )
vol *= delta[Lower(dim)] + delta[Upper(dim)]; vol *= delta[Lower(dim)] + delta[Upper(dim)];
return vol; return vol;
} }
@ -151,7 +152,7 @@ static inline void SolveEqs(Cut *cut, count ncut,
/*********************************************************************/ /*********************************************************************/
static count FindCuts(Cut *cut, Bounds *bounds, creal vol, static count FindCuts(This *t, Cut *cut, Bounds *bounds, creal vol,
real *xmajor, creal fmajor, creal fdiff) real *xmajor, creal fmajor, creal fdiff)
{ {
cint sign = (fdiff < 0) ? -1 : 1; cint sign = (fdiff < 0) ? -1 : 1;
@ -161,26 +162,22 @@ static count FindCuts(Cut *cut, Bounds *bounds, creal vol,
real gamma, fgamma, lhssq; real gamma, fgamma, lhssq;
count dim, div; count dim, div;
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
// cBounds *b = &bounds[dim]; cBounds *b = &bounds[dim];
// creal xsave = xmajor[dim]; creal xsave = xmajor[dim];
cBounds *b;
real xsave;
b = &bounds[dim];
xsave = xmajor[dim];
real dist = b->upper - xsave; real dist = b->upper - xsave;
if( dist >= BNDTOL*(b->upper - b->lower) ) { if( dist >= BNDTOL*(b->upper - b->lower) ) {
Cut *c = &cut[ncut++]; Cut *c = &cut[ncut++];
c->i = Upper(dim); c->i = Upper(dim);
c->save = dist; c->save = dist;
xmajor[dim] += dist *= FRACT; xmajor[dim] += dist *= FRACT;
c->f = Sample(xmajor); c->f = Sample(t, xmajor);
xmajor[dim] = xsave; xmajor[dim] = xsave;
} }
delta[Upper(dim)] = dist; delta[Upper(dim)] = dist;
} }
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
cBounds *b = &bounds[dim]; cBounds *b = &bounds[dim];
creal xsave = xmajor[dim]; creal xsave = xmajor[dim];
real dist = xsave - b->lower; real dist = xsave - b->lower;
@ -189,14 +186,14 @@ static count FindCuts(Cut *cut, Bounds *bounds, creal vol,
c->i = Lower(dim); c->i = Lower(dim);
c->save = dist; c->save = dist;
xmajor[dim] -= dist *= FRACT; xmajor[dim] -= dist *= FRACT;
c->f = Sample(xmajor); c->f = Sample(t, xmajor);
xmajor[dim] = xsave; xmajor[dim] = xsave;
} }
delta[Lower(dim)] = dist; delta[Lower(dim)] = dist;
} }
if( ncut == 0 ) { if( ncut == 0 ) {
SomeCut(cut, bounds); SomeCut(t, cut, bounds);
return 1; return 1;
} }
@ -213,13 +210,13 @@ static count FindCuts(Cut *cut, Bounds *bounds, creal vol,
} }
} }
gamma = Volume(delta)/vol; gamma = Volume(t, delta)/vol;
fgamma = fmajor + (gamma - 1)*fdiff; fgamma = fmajor + (gamma - 1)*fdiff;
if( sign*(mincut->f - fgamma) < 0 ) break; if( sign*(mincut->f - fgamma) < 0 ) break;
if( --ncut == 0 ) { if( --ncut == 0 ) {
SomeCut(cut, bounds); SomeCut(t, cut, bounds);
return 1; return 1;
} }
@ -247,11 +244,11 @@ repeat:
creal xsave = *x; creal xsave = *x;
delta[c->i] = c->delta + c->sol/div; delta[c->i] = c->delta + c->sol/div;
*x += SignedDelta(c->i); *x += SignedDelta(c->i);
c->f = Sample(xmajor); c->f = Sample(t, xmajor);
*x = xsave; *x = xsave;
} }
gammanew = Volume(delta)/vol; gammanew = Volume(t, delta)/vol;
fgamma = fmajor + (gammanew - 1)*fdiff; fgamma = fmajor + (gammanew - 1)*fdiff;
lhssqnew = SetupEqs(cut, ncut, fgamma); lhssqnew = SetupEqs(cut, ncut, fgamma);
@ -291,7 +288,7 @@ repeat:
/*********************************************************************/ /*********************************************************************/
static void Split(count iregion, int depth) static void Split(This *t, count iregion, int depth)
{ {
TYPEDEFREGION; TYPEDEFREGION;
@ -301,42 +298,42 @@ static void Split(count iregion, int depth)
real tmp; real tmp;
{ {
Region *const region = region_ + iregion; Region *const region = RegionPtr(iregion);
selectedcomp_ = region->cutcomp; t->selectedcomp = region->cutcomp;
neval_cut_ -= neval_; t->neval_cut -= t->neval;
ncut = FindCuts(cut, region->bounds, region->vol, ncut = FindCuts(t, cut, region->bounds, region->vol,
(real *)region->result + region->xmajor, region->fmajor, (real *)region->result + region->xmajor, region->fmajor,
region->fmajor - region->fminor); region->fmajor - region->fminor);
neval_cut_ += neval_; t->neval_cut += t->neval;
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
Errors *e = &errors[comp]; Errors *e = &errors[comp];
e->diff = region->result[comp].avg; e->diff = region->result[comp].avg;
e->spread = e->err = 0; e->spread = e->err = 0;
} }
} }
xregion = nregions_; xregion = t->nregions;
depth -= ncut; depth -= ncut;
if( Explore(iregion, &samples_[0], depth, 1) ) { if( Explore(t, iregion, &t->samples[0], depth, 1) ) {
Cut *c; Cut *c;
for( c = cut; ncut--; ++c ) { for( c = cut; ncut--; ++c ) {
real *b = (real *)region_[iregion].bounds; real *b = (real *)RegionPtr(iregion)->bounds;
ccount c0 = c->i, c1 = c0 ^ 1; ccount c0 = c->i, c1 = c0 ^ 1;
creal tmp = b[c1]; creal tmp = b[c1];
b[c1] = b[c0]; b[c1] = b[c0];
b[c0] = c->save; b[c0] = c->save;
if( !Explore(iregion, &samples_[0], depth++, ncut != 0) ) break; if( !Explore(t, iregion, &t->samples[0], depth++, ncut != 0) ) break;
if( ncut ) ((real *)region_[iregion].bounds)[c1] = tmp; if( ncut ) ((real *)RegionPtr(iregion)->bounds)[c1] = tmp;
} }
} }
nsplit = nregions_ - xregion + 1; nsplit = t->nregions - xregion + 1;
for( ireg = iregion, xreg = xregion; ireg < nregions_; ireg = xreg++ ) { for( ireg = iregion, xreg = xregion; ireg < t->nregions; ireg = xreg++ ) {
cResult *result = region_[ireg].result; cResult *result = RegionPtr(ireg)->result;
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
cResult *r = &result[comp]; cResult *r = &result[comp];
Errors *e = &errors[comp]; Errors *e = &errors[comp];
e->diff -= r->avg; e->diff -= r->avg;
@ -346,7 +343,7 @@ static void Split(count iregion, int depth)
} }
tmp = 1./nsplit; tmp = 1./nsplit;
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
Errors *e = &errors[comp]; Errors *e = &errors[comp];
e->diff = tmp*fabs(e->diff); e->diff = tmp*fabs(e->diff);
e->err = (e->err == 0) ? 1 : 1 + e->diff/e->err; e->err = (e->err == 0) ? 1 : 1 + e->diff/e->err;
@ -354,14 +351,14 @@ static void Split(count iregion, int depth)
} }
tmp = 1 - tmp; tmp = 1 - tmp;
for( ireg = iregion, xreg = xregion; ireg < nregions_; ireg = xreg++ ) { for( ireg = iregion, xreg = xregion; ireg < t->nregions; ireg = xreg++ ) {
Result *result = region_[ireg].result; Result *result = RegionPtr(ireg)->result;
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
Result *r = &result[comp]; Result *r = &result[comp];
cErrors *e = &errors[comp]; cErrors *e = &errors[comp];
creal c = tmp*e->diff; creal c = tmp*e->diff;
if( r->err > 0 ) r->err = r->err*e->err + c; if( r->err > 0 ) r->err = r->err*e->err + c;
r->spread = r->spread*e->spread + c*samples_[0].neff; r->spread = r->spread*e->spread + c*t->samples[0].neff;
} }
} }
} }

View File

@ -2,11 +2,11 @@
common.c common.c
includes most of the modules includes most of the modules
this file is part of Divonne this file is part of Divonne
last modified 5 May 09 th last modified 8 Jun 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -25,37 +25,35 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
static bool Explore(count iregion, cSamples *samples, cint depth, cint flags);
static void Split(count iregion, int depth);
#include "Random.c" #include "Random.c"
#include "ChiSquare.c" #include "ChiSquare.c"
#include "Rule.c" #include "Rule.c"
#include "Sample.c" #include "Sample.c"
#include "FindMinimum.c" #include "FindMinimum.c"
static bool Explore(This *t, count iregion, cSamples *samples,
cint depth, cint flags);
static void Split(This *t, count iregion, int depth);
#include "Explore.c" #include "Explore.c"
#include "Split.c" #include "Split.c"
static inline bool BadDimension(cThis *t, ccount key)
{
if( t->ndim > NDIM ) return true;
if( IsSobol(key) ) return
t->ndim < SOBOL_MINDIM || (t->seed == 0 && t->ndim > SOBOL_MAXDIM);
if( IsRule(key, t->ndim) ) return t->ndim < 1;
return t->ndim < KOROBOV_MINDIM || t->ndim > KOROBOV_MAXDIM;
}
static inline bool BadComponent(cThis *t)
{
if( t->ncomp > NCOMP ) return true;
return t->ncomp < 1;
}
#include "Integrate.c" #include "Integrate.c"
static inline bool BadDimension(ccount ndim, cint flags, ccount key)
{
#if NDIM > 0
if( ndim > NDIM ) return true;
#endif
if( IsSobol(key) ) return
ndim < SOBOL_MINDIM || (!PSEUDORNG && ndim > SOBOL_MAXDIM);
if( IsRule(key, ndim) ) return ndim < 1;
return ndim < KOROBOV_MINDIM || ndim > KOROBOV_MAXDIM;
}
static inline bool BadComponent(cint ncomp)
{
#if NCOMP > 0
if( ncomp > NCOMP ) return true;
#endif
return ncomp < 1;
}

View File

@ -2,11 +2,11 @@
decl.h decl.h
Type declarations Type declarations
this file is part of Divonne this file is part of Divonne
last modified 25 May 09 th last modified 8 Jun 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -25,11 +25,11 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
#include "stddecl.h" #include "stddecl.h"
#define EXTRAPOLATE_EPS (.25*border_.lower) #define Tag(x) ((x) | INT_MIN)
/*#define EXTRAPOLATE_EPS 0x1p-26*/ #define Untag(x) ((x) & INT_MAX)
typedef struct { typedef struct {
real lower, upper; real lower, upper;
@ -37,7 +37,6 @@ typedef struct {
typedef const Bounds cBounds; typedef const Bounds cBounds;
typedef struct { typedef struct {
real avg, spreadsq; real avg, spreadsq;
real spread, secondspread; real spread, secondspread;
@ -45,7 +44,6 @@ typedef struct {
int iregion; int iregion;
} Totals; } Totals;
typedef struct { typedef struct {
void *first, *last; void *first, *last;
real errcoeff[3]; real errcoeff[3];
@ -54,11 +52,10 @@ typedef struct {
typedef const Rule cRule; typedef const Rule cRule;
typedef struct samples { typedef struct samples {
real weight; real weight;
real *x, *f, *avg, *err; real *x, *f, *avg, *err;
void (*sampler)(const struct samples *, cBounds *, creal); void (*sampler)(struct _this *t, const struct samples *, cBounds *, creal);
cRule *rule; cRule *rule;
count coeff; count coeff;
number n, neff; number n, neff;
@ -66,6 +63,42 @@ typedef struct samples {
typedef const Samples cSamples; typedef const Samples cSamples;
typedef int (*Integrand)(ccount *, creal *, ccount *, real *, void *, cint *);
typedef void (*PeakFinder)(ccount *, cBounds *, number *, real *);
typedef struct _this {
count ndim, ncomp;
#ifndef MLVERSION
Integrand integrand;
void *userdata;
PeakFinder peakfinder;
#endif
real epsrel, epsabs;
int flags, seed;
number mineval, maxeval;
int key1, key2, key3;
count maxpass;
Bounds border;
real maxchisq, mindeviation;
number ngiven, nextra;
real *xgiven, *xextra, *fgiven, *fextra;
count ldxgiven;
count nregions;
number neval, neval_opt, neval_cut;
int phase;
count selectedcomp, size;
Samples samples[3];
Totals *totals;
Rule rule7, rule9, rule11, rule13;
RNGState rng;
void *voidregion;
jmp_buf abort;
} This;
typedef const This cThis;
#define CHUNKSIZE 4096
#define TYPEDEFREGION \ #define TYPEDEFREGION \
typedef struct { \ typedef struct { \
@ -81,10 +114,5 @@ typedef const Samples cSamples;
Result result[NCOMP]; \ Result result[NCOMP]; \
} Region } Region
#define CHUNKSIZE 4096 #define RegionPtr(n) (&((Region *)t->voidregion)[n])
typedef void (*Integrand)(ccount *, creal *, ccount *, real *, cint *);
typedef void (*PeakFinder)(ccount *, cBounds *, number *, real *);

View File

@ -6,7 +6,7 @@
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -25,6 +25,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
#if defined(HAVE_LONG_DOUBLE) && defined(HAVE_POWL) #if defined(HAVE_LONG_DOUBLE) && defined(HAVE_POWL)
typedef long double xdouble; typedef long double xdouble;
@ -48,34 +49,35 @@ typedef struct {
/*********************************************************************/ /*********************************************************************/
static void Fluct(Var *var, real flatness, static void Fluct(cThis *t, Var *var,
cBounds *b, creal *w, number n, ccount comp, creal avg, creal err) cBounds *b, creal *w, number n, ccount comp, creal avg, creal err)
{ {
creal *x = w + n, *f = x + n*ndim_ + comp; creal *x = w + n;
creal max = ldexp(1., (int)((XDBL_MAX_EXP - 2)/flatness)); creal *f = x + n*t->ndim + comp;
creal flat = 2/3./t->flatness;
creal max = ldexp(1., (int)((XDBL_MAX_EXP - 2)/t->flatness));
creal norm = 1/(err*Max(fabs(avg), err)); creal norm = 1/(err*Max(fabs(avg), err));
count nvar = 2*ndim_; count nvar = 2*t->ndim;
Clear(var, nvar); Clear(var, nvar);
while( n-- ) { while( n-- ) {
count dim; count dim;
const xdouble t = const xdouble ft =
powx(Min(1 + fabs(*w++)*Sq(*f - avg)*norm, max), flatness); powx(Min(1 + fabs(*w++)*Sq(*f - avg)*norm, max), t->flatness);
f += ncomp_; f += t->ncomp;
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
Var *v = &var[2*dim + (*x++ >= b[dim].mid)]; Var *v = &var[2*dim + (*x++ >= b[dim].mid)];
const xdouble f = v->fluct + t; const xdouble f = v->fluct + ft;
v->fluct = (f > XDBL_MAX/2) ? XDBL_MAX/2 : f; v->fluct = (f > XDBL_MAX/2) ? XDBL_MAX/2 : f;
++v->n; ++v->n;
} }
} }
flatness = 2/3./flatness;
while( nvar-- ) { while( nvar-- ) {
var->fluct = powx(var->fluct, flatness); var->fluct = powx(var->fluct, flat);
++var; ++var;
} }
} }

View File

@ -2,11 +2,11 @@
Grid.c Grid.c
utility functions for the Vegas grid utility functions for the Vegas grid
this file is part of Suave this file is part of Suave
last modified 15 Feb 08 th last modified 1 Jun 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -25,7 +25,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
static void RefineGrid(Grid grid, Grid margsum, cint flags) static void RefineGrid(cThis *t, Grid grid, Grid margsum)
{ {
real avgperbin, thisbin, newcur, delta; real avgperbin, thisbin, newcur, delta;
Grid imp, newgrid; Grid imp, newgrid;
@ -81,17 +81,17 @@ static void RefineGrid(Grid grid, Grid margsum, cint flags)
/*********************************************************************/ /*********************************************************************/
static void Reweight(Bounds *b, static void Reweight(cThis *t, Bounds *b,
creal *w, creal *f, creal *lastf, cResult *total, cint flags) creal *w, creal *f, creal *lastf, cResult *total)
{ {
Grid margsum[NDIM]; Grid margsum[NDIM];
real scale[NCOMP]; real scale[NCOMP];
cbin_t *bin = (cbin_t *)lastf; cbin_t *bin = (cbin_t *)lastf;
count dim, comp; count dim, comp;
if( ncomp_ == 1 ) scale[0] = 1; if( t->ncomp == 1 ) scale[0] = 1;
else { else {
for( comp = 0; comp < ncomp_; ++comp ) for( comp = 0; comp < t->ncomp; ++comp )
scale[comp] = (total[comp].avg == 0) ? 0 : 1/total[comp].avg; scale[comp] = (total[comp].avg == 0) ? 0 : 1/total[comp].avg;
} }
@ -99,17 +99,17 @@ static void Reweight(Bounds *b,
while( f < lastf ) { while( f < lastf ) {
real fsq = 0; real fsq = 0;
for( comp = 0; comp < ncomp_; ++comp ) for( comp = 0; comp < t->ncomp; ++comp )
fsq += Sq(*f++*scale[comp]); fsq += Sq(*f++*scale[comp]);
fsq *= Sq(*w++); fsq *= Sq(*w++);
if( fsq != 0 ) if( fsq != 0 )
for( dim = 0; dim < ndim_; ++dim ) for( dim = 0; dim < t->ndim; ++dim )
margsum[dim][bin[dim]] += fsq; margsum[dim][bin[dim]] += fsq;
bin += ndim_; bin += t->ndim;
} }
for( dim = 0; dim < ndim_; ++dim ) for( dim = 0; dim < t->ndim; ++dim )
RefineGrid(b[dim].grid, margsum[dim], flags); RefineGrid(t, b[dim].grid, margsum[dim]);
} }
/*********************************************************************/ /*********************************************************************/

View File

@ -2,11 +2,11 @@
Integrate.c Integrate.c
integrate over the unit hypercube integrate over the unit hypercube
this file is part of Suave this file is part of Suave
last modified 2 Jan 08 th last modified 16 Jun 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -25,15 +25,13 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
static int Integrate(creal epsrel, creal epsabs,
cint flags, cnumber mineval, cnumber maxeval, static int Integrate(This *t, real *integral, real *error, real *prob)
cnumber nnew, creal flatness,
real *integral, real *error, real *prob)
{ {
TYPEDEFREGION; TYPEDEFREGION;
count dim, comp, df; count dim, comp, df;
int fail = 1; int fail = -99;
Result totals[NCOMP]; Result totals[NCOMP];
Region *anchor = NULL, *region = NULL; Region *anchor = NULL, *region = NULL;
@ -42,26 +40,30 @@ static int Integrate(creal epsrel, creal epsabs,
sprintf(s, "Suave input parameters:\n" sprintf(s, "Suave input parameters:\n"
" ndim " COUNT "\n ncomp " COUNT "\n" " ndim " COUNT "\n ncomp " COUNT "\n"
" epsrel " REAL "\n epsabs " REAL "\n" " epsrel " REAL "\n epsabs " REAL "\n"
" flags %d\n mineval " NUMBER "\n maxeval " NUMBER "\n" " flags %d\n seed %d\n"
" mineval " NUMBER "\n maxeval " NUMBER "\n"
" nnew " NUMBER "\n flatness " REAL, " nnew " NUMBER "\n flatness " REAL,
ndim_, ncomp_, t->ndim, t->ncomp,
epsrel, epsabs, t->epsrel, t->epsabs,
flags, mineval, maxeval, t->flags, t->seed,
nnew, flatness); t->mineval, t->maxeval,
t->nnew, t->flatness);
Print(s); Print(s);
} }
#ifdef MLVERSION if( BadComponent(t) ) return -2;
if( setjmp(abort_) ) goto abort; if( BadDimension(t) ) return -1;
#endif
IniRandom(2*maxeval, flags); if( setjmp(t->abort) ) goto abort;
RegionAlloc(anchor, nnew, nnew); t->epsabs = Max(t->epsabs, NOTZERO);
IniRandom(t);
RegionAlloc(anchor, t->nnew, t->nnew);
anchor->next = NULL; anchor->next = NULL;
anchor->div = 0; anchor->div = 0;
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
Bounds *b = &anchor->bounds[dim]; Bounds *b = &anchor->bounds[dim];
b->lower = 0; b->lower = 0;
b->upper = 1; b->upper = 1;
@ -76,12 +78,13 @@ static int Integrate(creal epsrel, creal epsabs,
else Copy(b->grid, anchor->bounds[0].grid, NBINS); else Copy(b->grid, anchor->bounds[0].grid, NBINS);
} }
Sample(nnew, anchor, anchor->w, Sample(t, t->nnew, anchor, anchor->w,
anchor->w + nnew, anchor->w + (ndim_ + 1)*nnew, flags); anchor->w + t->nnew,
anchor->w + t->nnew + t->ndim*t->nnew);
df = anchor->df; df = anchor->df;
ResCopy(totals, anchor->result); ResCopy(totals, anchor->result);
for( nregions_ = 1; ; ++nregions_ ) { for( t->nregions = 1; ; ++t->nregions ) {
Var var[NDIM][2], *vLR; Var var[NDIM][2], *vLR;
real maxratio, maxerr, minfluct, bias, mid; real maxratio, maxerr, minfluct, bias, mid;
Region *regionL, *regionR, *reg, **parent, **par; Region *regionL, *regionR, *reg, **parent, **par;
@ -95,9 +98,9 @@ static int Integrate(creal epsrel, creal epsabs,
p += sprintf(p, "\n" p += sprintf(p, "\n"
"Iteration " COUNT ": " NUMBER " integrand evaluations so far", "Iteration " COUNT ": " NUMBER " integrand evaluations so far",
nregions_, neval_); t->nregions, t->neval);
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
cResult *tot = &totals[comp]; cResult *tot = &totals[comp];
p += sprintf(p, "\n[" COUNT "] " p += sprintf(p, "\n[" COUNT "] "
REAL " +- " REAL " \tchisq " REAL " (" COUNT " df)", REAL " +- " REAL " \tchisq " REAL " (" COUNT " df)",
@ -109,7 +112,7 @@ static int Integrate(creal epsrel, creal epsabs,
maxratio = -INFTY; maxratio = -INFTY;
maxcomp = 0; maxcomp = 0;
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
creal ratio = totals[comp].err/MaxErr(totals[comp].avg); creal ratio = totals[comp].err/MaxErr(totals[comp].avg);
if( ratio > maxratio ) { if( ratio > maxratio ) {
maxratio = ratio; maxratio = ratio;
@ -117,12 +120,12 @@ static int Integrate(creal epsrel, creal epsabs,
} }
} }
if( maxratio <= 1 && neval_ >= mineval ) { if( maxratio <= 1 && t->neval >= t->mineval ) {
fail = 0; fail = 0;
break; break;
} }
if( neval_ >= maxeval ) break; if( t->neval >= t->maxeval ) break;
maxerr = -INFTY; maxerr = -INFTY;
parent = &anchor; parent = &anchor;
@ -136,15 +139,15 @@ static int Integrate(creal epsrel, creal epsabs,
} }
} }
Fluct(var[0], flatness, Fluct(t, var[0],
region->bounds, region->w, region->n, maxcomp, region->bounds, region->w, region->n, maxcomp,
region->result[maxcomp].avg, Max(maxerr, epsabs)); region->result[maxcomp].avg, Max(maxerr, t->epsabs));
bias = (epsrel < 1e-50) ? 2 : bias = (t->epsrel < 1e-50) ? 2 :
Max(pow(2., -(real)region->div/ndim_)/epsrel, 2.); Max(pow(2., -(real)region->div/t->ndim)/t->epsrel, 2.);
minfluct = INFTY; minfluct = INFTY;
bisectdim = 0; bisectdim = 0;
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
cBounds *b = &region->bounds[dim]; cBounds *b = &region->bounds[dim];
creal fluct = (var[dim][0].fluct + var[dim][1].fluct)* creal fluct = (var[dim][0].fluct + var[dim][1].fluct)*
(bias - b->upper + b->lower); (bias - b->upper + b->lower);
@ -157,10 +160,10 @@ static int Integrate(creal epsrel, creal epsabs,
vLR = var[bisectdim]; vLR = var[bisectdim];
minfluct = vLR[0].fluct + vLR[1].fluct; minfluct = vLR[0].fluct + vLR[1].fluct;
nnewL = IMax( nnewL = IMax(
(minfluct == 0) ? nnew/2 : (count)(vLR[0].fluct/minfluct*nnew), (minfluct == 0) ? t->nnew/2 : (count)(vLR[0].fluct/minfluct*t->nnew),
MINSAMPLES ); MINSAMPLES );
nL = vLR[0].n + nnewL; nL = vLR[0].n + nnewL;
nnewR = IMax(nnew - nnewL, MINSAMPLES); nnewR = IMax(t->nnew - nnewL, MINSAMPLES);
nR = vLR[1].n + nnewR; nR = vLR[1].n + nnewR;
RegionAlloc(regionL, nL, nnewL); RegionAlloc(regionL, nL, nnewL);
@ -174,9 +177,9 @@ static int Integrate(creal epsrel, creal epsabs,
bounds = &region->bounds[bisectdim]; bounds = &region->bounds[bisectdim];
mid = bounds->mid; mid = bounds->mid;
n = region->n; n = region->n;
w = wlast = region->w; x = w + n; f = flast = x + n*ndim_; w = wlast = region->w; x = w + n; f = flast = x + n*t->ndim;
wL = regionL->w; xL = wL + nL; fL = xL + nL*ndim_; wL = regionL->w; xL = wL + nL; fL = xL + nL*t->ndim;
wR = regionR->w; xR = wR + nR; fR = xR + nR*ndim_; wR = regionR->w; xR = wR + nR; fR = xR + nR*t->ndim;
while( n-- ) { while( n-- ) {
cbool final = (*w < 0); cbool final = (*w < 0);
@ -184,24 +187,24 @@ static int Integrate(creal epsrel, creal epsabs,
if( final && wR > regionR->w ) *(wR - 1) = -fabs(*(wR - 1)); if( final && wR > regionR->w ) *(wR - 1) = -fabs(*(wR - 1));
*wL++ = *w++; *wL++ = *w++;
VecCopy(xL, x); VecCopy(xL, x);
xL += ndim_; xL += t->ndim;
ResCopy(fL, f); ResCopy(fL, f);
fL += ncomp_; fL += t->ncomp;
} }
else { else {
if( final && wL > regionL->w ) *(wL - 1) = -fabs(*(wL - 1)); if( final && wL > regionL->w ) *(wL - 1) = -fabs(*(wL - 1));
*wR++ = *w++; *wR++ = *w++;
VecCopy(xR, x); VecCopy(xR, x);
xR += ndim_; xR += t->ndim;
ResCopy(fR, f); ResCopy(fR, f);
fR += ncomp_; fR += t->ncomp;
} }
x += ndim_; x += t->ndim;
f += ncomp_; f += t->ncomp;
if( n && final ) wlast = w, flast = f; if( n && final ) wlast = w, flast = f;
} }
Reweight(region->bounds, wlast, flast, f, totals, flags); Reweight(t, region->bounds, wlast, flast, f, totals);
VecCopy(regionL->bounds, region->bounds); VecCopy(regionL->bounds, region->bounds);
VecCopy(regionR->bounds, region->bounds); VecCopy(regionR->bounds, region->bounds);
@ -212,12 +215,12 @@ static int Integrate(creal epsrel, creal epsabs,
StretchGrid(bounds->grid, boundsL->grid, boundsR->grid); StretchGrid(bounds->grid, boundsL->grid, boundsR->grid);
Sample(nnewL, regionL, wL, xL, fL, flags); Sample(t, nnewL, regionL, wL, xL, fL);
Sample(nnewR, regionR, wR, xR, fR, flags); Sample(t, nnewR, regionR, wR, xR, fR);
df += regionL->df + regionR->df - region->df; df += regionL->df + regionR->df - region->df;
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
cResult *r = &region->result[comp]; cResult *r = &region->result[comp];
Result *rL = &regionL->result[comp]; Result *rL = &regionL->result[comp];
Result *rR = &regionR->result[comp]; Result *rR = &regionR->result[comp];
@ -246,7 +249,7 @@ static int Integrate(creal epsrel, creal epsabs,
region = NULL; region = NULL;
} }
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
cResult *tot = &totals[comp]; cResult *tot = &totals[comp];
integral[comp] = tot->avg; integral[comp] = tot->avg;
error[comp] = tot->err; error[comp] = tot->err;
@ -256,22 +259,22 @@ static int Integrate(creal epsrel, creal epsabs,
#ifdef MLVERSION #ifdef MLVERSION
if( REGIONS ) { if( REGIONS ) {
MLPutFunction(stdlink, "List", 2); MLPutFunction(stdlink, "List", 2);
MLPutFunction(stdlink, "List", nregions_); MLPutFunction(stdlink, "List", t->nregions);
for( region = anchor; region; region = region->next ) { for( region = anchor; region; region = region->next ) {
real lower[NDIM], upper[NDIM]; real lower[NDIM], upper[NDIM];
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
cBounds *b = &region->bounds[dim]; cBounds *b = &region->bounds[dim];
lower[dim] = b->lower; lower[dim] = b->lower;
upper[dim] = b->upper; upper[dim] = b->upper;
} }
MLPutFunction(stdlink, "Cuba`Suave`region", 4); MLPutFunction(stdlink, "Cuba`Suave`region", 4);
MLPutRealList(stdlink, lower, ndim_); MLPutRealList(stdlink, lower, t->ndim);
MLPutRealList(stdlink, upper, ndim_); MLPutRealList(stdlink, upper, t->ndim);
MLPutFunction(stdlink, "List", ncomp_); MLPutFunction(stdlink, "List", t->ncomp);
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
cResult *r = &region->result[comp]; cResult *r = &region->result[comp];
real res[] = {r->avg, r->err, r->chisq}; real res[] = {r->avg, r->err, r->chisq};
MLPutRealList(stdlink, res, Elements(res)); MLPutRealList(stdlink, res, Elements(res));
@ -282,11 +285,8 @@ static int Integrate(creal epsrel, creal epsabs,
} }
#endif #endif
#ifdef MLVERSION
abort: abort:
#endif free(region);
if( region ) free(region);
while( (region = anchor) ) { while( (region = anchor) ) {
anchor = anchor->next; anchor = anchor->next;

View File

@ -2,11 +2,11 @@
Sample.c Sample.c
the sampling step of Suave the sampling step of Suave
this file is part of Suave this file is part of Suave
last modified 9 Feb 05 th last modified 13 Sep 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -25,6 +25,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
typedef struct { typedef struct {
real sum, sqsum; real sum, sqsum;
real weight, weightsum, avg, avgsum; real weight, weightsum, avg, avgsum;
@ -33,8 +34,8 @@ typedef struct {
/*********************************************************************/ /*********************************************************************/
static void Sample(cnumber nnew, void *voidregion, static void Sample(This *t, cnumber nnew, void *voidregion,
real *lastw, real *lastx, real *lastf, cint flags) real *lastw, real *lastx, real *lastf)
{ {
TYPEDEFREGION; TYPEDEFREGION;
@ -47,14 +48,14 @@ static void Sample(cnumber nnew, void *voidregion,
creal jacobian = 1/ldexp((real)nnew, region->div); creal jacobian = 1/ldexp((real)nnew, region->div);
real *w = lastw, *f = lastx; real *w = lastw, *f = lastx;
bin_t *bin = (bin_t *)(lastf + nnew*ncomp_); bin_t *bin = (bin_t *)(lastf + nnew*t->ncomp);
for( n = nnew; n; --n ) { for( n = nnew; n; --n ) {
real weight = jacobian; real weight = jacobian;
GetRandom(f); t->rng.getrandom(t, f);
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
cBounds *b = &region->bounds[dim]; cBounds *b = &region->bounds[dim];
creal pos = *f*NBINS; creal pos = *f*NBINS;
ccount ipos = (count)pos; ccount ipos = (count)pos;
@ -68,19 +69,19 @@ static void Sample(cnumber nnew, void *voidregion,
*w++ = weight; *w++ = weight;
} }
DoSample(nnew, lastw, lastx, lastf); DoSample(t, nnew, lastw, lastx, lastf, region->div + 1);
*(w - 1) = -*(w - 1); w[-1] = -w[-1];
lastw = w; lastw = w;
w = region->w; w = region->w;
region->n = lastw - w; region->n = lastw - w;
if( VERBOSE > 2 ) { if( VERBOSE > 2 ) {
char *p0; char *p0;
MemAlloc(ss, ndim_*64 + ncomp_*(sizeof(char *) + chars)); MemAlloc(ss, t->ndim*64 + t->ncomp*(sizeof(char *) + chars));
s = (char *)(ss + ncomp_); s = (char *)(ss + t->ncomp);
p0 = s + ndim_*64; p0 = s + t->ndim*64;
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
ss[comp] = p0; ss[comp] = p0;
p0 += chars; p0 += chars;
} }
@ -94,7 +95,7 @@ static void Sample(cnumber nnew, void *voidregion,
creal weight = fabs(*w++); creal weight = fabs(*w++);
++n; ++n;
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
Cumulants *c = &cumul[comp]; Cumulants *c = &cumul[comp];
creal wfun = weight*(*f++); creal wfun = weight*(*f++);
@ -134,7 +135,7 @@ static void Sample(cnumber nnew, void *voidregion,
region->df = --df; region->df = --df;
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
Result *r = &region->result[comp]; Result *r = &region->result[comp];
Cumulants *c = &cumul[comp]; Cumulants *c = &cumul[comp];
creal sigsq = 1/c->weightsum; creal sigsq = 1/c->weightsum;
@ -166,9 +167,9 @@ static void Sample(cnumber nnew, void *voidregion,
if( VERBOSE > 2 ) { if( VERBOSE > 2 ) {
char *p = s; char *p = s;
char *p0 = p + ndim_*64; char *p0 = p + t->ndim*64;
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
cBounds *b = &region->bounds[dim]; cBounds *b = &region->bounds[dim];
p += sprintf(p, p += sprintf(p,
(dim == 0) ? "\nRegion (" REALF ") - (" REALF ")" : (dim == 0) ? "\nRegion (" REALF ") - (" REALF ")" :
@ -176,7 +177,7 @@ static void Sample(cnumber nnew, void *voidregion,
b->lower, b->upper); b->lower, b->upper);
} }
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
cResult *r = &region->result[comp]; cResult *r = &region->result[comp];
p += sprintf(p, "%s \tchisq " REAL " (" COUNT " df)", p += sprintf(p, "%s \tchisq " REAL " (" COUNT " df)",
p0, r->chisq, df); p0, r->chisq, df);

View File

@ -2,11 +2,11 @@
Suave.c Suave.c
Subregion-adaptive Vegas Monte-Carlo integration Subregion-adaptive Vegas Monte-Carlo integration
by Thomas Hahn by Thomas Hahn
last modified 30 Aug 07 th last modified 13 Sep 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -25,21 +25,23 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
#include "util.c"
#include "decl.h"
#define Print(s) puts(s); fflush(stdout) #define Print(s) puts(s); fflush(stdout)
static Integrand integrand_;
/*********************************************************************/ /*********************************************************************/
static inline void DoSample(number n, creal *w, creal *x, real *f) static inline void DoSample(This *t, number n,
creal *w, creal *x, real *f, cint iter)
{ {
neval_ += n; t->neval += n;
while( n-- ) { while( n-- ) {
integrand_(&ndim_, x, &ncomp_, f, w++); if( t->integrand(&t->ndim, x, &t->ncomp, f, t->userdata,
x += ndim_; w++, &iter) == ABORT )
f += ncomp_; longjmp(t->abort, 1);
x += t->ndim;
f += t->ncomp;
} }
} }
@ -48,45 +50,64 @@ static inline void DoSample(number n, creal *w, creal *x, real *f)
#include "common.c" #include "common.c"
Extern void EXPORT(Suave)(ccount ndim, ccount ncomp, Extern void EXPORT(Suave)(ccount ndim, ccount ncomp,
Integrand integrand, Integrand integrand, void *userdata,
creal epsrel, creal epsabs, creal epsrel, creal epsabs,
cint flags, cnumber mineval, cnumber maxeval, cint flags, cint seed,
cnumber mineval, cnumber maxeval,
cnumber nnew, creal flatness, cnumber nnew, creal flatness,
count *pnregions, number *pneval, int *pfail, count *pnregions, number *pneval, int *pfail,
real *integral, real *error, real *prob) real *integral, real *error, real *prob)
{ {
ndim_ = ndim; This t;
ncomp_ = ncomp; t.ndim = ndim;
t.ncomp = ncomp;
t.integrand = integrand;
t.userdata = userdata;
t.epsrel = epsrel;
t.epsabs = epsabs;
t.flags = flags;
t.seed = seed;
t.mineval = mineval;
t.maxeval = maxeval;
t.nnew = nnew;
t.flatness = flatness;
t.nregions = 0;
t.neval = 0;
if( BadComponent(ncomp) || BadDimension(ndim, flags) ) *pfail = -1; *pfail = Integrate(&t, integral, error, prob);
else { *pnregions = t.nregions;
neval_ = 0; *pneval = t.neval;
integrand_ = integrand;
*pfail = Integrate(epsrel, Max(epsabs, NOTZERO),
flags, mineval, maxeval, nnew, flatness,
integral, error, prob);
*pnregions = nregions_;
*pneval = neval_;
}
} }
/*********************************************************************/ /*********************************************************************/
Extern void EXPORT(suave)(ccount *pndim, ccount *pncomp, Extern void EXPORT(suave)(ccount *pndim, ccount *pncomp,
Integrand integrand, Integrand integrand, void *userdata,
creal *pepsrel, creal *pepsabs, creal *pepsrel, creal *pepsabs,
cint *pflags, cnumber *pmineval, cnumber *pmaxeval, cint *pflags, cint *pseed,
cnumber *pmineval, cnumber *pmaxeval,
cnumber *pnnew, creal *pflatness, cnumber *pnnew, creal *pflatness,
count *pnregions, number *pneval, int *pfail, count *pnregions, number *pneval, int *pfail,
real *integral, real *error, real *prob) real *integral, real *error, real *prob)
{ {
EXPORT(Suave)(*pndim, *pncomp, This t;
integrand, t.ndim = *pndim;
*pepsrel, *pepsabs, t.ncomp = *pncomp;
*pflags, *pmineval, *pmaxeval, t.integrand = integrand;
*pnnew, *pflatness, t.userdata = userdata;
pnregions, pneval, pfail, t.epsrel = *pepsrel;
integral, error, prob); t.epsabs = *pepsabs;
t.flags = *pflags;
t.seed = *pseed;
t.mineval = *pmineval;
t.maxeval = *pmaxeval;
t.nnew = *pnnew;
t.flatness = *pflatness;
t.nregions = 0;
t.neval = 0;
*pfail = Integrate(&t, integral, error, prob);
*pnregions = t.nregions;
*pneval = t.neval;
} }

View File

@ -2,11 +2,11 @@
common.c common.c
includes most of the modules includes most of the modules
this file is part of Suave this file is part of Suave
last modified 14 Feb 05 th last modified 2 Jun 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -25,6 +25,25 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
#define RegionAlloc(p, n, nnew) MemAlloc(p, \
sizeof(Region) + \
(n)*(t->ndim + t->ncomp + 1)*sizeof(real) + \
(nnew)*t->ndim*sizeof(bin_t))
static inline bool BadDimension(cThis *t)
{
if( t->ndim > NDIM ) return true;
return t->ndim < SOBOL_MINDIM ||
(t->seed == 0 && t->ndim > SOBOL_MAXDIM);
}
static inline bool BadComponent(cThis *t)
{
if( t->ncomp > NCOMP ) return true;
return t->ncomp < 1;
}
#include "Random.c" #include "Random.c"
#include "ChiSquare.c" #include "ChiSquare.c"
#include "Grid.c" #include "Grid.c"
@ -32,21 +51,3 @@
#include "Fluct.c" #include "Fluct.c"
#include "Integrate.c" #include "Integrate.c"
static inline bool BadDimension(cint ndim, cint flags)
{
#if NDIM > 0
if( ndim > NDIM ) return true;
#endif
return ndim < SOBOL_MINDIM || (!PSEUDORNG && ndim > SOBOL_MAXDIM);
}
static inline bool BadComponent(cint ncomp)
{
#if NCOMP > 0
if( ncomp > NCOMP ) return true;
#endif
return ncomp < 1;
}

View File

@ -2,11 +2,11 @@
decl.h decl.h
Type declarations Type declarations
this file is part of Suave this file is part of Suave
last modified 30 Aug 07 th last modified 13 Sep 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -25,6 +25,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
#include "stddecl.h" #include "stddecl.h"
#define MINSAMPLES 10 #define MINSAMPLES 10
@ -46,7 +47,6 @@ typedef struct {
typedef const Result cResult; typedef const Result cResult;
typedef struct { typedef struct {
real lower, upper, mid; real lower, upper, mid;
Grid grid; Grid grid;
@ -54,6 +54,27 @@ typedef struct {
typedef const Bounds cBounds; typedef const Bounds cBounds;
typedef int (*Integrand)(ccount *, creal *, ccount *, real *,
void *, creal *, cint *);
typedef struct _this {
count ndim, ncomp;
#ifndef MLVERSION
Integrand integrand;
void *userdata;
#endif
real epsrel, epsabs;
int flags, seed;
number mineval, maxeval;
number nnew;
real flatness;
count nregions;
number neval;
RNGState rng;
jmp_buf abort;
} This;
typedef const This cThis;
#define TYPEDEFREGION \ #define TYPEDEFREGION \
typedef struct region { \ typedef struct region { \
@ -66,6 +87,3 @@ typedef const Bounds cBounds;
real w[]; \ real w[]; \
} Region } Region
typedef void (*Integrand)(ccount *, creal *, ccount *, real *, creal *);

View File

@ -2,11 +2,11 @@
Grid.c Grid.c
utility functions for the Vegas grid utility functions for the Vegas grid
this file is part of Vegas this file is part of Vegas
last modified 29 May 09 th last modified 28 May 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -25,18 +25,16 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
static inline void GetGrid(Grid *grid)
static inline void GetGrid(cThis *t, Grid *grid)
{ {
count bin, dim; count bin, dim;
unsigned const int slot = abs(EXPORT(vegasgridno)) - 1; unsigned const int slot = abs(t->gridno) - 1;
if( EXPORT(vegasgridno) < 0 ) { if( t->gridno < 0 && slot < MAXGRIDS ) griddim_[slot] = 0;
EXPORT(vegasgridno) = -EXPORT(vegasgridno);
if( slot < MAXGRIDS ) griddim_[slot] = 0;
}
if( slot < MAXGRIDS && gridptr_[slot] ) { if( slot < MAXGRIDS && gridptr_[slot] ) {
if( griddim_[slot] == ndim_ ) { if( griddim_[slot] == t->ndim ) {
VecCopy(grid, gridptr_[slot]); VecCopy(grid, gridptr_[slot]);
return; return;
} }
@ -46,26 +44,26 @@ static inline void GetGrid(Grid *grid)
for( bin = 0; bin < NBINS; ++bin ) for( bin = 0; bin < NBINS; ++bin )
grid[0][bin] = (bin + 1)/(real)NBINS; grid[0][bin] = (bin + 1)/(real)NBINS;
for( dim = 1; dim < ndim_; ++dim ) for( dim = 1; dim < t->ndim; ++dim )
Copy(&grid[dim], &grid[0], 1); Copy(&grid[dim], &grid[0], 1);
} }
/*********************************************************************/ /*********************************************************************/
static inline void PutGrid(Grid *grid) static inline void PutGrid(cThis *t, Grid *grid)
{ {
unsigned const int slot = EXPORT(vegasgridno) - 1; unsigned const int slot = abs(t->gridno) - 1;
if( slot < MAXGRIDS ) { if( slot < MAXGRIDS ) {
if( gridptr_[slot] == NULL ) Alloc(gridptr_[slot], ndim_); if( gridptr_[slot] == NULL ) Alloc(gridptr_[slot], t->ndim);
griddim_[slot] = ndim_; griddim_[slot] = t->ndim;
VecCopy(gridptr_[slot], grid); VecCopy(gridptr_[slot], grid);
} }
} }
/*********************************************************************/ /*********************************************************************/
static void RefineGrid(Grid grid, Grid margsum, cint flags) static void RefineGrid(cThis *t, Grid grid, Grid margsum)
{ {
real avgperbin, thisbin, newcur, delta; real avgperbin, thisbin, newcur, delta;
Grid imp, newgrid; Grid imp, newgrid;

View File

@ -2,11 +2,11 @@
Integrate.c Integrate.c
integrate over the unit hypercube integrate over the unit hypercube
this file is part of Vegas this file is part of Vegas
last modified 17 Dec 07 th last modified 13 Sep 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -25,14 +25,12 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
static int Integrate(creal epsrel, creal epsabs,
cint flags, cnumber mineval, cnumber maxeval, static int Integrate(This *t, real *integral, real *error, real *prob)
cnumber nstart, cnumber nincrease,
real *integral, real *error, real *prob)
{ {
real *sample; real *sample;
count dim, comp; count dim, comp;
int fail = 1; int fail = -99;
struct { struct {
count niter; count niter;
number nsamples, neval; number nsamples, neval;
@ -43,49 +41,55 @@ static int Integrate(creal epsrel, creal epsabs,
struct stat st; struct stat st;
if( VERBOSE > 1 ) { if( VERBOSE > 1 ) {
char s[256]; char s[512];
sprintf(s, "Vegas input parameters:\n" sprintf(s, "Vegas input parameters:\n"
" ndim " COUNT "\n ncomp " COUNT "\n" " ndim " COUNT "\n ncomp " COUNT "\n"
" epsrel " REAL "\n epsabs " REAL "\n" " epsrel " REAL "\n epsabs " REAL "\n"
" flags %d\n mineval " NUMBER "\n maxeval " NUMBER "\n" " flags %d\n seed %d\n"
" mineval " NUMBER "\n maxeval " NUMBER "\n"
" nstart " NUMBER "\n nincrease " NUMBER "\n" " nstart " NUMBER "\n nincrease " NUMBER "\n"
" vegasgridno %d\n vegasstate \"%s\"\n", " nbatch " NUMBER "\n gridno %d\n"
ndim_, ncomp_, " statefile \"%s\"\n",
epsrel, epsabs, t->ndim, t->ncomp,
flags, mineval, maxeval, t->epsrel, t->epsabs,
nstart, nincrease, t->flags, t->seed,
EXPORT(vegasgridno), EXPORT(vegasstate)); t->mineval, t->maxeval,
t->nstart, t->nincrease, t->nbatch,
t->gridno, t->statefile);
Print(s); Print(s);
} }
#ifdef MLVERSION if( BadComponent(t) ) return -2;
if( setjmp(abort_) ) goto abort; if( BadDimension(t) ) return -1;
#endif
IniRandom(2*maxeval, flags); SamplesAlloc(sample);
if( *EXPORT(vegasstate) && stat(EXPORT(vegasstate), &st) == 0 && if( setjmp(t->abort) ) goto abort;
st.st_size == sizeof(state) && (st.st_mode & 0400) ) {
cint h = open(EXPORT(vegasstate), O_RDONLY); IniRandom(t);
read(h, &state, sizeof(state));
if( t->statefile && *t->statefile &&
stat(t->statefile, &st) == 0 &&
st.st_size == sizeof state && (st.st_mode & 0400) ) {
cint h = open(t->statefile, O_RDONLY);
read(h, &state, sizeof state);
close(h); close(h);
SkipRandom(neval_ = state.neval); t->rng.skiprandom(t, t->neval = state.neval);
if( VERBOSE ) { if( VERBOSE ) {
char s[256]; char s[256];
sprintf(s, "\nRestoring state from %s.", EXPORT(vegasstate)); sprintf(s, "\nRestoring state from %s.", t->statefile);
Print(s); Print(s);
} }
} }
else { else {
t->statefile = NULL;
state.niter = 0; state.niter = 0;
state.nsamples = nstart; state.nsamples = t->nstart;
Zap(state.cumul); Zap(state.cumul);
GetGrid(state.grid); GetGrid(t, state.grid);
} }
SamplesAlloc(sample, EXPORT(vegasnbatch));
/* main iteration loop */ /* main iteration loop */
for( ; ; ) { for( ; ; ) {
@ -95,20 +99,20 @@ static int Integrate(creal epsrel, creal epsabs,
Zap(margsum); Zap(margsum);
for( ; nsamples > 0; nsamples -= EXPORT(vegasnbatch) ) { for( ; nsamples > 0; nsamples -= t->nbatch ) {
cnumber nbatch = IMin(EXPORT(vegasnbatch), nsamples); cnumber n = IMin(t->nbatch, nsamples);
real *w = sample; real *w = sample;
real *x = w + nbatch; real *x = w + n;
real *f = x + nbatch*ndim_; real *f = x + n*t->ndim;
real *lastf = f + nbatch*ncomp_; real *lastf = f + n*t->ncomp;
bin_t *bin = (bin_t *)lastf; bin_t *bin = (bin_t *)lastf;
while( x < f ) { while( x < f ) {
real weight = jacobian; real weight = jacobian;
GetRandom(x); t->rng.getrandom(t, x);
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
creal pos = *x*NBINS; creal pos = *x*NBINS;
ccount ipos = (count)pos; ccount ipos = (count)pos;
creal prev = (ipos == 0) ? 0 : state.grid[dim][ipos - 1]; creal prev = (ipos == 0) ? 0 : state.grid[dim][ipos - 1];
@ -121,7 +125,7 @@ static int Integrate(creal epsrel, creal epsabs,
*w++ = weight; *w++ = weight;
} }
DoSample(nbatch, sample, w, f); DoSample(t, n, sample, w, f, state.niter + 1);
w = sample; w = sample;
bin = (bin_t *)lastf; bin = (bin_t *)lastf;
@ -129,7 +133,7 @@ static int Integrate(creal epsrel, creal epsabs,
while( f < lastf ) { while( f < lastf ) {
creal weight = *w++; creal weight = *w++;
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
real wfun = weight*(*f++); real wfun = weight*(*f++);
if( wfun ) { if( wfun ) {
Cumulants *c = &state.cumul[comp]; Cumulants *c = &state.cumul[comp];
@ -137,12 +141,12 @@ static int Integrate(creal epsrel, creal epsabs,
c->sum += wfun; c->sum += wfun;
c->sqsum += wfun *= wfun; c->sqsum += wfun *= wfun;
for( dim = 0; dim < ndim_; ++dim ) for( dim = 0; dim < t->ndim; ++dim )
m[dim][bin[dim]] += wfun; m[dim][bin[dim]] += wfun;
} }
} }
bin += ndim_; bin += t->ndim;
} }
} }
@ -150,7 +154,7 @@ static int Integrate(creal epsrel, creal epsabs,
/* compute the integral and error values */ /* compute the integral and error values */
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
Cumulants *c = &state.cumul[comp]; Cumulants *c = &state.cumul[comp];
real avg, sigsq; real avg, sigsq;
real w = Weight(c->sum, c->sqsum, state.nsamples); real w = Weight(c->sum, c->sqsum, state.nsamples);
@ -177,9 +181,9 @@ static int Integrate(creal epsrel, creal epsabs,
p += sprintf(p, "\n" p += sprintf(p, "\n"
"Iteration " COUNT ": " NUMBER " integrand evaluations so far", "Iteration " COUNT ": " NUMBER " integrand evaluations so far",
state.niter + 1, neval_); state.niter + 1, t->neval);
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
cCumulants *c = &state.cumul[comp]; cCumulants *c = &state.cumul[comp];
p += sprintf(p, "\n[" COUNT "] " p += sprintf(p, "\n[" COUNT "] "
REAL " +- " REAL " \tchisq " REAL " (" COUNT " df)", REAL " +- " REAL " \tchisq " REAL " (" COUNT " df)",
@ -189,21 +193,21 @@ static int Integrate(creal epsrel, creal epsabs,
Print(s); Print(s);
} }
if( fail == 0 && neval_ >= mineval ) { if( fail == 0 && t->neval >= t->mineval ) {
if( *EXPORT(vegasstate) ) unlink(EXPORT(vegasstate)); if( t->statefile ) unlink(t->statefile);
break; break;
} }
if( neval_ >= maxeval && *EXPORT(vegasstate) == 0 ) break; if( t->neval >= t->maxeval && t->statefile == NULL ) break;
if( ncomp_ == 1 ) if( t->ncomp == 1 )
for( dim = 0; dim < ndim_; ++dim ) for( dim = 0; dim < t->ndim; ++dim )
RefineGrid(state.grid[dim], margsum[0][dim], flags); RefineGrid(t, state.grid[dim], margsum[0][dim]);
else { else {
for( dim = 0; dim < ndim_; ++dim ) { for( dim = 0; dim < t->ndim; ++dim ) {
Grid wmargsum; Grid wmargsum;
Zap(wmargsum); Zap(wmargsum);
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
real w = state.cumul[comp].avg; real w = state.cumul[comp].avg;
if( w != 0 ) { if( w != 0 ) {
creal *m = margsum[comp][dim]; creal *m = margsum[comp][dim];
@ -213,44 +217,41 @@ static int Integrate(creal epsrel, creal epsabs,
wmargsum[bin] += w*m[bin]; wmargsum[bin] += w*m[bin];
} }
} }
RefineGrid(state.grid[dim], wmargsum, flags); RefineGrid(t, state.grid[dim], wmargsum);
} }
} }
++state.niter; ++state.niter;
state.nsamples += nincrease; state.nsamples += t->nincrease;
if( *EXPORT(vegasstate) ) { if( t->statefile ) {
cint h = creat(EXPORT(vegasstate), 0666); cint h = creat(t->statefile, 0666);
if( h != -1 ) { if( h != -1 ) {
state.neval = neval_; state.neval = t->neval;
write(h, &state, sizeof(state)); write(h, &state, sizeof state);
close(h); close(h);
if( statemsg ) { if( statemsg ) {
char s[256]; char s[256];
sprintf(s, "\nSaving state to %s.", EXPORT(vegasstate)); sprintf(s, "\nSaving state to %s.", t->statefile);
Print(s); Print(s);
statemsg = false; statemsg = false;
} }
} }
if( neval_ >= maxeval ) break; if( t->neval >= t->maxeval ) break;
} }
} }
for( comp = 0; comp < ncomp_; ++comp ) { for( comp = 0; comp < t->ncomp; ++comp ) {
cCumulants *c = &state.cumul[comp]; cCumulants *c = &state.cumul[comp];
integral[comp] = c->avg; integral[comp] = c->avg;
error[comp] = c->err; error[comp] = c->err;
prob[comp] = ChiSquare(c->chisq, state.niter); prob[comp] = ChiSquare(c->chisq, state.niter);
} }
#ifdef MLVERSION
abort: abort:
#endif
free(sample); free(sample);
PutGrid(state.grid); PutGrid(t, state.grid);
return fail; return fail;
} }

View File

@ -2,11 +2,11 @@
Vegas.c Vegas.c
Vegas Monte-Carlo integration Vegas Monte-Carlo integration
by Thomas Hahn by Thomas Hahn
last modified 30 Aug 07 th last modified 13 Sep 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -25,21 +25,23 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
#include "util.c"
#include "decl.h"
#define Print(s) puts(s); fflush(stdout) #define Print(s) puts(s); fflush(stdout)
static Integrand integrand_;
/*********************************************************************/ /*********************************************************************/
static inline void DoSample(number n, creal *w, creal *x, real *f) static inline void DoSample(This *t, number n,
creal *w, creal *x, real *f, cint iter)
{ {
neval_ += n; t->neval += n;
while( n-- ) { while( n-- ) {
integrand_(&ndim_, x, &ncomp_, f, w++); if( t->integrand(&t->ndim, x, &t->ncomp, f, t->userdata,
x += ndim_; w++, &iter) == ABORT )
f += ncomp_; longjmp(t->abort, 1);
x += t->ndim;
f += t->ncomp;
} }
} }
@ -48,52 +50,79 @@ static inline void DoSample(number n, creal *w, creal *x, real *f)
#include "common.c" #include "common.c"
Extern void EXPORT(Vegas)(ccount ndim, ccount ncomp, Extern void EXPORT(Vegas)(ccount ndim, ccount ncomp,
Integrand integrand, Integrand integrand, void *userdata,
creal epsrel, creal epsabs, creal epsrel, creal epsabs, cint flags, cint seed,
cint flags, cnumber mineval, cnumber maxeval, cnumber mineval, cnumber maxeval,
cnumber nstart, cnumber nincrease, cnumber nstart, cnumber nincrease, cnumber nbatch,
cint gridno, cchar *statefile,
number *pneval, int *pfail, number *pneval, int *pfail,
real *integral, real *error, real *prob) real *integral, real *error, real *prob)
{ {
ndim_ = ndim; This t;
ncomp_ = ncomp; t.ndim = ndim;
t.ncomp = ncomp;
t.integrand = integrand;
t.userdata = userdata;
t.epsrel = epsrel;
t.epsabs = epsabs;
t.flags = flags;
t.seed = seed;
t.mineval = mineval;
t.maxeval = maxeval;
t.nstart = nstart;
t.nincrease = nincrease;
t.nbatch = nbatch;
t.gridno = gridno;
t.statefile = statefile;
t.neval = 0;
if( BadComponent(ncomp) || BadDimension(ndim, flags) ) *pfail = -1; *pfail = Integrate(&t, integral, error, prob);
else { *pneval = t.neval;
neval_ = 0;
integrand_ = integrand;
*pfail = Integrate(epsrel, epsabs,
flags, mineval, maxeval, nstart, nincrease,
integral, error, prob);
*pneval = neval_;
}
} }
/*********************************************************************/ /*********************************************************************/
Extern void EXPORT(vegas)(ccount *pndim, ccount *pncomp, Extern void EXPORT(vegas)(ccount *pndim, ccount *pncomp,
Integrand integrand, Integrand integrand, void *userdata,
creal *pepsrel, creal *pepsabs, creal *pepsrel, creal *pepsabs, cint *pflags, cint *pseed,
cint *pflags, cnumber *pmineval, cnumber *pmaxeval, cnumber *pmineval, cnumber *pmaxeval,
cnumber *pnstart, cnumber *pnincrease, cnumber *pnstart, cnumber *pnincrease,
cnumber *pnbatch, cint *pgridno, cchar *statefile,
number *pneval, int *pfail, number *pneval, int *pfail,
real *integral, real *error, real *prob) real *integral, real *error, real *prob, int statefilelen)
{ {
/* make sure the filename is null-terminated */ char *s = NULL;
if( *EXPORT(vegasstate) ) { This t;
char *p; t.ndim = *pndim;
EXPORT(vegasstate)[sizeof(EXPORT(vegasstate)) - 1] = 0; t.ncomp = *pncomp;
if( (p = strchr(EXPORT(vegasstate), ' ')) ) *p = 0; t.integrand = integrand;
} t.userdata = userdata;
t.epsrel = *pepsrel;
t.epsabs = *pepsabs;
t.flags = *pflags;
t.seed = *pseed;
t.mineval = *pmineval;
t.maxeval = *pmaxeval;
t.nstart = *pnstart;
t.nincrease = *pnincrease;
t.nbatch = *pnbatch;
t.gridno = *pgridno;
t.neval = 0;
EXPORT(Vegas)(*pndim, *pncomp, if( statefile ) {
integrand, /* strip trailing spaces */
*pepsrel, *pepsabs, while( statefilelen > 0 && statefile[statefilelen - 1] == ' ' )
*pflags, *pmineval, *pmaxeval, --statefilelen;
*pnstart, *pnincrease, if( statefilelen > 0 && (s = malloc(statefilelen + 1)) ) {
pneval, pfail, memcpy(s, statefile, statefilelen);
integral, error, prob); s[statefilelen] = 0;
}
}
t.statefile = s;
*pfail = Integrate(&t, integral, error, prob);
*pneval = t.neval;
free(s);
} }

View File

@ -1,12 +1,12 @@
/* /*
common.c common.c
include most of the modules Code common to Vegas.c and Vegas.tm
this file is part of Vegas this file is part of Vegas
last modified 14 Feb 05 th last modified 6 Jun 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -25,26 +25,27 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
#include "Random.c" #include "Random.c"
#include "ChiSquare.c" #include "ChiSquare.c"
#include "Grid.c" #include "Grid.c"
#define SamplesAlloc(p) MemAlloc(p, \
t->nbatch*((t->ndim + t->ncomp + 1)*sizeof(real) + \
t->ndim*sizeof(bin_t)))
static inline bool BadDimension(cThis *t)
{
if( t->ndim > NDIM ) return true;
return t->ndim < SOBOL_MINDIM ||
(t->seed == 0 && t->ndim > SOBOL_MAXDIM);
}
static inline bool BadComponent(cThis *t)
{
if( t->ncomp > NCOMP ) return true;
return t->ncomp < 1;
}
#include "Integrate.c" #include "Integrate.c"
static inline bool BadDimension(cint ndim, cint flags)
{
#if NDIM > 0
if( ndim > NDIM ) return true;
#endif
return ndim < SOBOL_MINDIM || (!PSEUDORNG && ndim > SOBOL_MAXDIM);
}
static inline bool BadComponent(cint ncomp)
{
#if NCOMP > 0
if( ncomp > NCOMP ) return true;
#endif
return ncomp < 1;
}

View File

@ -2,11 +2,11 @@
decl.h decl.h
Type declarations Type declarations
this file is part of Vegas this file is part of Vegas
last modified 30 Aug 07 th last modified 13 Sep 10 th
*/ */
/*************************************************************************** /***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn * * Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de * * hahn@feynarts.de *
* * * *
* This library is free software; you can redistribute it and/or * * This library is free software; you can redistribute it and/or *
@ -25,12 +25,11 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/ ***************************************************************************/
#include "stddecl.h" #include "stddecl.h"
#define MAXGRIDS 10 #define MAXGRIDS 10
#define MAXSTATESIZE 128
#define NBINS 128 #define NBINS 128
typedef unsigned char bin_t; typedef unsigned char bin_t;
@ -49,5 +48,28 @@ typedef struct {
typedef const Cumulants cCumulants; typedef const Cumulants cCumulants;
typedef void (*Integrand)(ccount *, creal *, ccount *, real *, creal *); typedef int (*Integrand)(ccount *, creal *, ccount *, real *,
void *, creal *, cint *);
typedef struct _this {
count ndim, ncomp;
#ifndef MLVERSION
Integrand integrand;
void *userdata;
#endif
real epsrel, epsabs;
int flags, seed;
number mineval, maxeval;
number nstart, nincrease, nbatch;
int gridno;
cchar *statefile;
number neval;
RNGState rng;
jmp_buf abort;
} This;
typedef const This cThis;
static Grid *gridptr_[MAXGRIDS];
static count griddim_[MAXGRIDS];