Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-01-27 02:49:59

0001 #include "DataFormats/GeometryVector/interface/Phi.h"
0002 
0003 #include <iostream>
0004 #include <iomanip>
0005 #include <cmath>
0006 #include <ctime>
0007 #include <chrono>
0008 
0009 using namespace angle0to2pi;
0010 using namespace Geom;
0011 using namespace std;
0012 using namespace reco;
0013 using namespace std::chrono;
0014 
0015 template <class valType>
0016 inline constexpr valType useReduceRange(valType angle) {
0017   constexpr valType twoPi = 2._pi;
0018   angle = reducePhiRange(angle);
0019   if (angle < 0.)
0020     angle += twoPi;
0021   return angle;
0022 }
0023 
0024 template <class valType>
0025 inline constexpr valType simpleMake0to2pi(valType angle) {
0026   constexpr valType twoPi = 2._pi;
0027 
0028   angle = fmod(angle, twoPi);
0029   if (angle < 0.)
0030     angle += twoPi;
0031   return angle;
0032 }
0033 
0034 template <class valType>
0035 static int testSmall() {  // Test with long double
0036   Phi<valType, ZeroTo2pi> ang1(15.3_pi);
0037   cout << "Phi that started as 15.3 pi is " << ang1 << endl;
0038   cout << "In degrees " << ang1.degrees() << endl;
0039   constexpr valType testval = 15.2999_pi;
0040   Phi<valType, ZeroTo2pi> ang2 = ang1 - testval;
0041   ang1 -= testval;
0042   if (ang1 != ang2) {
0043     cout << "angle1 = " << ang1 << " and angle2 = " << ang2;
0044     cout << " should be equal but they are not. Test failure." << endl;
0045     return (1);
0046   }
0047   if (ang1.nearZero()) {
0048     cout << "angle = " << ang1 << " close enough to zero to be considered zero." << endl;
0049   } else {
0050     cout << "angle = " << ang1 << " should be considered nearly 0 but it is not.";
0051     cout << " Test failure." << endl;
0052     return (1);
0053   }
0054   return (0);
0055 }
0056 
0057 template <class valType>
0058 static int iterationTest(valType increm) {
0059   Phi<valType, ZeroTo2pi> ang1 = 0.;
0060   const int iters = 1000 * 1000;
0061   steady_clock::time_point startTime = steady_clock::now();
0062   for (int cnt = 0; cnt < iters; ++cnt) {
0063     ang1 += increm;
0064   }
0065   steady_clock::time_point endTime = steady_clock::now();
0066   cout << "Phi after " << iters << " iterations is " << ang1 << endl;
0067   duration<double> time_span = duration_cast<duration<double>>(endTime - startTime);
0068   cout << "Time diff is  " << time_span.count() << endl;
0069   valType plainAng = 0.;
0070   startTime = steady_clock::now();
0071   for (int cnt = 0; cnt < iters; ++cnt) {
0072     plainAng = make0To2pi(increm + plainAng);
0073   }
0074   endTime = steady_clock::now();
0075   cout << "plainAng  is  now " << plainAng << endl;
0076   cout << "Base-type variable after " << iters << " iterations is " << plainAng << endl;
0077   duration<double> time_span2 = duration_cast<duration<double>>(endTime - startTime);
0078   cout << "Time diff is  " << time_span2.count() << endl;
0079   cout << "Ratio of class/base-type CPU time is " << (time_span.count() / time_span2.count()) << endl;
0080   if (ang1 != plainAng) {
0081     cout << "Angles should have come out the same but ang1 = " << ang1;
0082     cout << " and plainAng = " << plainAng << ". Test failure." << endl;
0083     return (1);
0084   }
0085   return (0);
0086 }
0087 
0088 template <class valType>
0089 static int iter3Test(valType increm) {
0090   // const int iters = 1234567899;
0091   const int iters = 1000 * 1000;
0092   valType ang1 = 0.;
0093   steady_clock::time_point startTime = steady_clock::now();
0094   for (int cnt = 0; cnt < iters; ++cnt) {
0095     ang1 = make0To2pi(increm + ang1);
0096   }
0097   steady_clock::time_point endTime = steady_clock::now();
0098   cout << "Fast version after " << iters << " iterations is " << ang1 << endl;
0099   duration<double> time_span = duration_cast<duration<double>>(endTime - startTime);
0100   cout << "Time diff is  " << time_span.count() << endl;
0101   valType plainAng = 0.;
0102   startTime = steady_clock::now();
0103   for (int cnt = 0; cnt < iters; ++cnt) {
0104     plainAng = simpleMake0to2pi(increm + plainAng);
0105   }
0106   endTime = steady_clock::now();
0107   cout << "Simple version after " << iters << " iterations is " << plainAng << endl;
0108   duration<double> time_span2 = duration_cast<duration<double>>(endTime - startTime);
0109   cout << "Time diff is  " << time_span2.count() << endl;
0110   plainAng = 0.;
0111   startTime = steady_clock::now();
0112   for (int cnt = 0; cnt < iters; ++cnt) {
0113     plainAng = useReduceRange(increm + plainAng);
0114   }
0115   endTime = steady_clock::now();
0116   cout << "ReduceRange after " << iters << " iterations is " << plainAng << endl;
0117   time_span2 = duration_cast<duration<double>>(endTime - startTime);
0118   cout << "Time diff is  " << time_span2.count() << endl;
0119   return (0);
0120 }
0121 
0122 int main() {
0123   cout << "long pi   = " << std::setprecision(32) << M_PIl << endl;
0124   cout << "double pi = " << std::setprecision(32) << M_PI << endl;
0125   cout << "pi difference = " << M_PIl - M_PI << endl;
0126   Phi<double, ZeroTo2pi> testval2{39.3_pi};
0127   cout << "testval2 initialized from 39.3pi, should be 0to2pi = " << testval2 << endl;
0128   Phi<double, ZeroTo2pi> testval = 39.3_pi;
0129   cout << "Sizes of Phi<double> and double = " << setprecision(16) << sizeof(testval) << ", " << sizeof(double) << endl;
0130   {
0131     Phi<double, ZeroTo2pi> angle = 3.3_pi;
0132     if (!angle.nearEqual(1.3_pi)) {
0133       cout << "Angle should be from 0-2pi but it is out of range = " << angle << endl;
0134       return (1);
0135     }
0136   }
0137   double getval = testval > 0. ? static_cast<float>(testval) : 3.f;
0138   cout << "getval should be 39.3pi = " << getval << endl;
0139   {
0140     Phi<long double, ZeroTo2pi> angle = -3.3_pi;
0141     if (!angle.nearEqual(0.7_pi)) {
0142       cout << "Angle should be from 0-2pi but it is out of range = " << angle << endl;
0143       return (1);
0144     }
0145   }
0146   // Test operations
0147   Phi<double, ZeroTo2pi> phi1, phi2;
0148   phi1 = 0.25_pi;
0149   phi2 = 1._pi / 6.;
0150   cout << "pi/4 + pi/6 = " << phi1 + phi2 << endl;
0151   cout << "pi/4 - pi/6 = " << phi1 - phi2 << endl;
0152   cout << "pi/4 * pi/6 = " << phi1 * phi2 << endl;
0153   cout << "pi/4 / pi/6 = " << phi1 / phi2 << endl;
0154 
0155   Phi<double, ZeroTo2pi> phi3{3.2_pi};
0156   cout << "Phi0To2pi started at 3.2pi but reduced to = " << phi3 << endl;
0157   phi3 += 1.9_pi;
0158   cout << "Phi0To2pi add 1.9pi = " << phi3 << endl;
0159   phi3 -= 8.9_pi;
0160   cout << "Phi0To2pi subtract 8.9pi = " << phi3 << endl;
0161   Phi<double, ZeroTo2pi> phi4{2.2_pi};
0162   phi3 = -phi4;
0163   phi4 = -30._pi;
0164   cout << "Phi0To2pi set to -2.2pi = " << phi3 << endl;
0165   cout << "Phi0To2pi set to -30.pi = " << phi4 << endl;
0166   phi4 = 2._pi;
0167   cout << "Phi0To2pi set to 2.pi = " << phi4 << endl;
0168   Phi0To2pi<float> phi5{-3._pi};
0169   cout << "Phi0To2pi set to -3.pi = " << phi5 << endl;
0170 
0171   cout << "Test with float\n";
0172   if (testSmall<float>() == 1)
0173     return (1);
0174   cout << "Test with double\n";
0175   if (testSmall<double>() == 1)
0176     return (1);
0177   cout << "Test with long double\n";
0178   if (testSmall<long double>() == 1)
0179     return (1);
0180   if (iterationTest<float>(7.77_pi) == 1)
0181     return (1);
0182   cout << "Test repeated large decrement\n";
0183   if (iterationTest<double>(-7.77_pi) == 1)
0184     return (1);
0185   cout << "Test repeated small increment\n";
0186   if (iterationTest<long double>(1._deg) == 1)
0187     return (1);
0188   cout << "Test repeated small decrement\n";
0189   if (iterationTest<double>(-1._deg) == 1)
0190     return (1);
0191 
0192   // long double smallincr = 1.39_deg;
0193   long double smallincr = 1._deg;
0194   long double bigincr = 7.77_pi;
0195 
0196   cout << "** Use double arithmetic **\n";
0197   cout << "Test 3 versions small decr\n";
0198   if (iter3Test<double>(-smallincr) == 1)
0199     return (1);
0200   cout << "Test 3 versions small incr\n";
0201   if (iter3Test<double>(smallincr) == 1)
0202     return (1);
0203   cout << "Test 3 versions big decre\n";
0204   if (iter3Test<double>(-bigincr) == 1)
0205     return (1);
0206   cout << "Test 3 versions big incr\n";
0207   if (iter3Test<double>(bigincr) == 1)
0208     return (1);
0209   cout << "** Use long double arithmetic **\n";
0210   cout << "Test 3 versions small decr\n";
0211   if (iter3Test<long double>(-smallincr) == 1)
0212     return (1);
0213   cout << "Test 3 versions small incr\n";
0214   if (iter3Test<long double>(smallincr) == 1)
0215     return (1);
0216   cout << "Test 3 versions big decre\n";
0217   if (iter3Test<long double>(-bigincr) == 1)
0218     return (1);
0219   cout << "Test 3 versions big incr\n";
0220   if (iter3Test<long double>(bigincr) == 1)
0221     return (1);
0222 
0223   return (0);
0224 }