56template <
size_t k,
size_t nTaps>
57bool NextLFSR(std::bitset<k> &lfsr, std::array<std::uint16_t, nTaps> taps,
bool left =
true)
59 static_assert(k <= 32,
"For the moment, only supported until k == 32.");
60 static_assert(k > 0,
"Non-zero degree is needed for the LFSR.");
61 static_assert(nTaps > 0,
"At least one tap is needed for the LFSR.");
62 static_assert(nTaps <= k,
"Cannot use more taps than polynomial order");
63 for (std::uint16_t j = 0; j < nTaps; ++j) {
64 assert(
static_cast<size_t>(taps[j] - 1) <= k &&
static_cast<size_t>(taps[j] - 1) > 0 &&
65 "Tap value is out of range [1,k]");
69 bool newBit = lfsr[taps[0] - 1];
70 for (std::uint16_t j = 1; j < nTaps; ++j) {
71 newBit ^= lfsr[taps[j] - 1];
106template <
size_t k,
size_t nTaps,
typename Output =
unsigned char>
108 bool wrapping =
false,
bool oppositeBit =
false)
110 std::vector<Output> result;
113 static_assert(k <= 32,
"For the moment, only supported until k == 32.");
114 static_assert(k > 0,
"Non-zero degree is needed for the LFSR.");
115 static_assert(nTaps >= 2,
"At least two taps are needed for a proper sequence");
116 static_assert(nTaps <= k,
"Cannot use more taps than polynomial order");
117 for (
auto tap : taps) {
118 if (tap > k || tap == 0) {
119 Error(
"ROOT::Math::LFSR",
"Tap %u is out of range [1,%lu]", tap, k);
124 Error(
"ROOT::Math::LFSR",
"A non-zero start value is needed");
129 const std::uint32_t maxPeriod = pow(2, k) - 1;
130 result.reserve(maxPeriod);
132 std::set<uint32_t> lfsrHistory;
133 std::bitset<k> lfsr(
start);
136 result.emplace_back(left ? lfsr[k - 1] : lfsr[0]);
141 bool newBit =
NextLFSR(lfsr, taps, left);
144 result.emplace_back(newBit);
146 result.emplace_back(left ? lfsr[k - 1] : lfsr[0]);
152 if (lfsrHistory.count(lfsr.to_ulong()))
155 lfsrHistory.insert(lfsr.to_ulong());
157 }
while (lfsr !=
start && i < maxPeriod);
162 result.shrink_to_fit();
Error("WriteTObject","The current directory (%s) is not associated with a file. The object (%s) has not been written.", GetName(), objname)
Pseudo Random Binary Sequence (PRBS) generator namespace with functions based on linear feedback shif...
bool NextLFSR(std::bitset< k > &lfsr, std::array< std::uint16_t, nTaps > taps, bool left=true)
Generate the next pseudo-random bit using the current state of a linear feedback shift register (LFSR...
std::vector< Output > GenerateSequence(std::bitset< k > start, std::array< std::uint16_t, nTaps > taps, bool left=true, bool wrapping=false, bool oppositeBit=false)
Generation of a sequence of pseudo-random bits using a linear feedback shift register (LFSR),...