For my data analysis I need to integrate a 4-dimensional parametric function, and I read the old RootTalk problem Integration of a multidimensional parametric functions. I followed that suggestion and modified my code by using ROOT::Math::WrappedParamFunction<>, it doesn’t work for me then. I upload my code here, could anyone can help me to look at it and point out what I should do for this purpose. Many thanks.
#include “Math/AdaptiveIntegratorMultiDim.h” #include <Math/WrappedParamFunction.h>
double f(double *x, double *par){
return par[0]*x[0]+par[1]*x[1]+par[2]*x[2]+x[3];
}
int NumericalIntegration()
{ // Create the function and wrap it
ROOT::Math::WrappedParamFunction<> wf( &f, 4, 3);
wf.SetParameters(1,2,3);
// Create the Integrator
ROOT::Math::AdaptiveIntegratorMultiDim ig;
// Set parameters of the integration
ig.SetFunction(wf);
ig.SetRelTolerance(0.001);
double xmin[] = {1,0,2,0};
double xmax[] = {3,3,4,5};
cout << ig.Integral(xmin, xmax) << endl;
return 0;
} BCfactortest.C (972 Bytes)
Thank you so much for your kind help. I download and run the corrected code, it shows me couple errors:
Error: expected ‘,’ or ‘;’ before ‘:’ /u/apps/root/5.30.00/root/include/Math/WrappedParamFunction.h:49:
Error: Symbol FreeParamMultiFunctionPtr func is not defined in current scope /u/apps/root/5.30.00/root/include/Math/WrappedParamFunction.h:49:
Error: Invalid type ‘unsigned’ in declaration of ‘int dim’ /u/apps/root/5.30.00/root/include/Math/WrappedParamFunction.h:49:
Error: Invalid type ‘unsigned’ in declaration of ‘int npar’ /u/apps/root/5.30.00/root/include/Math/WrappedParamFunction.h:49:
Error: Symbol double is not defined in current scope /u/apps/root/5.30.00/root/include/Math/WrappedParamFunction.h:49:
Error in : Dictionary generation failed!
*** Break *** segmentation violation
Do I have to define a FreeParamMultiFunctionPtr func? I am confused with these errors. I wondered if it works well for you without any error? If so, is it relate to my root version? Could you let me know what version do you use? Many thanks.
First things first (before you try to upgrade your ROOT) … the error that you show suggests that you tried this macro as “interpreted” … with ROOT 5, you must use it a “(pre)compiled macro” (e.g. using ACLiC):
root [0] .L BCfactortest.C++
root [1] NumericalIntegration()
Thank you so much for your kind reply. It works now by executing
root [0] .L BCfactortest.C++
root [1] NumericalIntegration() .
[color=#800080]
Furthermore[/color], I have one more question about this, it seams that the code doesn’t work for the function f defined as
float f( [color=#0000FF]float[/color] x, [color=#0000FF]float[/color] par){
return par[0]x[0]+par[1]x[1]+par[2]x[2]+x[3];
}
It shows errors:
Info in TUnixSystem::ACLiC: creating shared library /home/tianye/Downloads/./BCfactortest_C.so
In file included from /home/tianye/Downloads/BCfactortest_C_ACLiC_dict.h:34:0,
from /home/tianye/Downloads/BCfactortest_C_ACLiC_dict.cxx:17:
/home/tianye/Downloads/./BCfactortest.C: In function ‘int NumericalIntegration()’:
/home/tianye/Downloads/./BCfactortest.C:13:51: error: invalid conversion from ‘float ()(float, float)’ to ‘double ()(const double, const double*)’ [-fpermissive]
ROOT::Math::WrappedParamFunction<> wf( &f, 4, 3);
Since I have a Fortran complex 4-dimentional function, which is converted to C++, and it is not easy to change the function definition. So I wondered if there is a way, I can define the function as float f( [color=#0000FF]float[/color] *x, [color=#0000FF]float[/color] *par) and change my code to accept it?
You may need to write a “wrapper” function “double f(const double *x, const double *p)” which can internally call anything … e.g. something like this: [code]float MyFloatFunction(float *x, float *p) {
return p[0]*x[0]+p[1]*x[1]+p[2]*x[2]+x[3];
}