# Integration of a multidimensional parametric functions

Hi,

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/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
// 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)

Hi,

Your code has several errors. Here is the fixed one

Lorenzo

BCfactortest.C (754 Bytes)

Hi Lorenzo,

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.

Ye

Hi,

You are using a very old ROOT version, 5.30.00. Please try a newer one, certainly not older than 5.34, but preferably ROOT 6

Lorenzo

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
/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);

instead for double f( [color=#FF0000]const double[/color] *x, [color=#FF0000]const double[/color] *par){
return par[0]*x[0]+par[1]*x[1]+par[2]*x[2]+x[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?

Many thanks!

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];
}

double f(const double *x, const double *p) {
float fx[4], fp[3], v;
fx[0] = x[0]; fx[1] = x[1]; fx[2] = x[2]; fx[3] = x[3];
fp[0] = p[0]; fp[1] = p[1]; fp[2] = p[2];
v = MyFloatFunction(fx, fp);
return v; // automatic conversion from “float” to “double”
}[/code]

Hi Pepe

Thank you so much for your help. Now I solve my problem. Thanks a lot.