TF1 derivative within another TF1


ROOT Version: 6.08/00
Platform: Ubuntu 16.04
Compiler: 5.4.0


Hello,

I was wondering if I can take derivative of a user-defined TF1 in another TF1. Something like the following:

  TF1 * f1=new TF1("f1","([3]/[2])*((log(fabs([1]*exp([2]*x)))/sqrt([0]*[0]-[3]*[3]))+log(fabs((1.0/[3])*(sqrt(pow([0]+[1]*exp([2]*x),2)-[3]*[3])+[0]+[1]*exp([2]*x))))/([3]-[0]))",0,20000);
  f1->FixParameter(0,1.78);
  f1->FixParameter(1,-0.43);
  f1->FixParameter(2,-0.0132);
  f1->SetParameter(3,1.5);

  TF1 * f2=new TF1("f2","(([0]+[1]*exp([2]*x))/[3])*sqrt(1+pow(f1->Derivative(x),2))",0,1000);
  f2->FixParameter(0,1.78);
  f2->FixParameter(1,-0.43);
  f2->FixParameter(2,-0.0132);
  f2->FixParameter(3,299792458.0);

Please let me know if there is a way to do this.

Thanks,
Uzair

Hello,

You can try to wrap the TF1 derivative in a c++ function

// -- Create a curve ( a * x^2 )
TF1 myParab_f("myParab", "[0]*x*x" , 0 ,2, 1) // range (0,2), 1 parameter
//---- Check that works
//---- myParab_f.SetParameter(0,2)
//---- myParab_f.Draw()

//-- create a lambda function with the derivative of the previous curve,
auto ff = [&](double *x, double * par){ myParab_f.SetParameters(par); return myParab_f.Derivative(*x);}

//-- create the TF1 corresponding to the derivative,
TF1 myDeriv("myDeriv", ff, 0 ,2 ) // range (0,2)
myDeriv.SetParameter(0,3)
myDeriv.Draw()

I hope this can help.

Best regards,
atd
PS: I think that using lambda functions for building TF1 was deprecated for ROOT > 6.12

ROOT Version: 6.10/08
Platform: Ubuntu CC7
Compiler: gcc 4.8

Thanks alot for the reply! After consulting the root website and your answer I made this code which seems to work for me:

void checkfun(){

 TF1 *myParab_f=new TF1("myParab", "[0]*x*x" , 0 ,2); // range (0,2), 1 parameter
  myParab_f->SetParameter(0,-7);
  myParab_f->Draw();

// //-- create the TF1 corresponding to the derivative,
  TF1 *myDeriv=new TF1("myDeriv", [&](double *x, double *p){ return p[0]*myParab_f->Derivative(x[0]);}, 0 ,2 ,1); // range (0,2)
  myDeriv->SetParameter(0,1);
  myDeriv->Draw();

}

However my code seems to crash by giving a segmentation error if I do: root -l checkfun.C+

If I just do root -l checkun.C then it works.

Any idea on why would this happen? I have pasted the stack trace below:

The lines below might hint at the cause of the crash.
You may get help by asking at the ROOT forum http://root.cern.ch/forum.
Only if you are really convinced it is a bug in ROOT then please submit a
report at http://root.cern.ch/bugs. Please post the ENTIRE stack trace
from above as an attachment in addition to anything else
that might help us fixing this issue.

===========================================================
#6  0x00007f7abb268986 in ROOT::Math::ParamFunctorHandler<ROOT::Math::ParamFunctor, checkfun()::{lambda(double*, double*)#1}>::operator()(double*, double*) () from /home/uzair/Documents/raytrace/dtDR/fitray/dirmeth/checkfun_C.so
#7  0x00007f7abe23f3ed in ROOT::Math::ParamFunctor::operator() (this=<optimized out>, p=<optimized out>, x=<optimized out>) at /usr/local/root6/include/Math/ParamFunctor.h:292
#8  TF1::EvalPar (this=0x3cbb490, x=<optimized out>, params=<optimized out>) at /home/uzair/Downloads/root-6.08.00/hist/hist/src/TF1.cxx:1237
#9  0x00007f7abe246943 in TF1::DoCreateHistogram (this=0x3cbb490, xmin=<optimized out>, xmax=<optimized out>, recreate=<optimized out>) at /home/uzair/Downloads/root-6.08.00/hist/hist/src/TF1.cxx:2829
#10 0x00007f7abe246068 in TF1::Paint (this=0x3cbb490, option=0x38df099 "") at /home/uzair/Downloads/root-6.08.00/hist/hist/src/TF1.cxx:2706
#11 0x00007f7abe945b5b in TPad::PaintModified (this=0x3abf1e0) at /home/uzair/Downloads/root-6.08.00/graf2d/gpad/src/TPad.cxx:3213
#12 0x00007f7abe91d53d in TCanvas::Update (this=0x3abf1e0) at /home/uzair/Downloads/root-6.08.00/graf2d/gpad/src/TCanvas.cxx:2219
#13 0x00007f7acfe6bcd9 in TCling::UpdateAllCanvases () at /home/uzair/Downloads/root-6.08.00/core/meta/src/TCling.cxx:5754
===========================================================

Try catching the myParab_f as a copy, not as a reference, in your lambda function, i.e.

TF1 *myDeriv=new TF1("myDeriv", [myParab_f](double *x, double *p){ return p[0]*myParab_f->Derivative(x[0]);}, 0 ,2 ,1); // range (0,2)

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.