Computational Lab in Physics: Doing calculations in C++ and using ROOT. Derivatives Steven Kornreich www.beachlook.com ROOT: http://root.cern.ch/ Using ROOT Setting up ROOT in the Rm 106 linux cluster By default, root is not in your path. To add, add this line to your .bashrc: . /usr/local/root/bin/thisroot.sh You should have the following environment variables: ROOTSYS=/usr/local/root PATH should contain $ROOTSYS/bin 2 ROOT commands Starting root, just type “root” At the root prompt: .q = Exit from root .ls = list the files loaded into root session .! some-unix-command = execute some-unixcommand in the shell Most c++ commands can also be interpreted. Executing a macro “myMacro.C”: .x myMacro.C 3 ROOT Classes Since it is C++, everything is represented by classes: Windows (or canvases) : TCanvas Functions : TF1, TF2, TF3 Class used to plot data on a canvas Histograms: TH1, TH2, TH3 Classes to manipulate mathematical functions, such as sin(x), in order to draw, evaluate, and integrate them. Graphs : TGraph A window where we can draw data, functions, etc. Classes to manipulate histograms. Can draw them on a canvas, integrate them, obtain means and RMS values, evaluate bin contents. Tutorials (lots of code to try out ROOT): $ROOTSYS/tutorials/ For example: /hsimple.C, and /hist/h1draw.C 4 Derivatives. (Klein/Godunov Text, Ch. 5) Forward difference. (5.2) df f ( x x) f ( x) lim x 0 dx x A derivative is defined as a limit. Numerically, we need to use finite quantities Note: needs to us small numbers in the computer. But watch out! Computer has finite representation! Must avoid machine precision problems. We can define the Discrete Forward-difference operator: f ( x x) f ( x) D (f) x x Introduce an error, typcially varies a polynomial in x. O(xN) 5 Derivative: What is the order of the error? Use Taylor expansion. df ( x) h d 2 f ( x) f ( x h) f ( x ) h ... 2 dx 2! dx Which implies: df ( x) Dx ( f ) O(h) dx 2 The error on the derivative will be of the same order as the step size x. This is akin to approximating the function as a straight line between two x-values. 6 Homework, First part: Example: Calculate d sin(x)/dx Write a program that will do: Print a statement that will say that the program will calculate the derivative of sin(x) Ask us for the value of x Calculate the derivative, using the finite forward difference Print it to the screen. Note: Hwk: Chapter 5 Problem 1: Asks you to do this, plus a similar program for cos(x). 7 5.3: Central difference and higher order methods. Improvement on the error behavior. Use two versions of the Taylor expansion ℎ ′ ℎ2 ′′ ℎ3 ′′′ 𝑓 𝑥+ℎ =𝑓 𝑥 + 𝑓 𝑥 + 𝑓 𝑥 + 𝑓 𝑥 +⋯ 1! 2! 3! 2 ℎ ′ ℎ ′′ ℎ3 ′′′ 𝑓 𝑥−ℎ =𝑓 𝑥 − 𝑓 𝑥 + 𝑓 𝑥 − 𝑓 𝑥 +⋯ 1! 2! 3! Solve for f’(x) but first, subtract bottom from top equation. What do we get? 𝑓 𝑥+ℎ −𝑓 𝑥−ℎ = 2ℎ𝑓 ′ 𝑥 2ℎ 3 ′′′ + 𝑓 3! 𝑥 + odd terms 8 Central difference, and beyooond! ′ 𝑓 𝑥 = + 𝒪(ℎ2 ) Key: Size of error we make is of order h2. Improvement over forward difference Can we keep going? 𝑓 𝑥+ℎ −𝑓(𝑥−ℎ) 2ℎ Can we get to accuracy 𝒪 ℎ4 ? Yes! 1 𝑓 ′ 𝑥 = 12ℎ 𝑓 𝑥 − 2ℎ − 8𝑓 𝑥 − ℎ + 8𝑓 𝑥 + ℎ − 𝑓 𝑥 + 2ℎ + 𝒪(ℎ4 ) 9 Homework, part I Klein/Godunov Ch. 5 Problem 1 (25 points): Write a program to calculate the derivatives of sin(x) and cos(x). Ask for value of x, calculate the derivative at that value, print derivative. Use forward difference. h=10-5. Problem 2 (25 points) Repeat problem 1, use central difference. Can you verify that the error has improved? Check derivative of sin at x=1.57079632679 What do you get the two cases? (Comment on this 10 in your code) Plotting the derivatives, use ROOT Homework part II, Problem 3 (25 points) Use your programs to plot values of the derivatives Simple way: Calculate them between 0 – 2p, make 1000 points for each. Store these points as 2 arrays of x and y values. Make a TGraph to draw these x and y values See the TGraph example in the ROOT page. 11 TGraph Example, from ROOT web { TCanvas *c1 = new TCanvas("c1","A Simple Graph Example",200,10,700,500); Double_t x[100], y[100]; Int_t n = 20; for (Int_t i=0;i<n;i++) { x[i] = i*0.1; y[i] = 10*sin(x[i]+0.2); } gr = new TGraph(n,x,y); gr->Draw("AC*"); return c1; } 12 Graph Draw Options The various draw options for a graph are explained in TGraph::PaintGraph. They are: • "L" A simple poly-line between every points is drawn • "F" A fill area is drawn • “F1” Idem as "F" but fill area is no more repartee around X=0 or Y=0 • "F2" draw a fill area poly line connecting the center of bins • "A" Axis are drawn around the graph • "C" A smooth curve is drawn • "*" A star is plotted at each point • "P" The current marker of the graph is plotted at each point • "B" A bar chart is drawn at each point • "[]" Only the end vertical/horizontal lines of the error bars are drawn. This option only applies to the TGraphAsymmErrors. • "1" ylow = rwymin The options are not case sensitive and they can be concatenated in most cases. Let us look at some examples 13 Homework, part III: Derivative Operator Write a program which will calculate the first and second derivatives for any function you give See Sec 5.4 for higher order derivatives. Use central difference derivative To be specific, make an example which has a linear function f(x)=x a cubic function, f(x)=x3 Show that you can feed them into the same derivative operator (one for first, one for second), and obtain the derivatives. 14 Example code: derivative operator. #include <cmath> #include <iostream> using namespace std; double cube (double aD) { return pow(aD,3); } double linear(double aD) { return pow(aD,1); } int main() { double del = 1.0e-1; int choice; cout << "Choose a function:" << endl; cout << "1) cube " << endl; cout << "2) linear " << endl; cin >> choice; switch (choice) { case 1: cout << derivOperator(cube,1.0,del) << endl; break; case 2: cout << derivOperator(linear,1.0,del) << endl; break; default: cout << "Incorrect input, exiting." << endl; } return 0; } 15 Additional Material 16 Plotting simple functions in ROOT Using TF1 write explicitly the function in the 2nd argument E.g. Aebt + Ce-dt : TF1* myFunc = new TF1(“myFunc",”[0]*exp([1]*x)+[2]*exp(-[3]*x)”,0,10); Here: [0] is parameter A, [1] is b, etc. The parameters are set via, (e.g. if A=1): myFunc->SetParameter(0,1); 17 Plotting a user defined function in ROOT double mysine(double* x, double* par) { double Amplitude = par[0]; double wavelength = par[1]; double phase = par[2]; return Amplitude*sin(2*TMath::Pi()/wavelength*x[0]+phase); } void plotsine() { TCanvas* sineCanvas = new TCanvas("sineCanvas","A*sin(2pi/lambda*x + phi)",500,500); } TF1* sineFunc = new TF1("sineFunc",&mysine,0,2*TMath::Pi(),3); sineFunc->SetParameters(2,TMath::Pi(),TMath::Pi()/2); sineFunc->Draw(); return; 18 Resources for ROOT ROOT Web page: http://root.cern.ch/ User guides http://root.cern.ch/root/doc/RootDoc.html 19 Error dependence Note: the “approximation” is actually exact for the linear case. Error estimation for linear case is misleading. When del is small, rounding errors degrade the accuracy. double variables can do ~14 sig. figs. what happens if del=1.0e-17? 20