Cyclic Redundancy check : Single and double bit error - crc

Found this in the book by Forouzan (Data Communications and Networking 5E). But, not able to understand the logic behind this.
This is in the context of topic two isolated single-bit errors
In other words, g(x) must not divide x^t + 1, where t is between 0 and n − 1. However, t = 0 is meaningless and t = 1 is needed as we will see later. This means t should be between 2 and n – 1
why t=1 is excluded here? (x^1 + 1) is two consecutive errors, it must also be detected right using our g(x).

The third image states that (x+1) should be a factor of g(x), but this reduces the maximum length that the CRC is guaranteed to detect 2 bit errors from n-1 to (n/2)-1, but it provides the advantage of being able to detect any odd number of bit errors such as (x^k + x^j + x^i) where k+j+i <= (n/2)-1.
Not mentioned in the book, is that some generators can detect more than 3 errors, but sacrifice the maximum length of a message in order to do this.
If a CRC can detect e errors, then it can also correct floor(e/2) errors, but I'm not aware of an efficient algorithm to do this, other than a huge table lookup (if there is enough space). For example there is a 32 bit CRC (in hex: 1f1922815 = 787·557·465·3·3) that can detect 7 bit errors or correct 3 bit errors for a message size up to 1024 bits, but fast correction requires a 1.4 giga-byte lookup table.
As for the "t = 1 is needed", the book later clarifies this by noting that g(x) = (x+1) cannot detect adjacent bit errors. In the other statement, the book does not special case t = 0 or t = 1, it states, "If a generator cannot divide (x^t + 1), t between 0 and n-1, then all isolated double bit errors can be detected", except that if t = 0, (x^0 + 1) = (1 + 1) = 0, which would be a zero bit error case.

Related

GNU MultiRootFinder "not making progress"

I'm using the CERN ROOT Data Analysis Framework implementation of the GNU MultiRootFinder to solve for the unknowns, x and y, in the following system:
The system describes the solution to a localization problem. That is, given the locations [x_i, y_i] of three parties, the speed of some signal, and the time at which each party "saw" the signal, I want to determine the coordinates, [x,y], of the source. We can assume the three parties and the source are coplanar, for simplicity.
My code is as follows. Note that this code is designed to run in Cling, where it is a perfectly valid program. void localize() plays the role of int main() here. Some changes would be needed to compile this in, say, gcc.
#define x1 300000
#define y1 360000
#define x2 210000
#define y2 210000
#define x3 96000
#define y3 360000
#define c 29980000000
void localize(){
ROOT::RDataFrame frame("D","./path/to/data");
auto statn1 = frame.Take<double>("statn1");
auto statn2 = frame.Take<double>("statn2");
auto statn3 = frame.Take<double>("statn3");
TF2 *f1 = new TF2("f1","sqrt((x-[0])^2 + (y-[1])^2) + [2]*([3] - [4]) - sqrt((x-[5])^2 + (y-[6])^2)");
TF2 *f2 = new TF2("f2","sqrt((x-[0])^2 + (y-[1])^2) + [2]*([3] - [4]) - sqrt((x-[5])^2 + (y-[6])^2)");
ROOT::Math::MultiRootFinder rootFinder(0);
int i = 0;
f1->SetParameters(x1,y1,c, statn2->at(i), statn1->at(i), x2,y2);
f2->SetParameters(x2,y2,c, statn3->at(i), statn2->at(i), x3,y3);
ROOT::Math::WrappedMultiTF1 g1(*f1,2);
ROOT::Math::WrappedMultiTF1 g2(*f2,2);
rootFinder.AddFunction(g1);
rootFinder.AddFunction(g2);
rootFinder.SetPrintLevel(1);
double init[2] = {2000, 3200};
rootFinder.Solve(init);
}
When I run the code, I get the error
Error in <ROOT::Math::GSLMultiRootFinder::Solve>: The iteration is not
making any progress
I've set the iterations to the maximum number possible, and I've chosen the starting point to be the center of the circle circumscribed by the three parties.
I fed the solver only the first two equations. Feeding it all three is, as I understand it, unneccessary, and produces an error as the solution to all three includes a third unknown, the time of emission.
What am I doing wrong here? Apologies if this is a basic question. This isn't something I'm very familiar with.
EDIT:
I'm wondering if this has anything to do with the fact that two equations will produce two solutions, in general. So, perhaps the root finder isn't converging on a single solution, causing the error? I can't find anything in the docs that suggests this, but I can't find anything that doesn't either.
If this is the case, I'm wondering, how could I introduce the third equation so as to disambaguate?
EDIT:
I've tried playing with the tolerances and # of iterations. If I start at 3 iterations, I get a new error:
ROOT::Math::GSLMultiRootFinder::Solve: exceeded max iterations, reached tolerance is not sufficient; absTol = 1e-06
Where the tolerance is set to the default value of 1E-06 (obviously). This continues up to 10 iterations, when I get the "not making progress" error.

binary check for an operation

Suppose a class has n students due to take an exam.
We intend to devise the quickest way to find out if all students have taken the exam.
Since the state is stored in a repository - read and update operation is expensive.
Is this possible through bit shifting/toggling.
If n=5,the initial state is n bytes of 0 - 00000
Each student completing the exam pushes 1 ,starting from right.
00001
00011
00111
......
All bytes composed of 1 indicates closure.
How do we achieve this using bit operations?
Is there a more efficient way to achieve this?
You have all the steps already:
n bits of 0:
status = 0
Each student completing the exam pushes 1 ,starting from right.
status = status << 1 # push previous to left
status = status | 1 # set the lowest bit
All bytes composed of 1 indicates closure.
allOnes = (1<<num_students) -1
closure = (status == allOnes)
Is there a more efficient way to achieve this?
#Alain's comment is correct: The method you describe is just a less memory efficient way of counting from 1 to n. Why not use a simple counter instead?
takers +=1
completed = (takers == num_students)
The storage for this will take lg(n) bits instead of n bits. In either case there will be load/modify/test/store cycle for each taker, so there is no signifcant time savings. The only reason I could think to use the bitfield is if you are concerned that one person may take the test twice and throw off your count.

Using an if-statement for div by 0 protection in Modelica

I made a simple model of a heat pump which uses sensor data to calculate its COP.
while COP = heat / power
sometimes there is no power so the system does a (cannot divide by zero). I would like these values to just be zero. So i tried an IF-statementif-statement. if power(u) = 0 then COP(y) = 0. somehow this does not work (see time 8)COP output + data. Anyone who seems to notice the problem?
edit(still problems at time 8.1
edit(heat and power)
To make the computation a bit more generally applicable (e.g. the sign of power can change), take a look at the code below. It could also be a good idea to build a function from it (for the function the noEvent()-statements can be left out)...
model DivNoZeroExample
parameter Real eps = 1e-6 "Smallest number to be used as divisor";
Real power = 0.5-time "Some artificial value for power";
Real heat = 1 "Some artificial value for heat";
Real COP "To be computed";
equation
if noEvent(abs(power) < abs(eps)) then
COP = if noEvent(power>= 0) then heat/eps else heat/(-eps);
else
COP = heat/power;
end if;
end DivNoZeroExample;
Relational operations work a bit differently in Modelica.
If you replace if u>0 by if noEvent(u>0) it should work as you expected.
For details see section 8.5 Events and Synchronization in the Modelica specification https://modelica.org/documents/ModelicaSpec34.pdf

Trying to decode a FM like signal encoded on audio

I have an audio signal that has a kind of FM encoded signal on it. The encoded signal is using this Biphase mark coding technique <-- see at the end of this page.
This signal is a digital representation of a timecode, in hours, minutes, seconds and frames. It basically works like this:
lets consider that we are working in 25 frames per second;
we know that the code is transmitting 80 bits of information every frame (that is 80 bits per frame x 25 frames per second = 2000 bits per second);
The wave is being sampled at 44100 samples per second. So, if we divide 44100/2000 we see that every bit uses 22,05 samples;
A bit happens when the signal changes sign.
If the wave changes sign and keeps its sign during the whole bit period it is a ZERO. If the wave changes sign two times over one bit period it is a ONE;
What my code does is this:
detects the first zero crossing, that is the clock start (to)
measures the level for to = to + 0.75*bitPeriod... 0.75 to give a tolerance.
if that second level is different, we have a 1, if not we have a 0;
This is the code:
// data is a C array of floats representing the audio levels
float bitPeriod = ceil(44100 / 2000);
int firstZeroCrossIndex = findNextZeroCross(data);
// firstZeroCrossIndex is the value where the signal changed
// for example: data[0] = -0.23 and data[1] = 0.5
// firstZeroCrossIndex will be equal to 1
// if firstZeroCrossIndex is invalid, go away
if (firstZeroCrossIndex < 0) return
float firstValue = data[firstZeroCrossIndex];
int lastSignal = sign(firstValue);
if (lastSignal == 0) return; // invalid, go away
while (YES) {
float newValue = data[firstZeroCrossIndex + 0.75* bitPeriod];
int newSignal = sign(newValue);
if (lastSignal == newSignal)
printf("0");
else
printf("1");
firstZeroCrossIndex += bitPeriod;
// I think I must invert the signal here for the next loop interaction
lastSignal = -newSignal;
if (firstZeroCrossIndex > maximuPossibleIndex)
break;
}
This code appears logical to me but the result coming from it is a total nonsense. What am I missing?
NOTE: this code is executing over a live signal and reads values from a circular ring buffer. sign returns -1 if the value is negative, 1 if the value is positive or 0 if the value is zero.
Cool problem! :-)
The code fails in two independent ways:
You are searching for the first (any) zero crossing. This is good. But then there is a 50% chance, that this transition is the one which occurs before every bit (0 or 1) or whether this transition is one which marks a 1 bit. If you get it wrong in the beginning you end up with nonsense.
You keep on adding bitPeriod (float, 22.05) to firstZeroCrossIndex (int). This means that your sampling points will slowly run out of phase with your analog signal and you will see strange effects when you sample point gets near the signal transitions. You will get nonsense, periodically at least.
Solution to 1: You must search for at least one 0 first, so you know which transition indicates just the next bit and which indicates a 1 bit. In practice you will want to re-synchronize your sampler at every '0' bit.
Solution to 2: Do not add bitPeriod to your sampling point. Instead search for the next transition, like you did in the beginning. The next transition is either 'half a bit' away, or a 'complete bit' away, which gives you the information you want. After a 'half a bit' period you must see another 'half a bit' period. If not, you must re-synchronize since you took a middle transition for a start transition by accident. This is exactly the re-sync I was talking about in 1.

How to get rid of different results of logarithm between CUDA and CPU?

I want to realize an algorithm in GPU using CUDA. At the same time, I write a CPU edition using C++ to verify the results of GPU edition. However I got into trouble when using log() in CPU and GPU. A very simple piece of algorithm (used both on CPU and GPU) is shown below:
float U;
float R = U * log(U);
However, when I compare the results on CPU side, I find that there are many results (459883 out of 1843161) having small differences (max dif is 0.5). Some results are shown below:
U -- R (CPU side) -- R (GPU side) -- R using Python (U * math.log(U))
86312.0 -- 980998.375000 -- 980998.3125 -- 980998.3627440572
67405.0 -- 749440.750000 -- 749440.812500 -- 749440.7721980268
49652.0 -- 536876.875000 -- 536876.812500 -- 536876.8452369706
32261.0 -- 334921.250000 -- 334921.281250 -- 334921.2605240216
24232.0 -- 244632.437500 -- 244632.453125 -- 244632.4440747978
Can anybody give me some suggestions? Which one should I trust?
Which one should I trust?
You should trust the double-precision result computed by Python, that you could also have computed with CUDA or C++ in double-precision to obtain very similar (although likely not identical still) values.
To rephrase the first comment made by aland, if you care about an error of 0.0625 in 980998, you shouldn't be using single-precision in the first place. Both the CPU and the GPU result are “wrong” for that level of accuracy. On your examples, the CPU result happens to be more accurate, but you can see that both single-precision results are quite distant from the more accurate double-precision Python result. This is simply a consequence of using a format that allows 24 significant binary digits (about 7 decimal digits), not just for the input and the end result, but also for intermediate computations.
If the input is provided as float and you want the most accurate float result for R, compute U * log(U) using double and round to float only in the end. Then the results will almost always be identical between CPU and GPU.
By curiosity, I compared the last bit set in the significand (or in other words the number of trailing zeros in the significand)
I did it with Squeak Smalltalk because I'm more comfortable with it, but I'm pretty sure you can find equivalent libraries in Python:
CPU:
#(980998.375000 749440.750000 536876.875000 334921.250000 244632.437500)
collect: [:e | e asTrueFraction numerator highBit].
-> #(23 22 23 21 22)
GPU:
#(980998.3125 749440.812500 536876.812500 334921.281250 244632.453125)
collect: [:e | e asTrueFraction numerator highBit].
-> #(24 24 24 24 24)
That's interestingly not as random as we could expect, especially the GPU, but there is not enough clue at this stage...
Then I used an ArbitraryPrecisionFloat package to perform (emulate) the operations in extended precision, then round to nearest single precision float, the correct answer matches quite exactly the one of CPU:
#( 86312 67405 49652 32261 24232 ) collect: [:e |
| u r |
u := e asArbitraryPrecisionFloatNumBits: 80.
r = u*u ln.
(r asArbitraryPrecisionFloatNumBits: 24) asTrueFraction printShowingMaxDecimalPlaces: 100]
-> #('980998.375' '749440.75' '536876.875' '334921.25' '244632.4375')
It works as well with 64 bits.
But if I emulate the operations in single precision, then I can say the GPU matches the emulated results quite well too (except the second item):
#( 86312 67405 49652 32261 24232 ) collect: [:e |
| u r |
u := e asArbitraryPrecisionFloatNumBits: 24.
r = u*u ln.
r asTrueFraction printShowingMaxDecimalPlaces: 100]
-> #('980998.3125' '749440.75' '536876.8125' '334921.28125' '244632.453125')
So I'd say the CPU did probably use a double (or extended) precision to evaluate the log and perform the multiplication.
On the other side, the GPU did perform all the operations in single precision. Then the log function of ArbitraryPrecisionFloat package is correct to half ulp, but that's not a requirement of IEEE 754, so that can explain the observed mismatch on second item.
You may try to write the code so as to force float (like using logf instead of log if it's C99, or use intermediate results float ln=log(u); float r=u*ln;) and eventually use appropriate compilation flags to forbid extended precision (can't remember, I don't use C every day). But then you have very few guaranty to obtain 100% match on log function, the norms are too lax.