00001 #include "Math/Vector3D.h"
00002 #include "Math/Point3D.h"
00003 #include "TVector3.h"
00004
00005 #include "Math/Transform3D.h"
00006 #include "Math/Rotation3D.h"
00007 #include "Math/Translation3D.h"
00008 #include "Math/RotationZYX.h"
00009 #include "TRotation.h"
00010
00011 #include "TStopwatch.h"
00012 #include "TRandom3.h"
00013
00014 #include <vector>
00015
00016 using namespace ROOT::Math;
00017
00018 class VectorTest {
00019
00020 private:
00021
00022 size_t n2Loop ;
00023 size_t nGen;
00024
00025
00026 std::vector<double> dataX;
00027 std::vector<double> dataY;
00028 std::vector<double> dataZ;
00029
00030
00031
00032 public:
00033
00034 VectorTest(int n1, int n2) :
00035 n2Loop(n1),
00036 nGen(n2),
00037 dataX(std::vector<double>(n2)),
00038 dataY(std::vector<double>(n2)),
00039 dataZ(std::vector<double>(n2))
00040 {}
00041
00042
00043
00044
00045 void print(TStopwatch & time, std::string s) {
00046 int pr = std::cout.precision(8);
00047 std::cout << s << "\t" << " time = " << time.RealTime() << "\t(sec)\t"
00048
00049 << std::endl;
00050 std::cout.precision(pr);
00051 }
00052
00053
00054 int check(std::string name, double s1, double s2, double s3, double scale=1) {
00055 double eps = 10*scale*std::numeric_limits<double>::epsilon();
00056 if ( std::fabs(s1-s2) < eps*std::fabs(s1) && std::fabs(s1-s3) < eps*std::fabs(s1) ) return 0;
00057 std::cout.precision(16);
00058 std::cout << s1 << "\t" << s2 <<"\t" << s3 << "\n";
00059 std::cout << "Test " << name << " failed !!\n\n";
00060 return -1;
00061 }
00062
00063
00064 void genData() {
00065 int n = nGen;
00066
00067
00068 TRandom3 r;
00069 for (int i = 0; i < n ; ++ i) {
00070
00071 double phi = r.Rndm()*3.1415926535897931;
00072 double eta = r.Uniform(-5.,5.);
00073 double pt = r.Exp(10.);
00074
00075
00076
00077 ROOT::Math::RhoEtaPhiVector q( pt, eta, phi);
00078 dataX[i] = q.x();
00079 dataY[i] = q.y();
00080 dataZ[i] = q.z();
00081
00082 }
00083 }
00084
00085
00086
00087 template <class V>
00088 void testCreate( std::vector<V *> & dataV, TStopwatch & tim, double& t, std::string s) {
00089
00090 int n = dataX.size();
00091 dataV.resize(n);
00092 tim.Start();
00093 for (int i = 0; i < n; ++i) {
00094 dataV[i] = new V( dataX[i], dataY[i], dataZ[i] );
00095 }
00096 tim.Stop();
00097 t += tim.RealTime();
00098 print(tim,s);
00099 }
00100
00101
00102 template <class V>
00103 double testVectorAddition( const std::vector<V *> & dataV, TStopwatch & tim, double& t, std::string s) {
00104 unsigned int n = std::min(n2Loop, dataV.size() );
00105 tim.Start();
00106 V vSum = *(dataV[0]);
00107 for (unsigned int i = 1; i < n; ++i) {
00108 vSum += *(dataV[i]);
00109 }
00110 tim.Stop();
00111 print(tim,s);
00112 t += tim.RealTime();
00113 return vSum.Mag2();
00114 }
00115
00116 template <class P>
00117 double testPointAddition( const std::vector<P *> & dataP, TStopwatch & tim, double& t, std::string s) {
00118 unsigned int n = std::min(n2Loop, dataP.size() );
00119 tim.Start();
00120 P pSum = *(dataP[0]);
00121 for (unsigned int i = 1; i < n; ++i) {
00122 P & p2 = *(dataP[i]);
00123 #ifndef HEAP_CREATION
00124 pSum += ROOT::Math::XYZVector(p2);
00125 #else
00126 ROOT::Math::XYZVector * v2 = new ROOT::Math::XYZVector(p2);
00127 pSum += *v2;
00128 #endif
00129 }
00130 tim.Stop();
00131 print(tim,s);
00132 t += tim.RealTime();
00133 return pSum.Mag2();
00134 }
00135
00136 template<class V>
00137 double getSum(const V & v) {
00138 return v.x() + v.y() + v.z();
00139 }
00140
00141
00142
00143 template <class V>
00144 double testTranslation( std::vector<V *> & dataV, const Translation3D & tr, TStopwatch & tim, double& t, std::string s) {
00145
00146 unsigned int n = dataV.size();
00147 tim.Start();
00148 double sum = 0;
00149 double dx,dy,dz;
00150 tr.GetComponents(dx,dy,dz);
00151 V vtrans(dx,dy,dz);
00152 for (unsigned int i = 0; i < n; ++i) {
00153 V & v1 = *(dataV[i]);
00154 V v2 = v1 + vtrans;
00155 sum += getSum(v2);
00156 }
00157 tim.Stop();
00158 print(tim,s);
00159 t += tim.RealTime();
00160 return sum;
00161 }
00162
00163
00164 template <class V, class T>
00165 double testTransform( std::vector<V *> & dataV, const T & trans, TStopwatch & tim, double& t, std::string s) {
00166
00167 unsigned int n = dataV.size();
00168 tim.Start();
00169 double sum = 0;
00170 for (unsigned int i = 0; i < n; ++i) {
00171 V & v1 = *(dataV[i]);
00172 V v2 = trans * v1;
00173 sum += getSum(v2);
00174 }
00175 tim.Stop();
00176 print(tim,s);
00177 t += tim.RealTime();
00178 return sum;
00179 }
00180
00181
00182 template <class V, class T1, class T2>
00183 double testTransformProd( std::vector<V *> & dataV, const T1 & trans, const T2 &, TStopwatch & tim, double& t, std::string s) {
00184
00185 unsigned int n = dataV.size();
00186 tim.Start();
00187 double sum = 0;
00188 for (unsigned int i = 0; i < n; ++i) {
00189 V & v1 = *(dataV[i]);
00190 V v2 = T2(XYZVector(v1)) * trans * v1;
00191 sum += getSum(v2);
00192 }
00193 tim.Stop();
00194 print(tim,s);
00195 t += tim.RealTime();
00196 return sum;
00197 }
00198
00199
00200 template <class V, class T1, class T2>
00201 double testTransformProd2( std::vector<V *> & dataV, const T1 & trans, const T2 &, TStopwatch & tim, double& t, std::string s) {
00202
00203 unsigned int n = dataV.size();
00204 tim.Start();
00205 double sum = 0;
00206 for (unsigned int i = 0; i < n; ++i) {
00207 V & v1 = *(dataV[i]);
00208 V v2 = trans * T2(XYZVector(v1)) * v1;
00209 sum += getSum(v2);
00210 }
00211 tim.Stop();
00212 print(tim,s);
00213 t += tim.RealTime();
00214 return sum;
00215 }
00216
00217
00218 template <class V, class T1, class T2>
00219 double testTransformProd3( std::vector<V *> & dataV, const T1 & trans1, const T2 & trans2, TStopwatch & tim, double& t, std::string s) {
00220
00221 unsigned int n = dataV.size();
00222 tim.Start();
00223 double sum = 0;
00224 for (unsigned int i = 0; i < n; ++i) {
00225 V & v1 = *(dataV[i]);
00226 V v2 = trans2 * trans1 * v1;
00227 sum += getSum(v2);
00228 }
00229 tim.Stop();
00230 print(tim,s);
00231 t += tim.RealTime();
00232 return sum;
00233 }
00234
00235 };
00236
00237
00238 int main(int argc,const char *argv[]) {
00239
00240 int ngen = 1000000;
00241 if (argc > 1) ngen = atoi(argv[1]);
00242 int nloop2 = ngen;
00243 if (argc > 2) nloop2 = atoi(argv[1]);
00244
00245 std::cout << "Test with Ngen = " << ngen << " n2loop = " << nloop2 << std::endl;
00246
00247 TStopwatch t;
00248
00249 VectorTest a(ngen,nloop2);
00250
00251 a.genData();
00252
00253
00254 double t1 = 0;
00255 double t2 = 0;
00256 double t3 = 0;
00257
00258 std::vector<TVector3 *> v1;
00259 std::vector<ROOT::Math::XYZVector *> v2;
00260 std::vector<ROOT::Math::XYZPoint *> v3;
00261
00262 double s1,s2,s3;
00263
00264 a.genData();
00265 a.testCreate (v2, t, t2, "creation XYZVector " );
00266
00267 a.genData();
00268 a.testCreate (v3, t, t3, "creation XYZPoint " );
00269
00270 a.genData();
00271 a.testCreate (v1, t, t1, "creation TVector3 " );
00272
00273 std::cout << "\n";
00274
00275
00276 s1=a.testVectorAddition (v1, t, t1, "Addition TVector3 " );
00277 s2=a.testVectorAddition (v2, t, t2, "Addition XYZVector " );
00278 s3=a.testPointAddition (v3, t, t3, "Addition XYZPoint " );
00279
00280 a.check("Addition",s1,s2,s3);
00281
00282 #ifdef MORETEST
00283
00284 s2=a.testVectorAddition (v2, t, t2, "Addition XYZVector " );
00285 s1=a.testVectorAddition (v1, t, t1, "Addition TVector3 " );
00286 s3=a.testPointAddition (v3, t, t3, "Addition XYZPoint " );
00287
00288 s2=a.testVectorAddition (v2, t, t2, "Addition XYZVector " );
00289 s3=a.testPointAddition (v3, t, t3, "Addition XYZPoint " );
00290 s1=a.testVectorAddition (v1, t, t1, "Addition TVector3 " );
00291
00292 s1=a.testVectorAddition (v1, t, t1, "Addition TVector3 " );
00293 s3=a.testPointAddition (v3, t, t3, "Addition XYZPoint " );
00294 s2=a.testVectorAddition (v2, t, t2, "Addition XYZVector " );
00295
00296 s3=a.testPointAddition (v3, t, t3, "Addition XYZPoint " );
00297 s2=a.testVectorAddition (v2, t, t2, "Addition XYZVector " );
00298 s1=a.testVectorAddition (v1, t, t1, "Addition TVector3 " );
00299
00300 s3=a.testPointAddition (v3, t, t3, "Addition XYZPoint " );
00301 s1=a.testVectorAddition (v1, t, t1, "Addition TVector3 " );
00302 s2=a.testVectorAddition (v2, t, t2, "Addition XYZVector " );
00303
00304 #endif
00305 std::cout << "\n";
00306
00307
00308 TRotation r1; r1.RotateZ(3.); r1.RotateY(2.); r1.RotateX(1);
00309 Rotation3D r2 (RotationZYX(3., 2., 1.) );
00310
00311 s1=a.testTransform (v1, r1, t, t1, "TRotation TVector3 " );
00312 s2=a.testTransform (v2, r2, t, t2, "Rotation3D XYZVector " );
00313 s3=a.testTransform (v3, r2, t, t3, "Rotation3D XYZPoint " );
00314
00315 a.check("Rotation3D",s1,s2,s3);
00316 double s2a = s2;
00317 std::cout << "\n";
00318
00319 double s4;
00320 double t0;
00321 Translation3D tr(1.,2.,3.);
00322 s1=a.testTranslation (v1, tr, t, t1, "Shift TVector3 " );
00323 s2=a.testTranslation (v2, tr, t, t2, "Shift XYZVector " );
00324 s3=a.testTransform (v3, tr, t, t3, "Translation3D XYZPoint " );
00325 s4=a.testTransform (v2, tr, t, t0, "Translation3D XYZVector " );
00326
00327 a.check("Translation3D",s1,s2,s3);
00328
00329 std::cout << "\n";
00330
00331 Transform3D tf(r2,tr);
00332
00333 s2=a.testTransform (v2, tf, t, t0, "Transform3D XYZVector " );
00334 s3=a.testTransform (v3, tf, t, t0, "Transform3D XYZPoint " );
00335 double s2b = s2;
00336
00337
00338 std::cout << "\n";
00339
00340
00341
00342 double s5;
00343
00344
00345 s2=a.testTransformProd (v2, r2, tr, t, t0, "Delta * Rot XYZVector " );
00346 s3=a.testTransformProd (v3, r2, tr, t, t0, "Delta * Rot XYZPoint " );
00347
00348 Transform3D tfr(r2);
00349 s4=a.testTransformProd (v2, tfr, tf, t, t0, "Delta * Rot(T) XYZVector " );
00350 s5=a.testTransformProd (v3, tfr, tf, t, t0, "Delta * Rot(T) XYZPoint " );
00351 a.check("Delta * Rot",s3,s5,s5);
00352
00353 a.check("Trans Vec",s2a,s2b,s2);
00354 a.check("Trans Vec",s2a,s2,s4);
00355
00356
00357 std::cout << "\n";
00358
00359
00360
00361 s2=a.testTransformProd2 (v2, r2, tr, t, t0, "Rot * Delta XYZVector " );
00362 s3=a.testTransformProd2 (v3, r2, tr, t, t0, "Rot * Delta XYZPoint " );
00363
00364 s4=a.testTransformProd2 (v2, tfr, tf, t, t0, "Rot * Delta(T) XYZVector " );
00365 s5=a.testTransformProd2 (v3, tfr, tf, t, t0, "Rot * Delta(T) XYZPoint " );
00366
00367 a.check("Rot * Delta",s3,s5,s5);
00368
00369 a.check("Trans Vec",s2a,s2,s4);
00370
00371
00372 std::cout << "\n";
00373 s2=a.testTransformProd (v2, tf, Translation3D(), t, t0, "Delta * Trans XYZVector " );
00374 s3=a.testTransformProd (v3, tf, Translation3D(), t, t0, "Delta * Trans XYZPoint " );
00375 s4=a.testTransformProd (v2, tf, Transform3D(), t, t0, "TDelta * Trans XYZVector " );
00376 s5=a.testTransformProd (v3, tf, Transform3D(), t, t0, "TDelta * Trans XYZPoint " );
00377 a.check("Delta * Trans",s3,s5,s5);
00378 a.check("Delta * Trans Vec",s2a,s2,s4);
00379
00380 std::cout << "\n";
00381 s2=a.testTransformProd2 (v2, tf, Translation3D(), t, t0, "Trans * Delta XYZVector " );
00382 s3=a.testTransformProd2 (v3, tf, Translation3D(), t, t0, "Trans * Delta XYZPoint " );
00383 s4=a.testTransformProd2 (v2, tf, Transform3D(), t, t0, "Trans * TDelta XYZVector " );
00384 s5=a.testTransformProd2 (v3, tf, Transform3D(), t, t0, "Trans * TDelta XYZPoint " );
00385 a.check("Delta * Trans",s3,s5,s5);
00386 a.check("Delta * Trans Vec",s2a,s2,s4);
00387
00388 std::cout << "\n";
00389 s2=a.testTransformProd (v2, tf, Translation3D(), t, t0, "Delta * Trans XYZVector " );
00390 s3=a.testTransformProd (v3, tf, Translation3D(), t, t0, "Delta * Trans XYZPoint " );
00391 s4=a.testTransformProd (v2, tf, Transform3D(), t, t0, "TDelta * Trans XYZVector " );
00392 s5=a.testTransformProd (v3, tf, Transform3D(), t, t0, "TDelta * Trans XYZPoint " );
00393 a.check("Delta * Trans",s3,s5,s5);
00394 a.check("Delta * Trans Vec",s2a,s2,s4);
00395
00396 std::cout << "\n";
00397 s2=a.testTransformProd2 (v2, tf, Translation3D(), t, t0, "Trans * Delta XYZVector " );
00398 s3=a.testTransformProd2 (v3, tf, Translation3D(), t, t0, "Trans * Delta XYZPoint " );
00399 s4=a.testTransformProd2 (v2, tf, Transform3D(), t, t0, "Trans * TDelta XYZVector " );
00400 s5=a.testTransformProd2 (v3, tf, Transform3D(), t, t0, "Trans * TDelta XYZPoint " );
00401 a.check("Delta * Trans",s3,s5,s5);
00402 a.check("Delta * Trans Vec",s2a,s2,s4);
00403
00404 std::cout << "\n";
00405 s1=a.testTransformProd3 (v1, r2, r2, t, t0, "Rot * Rot TVector3 " );
00406 s2=a.testTransformProd3 (v2, r2, r2, t, t0, "Rot * Rot XYZVector " );
00407 s3=a.testTransformProd3 (v3, r2, r2, t, t0, "Rot * Rot XYZPoint " );
00408 a.check("Rot * Rot",s1,s2,s3);
00409 s2a = s2;
00410
00411 std::cout << "\n";
00412
00413 s2=a.testTransformProd3 (v2, tf, r2, t, t0, "Rot * Trans XYZVector " );
00414 s3=a.testTransformProd3 (v3, tf, r2, t, t0, "Rot * Trans XYZPoint " );
00415 s4=a.testTransformProd3 (v2, tf, Transform3D(r2), t, t0, "TRot * Trans XYZVector " );
00416 s5=a.testTransformProd3 (v3, tf, Transform3D(r2), t, t0, "TRot * Trans XYZPoint " );
00417 a.check("Rot * Trans Pnt",s3,s5,s5);
00418 a.check("Rot * Trans Vec",s2a,s2,s4);
00419
00420 std::cout << "\n";
00421
00422 s2=a.testTransformProd3 (v2, r2, tf, t, t0, "Trans * Rot XYZVector " );
00423 s3=a.testTransformProd3 (v3, r2, tf, t, t0, "Trans * Rot XYZPoint " );
00424 s4=a.testTransformProd3 (v2, Transform3D(r2), tf, t, t0, "Trans * TRot XYZVector " );
00425 s5=a.testTransformProd3 (v3, Transform3D(r2), tf, t, t0, "Trans * TRot XYZPoint " );
00426
00427 a.check("Rot * Trans Pnt",s3,s5,s5);
00428 a.check("Rot * Trans Vec",s2a,s2,s4);
00429
00430 std::cout << "\n";
00431
00432 std::cout << "Total Time for TVector3 = " << t1 << "\t(sec)" << std::endl;
00433 std::cout << "Total Time for XYZVector = " << t2 << "\t(sec)" << std::endl;
00434 std::cout << "Total Time for XYZPoint = " << t3 << "\t(sec)" << std::endl;
00435
00436 }