Comp Sci Solve C++ & ROOT Problems: 3 Questions Answered

  • Thread starter Thread starter RJLiberator
  • Start date Start date
  • Tags Tags
    C++ Root
AI Thread Summary
The discussion addresses three main issues related to C++ and ROOT programming. First, the user seeks to create multiple TLine objects for the bisection method but encounters problems when trying to reuse the same variable in a loop; a suggestion is made to use an array of TLine pointers instead. Second, the user struggles with implementing the exponential function in ROOT, and it is clarified that ROOT does not have a direct exp() function but can use TMath's Power() function for similar calculations. Lastly, the user attempts to display a variable in a TText object on a graph but finds it doesn't work as expected; the solution involves creating a string that includes the variable's value to pass to the TText constructor. Overall, the thread provides insights into resolving these programming challenges in ROOT.
RJLiberator
Gold Member
Messages
1,094
Reaction score
63
I have three problems that I've been trying to tackle for a while now.

1) I have a code for the bisection method. I would like to use TLine *line = new TLine function to create the lines that you normally see in the bisection method.

250px-Bisection_method.svg.png


These lines from a to F(a) are the ones I am talking about.

I have a for statement that does the following:

Code:
for(int i = 0; i < 10; i++)  //try 10 steps
{
  c = 0.5*(x1+x2);  // new midpoint
  tempy= f->Eval(c);

  w[ i ]=x1;
  y[ i ]=x2;

  if( fabs(tempy) < 0.00001 ) break;// found it!

  if( tempy*f(x1)  > 0 ) x1 =c;
  else x2=c;

cout<<"\nThe value is: ";
cout<< c <<"\n\n The function value at this point is: "<<tempy<<endl;

cout<<"x1 = "<<w[ i ]<<", x2 = " <<y[ i ]<<endl ;
cout<<"\n\n Function evaluated at x1 = "<<f->Eval(w[ i ])<<"\n\n Function evaluated at x2 = "<<f->Eval(y[ i ])<<endl;

}

And this works great! I get the x1 and x2 values that I need into the w[ i ]and y arrays, and I can even evaluate them at my function.

But when I type something like:

Code:
  TLine *line2 = new TLine(w[ i ], 0, w[ i ], f->Eval(w[ i ]));
  TLine *line3 = new TLine(y[ i ], 0, y[i], f->Eval(y[ i ]));
  line2->SetLineColor(kBlack);
  line3->SetLineColor(kBlack);
  line2->Draw("SAME");
  line3->Draw("SAME");

In a different for statement, it ruins the code.
I'm guessing this is because when I create the TLine i am creating just one TLine called 'line2' and trying to feed it many different lines.
But, I do not know how to make it so that I can get TLine *linei where i goes through the for loop i++.

2) The exponential function.
I am using root and I want to graph a function that looks like the following:
v = (a/b) (1-e^(-bt))

I try to define the exponential function part as float expo = exp(-b*t)
but this doesn't seem to work. I am guessing the exponential function does not work with root.
How can I get this to work? I know that there is some TMath:: things out there, but I have never been able to get them to work.

3. I am trying to write text on my graph, but It won't let me use a variable.

I have a simple TF1 graph that depicts free fall motion. I have solved it using the quadratic formula to find the root aka the time it takes for the particle to reach the floor.
I have this root labeled as t.

In my code I have the following:

Code:
TF1 *fa1 = new TF1("fa1","[0]*x*x+[1]*x+[2]",0,2*t);
  fa1->SetParameters(-0.5*g,v,h);
  fa1->SetTitle("Projectile Motion");
  fa1->GetYaxis()->SetTitle("Height in meters");
  fa1->GetXaxis()->SetTitle("Time in seconds");
  TLine *line = new TLine(0,0,2*t,0);
  line->SetLineColor(kBlue);
  TText *z = new TText(.5, -20, "Solution for t = ", t);
  z->SetTextSize(0.02);
  fa1->Draw();
  line->Draw();
  z->Draw();

As you can see, I am trying to use TText to let me write on the graph the "solution for t = " t.
But this doesn't work. The TText doesn't seem to know what to do when I simply write t.

Any suggestions on these three problems?

I thank you all greatly.
 
Last edited by a moderator:
Physics news on Phys.org
You have an array index that is causing the following text to be in italics, and will "eat" some of your code. I'm going to lock your post temporarily and fix things, and will then reopen it.
 
  • Like
Likes RJLiberator
OK, it's back open again. If you use i as the index on an array, the sequence of characters gets mistakenly taken as BBCode for italics, so x turns into just x, with the characters following showing up in italics. Aside from the weird change to italics, you also lose information about the array index.
 
  • Like
Likes RJLiberator
Damn. Thanks for checking in on that for me.

This is a tough assignment, already stayed up until 4-5am last night working on it. Have some kinks as mentioned in this post to work on tonight, will likely be up at it again all night.

I don't expect anyone here to know thoroughly about ROOT but perhaps some of the C++ in the code someone may be able to help me out with.
 
TLine *line2 = new TLine(w[ i ], 0, w[ i ], f->Eval(w[ i ]));

How does it break the code in the other function and are you certain this snippet is the only bit that is causing it to fail?
 
RJLiberator said:
I have three problems that I've been trying to tackle for a while now.

1) I have a code for the bisection method. I would like to use TLine *line = new TLine function to create the lines that you normally see in the bisection method.

250px-Bisection_method.svg.png


These lines from a to F(a) are the ones I am talking about.

I have a for statement that does the following:

Code:
for(int i = 0; i < 10; i++)  //try 10 steps
{
  c = 0.5*(x1+x2);  // new midpoint
  tempy= f->Eval(c);

  w[ i ]=x1;
  y[ i ]=x2;

  if( fabs(tempy) < 0.00001 ) break;// found it!

  if( tempy*f(x1)  > 0 ) x1 =c;
  else x2=c;

cout<<"\nThe value is: ";
cout<< c <<"\n\n The function value at this point is: "<<tempy<<endl;

cout<<"x1 = "<<w[ i ]<<", x2 = " <<y[ i ]<<endl ;
cout<<"\n\n Function evaluated at x1 = "<<f->Eval(w[ i ])<<"\n\n Function evaluated at x2 = "<<f->Eval(y[ i ])<<endl;

}

And this works great! I get the x1 and x2 values that I need into the w[ i ]and y arrays, and I can even evaluate them at my function.

But when I type something like:

Code:
  TLine *line2 = new TLine(w[ i ], 0, w[ i ], f->Eval(w[ i ]));
  TLine *line3 = new TLine(y[ i ], 0, y[i], f->Eval(y[ i ]));
  line2->SetLineColor(kBlack);
  line3->SetLineColor(kBlack);
  line2->Draw("SAME");
  line3->Draw("SAME");

In a different for statement, it ruins the code.
What do you mean, "it ruins the code"?
RJLiberator said:
I'm guessing this is because when I create the TLine i am creating just one TLine called 'line2' and trying to feed it many different lines.
But, I do not know how to make it so that I can get TLine *linei where i goes through the for loop i++.
line2 and line3 are pointers to TLine instances. If you need to save a bunch of these things you could create an array of pointers to type TLine.

Something like this, where n is a constant. Caveat emptor -- I haven't checked this code.
C:
TLine * lines[n] ;
lines[0] = new TLine(w[ i ], 0, w[ i ], f->Eval(w[ i ]));
// etc. for the other array elements
RJLiberator said:
2) The exponential function.
I am using root and I want to graph a function that looks like the following:
v = (a/b) (1-e^(-bt))

I try to define the exponential function part as float expo = exp(-b*t)
but this doesn't seem to work. I am guessing the exponential function does not work with root.
How can I get this to work? I know that there is some TMath:: things out there, but I have never been able to get them to work.
I looked at some docs for TMath and ROOT (many of the links to docs at CERN seem to be broken). As far as I can tell, there is no exp() function, but there is a Power() function and a member named E. You have to include xmath.h.
To get ##e^{-bt}## you need to do something like this:
C:
v = a/b * (1 - Power((const double &)E, (const double &) (-b*t));
RJLiberator said:
3. I am trying to write text on my graph, but It won't let me use a variable.

I have a simple TF1 graph that depicts free fall motion. I have solved it using the quadratic formula to find the root aka the time it takes for the particle to reach the floor.
I have this root labeled as t.

In my code I have the following:

Code:
TF1 *fa1 = new TF1("fa1","[0]*x*x+[1]*x+[2]",0,2*t);
  fa1->SetParameters(-0.5*g,v,h);
  fa1->SetTitle("Projectile Motion");
  fa1->GetYaxis()->SetTitle("Height in meters");
  fa1->GetXaxis()->SetTitle("Time in seconds");
  TLine *line = new TLine(0,0,2*t,0);
  line->SetLineColor(kBlue);
  TText *z = new TText(.5, -20, "Solution for t = ", t);
  z->SetTextSize(0.02);
  fa1->Draw();
  line->Draw();
  z->Draw();

As you can see, I am trying to use TText to let me write on the graph the "solution for t = " t.
But this doesn't work. The TText doesn't seem to know what to do when I simply write t.
The TText() constructor expects three arguments, not four. If you want to have it print, say, Solution for t = 4, you need to create a string that has the 4 in it, and then pass the string as the third arg in the TText() ctor.
RJLiberator said:
Any suggestions on these three problems?

I thank you all greatly.
 
  • Like
Likes RJLiberator
Mark44 said:
What do you mean, "it ruins the code"?
line2 and line3 are pointers to TLine instances. If you need to save a bunch of these things you could create an array of pointers to type TLine.

Something like this, where n is a constant. Caveat emptor -- I haven't checked this code.
C:
TLine * lines[n] ;
lines[0] = new TLine(w[ i ], 0, w[ i ], f->Eval(w[ i ]));
// etc. for the other array elements
I looked at some docs for TMath and ROOT (many of the links to docs at CERN seem to be broken). As far as I can tell, there is no exp() function, but there is a Power() function and a member named E. You have to include xmath.h.
To get ##e^{-bt}## you need to do something like this:
C:
v = a/b * (1 - Power((const double &)E, (const double &) (-b*t));
The TText() constructor expects three arguments, not four. If you want to have it print, say, Solution for t = 4, you need to create a string that has the 4 in it, and then pass the string as the third arg in the TText() ctor.
https://root.cern.ch/doc/master/TMath_8h_source.html#l00495

inline Double_t TMath::Exp(Double_t x)
{return exp(x); }

OP said they are trying to define exp() as a float, where it is expecting a Double_t?

Nice catch on TText() :-)
 
  • Like
Likes RJLiberator
RJLiberator said:
I try to define the exponential function part as float expo = exp(-b*t)
That would give a single value. TF1 with the full function should be the right thing here. Note the ugly ROOT syntax which requires you to write it in quotation marks.
Wee-Lamm said:
OP said they are trying to define exp() as a float, where it is expecting a Double_t?
Should be fine. Nearly all things in ROOT work with float, double, Double_t and so on in the same way. TTrees are the only counterexample I know of.
 
  • Like
Likes RJLiberator
Hey guys, just wanted to thank you all for the help.

I haven't quite got the all the kinks fixed, but I did fix some of them.

The exponential function can be read as exp([parameter]*x] when I use TF1.

The lines for the bisection method could be fixed in a much simpler way then I had initially thought.
 

Similar threads

Replies
2
Views
3K
Replies
1
Views
2K
Replies
7
Views
1K
Replies
9
Views
2K
Replies
2
Views
3K
Replies
23
Views
3K
Replies
13
Views
2K
Back
Top