Hi,
I keep getting an error and the only relevant hit I got using google was on this forum (for some reason I’m not allowed to link the post)
I’m trying to fit a non-linear curve using GSL (we have 1.15 here) I can’t compute the partial derivative of this curve with respect to it’s input parameters, or at least I don’t know how to. The curve represents the envelope of a frequency that’s send to a magnet in the LHC.
I used scipy.curve_fit in python and it worked like magic, but now I need to translate it in C++. I tried calculating the Jacobian matrix, but I think I did that wrong. I tried looking into the scipy.curve_fit implementation, but when I went down that rabbit hole I found myself looking at a Fortran implementation of GSL and now I’m even more lost.
I’m hoping to find a solution to fit a function here. does anyone have any experience in this?
This is the function I’m trying to fit, it basically looks like a trapezoid. it’s 0 before start, has a linear rising edge up until the flat top, is “almost” flat at the flat top and then a linear falling edge until its 0 again.
std::vector<double> envelope(std::vector<double> timestamps, double start, double startFlt, double endFlt, double end, double startAmpl, double endAmpl) {
std::vector<double> result(timestamps.size(), 0);
double startSlope = startAmpl/(startFlt-start);
double fltSlope = (endAmpl - startAmpl) / (endFlt - startFlt);
double endSlope = (-endAmpl/(end-endFlt));
for (size_t i=0; i<result.size(); i++) {
double timestamp = timestamps[i];
if (timestamp < start) {
// do nothing, is already initialized to zero
} else if (timestamp < startFlt) {
result[i] = (startSlope * (timestamp - start));
} else if (timestamp < endFlt) {
result[i] = (fltSlope * (timestamp - startFlt) + startAmpl);
} else if (timestamp < end) {
result[i] = (endSlope * (timestamp - endFlt) + endAmpl);
} else {
// do nothing, is already initialized to zero
}
}
return result;
}
Oh and by the way. The tutorial of installing ROOT mentions cmake, is there a way by using makefile?
Don’t know whether it can help, but I’m inviting @jonas and @moneta -our RooFit experts- to this topic. Maybe the can suggest you something useful.
No, ROOT build system is based on CMake. However, if you want to install ROOT, we encourage you to install it via a pre-compiled binary package or through Conda. See Installing ROOT - ROOT for detailed instructions.
Thank you for your reply. I’ll await the other suggestions.
No, ROOT build system is based on CMake. However, if you want to install ROOT
I think I misspoke. I meant, can I include root in my c++ project that uses makefile? I couldn’t find documentation on that. I 'm working through --root url–/install/build_from_source/
In an effort to supply more information:
I’m currently working with c++03 and gsl v1.15 is installed on the FEC. I can use c++11 while building ROOT from source, although I am stuck with gcc v4.8.5 (which has c++11 as an experimental feature) and cmake v2.8.12.2.
I found this forum because the error I was getting is spoken about here: --forum url–/t/gsl-cannot-reach-the-specified-tolerance/12172
I was using gsl_multifit_fdfsolver, because there is no implementation of gsl_multifit_fsolver_type in GSL v1.15 yet. I suspect I need to use ROOT::Math::GSLMultiFit in a way, but I’m not if it is the right solution.
I guess you should be able to “upgrade” your CMake (e.g., you could take the “cmake.org” binaries or the “cmake3” package from the “EPEL” repository).
You can use ordinary makefiles for your own projects. There exist plenty of examples, e.g., grab the ROOT source code, cd root_source_dir, and then: find t[eu]* -name "*akefile*"
The GSLMultiFit method works only for least-square and likelihood fits. It requires that the function you minimise is a derived class of ROOT::Math::BasicFitMethodFunction.
For this is expected that the NumericalMinimization.C tutorial does not work in this case, since it applies to minimise a generic function.