00001 #include <iostream>
00002
00003 #include "TMath.h"
00004 #include "TF1.h"
00005 #include "TCanvas.h"
00006 #include "TGraph.h"
00007 #include "TH2.h"
00008 #include "TStopwatch.h"
00009 #include <cmath>
00010
00011 using namespace std;
00012
00013 const double XMIN = 0, XMAX = 2*TMath::Pi();
00014 const Int_t NB = 100;
00015 const Int_t REP = 100000;
00016 const double TNORM = REP / 1000000.;
00017
00018 double sumTime = 0;
00019
00020 int ncall = 0;
00021
00022
00023 void DrawFunction(TF1* f1)
00024 {
00025 Double_t x[NB], y[NB], ceros[NB];
00026
00027 for ( Int_t i = (Int_t) XMIN; i < NB; ++i )
00028 {
00029 x[i] = (Double_t) i*(XMAX-XMIN)/(NB-1);
00030 y[i] = f1->Eval(x[i]);
00031 ceros[i] = 0;
00032 }
00033
00034 new TCanvas("c1", "Sin(x)", 600, 400);
00035 TH2F* hpx = new TH2F("hpx", "Sin(x)", NB, XMIN, XMAX, NB, -1,1);
00036 hpx->SetStats(kFALSE);
00037 hpx->Draw();
00038
00039 TGraph* gf = new TGraph(NB, x, y);
00040 gf->SetLineColor(1);
00041 gf->SetLineWidth(3);
00042 gf->SetTitle("Function: sin(x)");
00043 gf->Draw("SAME");
00044
00045 TGraph *axis = new TGraph(NB, x, ceros);
00046 axis->SetLineColor(1);
00047 axis->SetLineWidth(1);
00048 axis->SetLineStyle(2);
00049 axis->SetTitle("Function: axis");
00050 axis->Draw("SAME");
00051
00052 }
00053
00054 int PrintStatus(const char* begin, double result, double expected, double time)
00055 {
00056 double difference = std::abs(result-expected);
00057 string passed = "FALSE";
00058
00059 if ( difference < 1E-7 )
00060 passed = "OK";
00061
00062 cout << begin << " Obtained: ";
00063 cout.width(12);
00064 cout << result << " Expected: ";
00065 cout.width(12);
00066 cout << expected << " Difference: ";
00067 cout.width(12);
00068 cout << difference << " Time: ";
00069 cout.width(12);
00070 cout << time << " (micros/call) .............." << passed
00071 << endl;
00072
00073 return passed != "OK";
00074 }
00075
00076 int TestRoot(TF1* f1)
00077 {
00078 double x, root;
00079 int status = 0;
00080 TStopwatch w;
00081 double totalTime = 0;
00082
00083 cout << "ROOT TEST\n"
00084 << "---------------------------------------------------------"
00085 << endl;
00086
00087 w.Start(kTRUE);
00088 for ( int j = 0; j < REP; ++j )
00089 x = f1->GetX(0, XMIN, 1);
00090 w.Stop();
00091 root = 0;
00092 status += PrintStatus("Root", x, root, w.RealTime()/TNORM );
00093 totalTime += w.RealTime() ;
00094
00095 w.Start(kTRUE);
00096 for ( int j = 0; j < REP; ++j )
00097 x = f1->GetX(0, 2.5, 3.5);
00098 w.Stop();
00099 root = TMath::Pi();
00100 status += PrintStatus("Root", x, root, w.RealTime()/TNORM );
00101 totalTime += w.RealTime();
00102
00103 w.Start(kTRUE);
00104 for ( int j = 0; j < REP; ++j )
00105 x = f1->GetX(0, 6, XMAX);
00106 w.Stop();
00107 root = TMath::Pi() * 2;
00108 status += PrintStatus("Root", x, root, w.RealTime()/ TNORM );
00109 totalTime += w.RealTime();
00110
00111 cout << "Total Time: " << totalTime << endl;
00112
00113 sumTime += totalTime;
00114
00115 return status;
00116 }
00117
00118 int TestMaxMin(TF1* f1)
00119 {
00120 double x, maxmin;
00121 int status = 0;
00122 TStopwatch w;
00123 double totalTime = 0;
00124
00125 cout << "MAXMIN TEST\n"
00126 << "---------------------------------------------------------"
00127 << endl;
00128
00129 w.Start(kTRUE);
00130 for ( int j = 0; j < REP; ++j ) {
00131 ncall = 0;
00132 x = f1->GetMaximumX(XMIN, TMath::Pi());
00133 }
00134 w.Stop();
00135 maxmin = TMath::Pi() / 2;
00136 status += PrintStatus("Maximum", x, maxmin, w.RealTime()/ TNORM );
00137 std::cout << "ncall = " << ncall << std::endl;
00138 totalTime += w.RealTime();
00139
00140 w.Start(kTRUE);
00141 for ( int j = 0; j < REP; ++j )
00142 x = f1->GetMinimumX(TMath::Pi(), XMAX);
00143 w.Stop();
00144 maxmin = TMath::Pi() * 1.5;
00145 status += PrintStatus("Minimum", x, maxmin, w.RealTime()/ TNORM );
00146 totalTime += w.RealTime();
00147
00148 cout << "Total Time: " << totalTime << endl;
00149
00150 sumTime += totalTime;
00151
00152 return status;
00153 }
00154
00155 int TestDerivative(TF1* f1)
00156 {
00157 double x, derivative;
00158 int status = 0;
00159 TStopwatch w;
00160 double totalTime = 0;
00161
00162 cout << "Derivative TEST\n"
00163 << "---------------------------------------------------------"
00164 << endl;
00165
00166 for ( double i = XMIN; i < XMAX; i += 1.5 )
00167 {
00168 w.Start(kTRUE);
00169 for ( int j = 0; j < REP; ++j )
00170 x = f1->Derivative(i);
00171 w.Stop();
00172 derivative = TMath::Cos(i);
00173 status += PrintStatus("Derivative", x, derivative, w.RealTime()/ TNORM );
00174 totalTime += w.RealTime();
00175 }
00176
00177 cout << "Total Time: " << totalTime << endl;
00178
00179 sumTime += totalTime;
00180
00181 return status;
00182 }
00183
00184 int TestIntegral(TF1* f1)
00185 {
00186 double x, integral;
00187 int status = 0;
00188 TStopwatch w;
00189 double totalTime = 0;
00190
00191 cout << "Integral TEST\n"
00192 << "---------------------------------------------------------"
00193 << endl;
00194
00195 for ( double i = XMIN; i < XMAX; i += 1.5 )
00196 {
00197 w.Start(kTRUE);
00198 for ( int j = 0; j < REP; ++j )
00199 x = f1->Integral(0, i);
00200 w.Stop();
00201 integral = - TMath::Cos(i) + 1;
00202 status += PrintStatus("Integral", x, integral, w.RealTime()/ TNORM );
00203 totalTime += w.RealTime();
00204 }
00205
00206 cout << "Total Time: " << totalTime << endl;
00207
00208 sumTime += totalTime;
00209
00210 return status;
00211 }
00212
00213 double func(double * x, double * p) {
00214 double xx = *x;
00215 ncall++;
00216
00217 return p[0]*sin(xx) + p[1];
00218 }
00219 int stressTF1()
00220 {
00221 int status = 0;
00222 sumTime = 0;
00223
00224
00225 TF1* f1 = new TF1("f1", func, XMIN, XMAX,2);
00226
00227 double par[2] = {1.,0.};
00228 f1->SetParameters(par);
00229
00230 cout << "Starting Tests..." << endl;
00231
00232 status += TestRoot(f1);
00233 status += TestMaxMin(f1);
00234 status += TestDerivative(f1);
00235 status += TestIntegral(f1);
00236
00237 cout << "End of Tests..." << endl;
00238 cout << "Total time for all tests: " << sumTime << endl;
00239
00240
00241 return status;
00242 }
00243
00244 int main()
00245 {
00246 return stressTF1();
00247 }