Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:20:23

0001 #include "L1Trigger/L1TCalorimeter/interface/Cordic.h"
0002 
0003 #include <cstdint>
0004 #include <cmath>
0005 #include <vector>
0006 #include <iostream>
0007 #include <iomanip>
0008 
0009 Cordic::Cordic(const uint32_t& aPhiScale, const uint32_t& aMagnitudeBits, const uint32_t& aSteps)
0010     : mPhiScale(aPhiScale),
0011       mMagnitudeScale(1 << aMagnitudeBits),
0012       mMagnitudeBits(aMagnitudeBits),
0013       mSteps(aSteps),
0014       mPi(3.1415926535897932384626433832795) {
0015   mRotations.reserve(mSteps);
0016 
0017   double lValue(1.0);
0018 
0019   for (uint32_t lStep(0); lStep != mSteps; ++lStep) {
0020     lValue /= sqrt(1.0 + pow(4.0, -double(lStep)));
0021     mRotations.push_back(tower(atan(pow(2.0, -double(lStep)))));
0022   }
0023   mMagnitudeRenormalization = uint32_t(round(mMagnitudeScale * lValue));
0024 }
0025 
0026 Cordic::~Cordic() {}
0027 
0028 double Cordic::NormalizePhi(const uint32_t& aPhi) const { return double(aPhi) / double(mPhiScale); }
0029 
0030 double Cordic::NormalizeMagnitude(const uint32_t& aMagnitude) const {
0031   return double(aMagnitude) / double(mMagnitudeScale);
0032 }
0033 
0034 int32_t Cordic::IntegerizeMagnitude(const double& aMagnitude) const { return int32_t(aMagnitude * mMagnitudeScale); }
0035 
0036 uint32_t Cordic::tower(const double& aRadians) const { return uint32_t(round(mPhiScale * 0.5 * aRadians / mPi)); }
0037 
0038 void Cordic::operator()(int32_t aX, int32_t aY, int32_t& aPhi, uint32_t& aMagnitude) const {
0039   bool lSign(true);
0040 
0041   switch (((aY >= 0) ? 0x0 : 0x2) | ((aX >= 0) ? 0x0 : 0x1)) {
0042     case 0:
0043       aPhi = tower(mPi);
0044       break;
0045     case 1:
0046       aPhi = tower(2 * mPi);
0047       lSign = false;
0048       aX = -aX;
0049       break;
0050     case 2:
0051       aPhi = tower(mPi);
0052       lSign = false;
0053       aY = -aY;
0054       break;
0055     case 3:
0056       aPhi = 0;
0057       aX = -aX;
0058       aY = -aY;
0059       break;
0060     default:
0061       throw 0;
0062   }
0063 
0064   for (uint32_t lStep(0); lStep != mSteps; ++lStep) {
0065     if ((aY < 0) == lSign) {
0066       aPhi -= mRotations[lStep];
0067     } else {
0068       aPhi += mRotations[lStep];
0069     }
0070 
0071     int32_t lX(aX), lY(aY);
0072     if (lY < 0) {
0073       aX = lX - (lY >> lStep);
0074       aY = lY + (lX >> lStep);
0075     } else {
0076       aX = lX + (lY >> lStep);
0077       aY = lY - (lX >> lStep);
0078     }
0079   }
0080 
0081   aMagnitude = (aX * mMagnitudeRenormalization) >> mMagnitudeBits;
0082 }