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 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)
UPDATED built-in cuba-library to version 2.1 in BMWlibs
musrfit 0.8.0 - changes since 0.7.0
===================================

View File

@ -1,18 +1,22 @@
#---------------------------------------------------------------------
# INSTALL
# Andreas Suter, 2009/06/21
# BMW, 2011/01/27
# $Id: INSTALL 4013 2009-06-21
#---------------------------------------------------------------------
To get it all build:
./autogen.sh
sh autogen.sh
./configure --prefix=/apps/cern/root (or whereever musrfit should be installed)
make
make install (as superuser -- maybe)
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 ...
#---------------------------------------------------------------------

17
NEWS
View File

@ -1,23 +1,10 @@
#---------------------------------------------------------------------
# NEWS
# Andreas Suter, 2010/06/15
# BMW, 2011/01/27
# $Id: NEWS 4013 2009-06-21
#---------------------------------------------------------------------
musrfit 0.6.0
+ 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
Please check the ChangeLog to see what is new!
#---------------------------------------------------------------------
# this is the end ...

4
README
View File

@ -1,6 +1,6 @@
#---------------------------------------------------------------------
# README
# Andreas Suter, 2010/06/20
# BMW, 2011/01/27
# $Id: README 4013 2009-06-21
#---------------------------------------------------------------------
@ -8,9 +8,11 @@ musrfit - muSR data analysis package
Installation instructions can be found in INSTALL and at
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
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 ...

View File

@ -52,36 +52,39 @@ PLUGIN_MINOR_VERSION=0
PLUGIN_MICRO_VERSION=0
#release versioning
CUBA_MAJOR_VERSION=1
CUBA_MINOR_VERSION=6
CUBA_MAJOR_VERSION=2
CUBA_MINOR_VERSION=1
CUBA_MICRO_VERSION=0
#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)
LEM_API_VERSION=LEM_MAJOR_VERSION.LEM_MINOR_VERSION
LEM_API_VERSION=$LEM_MAJOR_VERSION.$LEM_MINOR_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)
MUD_API_VERSION=MUD_MAJOR_VERSION.MUD_MINOR_VERSION
MUD_API_VERSION=$MUD_MAJOR_VERSION.$MUD_MINOR_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)
CUBA_API_VERSION=CUBA_MAJOR_VERSION.CUBA_MINOR_VERSION
CUBA_API_VERSION=$CUBA_MAJOR_VERSION.$CUBA_MINOR_VERSION
AC_SUBST(CUBA_API_VERSION)
#shared library versioning
CUBA_LIBRARY_VERSION=1:6:0
PLUGIN_LIBRARY_VERSION=1:0:0
LEM_LIBRARY_VERSION=1:5:0
PSIBIN_LIBRARY_VERSION=0:1:0
MUD_LIBRARY_VERSION=0:0:0
MUSR_LIBRARY_VERSION=0:8:0
CUBA_LIBRARY_VERSION=$CUBA_MAJOR_VERSION:$CUBA_MINOR_VERSION:$CUBA_MICRO_VERSION
PLUGIN_LIBRARY_VERSION=$PLUGIN_MAJOR_VERSION:$PLUGIN_MINOR_VERSION:$PLUGIN_MICRO_VERSION
LEM_LIBRARY_VERSION=$LEM_MAJOR_VERSION:$LEM_MINOR_VERSION:$LEM_MICRO_VERSION
PSIBIN_LIBRARY_VERSION=$PSIBIN_MAJOR_VERSION:$PSIBIN_MINOR_VERSION:$PSIBIN_MICRO_VERSION
MUD_LIBRARY_VERSION=$MUD_MAJOR_VERSION:$MUD_MINOR_VERSION:$MUD_MICRO_VERSION
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 "x$GCC" = "xyes" ; then
CUBA_BUILD_CFLAGS=${USER_CFLAGS:--O3 -fomit-frame-pointer -ffast-math}
else
CUBA_BUILD_CFLAGS=${USER_CFLAGS:--O}
fi
AS_IF([test "x$GCC" = "xyes"],
[case "$($CC --version 2>&1 < /dev/null)" in
gcc*4.2* | gcc*4.4.3*)
opt=-O0
;;
*)
opt=-O3
;;
esac
CUBA_BUILD_CFLAGS=${USER_CFLAGS:-$opt -fomit-frame-pointer -ffast-math}],
[CUBA_BUILD_CFLAGS=${USER_CFLAGS:--O}])
AC_LANG_PUSH([C])

View File

@ -29,9 +29,12 @@
* 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;
@ -50,7 +53,7 @@ double TDWaveGapIntegralCuhre::IntegrateFunc()
int nregions, neval, fail;
double integral[NCOMP], error[NCOMP], prob[NCOMP];
Cuhre(fNDim, NCOMP, Integrand,
Cuhre(fNDim, NCOMP, Integrand, USERDATA,
EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL,
KEY,
&nregions, &neval, &fail, integral, error, prob);
@ -58,12 +61,12 @@ double TDWaveGapIntegralCuhre::IntegrateFunc()
return integral[0];
}
void TDWaveGapIntegralCuhre::Integrand(const int *ndim, const double x[],
const int *ncomp, double f[]) // x = {E, phi}, fPar = {twokBT, Delta(T), Ec, phic}
int TDWaveGapIntegralCuhre::Integrand(const int *ndim, const double x[],
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));
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;
@ -83,7 +86,7 @@ double TCosSqDWaveGapIntegralCuhre::IntegrateFunc()
int nregions, neval, fail;
double integral[NCOMP], error[NCOMP], prob[NCOMP];
Cuhre(fNDim, NCOMP, Integrand,
Cuhre(fNDim, NCOMP, Integrand, USERDATA,
EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL,
KEY,
&nregions, &neval, &fail, integral, error, prob);
@ -91,12 +94,12 @@ double TCosSqDWaveGapIntegralCuhre::IntegrateFunc()
return integral[0];
}
void TCosSqDWaveGapIntegralCuhre::Integrand(const int *ndim, const double x[],
const int *ncomp, double f[]) // x = {E, phi}, fPar = {twokBT, DeltaD(T), Ec, phic, DeltaS(T)}
int TCosSqDWaveGapIntegralCuhre::Integrand(const int *ndim, const double x[],
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));
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;
@ -116,7 +119,7 @@ double TSinSqDWaveGapIntegralCuhre::IntegrateFunc()
int nregions, neval, fail;
double integral[NCOMP], error[NCOMP], prob[NCOMP];
Cuhre(fNDim, NCOMP, Integrand,
Cuhre(fNDim, NCOMP, Integrand, USERDATA,
EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL,
KEY,
&nregions, &neval, &fail, integral, error, prob);
@ -124,12 +127,12 @@ double TSinSqDWaveGapIntegralCuhre::IntegrateFunc()
return integral[0];
}
void TSinSqDWaveGapIntegralCuhre::Integrand(const int *ndim, const double x[],
const int *ncomp, double f[]) // x = {E, phi}, fPar = {twokBT, DeltaD(T), Ec, phic, DeltaS(T)}
int TSinSqDWaveGapIntegralCuhre::Integrand(const int *ndim, const double x[],
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));
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;
double integral[NCOMP], error[NCOMP], prob[NCOMP];
Cuhre(fNDim, NCOMP, Integrand,
Cuhre(fNDim, NCOMP, Integrand, USERDATA,
EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL,
KEY,
&nregions, &neval, &fail, integral, error, prob);
@ -158,12 +161,12 @@ double TAnSWaveGapIntegralCuhre::IntegrateFunc()
return integral[0];
}
void TAnSWaveGapIntegralCuhre::Integrand(const int *ndim, const double x[],
const int *ncomp, double f[]) // x = {E, phi}, fPar = {twokBT, Delta(T),a, Ec, phic}
int TAnSWaveGapIntegralCuhre::Integrand(const int *ndim, const double x[],
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));
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;
@ -190,8 +193,8 @@ double TAnSWaveGapIntegralDivonne::IntegrateFunc()
int nregions, neval, fail;
double integral[NCOMP], error[NCOMP], prob[NCOMP];
Divonne(fNDim, NCOMP, Integrand,
EPSREL, EPSABS, VERBOSE, MINEVAL, MAXEVAL,
Divonne(fNDim, NCOMP, Integrand, USERDATA,
EPSREL, EPSABS, VERBOSE, SEED, MINEVAL, MAXEVAL,
KEY1, KEY2, KEY3, MAXPASS, BORDER, MAXCHISQ, MINDEVIATION,
NGIVEN, LDXGIVEN, NULL, NEXTRA, NULL,
&nregions, &neval, &fail, integral, error, prob);
@ -199,12 +202,12 @@ double TAnSWaveGapIntegralDivonne::IntegrateFunc()
return integral[0];
}
void TAnSWaveGapIntegralDivonne::Integrand(const int *ndim, const double x[],
const int *ncomp, double f[]) // x = {E, phi}, fPar = {twokBT, Delta(T),a, Ec, phic}
int TAnSWaveGapIntegralDivonne::Integrand(const int *ndim, const double x[],
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));
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;
@ -225,20 +228,20 @@ double TAnSWaveGapIntegralSuave::IntegrateFunc()
int nregions, neval, fail;
double integral[NCOMP], error[NCOMP], prob[NCOMP];
Suave(fNDim, NCOMP, Integrand,
EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL,
Suave(fNDim, NCOMP, Integrand, USERDATA,
EPSREL, EPSABS, VERBOSE | LAST, SEED, MINEVAL, MAXEVAL,
NNEW, FLATNESS,
&nregions, &neval, &fail, integral, error, prob);
return integral[0];
}
void TAnSWaveGapIntegralSuave::Integrand(const int *ndim, const double x[],
const int *ncomp, double f[]) // x = {E, phi}, fPar = {twokBT, Delta(T),a, Ec, phic}
int TAnSWaveGapIntegralSuave::Integrand(const int *ndim, const double x[],
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));
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;
@ -258,7 +261,7 @@ double TNonMonDWave1GapIntegralCuhre::IntegrateFunc()
int nregions, neval, fail;
double integral[NCOMP], error[NCOMP], prob[NCOMP];
Cuhre(fNDim, NCOMP, Integrand,
Cuhre(fNDim, NCOMP, Integrand, USERDATA,
EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL,
KEY,
&nregions, &neval, &fail, integral, error, prob);
@ -266,12 +269,12 @@ double TNonMonDWave1GapIntegralCuhre::IntegrateFunc()
return integral[0];
}
void TNonMonDWave1GapIntegralCuhre::Integrand(const int *ndim, const double x[],
const int *ncomp, double f[]) // x = {E, phi}, fPar = {twokBT, Delta(T),a, Ec, phic}
int TNonMonDWave1GapIntegralCuhre::Integrand(const int *ndim, const double x[],
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));
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;
@ -291,7 +294,7 @@ double TNonMonDWave2GapIntegralCuhre::IntegrateFunc()
int nregions, neval, fail;
double integral[NCOMP], error[NCOMP], prob[NCOMP];
Cuhre(fNDim, NCOMP, Integrand,
Cuhre(fNDim, NCOMP, Integrand, USERDATA,
EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL,
KEY,
&nregions, &neval, &fail, integral, error, prob);
@ -299,11 +302,11 @@ double TNonMonDWave2GapIntegralCuhre::IntegrateFunc()
return integral[0];
}
void TNonMonDWave2GapIntegralCuhre::Integrand(const int *ndim, const double x[],
const int *ncomp, double f[]) // x = {E, phi}, fPar = {twokBT, Delta(T),a, Ec, phic}
int TNonMonDWave2GapIntegralCuhre::Integrand(const int *ndim, const double x[],
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) \
/ 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);
return;
return 0;
}

View File

@ -128,7 +128,7 @@ class TDWaveGapIntegralCuhre {
TDWaveGapIntegralCuhre() : fNDim(2) {}
~TDWaveGapIntegralCuhre() { fPar.clear(); }
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();
protected:
@ -142,7 +142,7 @@ class TCosSqDWaveGapIntegralCuhre {
TCosSqDWaveGapIntegralCuhre() : fNDim(2) {}
~TCosSqDWaveGapIntegralCuhre() { fPar.clear(); }
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();
protected:
@ -156,7 +156,7 @@ class TSinSqDWaveGapIntegralCuhre {
TSinSqDWaveGapIntegralCuhre() : fNDim(2) {}
~TSinSqDWaveGapIntegralCuhre() { fPar.clear(); }
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();
protected:
@ -170,7 +170,7 @@ class TAnSWaveGapIntegralCuhre {
TAnSWaveGapIntegralCuhre() : fNDim(2) {}
~TAnSWaveGapIntegralCuhre() { fPar.clear(); }
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();
protected:
@ -184,7 +184,7 @@ class TAnSWaveGapIntegralDivonne {
TAnSWaveGapIntegralDivonne() : fNDim(2) {}
~TAnSWaveGapIntegralDivonne() { fPar.clear(); }
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();
protected:
@ -198,7 +198,7 @@ class TAnSWaveGapIntegralSuave {
TAnSWaveGapIntegralSuave() : fNDim(2) {}
~TAnSWaveGapIntegralSuave() { fPar.clear(); }
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();
protected:
@ -212,7 +212,7 @@ class TNonMonDWave1GapIntegralCuhre {
TNonMonDWave1GapIntegralCuhre() : fNDim(2) {}
~TNonMonDWave1GapIntegralCuhre() { fPar.clear(); }
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();
protected:
@ -226,7 +226,7 @@ class TNonMonDWave2GapIntegralCuhre {
TNonMonDWave2GapIntegralCuhre() : fNDim(2) {}
~TNonMonDWave2GapIntegralCuhre() { fPar.clear(); }
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();
protected:

View File

@ -1,7 +1,7 @@
#---------------------------------------------------------------------
# README
# Bastian M. Wojek, 2010/01/05
# $Id:
# Bastian M. Wojek, 2011/01/27
# $Id$
#---------------------------------------------------------------------
This directory contains a subset of the code
@ -19,4 +19,4 @@ http://www.feynarts.de/cuba
#---------------------------------------------------------------------
# this is the end ...
#---------------------------------------------------------------------
#---------------------------------------------------------------------

View File

@ -13,7 +13,7 @@ INCLUDES = -I. -Icommon
AM_CFLAGS = $(LOCAL_CUBA_LIB_CFLAGS)
AM_LDFLAGS = $(LOCAL_LIB_LDFLAGS)
CLEANFILES = *~ core
CLEANFILES = common/*~ cuhre/*~ divonne/*~ suave/*~ vegas/*~ *~ core
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 *
* *
* 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 *
* *
* 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 *
***************************************************************************/
static real Erfc(creal x)
{
static creal c[] = {

View File

@ -1,11 +1,11 @@
/*
Random.c
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 *
* *
* 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 *
***************************************************************************/
/*
PART 1: Sobol quasi-random-number generator
adapted from ACM TOMS algorithm 659
*/
#define SOBOL_MINDIM 1
#define SOBOL_MAXDIM 40
static void SobolGet(This *t, real *x)
{
number seq = t->rng.sobol.seq++;
count zerobit = 0, dim;
static struct {
real norm;
number v[SOBOL_MAXDIM][30], prev[SOBOL_MAXDIM];
number seq;
} sobol_;
while( seq & 1 ) {
++zerobit;
seq >>= 1;
}
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] = {
3, 1, 0, 0, 0, 0, 0, 0, 0,
@ -84,15 +109,16 @@ static inline void SobolIni(cnumber n)
count dim, bit, nbits;
number max, *pini = ini;
cnumber nmax = 2*t->maxeval;
for( nbits = 0, max = 1; max <= n; max <<= 1 ) ++nbits;
sobol_.norm = 1./max;
for( nbits = 0, max = 1; max <= nmax; max <<= 1 ) ++nbits;
t->rng.sobol.norm = 1./max;
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 ) {
number *pv = sobol_.v[dim], *pvv = pv;
for( dim = 1; dim < t->ndim; ++dim ) {
number *pv = t->rng.sobol.v[dim], *pvv = pv;
number powers = *pini++, j;
int inibits = -1, bit;
for( j = powers; j; j >>= 1 ) ++inibits;
@ -115,42 +141,11 @@ static inline void SobolIni(cnumber n)
pv[bit] <<= nbits - bit - 1;
}
sobol_.seq = 0;
VecClear(sobol_.prev);
}
t->rng.sobol.seq = 0;
VecClear(t->rng.sobol.prev);
static inline void SobolGet(real *x)
{
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];
}
t->rng.getrandom = SobolGet;
t->rng.skiprandom = SobolSkip;
}
@ -160,24 +155,9 @@ static inline void SobolSkip(number n)
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 */
#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)
{
@ -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;
for( j = MERSENNE_N - MERSENNE_M + 1; --j; ++s )
*s = s[MERSENNE_M] ^ Twist(s[0], s[1]);
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], 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 << 7) & 0x9d2c5680;
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
state_t a, b;
#endif
if( next >= MERSENNE_N ) {
MersenneReload();
MersenneReload(t->rng.mersenne.state);
next = 0;
}
#if RANDOM_BITS == 53
a = MersenneInt(next++) >> 5;
b = MersenneInt(next++) >> 6;
a = MersenneInt(t->rng.mersenne.state[next++]) >> 5;
b = MersenneInt(t->rng.mersenne.state[next++]) >> 6;
x[dim] = (67108864.*a + b)/9007199254740992.;
#else
x[dim] = MersenneInt(next++)/4294967296.;
x[dim] = MersenneInt(t->rng.mersenne.state[next++])/4294967296.;
#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
n = 2*n*ndim_ + mersenne_.next;
n = 2*n*t->ndim + t->rng.mersenne.next;
#else
n = n*ndim_ + mersenne_.next;
n = n*t->ndim + t->rng.mersenne.next;
#endif
mersenne_.next = n % MERSENNE_N;
t->rng.mersenne.next = 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
sequence of at least n ndim_-dimensional random vectors.
sequence of at least n ndim-dimensional random vectors.
- GetRandom retrieves one random vector.
- SkipRandom skips over n random vectors.
*/
static void IniRandom(cnumber n, cint flags)
static inline void IniRandom(This *t)
{
if( PSEUDORNG ) {
sobol_.seq = -1;
MersenneIni();
}
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);
if( t->seed == 0 ) SobolIni(t);
else if( RNG == 0 ) MersenneIni(t);
else RanluxIni(t);
}

View File

@ -1,11 +1,11 @@
/*
stddecl.h
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 *
* *
* 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 *
***************************************************************************/
#ifndef __stddecl_h__
#define __stddecl_h__
@ -39,45 +40,47 @@
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <setjmp.h>
#include <sys/stat.h>
#ifndef NDIM
#define NDIM ndim_
#define NDIM t->ndim
#endif
#ifndef NCOMP
#define NCOMP ncomp_
#define NCOMP t->ncomp
#endif
#define VERBOSE (flags & 3)
#define LAST (flags & 4)
#define PSEUDORNG (flags & 8)
#define SHARPEDGES (flags & 16)
#define REGIONS (flags & 256)
#define VERBOSE (t->flags & 3)
#define LAST (t->flags & 4)
#define SHARPEDGES (t->flags & 8)
#define REGIONS (t->flags & 128)
#define RNG (t->flags >> 8)
#define INFTY DBL_MAX
#define NOTZERO 0x1p-104
#define ABORT -999
#define Elements(x) (sizeof(x)/sizeof(*x))
#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 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 MaxErr(avg) Max(epsrel*fabs(avg), epsabs)
#define MaxErr(avg) Max(t->epsrel*fabs(avg), t->epsabs)
#ifdef __cplusplus
#define mallocset(p, n) (*(void **)&p = malloc(n))
@ -104,6 +107,8 @@
typedef enum { false, true } bool;
#endif
typedef const char cchar;
typedef const bool cbool;
typedef const int cint;
@ -140,6 +145,40 @@ typedef /*long*/ double real;
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
#define SUFFIX(s) s##_
#else
@ -175,6 +214,9 @@ static inline real Weight(creal sum, creal sqsum, cnumber n)
/* (a < 0) ? -1 : 0 */
#define NegQ(a) ((a) >> (sizeof(a)*8 - 1))
/* (a < 0) ? -1 : 1 */
#define Sign(a) (1 + 2*NegQ(a))
/* (a < 0) ? 0 : a */
#define IDim(a) ((a) & NegQ(-(a)))

View File

@ -2,11 +2,11 @@
cuba.h
Prototypes for the Cuba library
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 *
* *
* This library is free software; you can redistribute it and/or *
@ -29,59 +29,74 @@
extern "C" {
#endif
typedef void (*integrand_t)(const int *, const double [],
const int *, double []);
/* NB: Divonne actually passes a fifth argument, a const int *
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 *
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 void (*peakfinder_t)(const int *ndim, const double b[],
int *n, double x[]);
void Vegas(const int ndim, const int ncomp, integrand_t integrand,
void Vegas(const int ndim, const int ncomp,
integrand_t integrand, void *userdata,
const double epsrel, const double epsabs,
const int flags, const int mineval, const int maxeval,
const int nstart, const int nincrease,
const int flags, const int seed,
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,
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 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 nbatch,
const int gridno, const char *statefile,
long long int *neval, int *fail,
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 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,
int *nregions, int *neval, int *fail,
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 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,
int *nregions, long long int *neval, int *fail,
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 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 double border, const double maxchisq, const double mindeviation,
const int ngiven, const int ldxgiven, double xgiven[],
const int nextra,
void (*peakfinder)(const int *, const double [], int *, double []),
const int nextra, peakfinder_t peakfinder,
int *nregions, int *neval, int *fail,
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 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 double border, const double maxchisq, const double mindeviation,
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,
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 int flags, const int mineval, const int maxeval,
const int key,
int *nregions, int *neval, int *fail,
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 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,
int *nregions, long long int *neval, int *fail,
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
}
#endif

View File

@ -2,11 +2,11 @@
Cuhre.c
Adaptive integration using cubature rules
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 *
* *
* 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 *
***************************************************************************/
#include "util.c"
#include "decl.h"
#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-- ) {
integrand_(&ndim_, x, &ncomp_, f);
x += ndim_;
f += ncomp_;
if( t->integrand(&t->ndim, x, &t->ncomp, f, t->userdata) == ABORT )
longjmp(t->abort, 1);
x += t->ndim;
f += t->ncomp;
}
}
@ -48,44 +48,58 @@ static inline void DoSample(count n, creal *x, real *f)
#include "common.c"
Extern void EXPORT(Cuhre)(ccount ndim, ccount ncomp,
Integrand integrand,
Integrand integrand, void *userdata,
creal epsrel, creal epsabs,
cint flags, cnumber mineval, cnumber maxeval,
ccount key,
count *pnregions, number *pneval, int *pfail,
real *integral, real *error, real *prob)
{
ndim_ = ndim;
ncomp_ = ncomp;
if( BadComponent(ncomp) || BadDimension(ndim) ) *pfail = -1;
else {
neval_ = 0;
integrand_ = integrand;
*pfail = Integrate(epsrel, Max(epsabs, NOTZERO),
flags, mineval, maxeval, key,
integral, error, prob);
*pnregions = nregions_;
*pneval = neval_;
}
This t;
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;
*pfail = Integrate(&t, integral, error, prob);
*pnregions = t.nregions;
*pneval = t.neval;
}
/*********************************************************************/
Extern void EXPORT(cuhre)(ccount *pndim, ccount *pncomp,
Integrand integrand,
Integrand integrand, void *userdata,
creal *pepsrel, creal *pepsabs,
cint *pflags, cnumber *pmineval, cnumber *pmaxeval,
ccount *pkey,
count *pnregions, number *pneval, int *pfail,
real *integral, real *error, real *prob)
{
EXPORT(Cuhre)(*pndim, *pncomp, integrand,
*pepsrel, *pepsabs,
*pflags, *pmineval, *pmaxeval,
*pkey,
pnregions, pneval, pfail,
integral, error, prob);
This t;
t.ndim = *pndim;
t.ncomp = *pncomp;
t.integrand = integrand;
t.userdata = userdata;
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 over the unit hypercube
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 *
* *
* 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 *
***************************************************************************/
#define POOLSIZE 1024
static int Integrate(creal epsrel, creal epsabs,
cint flags, number mineval, cnumber maxeval, ccount key,
real *integral, real *error, real *prob)
static int Integrate(This *t, real *integral, real *error, real *prob)
{
TYPEDEFREGION;
typedef struct pool {
@ -37,9 +36,8 @@ static int Integrate(creal epsrel, creal epsabs,
Region region[POOLSIZE];
} Pool;
count dim, comp, ncur, nregions, ipool, npool;
int fail = 1;
Rule rule;
count dim, comp, ncur, ipool, npool;
int fail = -99;
Totals totals[NCOMP];
Pool *cur = NULL, *pool;
Region *region;
@ -51,31 +49,21 @@ static int Integrate(creal epsrel, creal epsabs,
" epsrel " REAL "\n epsabs " REAL "\n"
" flags %d\n mineval " NUMBER "\n maxeval " NUMBER "\n"
" key " COUNT,
ndim_, ncomp_,
epsrel, epsabs,
flags, mineval, maxeval,
key);
t->ndim, t->ncomp,
t->epsrel, t->epsabs,
t->flags, t->mineval, t->maxeval,
t->key);
Print(s);
}
#ifdef MLVERSION
if( setjmp(abort_) ) goto abort;
#endif
if( BadComponent(t) ) return -2;
if( BadDimension(t) ) return -1;
if( key == 13 && ndim_ == 2 ) Rule13Alloc(&rule);
else if( key == 11 && ndim_ == 3 ) Rule11Alloc(&rule);
else if( key == 9 ) Rule9Alloc(&rule);
else if( key == 7 ) Rule7Alloc(&rule);
else {
if( ndim_ == 2 ) Rule13Alloc(&rule);
else if( ndim_ == 3 ) Rule11Alloc(&rule);
else Rule9Alloc(&rule);
}
RuleAlloc(t);
t->epsabs = Max(t->epsabs, NOTZERO);
t->mineval = IMax(t->mineval, t->rule.n + 1);
Alloc(rule.x, rule.n*(ndim_ + ncomp_));
rule.f = rule.x + rule.n*ndim_;
mineval = IMax(mineval, rule.n + 1);
if( setjmp(t->abort) ) goto abort;
Alloc(cur, 1);
cur->next = NULL;
@ -83,15 +71,15 @@ static int Integrate(creal epsrel, creal epsabs,
region = cur->region;
region->div = 0;
for( dim = 0; dim < ndim_; ++dim ) {
for( dim = 0; dim < t->ndim; ++dim ) {
Bounds *b = &region->bounds[dim];
b->lower = 0;
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];
Result *r = &region->result[comp];
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;
}
for( nregions = 1; ; ++nregions ) {
for( t->nregions = 1; ; ++t->nregions ) {
count maxcomp, bisectdim;
real maxratio, maxerr;
Result result[NCOMP];
@ -113,13 +101,13 @@ static int Integrate(creal epsrel, creal epsabs,
p += sprintf(p, "\n"
"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];
p += sprintf(p, "\n[" COUNT "] "
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);
@ -127,7 +115,7 @@ static int Integrate(creal epsrel, creal epsabs,
maxratio = -INFTY;
maxcomp = 0;
for( comp = 0; comp < ncomp_; ++comp ) {
for( comp = 0; comp < t->ncomp; ++comp ) {
creal ratio = totals[comp].err/MaxErr(totals[comp].avg);
if( ratio > maxratio ) {
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;
break;
}
if( neval_ >= maxeval ) break;
if( t->neval >= t->maxeval ) break;
maxerr = -INFTY;
regionL = cur->region;
@ -172,10 +160,10 @@ static int Integrate(creal epsrel, creal epsabs,
bR = &regionR->bounds[bisectdim];
bL->upper = bR->lower = .5*(bL->upper + bL->lower);
Sample(&rule, regionL, flags);
Sample(&rule, regionR, flags);
Sample(t, regionL);
Sample(t, regionR);
for( comp = 0; comp < ncomp_; ++comp ) {
for( comp = 0; comp < t->ncomp; ++comp ) {
cResult *r = &result[comp];
Result *rL = &regionL->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];
integral[comp] = tot->avg;
error[comp] = tot->err;
prob[comp] = ChiSquare(tot->chisq, nregions - 1);
prob[comp] = ChiSquare(tot->chisq, t->nregions - 1);
}
#ifdef MLVERSION
if( REGIONS ) {
MLPutFunction(stdlink, "List", 2);
MLPutFunction(stdlink, "List", nregions);
MLPutFunction(stdlink, "List", t->nregions);
npool = ncur;
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];
real lower[NDIM], upper[NDIM];
for( dim = 0; dim < ndim_; ++dim ) {
for( dim = 0; dim < t->ndim; ++dim ) {
cBounds *b = &region->bounds[dim];
lower[dim] = b->lower;
upper[dim] = b->upper;
}
MLPutFunction(stdlink, "Cuba`Cuhre`region", 3);
MLPutRealList(stdlink, lower, ndim_);
MLPutRealList(stdlink, upper, ndim_);
MLPutRealList(stdlink, lower, t->ndim);
MLPutRealList(stdlink, upper, t->ndim);
MLPutFunction(stdlink, "List", ncomp_);
for( comp = 0; comp < ncomp_; ++comp ) {
MLPutFunction(stdlink, "List", t->ncomp);
for( comp = 0; comp < t->ncomp; ++comp ) {
cResult *r = &region->result[comp];
real res[] = {r->avg, r->err};
MLPutRealList(stdlink, res, Elements(res));
@ -252,19 +240,13 @@ static int Integrate(creal epsrel, creal epsabs,
}
#endif
#ifdef MLVERSION
abort:
#endif
while( (pool = cur) ) {
cur = cur->next;
free(pool);
}
free(rule.x);
RuleFree(&rule);
nregions_ = nregions;
RuleFree(t);
return fail;
}

View File

@ -4,11 +4,11 @@
code lifted with minor modifications from DCUHRE
by J. Berntsen, T. Espelid, and A. Genz
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 *
* *
* This library is free software; you can redistribute it and/or *
@ -38,14 +38,7 @@ enum { nrules = 5 };
/*********************************************************************/
static inline void RuleFree(Rule *rule)
{
free(rule->first);
}
/*********************************************************************/
static void Rule13Alloc(Rule *rule)
static void Rule13Alloc(This *t)
{
static creal w[][nrules] = {
{ .00844923090033615, .3213775489050763, .3372900883288987,
@ -93,7 +86,7 @@ static void Rule13Alloc(Rule *rule)
TYPEDEFSET;
count n, r;
Set *first, *last, *s, *t;
Set *first, *last, *s, *x;
Alloc(first, nsets);
Clear(first, nsets);
@ -175,20 +168,20 @@ static void Rule13Alloc(Rule *rule)
last->gen[0] = g[14];
last->gen[1] = g[15];
rule->first = first;
rule->last = last;
rule->errcoeff[0] = 10;
rule->errcoeff[1] = 1;
rule->errcoeff[2] = 5;
rule->n = n;
t->rule.first = first;
t->rule.last = last;
t->rule.errcoeff[0] = 10;
t->rule.errcoeff[1] = 1;
t->rule.errcoeff[2] = 5;
t->rule.n = n;
for( s = first; s <= last; ++s )
for( r = 1; r < nrules - 1; ++r ) {
creal scale = (s->weight[r] == 0) ? 100 :
-s->weight[r + 1]/s->weight[r];
real sum = 0;
for( t = first; t <= last; ++t )
sum += t->n*fabs(t->weight[r + 1] + scale*t->weight[r]);
for( x = first; x <= last; ++x )
sum += x->n*fabs(x->weight[r + 1] + scale*x->weight[r]);
s->scale[r] = scale;
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] = {
{ .0009903847688882167, 1.715006248224684, 1.936014978949526,
@ -241,7 +234,7 @@ static void Rule11Alloc(Rule *rule)
TYPEDEFSET;
count n, r;
Set *first, *last, *s, *t;
Set *first, *last, *s, *x;
Alloc(first, nsets);
Clear(first, nsets);
@ -322,20 +315,20 @@ static void Rule11Alloc(Rule *rule)
last->gen[1] = g[12];
last->gen[2] = g[13];
rule->first = first;
rule->last = last;
rule->errcoeff[0] = 4;
rule->errcoeff[1] = .5;
rule->errcoeff[2] = 3;
rule->n = n;
t->rule.first = first;
t->rule.last = last;
t->rule.errcoeff[0] = 4;
t->rule.errcoeff[1] = .5;
t->rule.errcoeff[2] = 3;
t->rule.n = n;
for( s = first; s <= last; ++s )
for( r = 1; r < nrules - 1; ++r ) {
creal scale = (s->weight[r] == 0) ? 100 :
-s->weight[r + 1]/s->weight[r];
real sum = 0;
for( t = first; t <= last; ++t )
sum += t->n*fabs(t->weight[r + 1] + scale*t->weight[r]);
for( x = first; x <= last; ++x )
sum += x->n*fabs(x->weight[r + 1] + scale*x->weight[r]);
s->scale[r] = scale;
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[] = {
-.0023611709677855117884, .11415390023857325268,
@ -377,10 +370,10 @@ static void Rule9Alloc(Rule *rule)
TYPEDEFSET;
ccount ndim = ndim_;
ccount ndim = t->ndim;
ccount twondim = 1 << ndim;
count dim, n, r;
Set *first, *last, *s, *t;
Set *first, *last, *s, *x;
Alloc(first, nsets);
Clear(first, nsets);
@ -466,20 +459,20 @@ static void Rule9Alloc(Rule *rule)
for( dim = 0; dim < ndim; ++dim )
last->gen[dim] = g[4];
rule->first = first;
rule->last = last;
rule->errcoeff[0] = 5;
rule->errcoeff[1] = 1;
rule->errcoeff[2] = 5;
rule->n = n;
t->rule.first = first;
t->rule.last = last;
t->rule.errcoeff[0] = 5;
t->rule.errcoeff[1] = 1;
t->rule.errcoeff[2] = 5;
t->rule.n = n;
for( s = first; s <= last; ++s )
for( r = 1; r < nrules - 1; ++r ) {
creal scale = (s->weight[r] == 0) ? 100 :
-s->weight[r + 1]/s->weight[r];
real sum = 0;
for( t = first; t <= last; ++t )
sum += t->n*fabs(t->weight[r + 1] + scale*t->weight[r]);
for( x = first; x <= last; ++x )
sum += x->n*fabs(x->weight[r + 1] + scale*x->weight[r]);
s->scale[r] = scale;
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[] = {
.019417866674748388428, -.40385257701150182546,
@ -510,10 +503,10 @@ static void Rule7Alloc(Rule *rule)
TYPEDEFSET;
ccount ndim = ndim_;
ccount ndim = t->ndim;
ccount twondim = 1 << ndim;
count dim, n, r;
Set *first, *last, *s, *t;
Set *first, *last, *s, *x;
Alloc(first, nsets);
Clear(first, nsets);
@ -569,20 +562,20 @@ static void Rule7Alloc(Rule *rule)
for( dim = 0; dim < ndim; ++dim )
last->gen[dim] = g[3];
rule->first = first;
rule->last = last;
rule->errcoeff[0] = 5;
rule->errcoeff[1] = 1;
rule->errcoeff[2] = 5;
rule->n = n;
t->rule.first = first;
t->rule.last = last;
t->rule.errcoeff[0] = 5;
t->rule.errcoeff[1] = 1;
t->rule.errcoeff[2] = 5;
t->rule.n = n;
for( s = first; s <= last; ++s )
for( r = 1; r < nrules - 1; ++r ) {
creal scale = (s->weight[r] == 0) ? 100 :
-s->weight[r + 1]/s->weight[r];
real sum = 0;
for( t = first; t <= last; ++t )
sum += t->n*fabs(t->weight[r + 1] + scale*t->weight[r]);
for( x = first; x <= last; ++x )
sum += x->n*fabs(x->weight[r + 1] + scale*x->weight[r]);
s->scale[r] = scale;
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:
/* Compute centrally symmetric sum for permutation of G */
@ -611,7 +629,7 @@ next:
for( dim = 1; dim < ndim; ++dim ) {
creal gd = g[dim];
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 ) {
creal tmp = g[i];
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;
TYPEDEFSET;
@ -647,16 +665,16 @@ static void Sample(cRule *rule, void *voidregion, cint flags)
Region *const region = (Region *)voidregion;
creal vol = ldexp(1., -region->div);
real *x = rule->x, *f = rule->f;
Set *first = (Set *)rule->first, *last = (Set *)rule->last, *s;
creal *errcoeff = rule->errcoeff;
real *x = t->rule.x, *f = t->rule.f;
Set *first = (Set *)t->rule.first, *last = (Set *)t->rule.last, *s;
creal *errcoeff = t->rule.errcoeff;
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;
real maxrange = 0;
for( dim = 0; dim < ndim_; ++dim ) {
for( dim = 0; dim < t->ndim; ++dim ) {
cBounds *b = &region->bounds[dim];
creal range = b->upper - b->lower;
if( range > maxrange ) {
@ -666,11 +684,11 @@ static void Sample(cRule *rule, void *voidregion, cint flags)
}
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];
real sum[nrules];
creal *f1 = f;
@ -678,9 +696,9 @@ static void Sample(cRule *rule, void *voidregion, cint flags)
real maxdiff = 0;
count bisectdim = maxdim;
for( dim = 0; dim < ndim_; ++dim ) {
creal *fp = f1 + ncomp_;
creal *fm = fp + ncomp_;
for( dim = 0; dim < t->ndim; ++dim ) {
creal *fp = f1 + t->ncomp;
creal *fm = fp + t->ncomp;
creal fourthdiff = fabs(base +
ratio*(fp[0] + fm[0]) - (fp[offset] + fm[offset]));
f1 = fm;
@ -696,7 +714,7 @@ static void Sample(cRule *rule, void *voidregion, cint flags)
for( s = first; s <= last; ++s )
for( n = s->n; n; --n ) {
creal fun = *f1;
f1 += ncomp_;
f1 += t->ncomp;
for( rul = 0; rul < nrules; ++rul )
sum[rul] += fun*s->weight[rul];
}
@ -724,7 +742,7 @@ static void Sample(cRule *rule, void *voidregion, cint flags)
if( VERBOSE > 2 ) {
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];
p += sprintf(p,
(dim == 0) ? "\nRegion (" REALF ") - (" REALF ")" :
@ -732,7 +750,7 @@ static void Sample(cRule *rule, void *voidregion, cint flags)
b->lower, b->upper);
}
for( comp = 0; comp < ncomp_; ++comp ) {
for( comp = 0; comp < t->ncomp; ++comp ) {
cResult *r = &region->result[comp];
p += sprintf(p, "\n[" COUNT "] "
REAL " +- " REAL, comp + 1, r->avg, r->err);

View File

@ -2,11 +2,11 @@
common.c
includes most of the modules
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 *
* *
* 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 *
***************************************************************************/
#include "ChiSquare.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"
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
Type declarations
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 *
* *
* This library is free software; you can redistribute it and/or *
@ -27,7 +26,6 @@
#include "stddecl.h"
typedef struct {
real avg, err;
count bisectdim;
@ -35,7 +33,6 @@ typedef struct {
typedef const Result cResult;
typedef struct {
real avg, err, lastavg, lasterr;
real weightsum, avgsum;
@ -44,14 +41,12 @@ typedef struct {
typedef const Totals cTotals;
typedef struct {
real lower, upper;
} Bounds;
typedef const Bounds cBounds;
typedef struct {
real *x, *f;
void *first, *last;
@ -61,6 +56,24 @@ typedef struct {
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 \
typedef struct region { \
@ -69,6 +82,3 @@ typedef const Rule cRule;
Bounds bounds[NDIM]; \
} Region
typedef void (*Integrand)(ccount *, creal *, ccount *, real *);

View File

@ -4,11 +4,11 @@
originally by J.H. Friedman and M.H. Wright
(CERNLIB subroutine D151)
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 *
* *
* 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 *
***************************************************************************/
#include "util.c"
#include "decl.h"
#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-- ) {
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;
f += ncomp_;
f += t->ncomp;
}
}
/*********************************************************************/
static inline count SampleExtra(cBounds *b)
static inline count SampleExtra(This *t, cBounds *b)
{
number n = nextra_;
peakfinder_(&ndim_, b, &n, xextra_);
DoSample(n, ldxgiven_, xextra_, fextra_);
number n = t->nextra;
t->peakfinder(&t->ndim, b, &n, t->xextra);
DoSample(t, n, t->ldxgiven, t->xextra, t->fextra);
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"
Extern void EXPORT(Divonne)(ccount ndim, ccount ncomp,
Integrand integrand,
Integrand integrand, void *userdata,
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,
creal border, creal maxchisq, creal mindeviation,
cnumber ngiven, ccount ldxgiven, real *xgiven,
cnumber ngiven, ccount ldxgiven, creal *xgiven,
cnumber nextra, PeakFinder peakfinder,
int *pnregions, number *pneval, int *pfail,
real *integral, real *error, real *prob)
{
ndim_ = ndim;
ncomp_ = ncomp;
This t;
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) ||
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;
AllocGiven(&t, xgiven);
if( ngiven + nextra ) {
cnumber nxgiven = ngiven*ldxgiven;
cnumber nxextra = nextra*ldxgiven;
cnumber nfgiven = ngiven*ncomp;
cnumber nfextra = nextra*ncomp;
*pfail = Integrate(&t, integral, error, prob);
*pnregions = t.nregions;
*pneval = t.neval;
Alloc(xgiven_, nxgiven + nxextra + nfgiven + nfextra);
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_);
}
free(t.xgiven);
}
/*********************************************************************/
Extern void EXPORT(divonne)(ccount *pndim, ccount *pncomp,
Integrand integrand,
Integrand integrand, void *userdata,
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,
creal *pborder, creal *pmaxchisq, creal *pmindeviation,
cnumber *pngiven, ccount *pldxgiven, real *xgiven,
cnumber *pngiven, ccount *pldxgiven, creal *xgiven,
cnumber *pnextra, PeakFinder peakfinder,
int *pnregions, number *pneval, int *pfail,
real *integral, real *error, real *prob)
{
EXPORT(Divonne)(*pndim, *pncomp,
integrand,
*pepsrel, *pepsabs,
*pflags, *pmineval, *pmaxeval,
*pkey1, *pkey2, *pkey3, *pmaxpass,
*pborder, *pmaxchisq, *pmindeviation,
*pngiven, *pldxgiven, xgiven,
*pnextra, peakfinder,
pnregions, pneval, pfail,
integral, error, prob);
This t;
t.ndim = *pndim;
t.ncomp = *pncomp;
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.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
sample region, determine min and max, split if necessary
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 *
* *
* 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 *
***************************************************************************/
typedef struct {
real fmin, fmax;
real *xmin, *xmax;
creal *xmin, *xmax;
} 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 HAVESAMPLES (flags & 2)
@ -42,7 +44,8 @@ static bool Explore(count iregion, cSamples *samples, cint depth, cint flags)
count n, dim, comp, maxcomp;
Extrema extrema[NCOMP];
Result *r;
real *x, *f;
creal *x;
real *f;
real halfvol, maxerr;
Region *region;
Bounds *bounds;
@ -52,18 +55,18 @@ static bool Explore(count iregion, cSamples *samples, cint depth, cint flags)
sizeof(*region);
if( SPLICE ) {
if( nregions_ == size_ ) {
size_ += CHUNKSIZE;
ReAlloc(voidregion_, size_*sizeof(Region));
if( t->nregions == t->size ) {
t->size += CHUNKSIZE;
ReAlloc(t->voidregion, t->size*sizeof(Region));
}
VecCopy(region_[nregions_].bounds, region_[iregion].bounds);
iregion = nregions_++;
VecCopy(RegionPtr(t->nregions)->bounds, RegionPtr(iregion)->bounds);
iregion = t->nregions++;
}
region = &region_[iregion];
region = RegionPtr(iregion);
bounds = region->bounds;
result = region->result;
for( comp = 0; comp < ncomp_; ++comp ) {
for( comp = 0; comp < t->ncomp; ++comp ) {
Extrema *e = &extrema[comp];
e->fmin = INFTY;
e->fmax = -INFTY;
@ -72,78 +75,76 @@ static bool Explore(count iregion, cSamples *samples, cint depth, cint flags)
if( !HAVESAMPLES ) {
real vol = 1;
for( dim = 0; dim < ndim_; ++dim ) {
for( dim = 0; dim < t->ndim; ++dim ) {
cBounds *b = &bounds[dim];
vol *= b->upper - b->lower;
}
region->vol = vol;
for( comp = 0; comp < ncomp_; ++comp ) {
for( comp = 0; comp < t->ncomp; ++comp ) {
Result *r = &result[comp];
r->fmin = INFTY;
r->fmax = -INFTY;
}
x = xgiven_;
f = fgiven_;
n = ngiven_;
if( nextra_ ) n += SampleExtra(bounds);
x = t->xgiven;
f = t->fgiven;
n = t->ngiven;
if( t->nextra ) n += SampleExtra(t, bounds);
for( ; n; --n ) {
for( dim = 0; dim < ndim_; ++dim ) {
for( dim = 0; dim < t->ndim; ++dim ) {
cBounds *b = &bounds[dim];
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];
creal y = f[comp];
if( y < e->fmin ) e->fmin = y, e->xmin = x;
if( y > e->fmax ) e->fmax = y, e->xmax = x;
}
skip:
x += ldxgiven_;
f += ncomp_;
x += t->ldxgiven;
f += t->ncomp;
}
samples->sampler(samples, bounds, vol);
samples->sampler(t, samples, bounds, vol);
}
x = samples->x;
f = samples->f;
for( n = samples->n; n; --n ) {
for( comp = 0; comp < ncomp_; ++comp ) {
for( comp = 0; comp < t->ncomp; ++comp ) {
Extrema *e = &extrema[comp];
creal y = *f++;
if( y < e->fmin ) e->fmin = y, e->xmin = 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;
maxerr = -INFTY;
maxcomp = -1;
for( comp = 0; comp < ncomp_; ++comp ) {
for( comp = 0; comp < t->ncomp; ++comp ) {
Extrema *e = &extrema[comp];
Result *r = &result[comp];
real xtmp[NDIM], ftmp, err;
if( e->xmin ) { /* not all NaNs */
selectedcomp_ = comp;
sign_ = 1;
t->selectedcomp = comp;
VecCopy(xtmp, e->xmin);
ftmp = FindMinimum(bounds, xtmp, e->fmin);
ftmp = FindMinimum(t, bounds, xtmp, e->fmin);
if( ftmp < r->fmin ) {
r->fmin = ftmp;
VecCopy(r->xmin, xtmp);
}
sign_ = -1;
t->selectedcomp = Tag(comp);
VecCopy(xtmp, e->xmax);
ftmp = -FindMinimum(bounds, xtmp, -e->fmax);
ftmp = -FindMinimum(t, bounds, xtmp, -e->fmax);
if( ftmp > r->fmax ) {
r->fmax = ftmp;
VecCopy(r->xmax, xtmp);
@ -161,9 +162,9 @@ skip:
}
}
neval_opt_ += neval_;
t->neval_opt += t->neval;
if( maxcomp == -1 ) { /* all NaNs */
if( maxcomp == -1 ) { /* all NaNs */
region->depth = 0;
return false;
}
@ -185,14 +186,14 @@ skip:
if( !HAVESAMPLES ) {
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 )
for( comp = 0; comp < ncomp_; ++comp )
totals_[comp].secondspread =
Max(totals_[comp].secondspread, result[comp].spread);
for( comp = 0; comp < t->ncomp; ++comp )
t->totals[comp].secondspread =
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;
}

View File

@ -2,11 +2,11 @@
FindMinimum.c
find minimum (maximum) of hyperrectangular region
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 *
* *
* 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 *
***************************************************************************/
#define EPS 0x1p-52
#define RTEPS 0x1p-26
#define QEPS 0x1p-13
@ -43,23 +44,12 @@
#define FTOL 5e-2
#define GTOL 1e-2
#define Hessian(i, j) hessian[(i)*ndim_ + j]
#define Tag(x) ((x) | 0x8000)
#define Untag(x) ((x) & 0x7fff)
#define TaggedQ(x) ((x) & 0x8000)
#define Hessian(i, j) hessian[(i)*t->ndim + j]
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)
{
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)
{
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)
{
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)
{
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)
{
real y[NDIM], c;
@ -179,14 +169,14 @@ static inline void BFGS(ccount n, real *hessian,
y[i] = gnew[i] - g[i];
c = dx*Dot(n, y, p);
if( c < 1e-10 ) return;
RenormalizeCholesky(n, hessian, y, 1/c);
RenormalizeCholesky(t, n, hessian, y, 1/c);
c = Dot(n, g, p);
if( c >= 0 ) return;
c = 1/sqrt(-c);
for( i = 0; i < n; ++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( 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)
{
count i;
@ -205,14 +195,14 @@ static void Gradient(ccount nfree, ccount *ifree,
creal xd = x[dim];
creal delta = (b[dim].upper - xd < DELTA) ? -DELTA : DELTA;
x[dim] += delta;
grad[i] = (SignSample(x) - y)/delta;
grad[i] = (Sample(t, x) - y)/delta;
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,
real step, creal range, creal grad,
creal ftol, creal xtol, creal gtol)
@ -260,7 +250,7 @@ static Point LineSearch(ccount nfree, ccount *ifree,
ccount dim = ifree[i];
x[dim] = xini[dim] + dist*p[i];
}
cur.f = SignSample(x);
cur.f = Sample(t, x);
if( cur.f <= min.f ) {
v = w;
@ -347,7 +337,7 @@ static Point LineSearch(ccount nfree, ccount *ifree,
ccount dim = ifree[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 ) {
cur.dx = 0;
@ -367,8 +357,8 @@ static Point LineSearch(ccount nfree, ccount *ifree,
/*********************************************************************/
static real LocalSearch(ccount nfree, ccount *ifree, cBounds *b,
creal *x, creal fx, real *z)
static real LocalSearch(This *t, ccount nfree, ccount *ifree,
cBounds *b, creal *x, creal fx, real *z)
{
real delta, smax, sopp, spmax, snmax;
real y[NDIM], fy, fz, ftest;
@ -408,7 +398,7 @@ static real LocalSearch(ccount nfree, ccount *ifree, cBounds *b,
ccount dim = ifree[i];
y[dim] = x[dim] + delta*p[i];
}
fy = SignSample(y);
fy = Sample(t, y);
if( fabs(fy - fx) > ftest ) break;
} while( delta != smax );
@ -461,7 +451,7 @@ static real LocalSearch(ccount nfree, ccount *ifree, cBounds *b,
ccount dim = ifree[i];
z[dim] = y[dim] + delta*p[i];
}
fz = SignSample(z);
fz = Sample(t, z);
if( fabs(fz - fy) > ftest ) break;
} while( delta != smax );
@ -485,7 +475,7 @@ static real LocalSearch(ccount nfree, ccount *ifree, cBounds *b,
}
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);
fz = low.f;
}
@ -522,7 +512,7 @@ static real LocalSearch(ccount nfree, ccount *ifree, cBounds *b,
ccount dim = ifree[i];
z[dim] = x[dim] - delta*p[i];
}
fz = SignSample(z);
fz = Sample(t, z);
if( fz < fx ) {
grad = (fz - fx)/delta;
range = snmax;
@ -533,7 +523,7 @@ static real LocalSearch(ccount nfree, ccount *ifree, cBounds *b,
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);
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 gfree[NDIM], p[NDIM];
real tmp[NDIM], ftmp, fini = fmin;
ccount maxeval = neval_ + 50*ndim_;
ccount maxeval = t->neval + 50*t->ndim;
count nfree, nfix;
count ifree[NDIM], ifix[NDIM];
count dim, local;
Zap(hessian);
for( dim = 0; dim < ndim_; ++dim )
for( dim = 0; dim < t->ndim; ++dim )
Hessian(dim, dim) = 1;
/* 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 ) {
bool resample = false;
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 ) {
xmin[dim] = b[dim].lower;
ifix[nfix++] = dim;
@ -579,21 +569,21 @@ static real FindMinimum(cBounds *b, real *xmin, real fmin)
else ifree[nfree++] = dim;
}
if( resample ) fini = fmin = SignSample(xmin);
if( resample ) fini = fmin = Sample(t, xmin);
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;
ftmp = LocalSearch(nfree, ifree, b, xmin, fmin, tmp);
ftmp = LocalSearch(t, nfree, ifree, b, xmin, fmin, tmp);
if( ftmp > fmin - (1 + fabs(fmin))*RTEPS )
goto releasebounds;
fmin = ftmp;
VecCopy(xmin, tmp);
}
while( neval_ <= maxeval ) {
while( t->neval <= maxeval ) {
/* Step 2a: perform a quasi-Newton iteration on the free
variables only. */
@ -601,10 +591,10 @@ static real FindMinimum(cBounds *b, real *xmin, real fmin)
if( nfree > 0 ) {
real plen, pleneps;
real minstep;
count i, mini, minfix;
count i, mini = 0, minfix = 0;
Point low;
LinearSolve(nfree, hessian, gfree, p);
LinearSolve(t, nfree, hessian, gfree, p);
plen = Length(nfree, p);
pleneps = plen + RTEPS;
@ -645,7 +635,7 @@ fixbound:
Copy(&Hessian(i, 0), &Hessian(i + 1, 0), i);
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(&gfree[mini], &gfree[mini + 1], nfree - mini);
@ -653,7 +643,7 @@ fixbound:
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),
RTEPS/pleneps, DELTA/pleneps, .2);
@ -663,8 +653,8 @@ fixbound:
fmin = low.f;
VecCopy(xmin, tmp);
Gradient(nfree, ifree, b, xmin, fmin, tmp);
BFGS(nfree, hessian, tmp, gfree, p, low.dx);
Gradient(t, nfree, ifree, b, xmin, fmin, tmp);
BFGS(t, nfree, hessian, tmp, gfree, p, low.dx);
VecCopy(gfree, tmp);
if( fabs(low.dx - minstep) < QEPS*minstep ) goto fixbound;
@ -672,7 +662,7 @@ fixbound:
fdiff = fini - fmin;
fini = fmin;
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;
bool repeat = false;
Gradient(nfix, ifix, b, xmin, fmin, tmp);
Gradient(t, nfix, ifix, b, xmin, fmin, tmp);
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 ) {
repeat = true;
if( grad < mingrad ) {

View File

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

View File

@ -4,11 +4,11 @@
code lifted with minor modifications from DCUHRE
by J. Berntsen, T. Espelid, and A. Genz
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 *
* *
* This library is free software; you can redistribute it and/or *
@ -38,21 +38,7 @@ enum { nrules = 5 };
/*********************************************************************/
static inline void RuleIni(Rule *rule)
{
rule->first = NULL;
}
/*********************************************************************/
static inline void RuleFree(Rule *rule)
{
if( rule->first ) free(rule->first);
}
/*********************************************************************/
static void Rule13Alloc(Rule *rule)
static void Rule13Alloc(This *t)
{
static creal w[][nrules] = {
{ .00844923090033615, .3213775489050763, .3372900883288987,
@ -100,7 +86,7 @@ static void Rule13Alloc(Rule *rule)
TYPEDEFSET;
count n, r;
Set *first, *last, *s, *t;
Set *first, *last, *s, *x;
Alloc(first, nsets);
Clear(first, nsets);
@ -182,20 +168,20 @@ static void Rule13Alloc(Rule *rule)
last->gen[0] = g[14];
last->gen[1] = g[15];
rule->first = first;
rule->last = last;
rule->errcoeff[0] = 10;
rule->errcoeff[1] = 1;
rule->errcoeff[2] = 5;
rule->n = n;
t->rule13.first = first;
t->rule13.last = last;
t->rule13.errcoeff[0] = 10;
t->rule13.errcoeff[1] = 1;
t->rule13.errcoeff[2] = 5;
t->rule13.n = n;
for( s = first; s <= last; ++s )
for( r = 1; r < nrules - 1; ++r ) {
creal scale = (s->weight[r] == 0) ? 100 :
-s->weight[r + 1]/s->weight[r];
real sum = 0;
for( t = first; t <= last; ++t )
sum += t->n*fabs(t->weight[r + 1] + scale*t->weight[r]);
for( x = first; x <= last; ++x )
sum += x->n*fabs(x->weight[r + 1] + scale*x->weight[r]);
s->scale[r] = scale;
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] = {
{ .0009903847688882167, 1.715006248224684, 1.936014978949526,
@ -248,7 +234,7 @@ static void Rule11Alloc(Rule *rule)
TYPEDEFSET;
count n, r;
Set *first, *last, *s, *t;
Set *first, *last, *s, *x;
Alloc(first, nsets);
Clear(first, nsets);
@ -329,20 +315,20 @@ static void Rule11Alloc(Rule *rule)
last->gen[1] = g[12];
last->gen[2] = g[13];
rule->first = first;
rule->last = last;
rule->errcoeff[0] = 4;
rule->errcoeff[1] = .5;
rule->errcoeff[2] = 3;
rule->n = n;
t->rule11.first = first;
t->rule11.last = last;
t->rule11.errcoeff[0] = 4;
t->rule11.errcoeff[1] = .5;
t->rule11.errcoeff[2] = 3;
t->rule11.n = n;
for( s = first; s <= last; ++s )
for( r = 1; r < nrules - 1; ++r ) {
creal scale = (s->weight[r] == 0) ? 100 :
-s->weight[r + 1]/s->weight[r];
real sum = 0;
for( t = first; t <= last; ++t )
sum += t->n*fabs(t->weight[r + 1] + scale*t->weight[r]);
for( x = first; x <= last; ++x )
sum += x->n*fabs(x->weight[r + 1] + scale*x->weight[r]);
s->scale[r] = scale;
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[] = {
-.0023611709677855117884, .11415390023857325268,
@ -384,10 +370,10 @@ static void Rule9Alloc(Rule *rule)
TYPEDEFSET;
ccount ndim = ndim_;
ccount ndim = t->ndim;
ccount twondim = 1 << ndim;
count dim, n, r;
Set *first, *last, *s, *t;
Set *first, *last, *s, *x;
Alloc(first, nsets);
Clear(first, nsets);
@ -473,20 +459,20 @@ static void Rule9Alloc(Rule *rule)
for( dim = 0; dim < ndim; ++dim )
last->gen[dim] = g[4];
rule->first = first;
rule->last = last;
rule->errcoeff[0] = 5;
rule->errcoeff[1] = 1;
rule->errcoeff[2] = 5;
rule->n = n;
t->rule9.first = first;
t->rule9.last = last;
t->rule9.errcoeff[0] = 5;
t->rule9.errcoeff[1] = 1;
t->rule9.errcoeff[2] = 5;
t->rule9.n = n;
for( s = first; s <= last; ++s )
for( r = 1; r < nrules - 1; ++r ) {
creal scale = (s->weight[r] == 0) ? 100 :
-s->weight[r + 1]/s->weight[r];
real sum = 0;
for( t = first; t <= last; ++t )
sum += t->n*fabs(t->weight[r + 1] + scale*t->weight[r]);
for( x = first; x <= last; ++x )
sum += x->n*fabs(x->weight[r + 1] + scale*x->weight[r]);
s->scale[r] = scale;
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[] = {
.019417866674748388428, -.40385257701150182546,
@ -517,10 +503,10 @@ static void Rule7Alloc(Rule *rule)
TYPEDEFSET;
ccount ndim = ndim_;
ccount ndim = t->ndim;
ccount twondim = 1 << ndim;
count dim, n, r;
Set *first, *last, *s, *t;
Set *first, *last, *s, *x;
Alloc(first, nsets);
Clear(first, nsets);
@ -576,20 +562,20 @@ static void Rule7Alloc(Rule *rule)
for( dim = 0; dim < ndim; ++dim )
last->gen[dim] = g[3];
rule->first = first;
rule->last = last;
rule->errcoeff[0] = 5;
rule->errcoeff[1] = 1;
rule->errcoeff[2] = 5;
rule->n = n;
t->rule7.first = first;
t->rule7.last = last;
t->rule7.errcoeff[0] = 5;
t->rule7.errcoeff[1] = 1;
t->rule7.errcoeff[2] = 5;
t->rule7.n = n;
for( s = first; s <= last; ++s )
for( r = 1; r < nrules - 1; ++r ) {
creal scale = (s->weight[r] == 0) ? 100 :
-s->weight[r + 1]/s->weight[r];
real sum = 0;
for( t = first; t <= last; ++t )
sum += t->n*fabs(t->weight[r + 1] + scale*t->weight[r]);
for( x = first; x <= last; ++x )
sum += x->n*fabs(x->weight[r + 1] + scale*x->weight[r]);
s->scale[r] = scale;
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:
/* Compute centrally symmetric sum for permutation of G */
@ -617,19 +624,18 @@ next:
for( dim = 1; dim < ndim; ++dim ) {
creal gd = g[dim];
count big = dim - 1;
if( g[big] > gd ) {
count i, j = dim, lastbig = big;
if( g[dim - 1] > gd ) {
count i, j = dim, ix = dim, dx = dim - 1;
for( i = 0; i < --j; ++i ) {
creal tmp = g[i];
g[i] = g[j];
g[j] = tmp;
if( tmp <= gd ) --big;
if( g[i] > gd ) lastbig = i;
if( tmp <= gd ) --dx;
if( g[i] > gd ) ix = i;
}
if( g[big] <= gd ) big = lastbig;
g[dim] = g[big];
g[big] = gd;
if( g[dx] <= gd ) dx = ix;
g[dim] = g[dx];
g[dx] = gd;
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;
@ -659,11 +665,11 @@ static void SampleRule(cSamples *samples, cBounds *b, creal vol)
count comp, rul, n;
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];
creal *f1 = f++;
@ -671,7 +677,7 @@ static void SampleRule(cSamples *samples, cBounds *b, creal vol)
for( s = first; s <= last; ++s )
for( n = s->n; n; --n ) {
creal fun = *f1;
f1 += ncomp_;
f1 += t->ncomp;
for( rul = 0; rul < nrules; ++rul )
sum[rul] += fun*s->weight[rul];
}

View File

@ -2,11 +2,11 @@
Sample.c
most of what is related to sampling
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 *
* *
* 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 *
***************************************************************************/
#define MARKMASK 0xfffffff
#define Marked(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)
{
MEM(samples) = NULL;
samples->x = NULL;
}
/*********************************************************************/
static inline bool SamplesIniQ(cSamples *samples)
{
return samples->x == NULL;
}
/*********************************************************************/
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;
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;
for( i = 0; i < n; ++i ) {
GetRandom(x);
for( dim = 0; dim < ndim_; ++x, ++dim )
t->rng.getrandom(t, x);
for( dim = 0; dim < t->ndim; ++x, ++dim )
*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);
f += ncomp_;
f += t->ncomp;
for( i = 1; i < n; ++i )
for( comp = 0; comp < ncomp_; ++comp )
for( comp = 0; comp < t->ncomp; ++comp )
avg[comp] += *f++;
for( comp = 0; comp < ncomp_; ++comp )
for( comp = 0; comp < t->ncomp; ++comp )
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;
real *x = samples->x, *xlast = x + ndim_;
real *f = samples->f, *flast = f + ncomp_;
real *x = samples->x, *xlast = x + t->ndim;
real *f = samples->f, *flast = f + t->ncomp;
real *avg = samples->avg;
cnumber n = samples->n, neff = samples->neff;
number nextra = n, i;
@ -88,47 +97,47 @@ static void SampleKorobov(cSamples *samples, cBounds *b, creal vol)
for( i = 1; i < n; ++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;
*xlast++ = b[dim].lower + dx*(b[dim].upper - b[dim].lower);
c = c*samples->coeff % neff;
}
}
for( dim = 0; dim < ndim_; ++dim ) {
creal dx = (x[dim] = b[dim].upper) - border_.upper;
for( dim = 0; dim < t->ndim; ++dim ) {
creal dx = (x[dim] = b[dim].upper) - t->border.upper;
if( dx > 0 ) dist += Sq(dx);
}
if( dist > 0 ) {
dist = sqrt(dist)/EXTRAPOLATE_EPS;
for( dim = 0; dim < ndim_; ++dim ) {
real x2 = x[dim], dx = x2 - border_.upper;
for( dim = 0; dim < t->ndim; ++dim ) {
real x2 = x[dim], dx = x2 - t->border.upper;
if( dx > 0 ) {
x[dim] = border_.upper;
x2 = border_.upper - dx/dist;
x[dim] = t->border.upper;
x2 = t->border.upper - dx/dist;
}
xlast[dim] = x2;
}
++nextra;
}
DoSample(nextra, ndim_, x, f);
DoSample(t, nextra, t->ndim, x, f);
ResCopy(avg, flast);
flast += ncomp_;
flast += t->ncomp;
for( i = 2; i < n; ++i )
for( comp = 0; comp < ncomp_; ++comp )
for( comp = 0; comp < t->ncomp; ++comp )
avg[comp] += *flast++;
if( nextra > n ) {
for( comp = 0; comp < ncomp_; ++comp )
for( comp = 0; comp < t->ncomp; ++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;
}
for( comp = 0; comp < ncomp_; ++comp )
for( comp = 0; comp < t->ncomp; ++comp )
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,
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)
{
number n;
if( key == 13 && ndim_ == 2 ) {
if( rule13_.first == NULL ) Rule13Alloc(&rule13_);
samples->rule = &rule13_;
samples->n = n = nmin = rule13_.n;
if( key == 13 && t->ndim == 2 ) {
if( RuleIniQ(&t->rule13) ) Rule13Alloc(t);
samples->rule = &t->rule13;
samples->n = n = nmin = t->rule13.n;
samples->sampler = SampleRule;
}
else if( key == 11 && ndim_ == 3 ) {
if( rule11_.first == NULL ) Rule11Alloc(&rule11_);
samples->rule = &rule11_;
samples->n = n = nmin = rule11_.n;
else if( key == 11 && t->ndim == 3 ) {
if( RuleIniQ(&t->rule11) ) Rule11Alloc(t);
samples->rule = &t->rule11;
samples->n = n = nmin = t->rule11.n;
samples->sampler = SampleRule;
}
else if( key == 9 ) {
if( rule9_.first == NULL ) Rule9Alloc(&rule9_);
samples->rule = &rule9_;
samples->n = n = nmin = rule9_.n;
if( RuleIniQ(&t->rule9) ) Rule9Alloc(t);
samples->rule = &t->rule9;
samples->n = n = nmin = t->rule9.n;
samples->sampler = SampleRule;
}
else if( key == 7 ) {
if( rule7_.first == NULL ) Rule7Alloc(&rule7_);
samples->rule = &rule7_;
samples->n = n = nmin = rule7_.n;
if( RuleIniQ(&t->rule7) ) Rule7Alloc(t);
samples->rule = &t->rule7;
samples->n = n = nmin = t->rule7.n;
samples->sampler = SampleRule;
}
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 MarkLast(x) (x | Marked(INT_MAX))
@ -215,18 +224,18 @@ static void SamplesAlloc(Samples *samples)
i += Min1(d);
}
samples->coeff = coeff[i][ndim_ - KOROBOV_MINDIM];
samples->coeff = coeff[i][t->ndim - KOROBOV_MINDIM];
samples->neff = p = Unmark(p);
samples->n = p/2 + 1;
}
nx = ndim_*(samples->n + 1); /* need 1 for extrapolation */
nf = ncomp_*(samples->n + 1);
nx = t->ndim*(samples->n + 1); /* need 1 for extrapolation */
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->avg = samples->f + nf;
samples->err = samples->avg + ncomp_;
samples->err = samples->avg + t->ncomp;
ResClear(samples->err);
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 dist = 0;
count dim;
count dim, comp;
number nextra = 1;
for( dim = 0; dim < ndim_; ++dim ) {
for( dim = 0; dim < t->ndim; ++dim ) {
creal x1 = *xlast++ = Min(Max(*x0++, 0.), 1.);
real dx;
if( (dx = x1 - border_.lower) < 0 ||
(dx = x1 - border_.upper) > 0 ) dist += Sq(dx);
if( (dx = x1 - t->border.lower) < 0 ||
(dx = x1 - t->border.upper) > 0 ) dist += Sq(dx);
}
if( dist > 0 ) {
dist = sqrt(dist)/EXTRAPOLATE_EPS;
for( dim = 0; dim < ndim_; ++dim ) {
for( dim = 0; dim < t->ndim; ++dim ) {
real x2 = xtmp[dim], dx, b;
if( (dx = x2 - (b = border_.lower)) < 0 ||
(dx = x2 - (b = border_.upper)) > 0 ) {
if( (dx = x2 - (b = t->border.lower)) < 0 ||
(dx = x2 - (b = t->border.upper)) > 0 ) {
xtmp[dim] = b;
x2 = b - dx/dist;
}
@ -262,11 +271,12 @@ static real Sample(creal *x0)
nextra = 2;
}
DoSample(nextra, ndim_, xtmp, ftmp);
DoSample(t, nextra, t->ndim, xtmp, ftmp);
f = ftmp[selectedcomp_];
if( nextra > 1 ) f += dist*(f - ftmp[selectedcomp_ + ncomp_]);
comp = Untag(t->selectedcomp);
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
determine optimal cuts for splitting a region
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 *
* *
* 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 *
***************************************************************************/
#define BNDTOL .05
#define FRACT .5
#define BIG 1e10
@ -37,7 +38,7 @@
#define Lower(d) (2*d)
#define Upper(d) (2*d + 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 {
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;
static count nextdim = 0;
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);
ymid = Sample(xmid);
ymid = Sample(t, xmid);
maxdev = 0;
maxdim = 0;
for( dim = 0; dim < ndim_; ++dim ) {
for( dim = 0; dim < t->ndim; ++dim ) {
real ylower, yupper, dev;
creal x = xmid[dim];
xmid[dim] = b[dim].lower;
ylower = Sample(xmid);
ylower = Sample(t, xmid);
xmid[dim] = b[dim].upper;
yupper = Sample(xmid);
yupper = Sample(t, xmid);
xmid[dim] = x;
dev = fabs(ymid - .5*(ylower + yupper));
@ -90,7 +91,7 @@ static void SomeCut(Cut *cut, Bounds *b)
}
if( maxdev > 0 ) nextdim = 0;
else maxdim = nextdim++ % ndim_;
else maxdim = nextdim++ % t->ndim;
cut->i = Upper(maxdim);
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;
count dim;
for( dim = 0; dim < ndim_; ++dim )
for( dim = 0; dim < t->ndim; ++dim )
vol *= delta[Lower(dim)] + delta[Upper(dim)];
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)
{
cint sign = (fdiff < 0) ? -1 : 1;
@ -161,26 +162,22 @@ static count FindCuts(Cut *cut, Bounds *bounds, creal vol,
real gamma, fgamma, lhssq;
count dim, div;
for( dim = 0; dim < ndim_; ++dim ) {
// cBounds *b = &bounds[dim];
// creal xsave = xmajor[dim];
cBounds *b;
real xsave;
b = &bounds[dim];
xsave = xmajor[dim];
for( dim = 0; dim < t->ndim; ++dim ) {
cBounds *b = &bounds[dim];
creal xsave = xmajor[dim];
real dist = b->upper - xsave;
if( dist >= BNDTOL*(b->upper - b->lower) ) {
Cut *c = &cut[ncut++];
c->i = Upper(dim);
c->save = dist;
xmajor[dim] += dist *= FRACT;
c->f = Sample(xmajor);
c->f = Sample(t, xmajor);
xmajor[dim] = xsave;
}
delta[Upper(dim)] = dist;
}
for( dim = 0; dim < ndim_; ++dim ) {
for( dim = 0; dim < t->ndim; ++dim ) {
cBounds *b = &bounds[dim];
creal xsave = xmajor[dim];
real dist = xsave - b->lower;
@ -189,14 +186,14 @@ static count FindCuts(Cut *cut, Bounds *bounds, creal vol,
c->i = Lower(dim);
c->save = dist;
xmajor[dim] -= dist *= FRACT;
c->f = Sample(xmajor);
c->f = Sample(t, xmajor);
xmajor[dim] = xsave;
}
delta[Lower(dim)] = dist;
}
if( ncut == 0 ) {
SomeCut(cut, bounds);
SomeCut(t, cut, bounds);
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;
if( sign*(mincut->f - fgamma) < 0 ) break;
if( --ncut == 0 ) {
SomeCut(cut, bounds);
SomeCut(t, cut, bounds);
return 1;
}
@ -247,11 +244,11 @@ repeat:
creal xsave = *x;
delta[c->i] = c->delta + c->sol/div;
*x += SignedDelta(c->i);
c->f = Sample(xmajor);
c->f = Sample(t, xmajor);
*x = xsave;
}
gammanew = Volume(delta)/vol;
gammanew = Volume(t, delta)/vol;
fgamma = fmajor + (gammanew - 1)*fdiff;
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;
@ -301,42 +298,42 @@ static void Split(count iregion, int depth)
real tmp;
{
Region *const region = region_ + iregion;
selectedcomp_ = region->cutcomp;
neval_cut_ -= neval_;
ncut = FindCuts(cut, region->bounds, region->vol,
Region *const region = RegionPtr(iregion);
t->selectedcomp = region->cutcomp;
t->neval_cut -= t->neval;
ncut = FindCuts(t, cut, region->bounds, region->vol,
(real *)region->result + region->xmajor, region->fmajor,
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];
e->diff = region->result[comp].avg;
e->spread = e->err = 0;
}
}
xregion = nregions_;
xregion = t->nregions;
depth -= ncut;
if( Explore(iregion, &samples_[0], depth, 1) ) {
if( Explore(t, iregion, &t->samples[0], depth, 1) ) {
Cut *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;
creal tmp = b[c1];
b[c1] = b[c0];
b[c0] = c->save;
if( !Explore(iregion, &samples_[0], depth++, ncut != 0) ) break;
if( ncut ) ((real *)region_[iregion].bounds)[c1] = tmp;
if( !Explore(t, iregion, &t->samples[0], depth++, ncut != 0) ) break;
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++ ) {
cResult *result = region_[ireg].result;
for( comp = 0; comp < ncomp_; ++comp ) {
for( ireg = iregion, xreg = xregion; ireg < t->nregions; ireg = xreg++ ) {
cResult *result = RegionPtr(ireg)->result;
for( comp = 0; comp < t->ncomp; ++comp ) {
cResult *r = &result[comp];
Errors *e = &errors[comp];
e->diff -= r->avg;
@ -346,7 +343,7 @@ static void Split(count iregion, int depth)
}
tmp = 1./nsplit;
for( comp = 0; comp < ncomp_; ++comp ) {
for( comp = 0; comp < t->ncomp; ++comp ) {
Errors *e = &errors[comp];
e->diff = tmp*fabs(e->diff);
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;
for( ireg = iregion, xreg = xregion; ireg < nregions_; ireg = xreg++ ) {
Result *result = region_[ireg].result;
for( comp = 0; comp < ncomp_; ++comp ) {
for( ireg = iregion, xreg = xregion; ireg < t->nregions; ireg = xreg++ ) {
Result *result = RegionPtr(ireg)->result;
for( comp = 0; comp < t->ncomp; ++comp ) {
Result *r = &result[comp];
cErrors *e = &errors[comp];
creal c = tmp*e->diff;
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
includes most of the modules
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 *
* *
* 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 *
***************************************************************************/
static bool Explore(count iregion, cSamples *samples, cint depth, cint flags);
static void Split(count iregion, int depth);
#include "Random.c"
#include "ChiSquare.c"
#include "Rule.c"
#include "Sample.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 "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"
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
Type declarations
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 *
* *
* 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 *
***************************************************************************/
#include "stddecl.h"
#define EXTRAPOLATE_EPS (.25*border_.lower)
/*#define EXTRAPOLATE_EPS 0x1p-26*/
#define Tag(x) ((x) | INT_MIN)
#define Untag(x) ((x) & INT_MAX)
typedef struct {
real lower, upper;
@ -37,7 +37,6 @@ typedef struct {
typedef const Bounds cBounds;
typedef struct {
real avg, spreadsq;
real spread, secondspread;
@ -45,7 +44,6 @@ typedef struct {
int iregion;
} Totals;
typedef struct {
void *first, *last;
real errcoeff[3];
@ -54,11 +52,10 @@ typedef struct {
typedef const Rule cRule;
typedef struct samples {
real weight;
real *x, *f, *avg, *err;
void (*sampler)(const struct samples *, cBounds *, creal);
void (*sampler)(struct _this *t, const struct samples *, cBounds *, creal);
cRule *rule;
count coeff;
number n, neff;
@ -66,6 +63,42 @@ typedef struct samples {
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 \
typedef struct { \
@ -81,10 +114,5 @@ typedef const Samples cSamples;
Result result[NCOMP]; \
} Region
#define CHUNKSIZE 4096
typedef void (*Integrand)(ccount *, creal *, ccount *, real *, cint *);
typedef void (*PeakFinder)(ccount *, cBounds *, number *, real *);
#define RegionPtr(n) (&((Region *)t->voidregion)[n])

View File

@ -6,7 +6,7 @@
*/
/***************************************************************************
* Copyright (C) 2004-2009 by Thomas Hahn *
* Copyright (C) 2004-2010 by Thomas Hahn *
* hahn@feynarts.de *
* *
* 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 *
***************************************************************************/
#if defined(HAVE_LONG_DOUBLE) && defined(HAVE_POWL)
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)
{
creal *x = w + n, *f = x + n*ndim_ + comp;
creal max = ldexp(1., (int)((XDBL_MAX_EXP - 2)/flatness));
creal *x = w + n;
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));
count nvar = 2*ndim_;
count nvar = 2*t->ndim;
Clear(var, nvar);
while( n-- ) {
count dim;
const xdouble t =
powx(Min(1 + fabs(*w++)*Sq(*f - avg)*norm, max), flatness);
const xdouble ft =
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)];
const xdouble f = v->fluct + t;
const xdouble f = v->fluct + ft;
v->fluct = (f > XDBL_MAX/2) ? XDBL_MAX/2 : f;
++v->n;
}
}
flatness = 2/3./flatness;
while( nvar-- ) {
var->fluct = powx(var->fluct, flatness);
var->fluct = powx(var->fluct, flat);
++var;
}
}

View File

@ -2,11 +2,11 @@
Grid.c
utility functions for the Vegas grid
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 *
* *
* 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 *
***************************************************************************/
static void RefineGrid(Grid grid, Grid margsum, cint flags)
static void RefineGrid(cThis *t, Grid grid, Grid margsum)
{
real avgperbin, thisbin, newcur, delta;
Grid imp, newgrid;
@ -81,17 +81,17 @@ static void RefineGrid(Grid grid, Grid margsum, cint flags)
/*********************************************************************/
static void Reweight(Bounds *b,
creal *w, creal *f, creal *lastf, cResult *total, cint flags)
static void Reweight(cThis *t, Bounds *b,
creal *w, creal *f, creal *lastf, cResult *total)
{
Grid margsum[NDIM];
real scale[NCOMP];
cbin_t *bin = (cbin_t *)lastf;
count dim, comp;
if( ncomp_ == 1 ) scale[0] = 1;
if( t->ncomp == 1 ) scale[0] = 1;
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;
}
@ -99,17 +99,17 @@ static void Reweight(Bounds *b,
while( f < lastf ) {
real fsq = 0;
for( comp = 0; comp < ncomp_; ++comp )
for( comp = 0; comp < t->ncomp; ++comp )
fsq += Sq(*f++*scale[comp]);
fsq *= Sq(*w++);
if( fsq != 0 )
for( dim = 0; dim < ndim_; ++dim )
for( dim = 0; dim < t->ndim; ++dim )
margsum[dim][bin[dim]] += fsq;
bin += ndim_;
bin += t->ndim;
}
for( dim = 0; dim < ndim_; ++dim )
RefineGrid(b[dim].grid, margsum[dim], flags);
for( dim = 0; dim < t->ndim; ++dim )
RefineGrid(t, b[dim].grid, margsum[dim]);
}
/*********************************************************************/

View File

@ -2,11 +2,11 @@
Integrate.c
integrate over the unit hypercube
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 *
* *
* 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 *
***************************************************************************/
static int Integrate(creal epsrel, creal epsabs,
cint flags, cnumber mineval, cnumber maxeval,
cnumber nnew, creal flatness,
real *integral, real *error, real *prob)
static int Integrate(This *t, real *integral, real *error, real *prob)
{
TYPEDEFREGION;
count dim, comp, df;
int fail = 1;
int fail = -99;
Result totals[NCOMP];
Region *anchor = NULL, *region = NULL;
@ -42,26 +40,30 @@ static int Integrate(creal epsrel, creal epsabs,
sprintf(s, "Suave input parameters:\n"
" ndim " COUNT "\n ncomp " COUNT "\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,
ndim_, ncomp_,
epsrel, epsabs,
flags, mineval, maxeval,
nnew, flatness);
t->ndim, t->ncomp,
t->epsrel, t->epsabs,
t->flags, t->seed,
t->mineval, t->maxeval,
t->nnew, t->flatness);
Print(s);
}
#ifdef MLVERSION
if( setjmp(abort_) ) goto abort;
#endif
if( BadComponent(t) ) return -2;
if( BadDimension(t) ) return -1;
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->div = 0;
for( dim = 0; dim < ndim_; ++dim ) {
for( dim = 0; dim < t->ndim; ++dim ) {
Bounds *b = &anchor->bounds[dim];
b->lower = 0;
b->upper = 1;
@ -76,12 +78,13 @@ static int Integrate(creal epsrel, creal epsabs,
else Copy(b->grid, anchor->bounds[0].grid, NBINS);
}
Sample(nnew, anchor, anchor->w,
anchor->w + nnew, anchor->w + (ndim_ + 1)*nnew, flags);
Sample(t, t->nnew, anchor, anchor->w,
anchor->w + t->nnew,
anchor->w + t->nnew + t->ndim*t->nnew);
df = anchor->df;
ResCopy(totals, anchor->result);
for( nregions_ = 1; ; ++nregions_ ) {
for( t->nregions = 1; ; ++t->nregions ) {
Var var[NDIM][2], *vLR;
real maxratio, maxerr, minfluct, bias, mid;
Region *regionL, *regionR, *reg, **parent, **par;
@ -95,9 +98,9 @@ static int Integrate(creal epsrel, creal epsabs,
p += sprintf(p, "\n"
"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];
p += sprintf(p, "\n[" COUNT "] "
REAL " +- " REAL " \tchisq " REAL " (" COUNT " df)",
@ -109,7 +112,7 @@ static int Integrate(creal epsrel, creal epsabs,
maxratio = -INFTY;
maxcomp = 0;
for( comp = 0; comp < ncomp_; ++comp ) {
for( comp = 0; comp < t->ncomp; ++comp ) {
creal ratio = totals[comp].err/MaxErr(totals[comp].avg);
if( ratio > maxratio ) {
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;
break;
}
if( neval_ >= maxeval ) break;
if( t->neval >= t->maxeval ) break;
maxerr = -INFTY;
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->result[maxcomp].avg, Max(maxerr, epsabs));
region->result[maxcomp].avg, Max(maxerr, t->epsabs));
bias = (epsrel < 1e-50) ? 2 :
Max(pow(2., -(real)region->div/ndim_)/epsrel, 2.);
bias = (t->epsrel < 1e-50) ? 2 :
Max(pow(2., -(real)region->div/t->ndim)/t->epsrel, 2.);
minfluct = INFTY;
bisectdim = 0;
for( dim = 0; dim < ndim_; ++dim ) {
for( dim = 0; dim < t->ndim; ++dim ) {
cBounds *b = &region->bounds[dim];
creal fluct = (var[dim][0].fluct + var[dim][1].fluct)*
(bias - b->upper + b->lower);
@ -157,10 +160,10 @@ static int Integrate(creal epsrel, creal epsabs,
vLR = var[bisectdim];
minfluct = vLR[0].fluct + vLR[1].fluct;
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 );
nL = vLR[0].n + nnewL;
nnewR = IMax(nnew - nnewL, MINSAMPLES);
nnewR = IMax(t->nnew - nnewL, MINSAMPLES);
nR = vLR[1].n + nnewR;
RegionAlloc(regionL, nL, nnewL);
@ -174,9 +177,9 @@ static int Integrate(creal epsrel, creal epsabs,
bounds = &region->bounds[bisectdim];
mid = bounds->mid;
n = region->n;
w = wlast = region->w; x = w + n; f = flast = x + n*ndim_;
wL = regionL->w; xL = wL + nL; fL = xL + nL*ndim_;
wR = regionR->w; xR = wR + nR; fR = xR + nR*ndim_;
w = wlast = region->w; x = w + n; f = flast = x + n*t->ndim;
wL = regionL->w; xL = wL + nL; fL = xL + nL*t->ndim;
wR = regionR->w; xR = wR + nR; fR = xR + nR*t->ndim;
while( n-- ) {
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));
*wL++ = *w++;
VecCopy(xL, x);
xL += ndim_;
xL += t->ndim;
ResCopy(fL, f);
fL += ncomp_;
fL += t->ncomp;
}
else {
if( final && wL > regionL->w ) *(wL - 1) = -fabs(*(wL - 1));
*wR++ = *w++;
VecCopy(xR, x);
xR += ndim_;
xR += t->ndim;
ResCopy(fR, f);
fR += ncomp_;
fR += t->ncomp;
}
x += ndim_;
f += ncomp_;
x += t->ndim;
f += t->ncomp;
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(regionR->bounds, region->bounds);
@ -212,12 +215,12 @@ static int Integrate(creal epsrel, creal epsabs,
StretchGrid(bounds->grid, boundsL->grid, boundsR->grid);
Sample(nnewL, regionL, wL, xL, fL, flags);
Sample(nnewR, regionR, wR, xR, fR, flags);
Sample(t, nnewL, regionL, wL, xL, fL);
Sample(t, nnewR, regionR, wR, xR, fR);
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];
Result *rL = &regionL->result[comp];
Result *rR = &regionR->result[comp];
@ -246,7 +249,7 @@ static int Integrate(creal epsrel, creal epsabs,
region = NULL;
}
for( comp = 0; comp < ncomp_; ++comp ) {
for( comp = 0; comp < t->ncomp; ++comp ) {
cResult *tot = &totals[comp];
integral[comp] = tot->avg;
error[comp] = tot->err;
@ -256,22 +259,22 @@ static int Integrate(creal epsrel, creal epsabs,
#ifdef MLVERSION
if( REGIONS ) {
MLPutFunction(stdlink, "List", 2);
MLPutFunction(stdlink, "List", nregions_);
MLPutFunction(stdlink, "List", t->nregions);
for( region = anchor; region; region = region->next ) {
real lower[NDIM], upper[NDIM];
for( dim = 0; dim < ndim_; ++dim ) {
for( dim = 0; dim < t->ndim; ++dim ) {
cBounds *b = &region->bounds[dim];
lower[dim] = b->lower;
upper[dim] = b->upper;
}
MLPutFunction(stdlink, "Cuba`Suave`region", 4);
MLPutRealList(stdlink, lower, ndim_);
MLPutRealList(stdlink, upper, ndim_);
MLPutRealList(stdlink, lower, t->ndim);
MLPutRealList(stdlink, upper, t->ndim);
MLPutFunction(stdlink, "List", ncomp_);
for( comp = 0; comp < ncomp_; ++comp ) {
MLPutFunction(stdlink, "List", t->ncomp);
for( comp = 0; comp < t->ncomp; ++comp ) {
cResult *r = &region->result[comp];
real res[] = {r->avg, r->err, r->chisq};
MLPutRealList(stdlink, res, Elements(res));
@ -282,11 +285,8 @@ static int Integrate(creal epsrel, creal epsabs,
}
#endif
#ifdef MLVERSION
abort:
#endif
if( region ) free(region);
free(region);
while( (region = anchor) ) {
anchor = anchor->next;

View File

@ -2,11 +2,11 @@
Sample.c
the sampling step 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 *
* *
* 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 *
***************************************************************************/
typedef struct {
real sum, sqsum;
real weight, weightsum, avg, avgsum;
@ -33,8 +34,8 @@ typedef struct {
/*********************************************************************/
static void Sample(cnumber nnew, void *voidregion,
real *lastw, real *lastx, real *lastf, cint flags)
static void Sample(This *t, cnumber nnew, void *voidregion,
real *lastw, real *lastx, real *lastf)
{
TYPEDEFREGION;
@ -47,14 +48,14 @@ static void Sample(cnumber nnew, void *voidregion,
creal jacobian = 1/ldexp((real)nnew, region->div);
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 ) {
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];
creal pos = *f*NBINS;
ccount ipos = (count)pos;
@ -68,19 +69,19 @@ static void Sample(cnumber nnew, void *voidregion,
*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;
w = region->w;
region->n = lastw - w;
if( VERBOSE > 2 ) {
char *p0;
MemAlloc(ss, ndim_*64 + ncomp_*(sizeof(char *) + chars));
s = (char *)(ss + ncomp_);
p0 = s + ndim_*64;
for( comp = 0; comp < ncomp_; ++comp ) {
MemAlloc(ss, t->ndim*64 + t->ncomp*(sizeof(char *) + chars));
s = (char *)(ss + t->ncomp);
p0 = s + t->ndim*64;
for( comp = 0; comp < t->ncomp; ++comp ) {
ss[comp] = p0;
p0 += chars;
}
@ -94,7 +95,7 @@ static void Sample(cnumber nnew, void *voidregion,
creal weight = fabs(*w++);
++n;
for( comp = 0; comp < ncomp_; ++comp ) {
for( comp = 0; comp < t->ncomp; ++comp ) {
Cumulants *c = &cumul[comp];
creal wfun = weight*(*f++);
@ -134,7 +135,7 @@ static void Sample(cnumber nnew, void *voidregion,
region->df = --df;
for( comp = 0; comp < ncomp_; ++comp ) {
for( comp = 0; comp < t->ncomp; ++comp ) {
Result *r = &region->result[comp];
Cumulants *c = &cumul[comp];
creal sigsq = 1/c->weightsum;
@ -166,9 +167,9 @@ static void Sample(cnumber nnew, void *voidregion,
if( VERBOSE > 2 ) {
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];
p += sprintf(p,
(dim == 0) ? "\nRegion (" REALF ") - (" REALF ")" :
@ -176,7 +177,7 @@ static void Sample(cnumber nnew, void *voidregion,
b->lower, b->upper);
}
for( comp = 0; comp < ncomp_; ++comp ) {
for( comp = 0; comp < t->ncomp; ++comp ) {
cResult *r = &region->result[comp];
p += sprintf(p, "%s \tchisq " REAL " (" COUNT " df)",
p0, r->chisq, df);

View File

@ -2,11 +2,11 @@
Suave.c
Subregion-adaptive Vegas Monte-Carlo integration
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 *
* *
* 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 *
***************************************************************************/
#include "util.c"
#include "decl.h"
#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-- ) {
integrand_(&ndim_, x, &ncomp_, f, w++);
x += ndim_;
f += ncomp_;
if( t->integrand(&t->ndim, x, &t->ncomp, f, t->userdata,
w++, &iter) == ABORT )
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"
Extern void EXPORT(Suave)(ccount ndim, ccount ncomp,
Integrand integrand,
Integrand integrand, void *userdata,
creal epsrel, creal epsabs,
cint flags, cnumber mineval, cnumber maxeval,
cint flags, cint seed,
cnumber mineval, cnumber maxeval,
cnumber nnew, creal flatness,
count *pnregions, number *pneval, int *pfail,
real *integral, real *error, real *prob)
{
ndim_ = ndim;
ncomp_ = ncomp;
This t;
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;
else {
neval_ = 0;
integrand_ = integrand;
*pfail = Integrate(epsrel, Max(epsabs, NOTZERO),
flags, mineval, maxeval, nnew, flatness,
integral, error, prob);
*pnregions = nregions_;
*pneval = neval_;
}
*pfail = Integrate(&t, integral, error, prob);
*pnregions = t.nregions;
*pneval = t.neval;
}
/*********************************************************************/
Extern void EXPORT(suave)(ccount *pndim, ccount *pncomp,
Integrand integrand,
Integrand integrand, void *userdata,
creal *pepsrel, creal *pepsabs,
cint *pflags, cnumber *pmineval, cnumber *pmaxeval,
cint *pflags, cint *pseed,
cnumber *pmineval, cnumber *pmaxeval,
cnumber *pnnew, creal *pflatness,
count *pnregions, number *pneval, int *pfail,
real *integral, real *error, real *prob)
{
EXPORT(Suave)(*pndim, *pncomp,
integrand,
*pepsrel, *pepsabs,
*pflags, *pmineval, *pmaxeval,
*pnnew, *pflatness,
pnregions, pneval, pfail,
integral, error, prob);
This t;
t.ndim = *pndim;
t.ncomp = *pncomp;
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.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
includes most of the modules
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 *
* *
* 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 *
***************************************************************************/
#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 "ChiSquare.c"
#include "Grid.c"
@ -32,21 +51,3 @@
#include "Fluct.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
Type declarations
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 *
* *
* 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 *
***************************************************************************/
#include "stddecl.h"
#define MINSAMPLES 10
@ -46,7 +47,6 @@ typedef struct {
typedef const Result cResult;
typedef struct {
real lower, upper, mid;
Grid grid;
@ -54,6 +54,27 @@ typedef struct {
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 \
typedef struct region { \
@ -66,6 +87,3 @@ typedef const Bounds cBounds;
real w[]; \
} Region
typedef void (*Integrand)(ccount *, creal *, ccount *, real *, creal *);

View File

@ -2,11 +2,11 @@
Grid.c
utility functions for the Vegas grid
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 *
* *
* 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 *
***************************************************************************/
static inline void GetGrid(Grid *grid)
static inline void GetGrid(cThis *t, Grid *grid)
{
count bin, dim;
unsigned const int slot = abs(EXPORT(vegasgridno)) - 1;
unsigned const int slot = abs(t->gridno) - 1;
if( EXPORT(vegasgridno) < 0 ) {
EXPORT(vegasgridno) = -EXPORT(vegasgridno);
if( slot < MAXGRIDS ) griddim_[slot] = 0;
}
if( t->gridno < 0 && slot < MAXGRIDS ) griddim_[slot] = 0;
if( slot < MAXGRIDS && gridptr_[slot] ) {
if( griddim_[slot] == ndim_ ) {
if( griddim_[slot] == t->ndim ) {
VecCopy(grid, gridptr_[slot]);
return;
}
@ -46,26 +44,26 @@ static inline void GetGrid(Grid *grid)
for( bin = 0; bin < NBINS; ++bin )
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);
}
/*********************************************************************/
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( gridptr_[slot] == NULL ) Alloc(gridptr_[slot], ndim_);
griddim_[slot] = ndim_;
if( gridptr_[slot] == NULL ) Alloc(gridptr_[slot], t->ndim);
griddim_[slot] = t->ndim;
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;
Grid imp, newgrid;

View File

@ -2,11 +2,11 @@
Integrate.c
integrate over the unit hypercube
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 *
* *
* 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 *
***************************************************************************/
static int Integrate(creal epsrel, creal epsabs,
cint flags, cnumber mineval, cnumber maxeval,
cnumber nstart, cnumber nincrease,
real *integral, real *error, real *prob)
static int Integrate(This *t, real *integral, real *error, real *prob)
{
real *sample;
count dim, comp;
int fail = 1;
int fail = -99;
struct {
count niter;
number nsamples, neval;
@ -43,49 +41,55 @@ static int Integrate(creal epsrel, creal epsabs,
struct stat st;
if( VERBOSE > 1 ) {
char s[256];
char s[512];
sprintf(s, "Vegas input parameters:\n"
" ndim " COUNT "\n ncomp " COUNT "\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"
" vegasgridno %d\n vegasstate \"%s\"\n",
ndim_, ncomp_,
epsrel, epsabs,
flags, mineval, maxeval,
nstart, nincrease,
EXPORT(vegasgridno), EXPORT(vegasstate));
" nbatch " NUMBER "\n gridno %d\n"
" statefile \"%s\"\n",
t->ndim, t->ncomp,
t->epsrel, t->epsabs,
t->flags, t->seed,
t->mineval, t->maxeval,
t->nstart, t->nincrease, t->nbatch,
t->gridno, t->statefile);
Print(s);
}
#ifdef MLVERSION
if( setjmp(abort_) ) goto abort;
#endif
if( BadComponent(t) ) return -2;
if( BadDimension(t) ) return -1;
IniRandom(2*maxeval, flags);
SamplesAlloc(sample);
if( *EXPORT(vegasstate) && stat(EXPORT(vegasstate), &st) == 0 &&
st.st_size == sizeof(state) && (st.st_mode & 0400) ) {
cint h = open(EXPORT(vegasstate), O_RDONLY);
read(h, &state, sizeof(state));
if( setjmp(t->abort) ) goto abort;
IniRandom(t);
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);
SkipRandom(neval_ = state.neval);
t->rng.skiprandom(t, t->neval = state.neval);
if( VERBOSE ) {
char s[256];
sprintf(s, "\nRestoring state from %s.", EXPORT(vegasstate));
sprintf(s, "\nRestoring state from %s.", t->statefile);
Print(s);
}
}
else {
t->statefile = NULL;
state.niter = 0;
state.nsamples = nstart;
state.nsamples = t->nstart;
Zap(state.cumul);
GetGrid(state.grid);
GetGrid(t, state.grid);
}
SamplesAlloc(sample, EXPORT(vegasnbatch));
/* main iteration loop */
for( ; ; ) {
@ -95,20 +99,20 @@ static int Integrate(creal epsrel, creal epsabs,
Zap(margsum);
for( ; nsamples > 0; nsamples -= EXPORT(vegasnbatch) ) {
cnumber nbatch = IMin(EXPORT(vegasnbatch), nsamples);
for( ; nsamples > 0; nsamples -= t->nbatch ) {
cnumber n = IMin(t->nbatch, nsamples);
real *w = sample;
real *x = w + nbatch;
real *f = x + nbatch*ndim_;
real *lastf = f + nbatch*ncomp_;
real *x = w + n;
real *f = x + n*t->ndim;
real *lastf = f + n*t->ncomp;
bin_t *bin = (bin_t *)lastf;
while( x < f ) {
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;
ccount ipos = (count)pos;
creal prev = (ipos == 0) ? 0 : state.grid[dim][ipos - 1];
@ -121,7 +125,7 @@ static int Integrate(creal epsrel, creal epsabs,
*w++ = weight;
}
DoSample(nbatch, sample, w, f);
DoSample(t, n, sample, w, f, state.niter + 1);
w = sample;
bin = (bin_t *)lastf;
@ -129,7 +133,7 @@ static int Integrate(creal epsrel, creal epsabs,
while( f < lastf ) {
creal weight = *w++;
for( comp = 0; comp < ncomp_; ++comp ) {
for( comp = 0; comp < t->ncomp; ++comp ) {
real wfun = weight*(*f++);
if( wfun ) {
Cumulants *c = &state.cumul[comp];
@ -137,12 +141,12 @@ static int Integrate(creal epsrel, creal epsabs,
c->sum += wfun;
c->sqsum += wfun *= wfun;
for( dim = 0; dim < ndim_; ++dim )
for( dim = 0; dim < t->ndim; ++dim )
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 */
for( comp = 0; comp < ncomp_; ++comp ) {
for( comp = 0; comp < t->ncomp; ++comp ) {
Cumulants *c = &state.cumul[comp];
real avg, sigsq;
real w = Weight(c->sum, c->sqsum, state.nsamples);
@ -177,9 +181,9 @@ static int Integrate(creal epsrel, creal epsabs,
p += sprintf(p, "\n"
"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];
p += sprintf(p, "\n[" COUNT "] "
REAL " +- " REAL " \tchisq " REAL " (" COUNT " df)",
@ -189,21 +193,21 @@ static int Integrate(creal epsrel, creal epsabs,
Print(s);
}
if( fail == 0 && neval_ >= mineval ) {
if( *EXPORT(vegasstate) ) unlink(EXPORT(vegasstate));
if( fail == 0 && t->neval >= t->mineval ) {
if( t->statefile ) unlink(t->statefile);
break;
}
if( neval_ >= maxeval && *EXPORT(vegasstate) == 0 ) break;
if( t->neval >= t->maxeval && t->statefile == NULL ) break;
if( ncomp_ == 1 )
for( dim = 0; dim < ndim_; ++dim )
RefineGrid(state.grid[dim], margsum[0][dim], flags);
if( t->ncomp == 1 )
for( dim = 0; dim < t->ndim; ++dim )
RefineGrid(t, state.grid[dim], margsum[0][dim]);
else {
for( dim = 0; dim < ndim_; ++dim ) {
for( dim = 0; dim < t->ndim; ++dim ) {
Grid wmargsum;
Zap(wmargsum);
for( comp = 0; comp < ncomp_; ++comp ) {
for( comp = 0; comp < t->ncomp; ++comp ) {
real w = state.cumul[comp].avg;
if( w != 0 ) {
creal *m = margsum[comp][dim];
@ -213,44 +217,41 @@ static int Integrate(creal epsrel, creal epsabs,
wmargsum[bin] += w*m[bin];
}
}
RefineGrid(state.grid[dim], wmargsum, flags);
RefineGrid(t, state.grid[dim], wmargsum);
}
}
++state.niter;
state.nsamples += nincrease;
state.nsamples += t->nincrease;
if( *EXPORT(vegasstate) ) {
cint h = creat(EXPORT(vegasstate), 0666);
if( t->statefile ) {
cint h = creat(t->statefile, 0666);
if( h != -1 ) {
state.neval = neval_;
write(h, &state, sizeof(state));
state.neval = t->neval;
write(h, &state, sizeof state);
close(h);
if( statemsg ) {
char s[256];
sprintf(s, "\nSaving state to %s.", EXPORT(vegasstate));
sprintf(s, "\nSaving state to %s.", t->statefile);
Print(s);
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];
integral[comp] = c->avg;
error[comp] = c->err;
prob[comp] = ChiSquare(c->chisq, state.niter);
}
#ifdef MLVERSION
abort:
#endif
free(sample);
PutGrid(state.grid);
PutGrid(t, state.grid);
return fail;
}

View File

@ -2,11 +2,11 @@
Vegas.c
Vegas Monte-Carlo integration
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 *
* *
* 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 *
***************************************************************************/
#include "util.c"
#include "decl.h"
#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-- ) {
integrand_(&ndim_, x, &ncomp_, f, w++);
x += ndim_;
f += ncomp_;
if( t->integrand(&t->ndim, x, &t->ncomp, f, t->userdata,
w++, &iter) == ABORT )
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"
Extern void EXPORT(Vegas)(ccount ndim, ccount ncomp,
Integrand integrand,
creal epsrel, creal epsabs,
cint flags, cnumber mineval, cnumber maxeval,
cnumber nstart, cnumber nincrease,
Integrand integrand, void *userdata,
creal epsrel, creal epsabs, cint flags, cint seed,
cnumber mineval, cnumber maxeval,
cnumber nstart, cnumber nincrease, cnumber nbatch,
cint gridno, cchar *statefile,
number *pneval, int *pfail,
real *integral, real *error, real *prob)
{
ndim_ = ndim;
ncomp_ = ncomp;
This t;
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;
else {
neval_ = 0;
integrand_ = integrand;
*pfail = Integrate(epsrel, epsabs,
flags, mineval, maxeval, nstart, nincrease,
integral, error, prob);
*pneval = neval_;
}
*pfail = Integrate(&t, integral, error, prob);
*pneval = t.neval;
}
/*********************************************************************/
Extern void EXPORT(vegas)(ccount *pndim, ccount *pncomp,
Integrand integrand,
creal *pepsrel, creal *pepsabs,
cint *pflags, cnumber *pmineval, cnumber *pmaxeval,
Integrand integrand, void *userdata,
creal *pepsrel, creal *pepsabs, cint *pflags, cint *pseed,
cnumber *pmineval, cnumber *pmaxeval,
cnumber *pnstart, cnumber *pnincrease,
cnumber *pnbatch, cint *pgridno, cchar *statefile,
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 */
if( *EXPORT(vegasstate) ) {
char *p;
EXPORT(vegasstate)[sizeof(EXPORT(vegasstate)) - 1] = 0;
if( (p = strchr(EXPORT(vegasstate), ' ')) ) *p = 0;
}
char *s = NULL;
This t;
t.ndim = *pndim;
t.ncomp = *pncomp;
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,
integrand,
*pepsrel, *pepsabs,
*pflags, *pmineval, *pmaxeval,
*pnstart, *pnincrease,
pneval, pfail,
integral, error, prob);
if( statefile ) {
/* strip trailing spaces */
while( statefilelen > 0 && statefile[statefilelen - 1] == ' ' )
--statefilelen;
if( statefilelen > 0 && (s = malloc(statefilelen + 1)) ) {
memcpy(s, statefile, statefilelen);
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
include most of the modules
Code common to Vegas.c and Vegas.tm
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 *
* *
* 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 *
***************************************************************************/
#include "Random.c"
#include "ChiSquare.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"
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
Type declarations
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 *
* *
* 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 *
***************************************************************************/
#include "stddecl.h"
#define MAXGRIDS 10
#define MAXSTATESIZE 128
#define NBINS 128
typedef unsigned char bin_t;
@ -49,5 +48,28 @@ typedef struct {
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];