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() {
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
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
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
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 }