ROOT  6.06/09
Reference Guide
vectorOperation.cxx
Go to the documentation of this file.
1 // test performance of all vectors operations +,- and *
2 
3 // results on mactelm g++ 4.01 showing ROOT::Math performs best overall
4 
5 //v3 = v1+v2 v2 += v1 v3 = v1-v2 v2 -= v1 v2 = a*v1 v1 *= a v2 = v1/a v1 /= a
6 // 0.59 0.57 0.58 0.56 0.69 0.7 1.65 1.64 2D
7 // 0.79 0.79 0.78 0.8 0.97 0.95 1.85 1.84 3D
8 // 1.07 1.07 1.07 1.07 1.32 1.31 1.72 1.71 4D
9 
10 // ROOT Physics Vector (TVector's):
11 //v3 = v1+v2 v2 += v1 v3 = v1-v2 v2 -= v1 v2 = a*v1 v1 *= a
12 // 4.4 0.97 4.41 0.96 4.43 1.13 2D
13 // 5.44 1.25 5.48 1.24 6.12 1.46 3D
14 // 17.65 7.32 17.65 7.35 10.25 7.79 4D
15 
16 // CLHEP Vector (HepVector's):
17 //v3 = v1+v2 v2 += v1 v3 = v1-v2 v2 -= v1 v2 = a*v1 v1 *= a
18 // 0.57 0.55 0.56 0.55 0.7 0.7 2D
19 // 0.8 0.79 0.78 0.77 0.96 0.94 2.7 3.7 3D
20 // 1.06 1.02 1.06 1.02 1.26 1.26 2.99 3.98 4D
21 
22 
23 
24 
25 #include "TRandom2.h"
26 #include "TStopwatch.h"
27 
28 #include <vector>
29 #include <iostream>
30 #include <iomanip>
31 
32 #ifdef DIM_2
33 #ifdef USE_POINT
34 #include "Math/Point2D.h"
36 #elif USE_CLHEP
37 #include "CLHEP/Vector/TwoVector.h"
38 typedef Hep2Vector VecType;
39 #elif USE_ROOT
40 #include "TVector2.h"
41 typedef TVector2 VecType;
42 #else
43 #include "Math/Vector2D.h"
45 #endif
46 
47 #ifndef USE_ROOT
48 #define VSUM(v) v.x() + v.y()
49 #else
50 #define VSUM(v) v.X() + v.Y()
51 #endif
52 
53 
54 #elif DIM_3 // 3 Dimensions
55 
56 #ifdef USE_POINT
57 #include "Math/Point3D.h"
59 #elif USE_CLHEP
60 #include "CLHEP/Vector/ThreeVector.h"
61 typedef Hep3Vector VecType;
62 #elif USE_ROOT
63 #include "TVector3.h"
64 typedef TVector3 VecType;
65 #else
66 #include "Math/Vector3D.h"
68 #endif
69 
70 #ifndef USE_ROOT
71 #define VSUM(v) v.x() + v.y() + v.z()
72 #else
73 #define VSUM(v) v.X() + v.Y() + v.Z()
74 #endif
75 
76 #else // default is 4D
77 
78 #undef USE_POINT
79 #ifdef USE_CLHEP
80 #include "CLHEP/Vector/LorentzVector.h"
81 typedef HepLorentzVector VecType;
82 #elif USE_ROOT
83 #include "TLorentzVector.h"
84 typedef TLorentzVector VecType;
85 #else
86 #include "Math/Vector4D.h"
88 #endif
89 
90 #ifndef USE_ROOT
91 #define VSUM(v) v.x() + v.y() + v.z() + v.t()
92 #else
93 #define VSUM(v) v.X() + v.Y() + v.Z() + v.T()
94 #endif
95 
96 #endif
97 
98 
99 const int N = 1000000;
100 
101 template<class Vector>
102 class TestVector {
103 public:
104 
105  TestVector();
106  void Add();
107  void Add2();
108  void Sub();
109  void Sub2();
110  void Scale();
111  void Scale2();
112  void Divide();
113  void Divide2();
114 
115  void PrintSummary();
116 
117 private:
118 
119  std::vector<Vector> vlist;
120  std::vector<double> scale;
121  double fTime[10]; // timing results
122  int fTest;
123 };
124 
125 
126 
127 template<class Vector>
128 TestVector<Vector>::TestVector() :
129  vlist(std::vector<Vector>(N) ),
130  scale(std::vector<double>(N) ),
131  fTest(0)
132 {
133 
134  // create list of vectors and fill them
135 
136  TRandom2 r(111);
137  for (int i = 0; i< N; ++i) {
138 #ifdef DIM_2
139  vlist[i] = Vector( r.Uniform(-1,1), r.Uniform(-1,1) );
140 #elif DIM_3
141  vlist[i] = Vector( r.Uniform(-1,1),r.Uniform(-1,1),r.Uniform(-1,1) );
142 #else // 4D
143  vlist[i] = Vector( r.Uniform(-1,1),r.Uniform(-1,1),r.Uniform(-1,1), r.Uniform(2,10) );
144 #endif
145  scale[i] = r.Uniform(0,1);
146  }
147 
148  std::cout << "test using " << typeid(vlist[0]).name() << std::endl;
149 }
150 
151 template<class Vector>
153  // normal addition
154 {
155  TStopwatch w;
156  w.Start();
157  double s = 0;
158  for (int l = 0; l<100; ++l) {
159  for (int i = 1; i< N; ++i) {
160  Vector v3 = vlist[i-1] + vlist[i];
161  s += VSUM(v3);
162  }
163  }
164 
165  std::cout << "Time for v3 = v1 + v2 :\t" << w.RealTime() << "\t" << w.CpuTime() << std::endl;
166  std::cout << "value " << s << std::endl << std::endl;
167  fTime[fTest++] = w.CpuTime();
168 }
169 
170 template<class Vector>
171 void TestVector<Vector>::Add2()
172 {
173  // self addition
174  TStopwatch w;
175  Vector v3;
176  w.Start();
177  double s = 0;
178  for (int l = 0; l<100; ++l) {
179  for (int i = 0; i< N; ++i) {
180  v3 += vlist[i];
181  s += VSUM(v3);
182  }
183  }
184 
185  std::cout << "Time for v2 += v1 :\t" << w.RealTime() << "\t" << w.CpuTime() << std::endl;
186  std::cout << "value " << s << std::endl << std::endl;
187  fTime[fTest++] = w.CpuTime();
188 }
189 
190 template<class Vector>
191 void TestVector<Vector>::Sub()
192 {
193  // normal sub
194  TStopwatch w;
195  w.Start();
196  double s = 0;
197  for (int l = 0; l<100; ++l) {
198  for (int i = 1; i< N; ++i) {
199  Vector v3 = vlist[i-1] - vlist[i];
200  s += VSUM(v3);
201  }
202  }
203 
204  std::cout << "Time for v3 = v1 - v2 :\t" << w.RealTime() << "\t" << w.CpuTime() << std::endl;
205  std::cout << "value " << s << std::endl << std::endl;
206  fTime[fTest++] = w.CpuTime();
207 }
208 
209 template<class Vector>
210 void TestVector<Vector>::Sub2()
211 {
212  // self subtruction
213  TStopwatch w;
214  Vector v3;
215  w.Start();
216  double s = 0;
217  for (int l = 0; l<100; ++l) {
218  for (int i = 0; i< N; ++i) {
219  v3 -= vlist[i];
220  s += VSUM(v3);
221  }
222  }
223 
224  std::cout << "Time for v2 -= v1 :\t" << w.RealTime() << "\t" << w.CpuTime() << std::endl;
225  std::cout << "value " << s << std::endl << std::endl;
226  fTime[fTest++] = w.CpuTime();
227 }
228 
229 
230 template<class Vector>
231 void TestVector<Vector>::Scale()
232 {
233 // normal multiply
234  TStopwatch w;
235  w.Start();
236  double s = 0;
237  for (int l = 0; l<100; ++l) {
238  for (int i = 1; i< N; ++i) {
239  Vector v3 = scale[i]*vlist[i];
240  s += VSUM(v3);
241  }
242  }
243 
244  std::cout << "Time for v2 = A * v1 :\t" << w.RealTime() << "\t" << w.CpuTime() << std::endl;
245  std::cout << "value " << s << std::endl << std::endl;
246  fTime[fTest++] = w.CpuTime();
247 }
248 
249 template<class Vector>
250 void TestVector<Vector>::Scale2()
251 {
252  // self scale
253  TStopwatch w;
254  Vector v3;
255  w.Start();
256  double s = 0;
257  for (int l = 0; l<100; ++l) {
258  for (int i = 0; i< N; ++i) {
259  v3 = vlist[i];
260  v3 *= scale[i];
261  s += VSUM(v3);
262  }
263  }
264 
265  std::cout << "Time for v *= a :\t" << w.RealTime() << "\t" << w.CpuTime() << std::endl;
266  std::cout << "value " << s << std::endl << std::endl;
267  fTime[fTest++] = w.CpuTime();
268 }
269 
270 template<class Vector>
271 void TestVector<Vector>::Divide()
272 {
273 // normal divide
274  TStopwatch w;
275  w.Start();
276  double s = 0;
277  for (int l = 0; l<100; ++l) {
278  for (int i = 1; i< N; ++i) {
279  Vector v3 = vlist[i]/scale[i];
280  s += VSUM(v3);
281  }
282  }
283 
284  std::cout << "Time for v2 = v1 / a :\t" << w.RealTime() << "\t" << w.CpuTime() << std::endl;
285  std::cout << "value " << s << std::endl << std::endl;
286  fTime[fTest++] = w.CpuTime();
287 }
288 
289 template<class Vector>
290 void TestVector<Vector>::Divide2()
291 {
292  // self divide
293  TStopwatch w;
294  Vector v3;
295  w.Start();
296  double s = 0;
297  for (int l = 0; l<100; ++l) {
298  for (int i = 0; i< N; ++i) {
299  v3 = vlist[i];
300  v3 /= scale[i];
301  s += VSUM(v3);
302  }
303  }
304 
305  std::cout << "Time for v /= a :\t" << w.RealTime() << "\t" << w.CpuTime() << std::endl;
306  std::cout << "value " << s << std::endl << std::endl;
307  fTime[fTest++] = w.CpuTime();
308 }
309 
310 
311 template<class Vector>
312 void TestVector<Vector>::PrintSummary()
313 {
314  std::cout << "\nResults for " << typeid(vlist[0]).name() << std::endl;
315  std::cout << " v3 = v1+v2"
316  << " v2 += v1 "
317  << " v3 = v1-v2"
318  << " v2 -= v1 "
319  << " v2 = a*v1 "
320  << " v1 *= a "
321  << " v2 = v1/a "
322  << " v1 /= a " << std::endl;
323 
324  for (int i = 0; i < fTest; ++i) {
325  std::cout << std::setw(8) << fTime[i] << " ";
326  }
327  std::cout << std::endl << std::endl;
328 }
329 
330 int main() {
331  TestVector<VecType> t;
332 #ifndef USE_POINT
333  t.Add();
334  t.Add2();
335  t.Sub();
336  t.Sub2();
337 #endif
338  t.Scale();
339  t.Scale2();
340 #ifndef USE_ROOT
341  t.Divide();
342  t.Divide2();
343 #endif
344 
345  // summurize test
346  t.PrintSummary();
347 }
Class describing a generic LorentzVector in the 4D space-time, using the specified coordinate system ...
Definition: LorentzVector.h:54
Double_t RealTime()
Stop the stopwatch (if it is running) and return the realtime (in seconds) passed between the start a...
Definition: TStopwatch.cxx:108
void Add(THist< DIMENSION, PRECISIONA > &to, THist< DIMENSION, PRECISIONB > &from)
Definition: THist.h:335
void Start(Bool_t reset=kTRUE)
Start the stopwatch.
Definition: TStopwatch.cxx:56
#define VSUM(v)
Random number generator class based on the maximally quidistributed combined Tausworthe generator by ...
Definition: TRandom2.h:29
Class describing a generic position vector (point) in 3 dimensions.
Double_t CpuTime()
Stop the stopwatch (if it is running) and return the cputime (in seconds) passed between the start an...
Definition: TStopwatch.cxx:123
int main()
STL namespace.
const int N
ROOT::R::TRInterface & r
Definition: Object.C:4
TLine * l
Definition: textangle.C:4
Class describing a generic position vector (point) in 2 dimensions.
ROOT::Math::XYZTVector VecType
#define name(a, b)
Definition: linkTestLib0.cpp:5
Class describing a generic displacement vector in 2 dimensions.
Stopwatch class.
Definition: TStopwatch.h:30