Where the Hamming Distance Constants Came From - cryptography

The function:
function popcount (x, n) {
if (n !== undefined) {
x &= (1 << n) - 1
}
x -= x >> 1 & 0x55555555
x = (x & 0x33333333) + (x >> 2 & 0x33333333)
x = x + (x >> 4) & 0x0f0f0f0f
x += x >> 8
x += x >> 16
return x & 0x7f
}
Is for calculating Hamming Weight. I am wondering where these constants come from and generally how this method was discovered. Wondering if anyone knows the resource that describes it.

There masks select the even numbered k-bit parts, k=1 gives 0x55555555, k=2 gives 0x33333333, k=4 gives 0x0f0f0f0f.
In binary the masks look like:
0x55555555 = 01010101010101010101010101010101
0x33333333 = 00110011001100110011001100110011
0x0f0f0f0f = 00001111000011110000111100001111
They are also the result of 0xffffffff / 3, 0xffffffff / 5 and 0xffffffff / 17 but this arithmetic insight is probably not useful in this context.
Overall this method of computing the Hamming weight has the form of a tree where first adjacent bits are summed into a 2-bit number, then adjacent 2-bit numbers are summed into 4-bit numbers, and so on.
All the steps could have this form:
x = (x & m[k]) + ((x >> k) & m[k])
where m[k] is a mask selecting the even-numbered k-bit parts.
But many steps have short-cuts available for them. For example, to sum adjacent bits, there are only 4 cases to consider:
00 -> 00
01 -> 01
10 -> 01
11 -> 10
This could be done by extracting both bits and summing them, but x -= x >> 1 & 0x55555555 also works. This subtracts the top bit from the 2-bit part, so
00 -> 00 - 0 = 00
01 -> 01 - 0 = 01
10 -> 10 - 1 = 01
11 -> 11 - 1 = 10
Maybe this could be discovered through "cleverness and insight", whatever those are.
In the step x = (x + (x >> 4)) & 0x0f0f0f0f (extra parentheses added for clarity), a couple of properties are used. The results from the previous steps are the Hamming weights of 4-bit strings stored in 4 bits each, so they are at most 0100. That means two of them can be added in-place without carrying into the next higher part, because their sum will be at most 1000 which still fits. So instead of masking twice before the sum, it is enough to mask once after the sum, this mask effectively zero-extends the even numbered 4-bit parts into 8-bit parts. This could be discovered by considering the maximum values at each step.
The step x += x >> 8 has similar reasoning but it works out even better, even masking after the sum is not needed, this leaves some "stray bits" in the second byte from the bottom and in the top byte, but that is not damaging to the next step: the >> 16 throws away the second byte from the bottom, in the end all the stray bits are removed with x & 0x7f.

Related

Why is code like i=i*2 considered O(logN) when in a loop?

Why because of the i=i*2 is the runtime of the loop below considered O(logN)?
for (int i = 1; i <= N;) {
code with O(1);
i = i * 2;
}
Look at 1024 = 210. How many times do you have to double the number 1 to get 1024?
Times 1 2 3 4 5 6 7 8 9 10
Result 2 4 8 16 32 64 128 256 512 1024
So you would have to run your doubling loop ten times to get 210 And in general, you have to run your doubling loop n times to get 2n. But what is n? It's the log2 2n, so in general if n is some power of 2, the loop has to run log2n times to reach it.
To have the algorithm in O(logN), for any N it would need (around) log N steps. In the example of N=32 (where log 32 = 5) this can be seen:
i = 1 (start)
i = 2
i = 4
i = 8
i = 16
i = 32 (5 iterations)
i = 64 (abort after 6 iterations)
In general, after x iterations, i=2^x holds. To reach i>N you need x = log N + 1.
PS: When talking about complexities, the log base (2, 10, e, ...) is not relevant. Furthermore, it is not relevant if you have i <= N or i < N as this only changes the number of iterations by one.
You can prove it pretty simply.
Claim:
For the tth (0 base) iteration, i=2^t
Proof, by induction.
Base: 2^0 = 1, and indeed in the first iteration, i=1.
Step: For some t+1, the value of i is 2*i(t) (where i(t) is the value of i in the t iteration). From Induction Hypothesis we know that i(t)=2^t, and thus i(t+1) = 2*i(t) = 2*2^t = 2^(t+1), and the claim holds.
Now, let's examine our stop criteria. We iterate the loop while i <= N, and from the above claim, that means we iterate while 2^t <= N. By Doing log_2 on both sides, we get log_2(2^t) <= log_2(N), and since log_2(2^t) = t, we get that we iterate while t <= log_2(N) - so we iterate Theta(log_2(N)) times. (And that concludes the proof).
i starts in 1. In each iteration you multiply i by 2, so in the K-th iteration, i will be 2K-1.
After a number K of iterations, 2K-1 will be bigger than (or to) N.
this means N ≤ 2K-1
this means log2(N) ≤ K-1
K-1 will be the number of iterations your loop will run, and since K-1 is greater or equal to log(N), your algorithm is logarithmic.

VB.NET doesn't round numbers correctly?

I'm testing the speed of some functions so I made a test to run the functions over and over again and I stored the results in an array. I needed them to be sorted by the size of the array I randomly generated. I generate 100 elements. Merge sort to the rescue! I used this link to get me started.
The section of code I'm focusing on:
private void mergesort(int low, int high) {
// check if low is smaller then high, if not then the array is sorted
if (low < high) {
// Get the index of the element which is in the middle
int middle = low + (high - low) / 2;
// Sort the left side of the array
mergesort(low, middle);
// Sort the right side of the array
mergesort(middle + 1, high);
// Combine them both
merge(low, middle, high);
}
}
which translated to VB.NET is
private sub mergesort(low as integer, high as integer)
' check if low is smaller then high, if not then the array is sorted
if (low < high)
' Get the index of the element which is in the middle
dim middle as integer = low + (high - low) / 2
' Sort the left side of the array
mergesort(low, middle)
' Sort the right side of the array
mergesort(middle + 1, high)
' Combine them both
merge(low, middle, high)
end if
end sub
Of more importance the LOC that only matters to this question is
dim middle as integer = low + (high - low) / 2
In case you wanna see how merge sort is gonna run this baby
high low high low
100 0 10 0
50 0 6 4
25 0 5 4
12 0 12 7
6 0 10 7
3 0 8 7
2 0 :stackoverflow error:
The error comes from the fact 7 + (8 - 7) / 2 = 8. You'll see 7 and 8 get passed in to mergesort(low, middle) and then we infinite loop. Now earlier in the sort you see a comparison like this again. At 5 and 4. 4 + (5 - 4) / 2 = 4. So essentially for 5 and 4 it becomes 4 + (1) / 2 = 4.5 = 4. For 8 and 7 though it's 7 + (1) / 2 = 7.5 = 8. Remember the numbers are typecasted to an int.
Maybe I'm just using a bad implementation of it or my typecasting is wrong, but my question is: Shouldn't this be a red flag signaling something isn't right with the rounding that's occuring?
Without understanding the whole algorithm, note that VB.NET / is different than C# /. The latter has integer division by default, if you want to truncate decimal places also in VB.NET you have to use \.
Read: \ Operator
So i think that this is what you want:
Dim middle as Int32 = low + (high - low) \ 2
You are correct in your diagnosis: there's something inconsistent with the rounding that's occurring, but this is entirely expected if you know where to look.
From the VB.NET documentation on the / operator:
Divides two numbers and returns a floating-point result.
This documentation explicitly states that , if x and y are integral types, x / y returns a Double. So, 5 / 2 in VB.NET would be expected to be 2.5.
From the C# documentation on the / operator:
All numeric types have predefined division operators.
And further down the page:
When you divide two integers, the result is always an integer.
In the case of C#, if x and y are integers, x / y returns an integer (rounded down). 5 / 2 in C# is expected to return 2.

Find Maximum sum in a path in a 2D matrix with positive integers

I would like to know where I can read about algorithms for solving this problem efficiently:
Four directions allowed: up, down, left, right
Cells containing zero can't be visited.
Visiting the same cell twice is illegal.
Moves wraps around the edges:
(first row is connected with last row)
(first col is connected with last col)
Example, 5x5 and 5 steps:
9 1 3 1 9
6 3 2 4 1
0 7 * 7 7
5 4 9 4 9
7 9 1 5 5
Starting point: *
Solution: down,left,down,left,down. That is 9 + 4 + 9 + 7 + 9 = 38
[9] 1 3 1 9
6 3 2 4 1
0 7 * 7 7
5 [4][9] 4 9
[7][9] 1 5 5
This problem is probably not related to:
Finding the maximum sub matrix
Dynamic programming
You specified in comments that you wanted a sub-second way of finding the best value 20-step path out of a 5x5 matrix. I've implemented a basic recursive search tree that does this. Ultimately, the difficulty of this is still O(3^k), but highly saturated cases like yours (21 out of 24 allowed nodes visited) will solve much faster because the problem simplifies to "skip the n*n-z-k-1 lowest value cells" (in this case, n=5, z=1 and k+1 = 21; the winning path skips three 1's).
The problem instance in your question solves in 0.231seconds on a 3 year old i5 laptop and about half a second on ideone.com. I've provided code here http://ideone.com/5kOyxq (note that 'up' and 'down' are reversed because of the way I input the data).
For less saturated problems you may need to add a Bound/Cut method. You can generate a Bound as follows:
First, run over the NxN matrix and collect the K highest value elements (can be done in N² log K) and sort them by max-first. Then, cumulatively calculate the value UB[t] = SUM[i::0->t] SortedElements[i]. So, any t-length path has a UB of UB[t] (max t elements).
At step T, the current Branch's UB is UB[t]. If ValueSoFar[T] + UB[K-T] <= BestPathValue, you can stop that branch.
There may be better ways, but this should be sufficient for reasonably sized matrices and path lengths.
Game or puzzle. Given a matrix, number of steps and a sum, find the path.
Would be nice if there is a real world application for this, but i haven't found it.
Games tend to "burn in" knowledge in young brains, so why not burn in something useful, like addition?
#include<iostream>
#include<climits>
#define R 3
#define C 3
int MAX(int x, int y, int z);
int Max_Cost(int cost[R][C], int m, int n)
{
if (n < 0 || m < 0)
return INT_MIN;
else if (m == 0 && n == 0)
return cost[m][n];
else
return cost[m][n] + MIN( Max_Cost(cost, m-1, n-1),
Max_Cost(cost, m-1, n),
Max_Cost(cost, m, n-1)
);
}
int MAX(int x, int y, int z)
{
return max(max(x, y), z);
}
int main()
{
int cost[R][C] = { {3, 2, 5},
{5, 8, 2},
{9, 7, 1}
};
cout<<Max_Cost(cost, 2, 1);
return 0;
}

What does a percentage sign (%) do mathematically in Objective C?

I am super confused what the percentage sign does in Objective C. Can someone explain to me in language that an average idiot like myself can understand?! Thanks.
% is the modulo operator, so for example 10 % 3 would result in 1.
If you have some numbers a and b, a % b gives you just the remainder of a divided by b.
So in the example 10 % 3, 10 divided by 3 is 3 with remainder 1, so the answer is 1.
If there is no remainder to a divided by b, the answer is zero, so for example, 4 % 2 = 0.
Here's a relevant SO question about modular arithmetic.
Same as what it does in C, it's "modulo" (also known as integer remainder).
% is the modulo operator. It returns the remainder of <number> / <number>. For example:
5 % 2
means 5 / 2, which equals 2 with a remainder of 1, so, 1 is the value that is returned. Here's some more examples:
3 % 3 == 0 //remainder of 3/3 is 0
6 % 3 == 0 //remainder of 6/3 is 0
5 % 3 == 2 //remainder of 5/3 is 2
15 % 4 == 3 //remainder of 15/4 is 3
99 % 30 == 9 //remainder of 99/30 is 9
The definition of modulo is:
mod·u·lo
(in number theory) with respect to or using a modulus of a specified number. Two numbers are congruent modulo a given number if they give the same remainder when divided by that number.
In Mathematics, The Percentage Sign %, Called Modulo (Or Sometimes The Remainder Operator) Is A Operator Which Will Find The Remainder Of Two Numbers x And y. Mathematically Speaking, If x/y = {(z, r) : y * z + r = x}, Where All x, y, and z Are All Integers, Then
x % y = {r: ∃z: x/y = (z, r)}. So, For Example, 10 % 3 = 1.
Some Theorems And Properties About Modulo
If x < y, Then x % y = x
x % 1 = 0
x % x = 0
If n < x, Then (x + n) % x = n
x Is Even If And Only If x % 2 = 0
x Is Odd If And Only If x % 2 = 1
And Much More!
Now, One Might Ask: How Do We Find x % y? Well, Here's A Fairly Simple Way:
Do Long Division. I Could Explain How To Do It, But Instead, Here's A Link To A Page Which Explains Long Division: https://www.mathsisfun.com/numbers/long-division-index.html
Stop At Fractions. Once We Reach The Part Where We Would Normally Write The Answer As A Fraction, We Should Stop. So, For Example, 101/2 Would Be 50.5, But, As We Said, We Would Stop At The Fractions, So Our Answer Ends Up Being 50.
Output What's Left As The Answer. Here's An Example: 103/3. First, Do Long Division. 103 - 90 = 13. 13 - 12 = 1. Now, As We Said, We Stop At The Fractions. So Instead Of Continuing The Process And Getting The Answer 34.3333333..., We Get 34. And Finally, We Output The Remainder, In This Case, 1.
NOTE: Some Mathematicians Write x mod y Instead Of x % y, But Most Programming Languages Only Understand %.

How does this color blending trick that works on color components in parallel work?

I saw this Java code that does a perfect 50% blend between two RGB888 colors extremely efficiently:
public static int blendRGB(int a, int b) {
return (a + b - ((a ^ b) & 0x00010101)) >> 1;
}
That's apparently equivalent to extracting and averaging the channels individually. Something like this:
public static int blendRGB_(int a, int b) {
int aR = a >> 16;
int bR = b >> 16;
int aG = (a >> 8) & 0xFF;
int bG = (b >> 8) & 0xFF;
int aB = a & 0xFF;
int bB = b & 0xFF;
int cR = (aR + bR) >> 1;
int cG = (aG + bG) >> 1;
int cB = (aB + bB) >> 1;
return (cR << 16) | (cG << 8) | cB;
}
But the first way is much more efficient. My questions are: How does this magic work? What else can I do with it? And are there more tricks similar to this?
(a ^ b) & 0x00010101 is what the least significant bits of the channels would have been in a + b if no carry had come from the right.
Subtracting it from the sum guarantees that the bit that is shifted into the most significant bit of the next channel is just the carry from that channel, untainted by this channel. Of course that also means that this channel is no longer effected by the carry from the next channel.
An other way to look this, not the way it does it but a way that may help you understand it, is that effectively the inputs are changed so that their sum is even for all channels. The carries then go nicely into the least significant bits (which are zero, because even), without disturbing anything. Of course what it actually does is sort of the other way around, first it just sums them, and only then does it ensure that the sums are even for all channels. But the order doesn't matter.
More concretely, there are 4 cases (before the carry from the next channel is applied):
the lsb of a channel is 0 and there is no carry from the next channel.
the lsb of a channel is 0 and there is a carry from the next channel.
the lsb of a channel is 1 and there is no carry from the next channel.
the lsb of a channel is 1 and there is a carry from the next channel.
The first two cases are trivial. The shift puts the carried bit back in channel it belongs to, it doesn't even matter whether it was 0 or 1.
Case 3 is more interesting. If the lsb is 1, that means the shift would shift that bit into the most significant bit of the next channel. That's bad. That bit has to be unset somehow - but you can't just mask it away because maybe you're in case 4.
Case 4 is the most interesting. If the lsb is 1 and there is a carry into that bit, it rolls over to a 0 and the carry is propagated. That can't be undone by masking, but it can be done by reversing the process, ie subtracting 1 from the lsb (which puts it back to 1 and undoes any damage done by the propagated carry).
As you can see, in both case 3 and case 4, the cure is subtracting 1 from the lsb, and those are also the cases in which the lsb really wanted to be 1 (though maybe it isn't any more, due to a carry from the next channel), and in both case 1 and 2, you don't have to anything (in other words, subtract 0). That exactly corresponds to subtracting "what the lsb would have been in a + b if no carry had come from the right".
Also, the blue channel can only fall into cases 1 or 3 (there is no next channel which could carry), and the shift would just discard that bit instead of putting it in the next channel (because there is none). So alternatively, you may write (note the mask has lost the least significant 1)
public static int blendRGB(int a, int b) {
return (a + b - ((a ^ b) & 0x00010100)) >> 1;
}
Doesn't really make any difference, though.
To make it work for ARGB8888, you can switch to the good old "SWAR average":
// channel-by-channel average, no alpha blending
public static int blendARGB(int a, int b) {
return (a & b) + (((a ^ b) & 0xFEFEFEFE) >>> 1);
}
Which is a variation on a recursive way to define addition: x + y = (x ^ y) + ((x & y) << 1) which computes the sum without carries, then adds the carries in separately. The base case is when one of the operands is zero.
Both halves are effectively shifted right by 1, in such a way that the carry out of the most significant bit is never lost. The mask ensures that bits don't move to a channel to the right, and simultaneously ensures that a carry won't propagate out of its channel.