00001 #include "integratevec.h"
00002 #include "message.h"
00003 #include "cfortran.h"
00004 #include "utils.h"
00005 #include <cmath>
00006 #include <iostream>
00007 using namespace std;
00008
00009 #define nint iround<double>
00010
00011
00012
00013
00014 PROTOCCALLSFSUB17(DCUHRE,dcuhre,INT,INT,DOUBLEV,DOUBLEV,INT,INT,ROUTINE,DOUBLE,DOUBLE,INT,INT,INT,DOUBLEV,DOUBLEV,PINT,PINT,DOUBLEV)
00015 #define DCUHRE(NDIM,NUMFUN,A,B,MINPTS,MAXPTS,FUNSUB,EPSABS,EPSREL,KEY,NW,RESTAR,RESULT,ABSERR,NEVAL,IFAIL,WORK) CCALLSFSUB17(DCUHRE,dcuhre,INT,INT,DOUBLEV,DOUBLEV,INT,INT,ROUTINE,DOUBLE,DOUBLE,INT,INT,INT,DOUBLEV,DOUBLEV,PINT,PINT,DOUBLEV,NDIM,NUMFUN,A,B,MINPTS,MAXPTS,FUNSUB,EPSABS,EPSREL,KEY,NW,RESTAR,RESULT,ABSERR,NEVAL,IFAIL,WORK)
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 void* Global_CIntegrateVector_ClassPtr;
00026 void (*Global_CIntegrateVector_FuncPtr)(void*,int*,double*,int*,double*);
00027 void Global_CIntegrateVector_FuncWrapper(int* i, double* x, int* j, double* y){
00028 return Global_CIntegrateVector_FuncPtr(Global_CIntegrateVector_ClassPtr,i,x,j,y);
00029 }
00030
00031
00032
00033
00034 CIntegrateVector::CIntegrateVector(void){
00035 _ndim=0;
00036 _numfunc=0;
00037 _lowerlimits=NULL;
00038 _upperlimits=NULL;
00039 _minpts=10;
00040 _maxpts=100;
00041 _abserr=1e-14;
00042 _relerr=1e-6;
00043 _key=0;
00044 _restart=0;
00045 _results=NULL;
00046 _error=NULL;
00047 _work=NULL;
00048 _numftncalls=127;
00049 }
00050
00051
00052
00053
00054 CIntegrateVector::~CIntegrateVector(void){
00055 DeleteWorkArray();
00056 DeleteResults();
00057 DeleteLimits();
00058 }
00059
00060
00061
00062
00063 void CIntegrateVector::CheckNDim(void){
00064 if ((1>_ndim)||(_ndim>15)) {MESSAGE<<"Bad NDIM"<<ENDM_FATAL; exit(-1);}
00065 }
00066
00067
00068
00069
00070 void CIntegrateVector::CheckKey(void){
00071 if ((0>_key)||(_key>4)) {MESSAGE<<"Bad KEY"<<ENDM_FATAL; exit(-1);}
00072 }
00073
00074
00075
00076
00077 void CIntegrateVector::CheckMaxPts(void){
00078 if (_maxpts < _minpts) {MESSAGE<<"Bad MAXPTS"<<ENDM_FATAL; exit(-1);}
00079 if (_maxpts<3*_numftncalls) {
00080 _maxpts=3*_numftncalls+1;
00081 MESSAGE << "MAXPTS to low in CIntegrateVector. Restting value to "<<
00082 _maxpts<<ENDM_WARN;
00083 }
00084 }
00085
00086
00087
00088
00089 void CIntegrateVector::NewLimits(void){
00090 if (_lowerlimits != NULL) DeleteLimits();
00091 if (_upperlimits != NULL) DeleteLimits();
00092 if (_ndim<=0) {MESSAGE<<"Bad NDIM"<<ENDM_FATAL; exit(-1);}
00093 _lowerlimits = new double[_ndim];
00094 _upperlimits = new double[_ndim];
00095 }
00096
00097
00098
00099 void CIntegrateVector::DeleteLimits(void){
00100 if (_lowerlimits != NULL) delete [] _lowerlimits;
00101 if (_upperlimits != NULL) delete [] _upperlimits;
00102 _ndim=0;
00103 _lowerlimits=NULL;
00104 _upperlimits=NULL;
00105 }
00106
00107
00108
00109
00110 void CIntegrateVector::NewResults(void){
00111 if (_results != NULL) DeleteResults();
00112 if (_numfunc<=0) {MESSAGE<<"Bad NUMFUNC"<<ENDM_FATAL; exit(-1);}
00113 _results = new double[_numfunc];
00114 _error = new double[_numfunc];
00115 }
00116
00117
00118
00119
00120 void CIntegrateVector::DeleteResults(void){
00121 if (_results != NULL) delete [] _results;
00122 if (_error != NULL) delete [] _error;
00123 _numfunc=0;
00124 _results=NULL;
00125 _error=NULL;
00126 }
00127
00128
00129
00130
00131 void CIntegrateVector::NewWorkArray(void){
00132 if (_work != NULL) DeleteWorkArray();
00133 SetNW();
00134 if (_nw<=0) {MESSAGE<<"Bad NW"<<ENDM_FATAL; exit(-1);}
00135 _work = new double[_nw];
00136 }
00137
00138
00139
00140
00141 void CIntegrateVector::DeleteWorkArray(void){
00142 if (_work == NULL) return;
00143 delete [] _work;
00144 _nw=0;
00145 _work=NULL;
00146 }
00147
00148
00149
00150
00151 void CIntegrateVector::SetNumFtnCalls(void){
00152 if (_ndim == 2) {_numftncalls=65;}
00153 else if (_ndim == 3) {_numftncalls=127;}
00154 else {
00155 _numftncalls = 1 + 4*2*_ndim + 2*_ndim*(_ndim-1) + 4*_ndim*(_ndim-1) +
00156 4*_ndim*(_ndim-1)*(_ndim-2)/3 + nint(pow(2.,_ndim));
00157 }
00158 if (_key == 4) {
00159 _numftncalls = 1 + 3*2*_ndim + 2*_ndim*(_ndim-1)
00160 + nint(pow(2.,_ndim));
00161 }
00162 }
00163
00164
00165
00166 void CIntegrateVector::SetNW(void){
00167 int MDIV=1;
00168 int MAXSUB=(_maxpts-_numftncalls)/(2*_numftncalls)+1;
00169 _nw=MAXSUB*(2*_ndim+2*_numfunc+2) + 17*_numfunc*MDIV + 1;
00170 }
00171
00172
00173
00174
00175 void CIntegrateVector::Compute(void (*_func)(int*,double*,int*,double*)){
00176 SetNumFtnCalls();
00177 CheckMaxPts();
00178 NewWorkArray();
00179 DCUHRE(_ndim,_numfunc,_lowerlimits,_upperlimits,_minpts,_maxpts,_func,
00180 _abserr,_relerr,_key,_nw,_restart,_results,_error,_neval,_ifail,_work);
00181 }
00182 void CIntegrateVector::Compute(void* classptr, void (*_func)(void*,int*,double*,int*,double*)){
00183 SetNumFtnCalls();
00184 CheckMaxPts();
00185 NewWorkArray();
00186 Global_CIntegrateVector_ClassPtr = classptr;
00187 Global_CIntegrateVector_FuncPtr = _func;
00188 DCUHRE(_ndim,_numfunc,_lowerlimits,_upperlimits,_minpts,_maxpts,
00189 Global_CIntegrateVector_FuncWrapper,
00190 _abserr,_relerr,_key,_nw,_restart,_results,_error,_neval,_ifail,_work);
00191 }
00192