4

I want to find a way to figure out what are the most closest neighbors in a Gray Code sequence.

For example I have 010110, and I need to figure out which are its neighbors.

I can apply the binary reflection algorithm from Wikipedia, I know. I did it and found 010010 and 010111, but what if I have 0101100101010 instead of 010110?

hardmath
  • 37,015
ADDA
  • 43
  • 1
  • 3
  • 2
    The answer depends on which Gray code is being used. A more generic answer is that the neighbors are necessarily from the set of $n$ vectors at Hamming distance $1$ from the given vector of length $n$. This set is easy to write down. But which two from the set are the neighbors depends on the specific Gray code. – Dilip Sarwate Oct 09 '14 at 14:29
  • @DilipSarwate I don't know how many types of Gray Codes are but I'm talking about the one presented on wikipedia, the one where two successive values differ in only one bit. – ADDA Oct 09 '14 at 15:18
  • I, too, did not know how many Gray Codes there are (it obviously being an increasing count with number $n$ of bits), but OEIS A066037 gives counts for cyclic Gray codes without distinguishing starting point or direction (which would otherwise introduce a factor of $2^{n+1}$ in the counts). Even so a factor of $n!/2$ remains in each count because of the possibility of permuting the order in which each bit position is first set to 1 (assuming a start from all 0's for reference). – hardmath Oct 09 '14 at 15:30

3 Answers3

5

If you want find the neighbours of a Gray code, there are better methods than converting the Gray code to a regular binary representation, adding/subtracting $1$ and converting it back to a Gray code. We can use the properties described in The Gray Code by R. W. Doran. Let's take the first property from the paper:

Property P1: Adjacent words in the Gray code sequence differ in one bit position only.

That means that, in order to find a neighbour, you will only have to find the bit to switch in the sequence. The twelfth property from the paper gives us the position of the bit that has to be switched (the rightmost bit is at position $0$):

Property P12: When counting an n-bit Gray Code in direction d ($=0$ for up, $=1$ for down), the next bit s to be switched is given by:

  • $ P(G) = d $ then $ s = 0 $
  • $ P(G) = $ not $ d $ then s is such that $ G_{s-1} = 1 $ and $ G_i = 0, i > s-1 $

That means that, depending on the parity of the Gray code, the next bit to switch will either the lowest (rightmost) one, either the one left to the rightmost $1$ in the sequence. Lets take an example: $0111$ is the Gray code for $5$. If you switch the rightmost bit, you get $0110$ which is the Gray code for $4$. If you switch the bit which is at the left of the rightmost $1$ in the sequence, you get $0101$ which is the Gray code for $6$.

If your Gray code is even, switching the rightmost bit will give the Gray code corresponding to the next integer, otherwise it will give you the Gray code corresponding to the previous integer. However, in order to perform these simple switches, we need to know the parity of the Gray code. We can use the following porperty:

A Gray code sequence is even iff the number of $1$ in the sequence is even.

To sum up: to find the neighbours of a Gray code, switch either the rightmost bit or the bit left to the rightmost $1$ and check the parity to know whether you just got the next or the previous neighbour. It is easy to do by hand and can be faster than a conversion to and from a regular integer for a computer (it will depend on the algorithm used to compute the parity).

Morwenn
  • 437
  • This is the only answer that actually reflects the structure of Gray code. But this sentence got garbled: "the next bit to switch will either the lowest (rightmost) one, either the one left to the rightmost 1 in the sequence." – Tom Swirly Dec 12 '20 at 10:45
2

The specific code that Frank Gray called "reflected binary code" (1947 patent application, granted 1953) is now often labeled BRGC for "binary reflected Gray code" after him. [However such a code appears as early as 1878 with Baudot's work on telegraphy.]

A formula for calculating the binary pattern appearing in the $k$th position of the BRGC sequence, $k=1,..,2^n$, is given in the Wikipedia article and discussed in this StackOverflow Q&A: the nth gray code. Mathematically speaking, let $k$ be the entry we want and $g(k)$ the corresponding BRGC entry:

$$ g(k) = \lfloor (k-1)/2 \rfloor \text{ XOR } (k-1) $$

The minus 1 from $k$ is only to start the sequence with first element all zeros. If you are comfortable with 0-indexing, feel free to simplify.

It follows that many questions such as the one posed here (find neighboring entries) can be solved if an inverse to this formula is known, telling us in which BRGC position a specified binary pattern can be found. The Wikipedia article also supplies us with code for that operation, though it is less easily expressed in a single formula (but see Added below).

As a C-like looping routine:

unsigned int grayToBinary(unsigned int num)
{
    unsigned int mask;
    for (mask = num >> 1; mask != 0; mask = mask >> 1)
    {
        num = num ^ mask;
    }
    return num+1;
}

This differs from the Wikipedia snippet only in adding 1 to the return value, consistent with what we discuss above about 1-indexing vs. 0-indexing of the BRGC sequence.

That is, given a binary pattern g of width that fits in an unsigned integer, we can call the routine k = grayToBinary(g). The return value k or $k$ can then be incremented/decremented to produce the successor/predecessor BRGC entries by applying the formula previously cited.

Note that the code snippet does not reference the entry widths $n$ of the binary patterns. This is possible because the BRGC sequences of different widths agree on (conserve) common initial segments (an easy consequence of the recursive definition).

Added:

I implemented the coding (index to Gray code) formula and decoding (Gray code to index) routine above in a spreadsheet (to make sure I hadn't committed an obscure error), and they both worked.

We could write the decoding as a formula if only we had a symbol for accumulating bitwise exclusive-or in a manner like $\Sigma$ accumulates summation. For no particular reason other than it looks cool to me, I'll nominate $\Xi$ for this purpose. After all, bitwise exclusive-or on unsigned (nonnegative) integers is associate and commutative, so an iterated XOR makes as much sense as iterated sums or products. Then we could locate the index of bit pattern $m$ as follows:

$$ g^{-1}(m) = 1 + \operatorname{\Xi}\limits_{j=0}^{\lfloor \log_2 m \rfloor} \left\lfloor \frac{m}{2^j} \right\rfloor $$

hardmath
  • 37,015
2

In all Gray codes, successive values differ in only one bit. Here are two different (cyclic) Gray codes: $$000,001,011,010,110,111,101,100$$ and $$000,001,011,111,101,100,110,010$$ The first is the standard binary reflected Gray code. The Wikipedia article you link to describes a method to convert standard binary reflected Gray code representation of $n$ to natural binary representation of $n$, and also how to convert from natural binary representation of $n$ to standard binary reflected Gray code representation of $n$.

So, given Gray code 0101100101010 which is the standard binary reflected Gray code representation of some integer $n$ (you don't, as yet, know what $n$ is)

  1. Convert the Gray code representation to natural binary representation using the method in the Wikipedia article. At this point, you can more easily find out the value of $n$, but knowledge that $n$ equals $1135$ (say) is not necessary for finding the neighbors.
  2. Add and subtract $1$ to the natural binary representation of $n$ that you found in Step 1. You now have the natural binary representations of $n-1$ and $n+1$.
  3. Convert the natural binary representations of $n-1$ and $n+1$ to standard binary reflected Gray code representations as described in the Wikipedia article. These are the neighbors of 0101100101010 in the standard binary reflected Gray code.
Dilip Sarwate
  • 25,197
  • 1
    I don't know if that method is following the rule of the Gray Code. If we take 010110 witch is 22 will have 21 and 23 which means that we will have 10101 - 010110 - 10111 which is wrong because there is more than 1 different bit. Maybe I didn't understood it. If so please write me a simple quick example of your logic. Thank you so much! – ADDA Oct 11 '14 at 09:00
  • No, 010110 in BRGC is $27 = 011011$ as computed via the algorithm in Wikipedia: $b_0 = g_0; b_i = g_i \oplus b_{i-1}$ (note that leftmost bits are $b_0$ and $g_0$). The predecessor and successor in standard binary notation are $26 = 011010$ and $28=011100$ respectively which correctly convert to 010111 and 010010 using Wikipedia's algorithm $\mathbf b \oplus \lfloor \mathbf b/2\rfloor$, that is, XOR the standard binary representation and its arithmetic right shift. – Dilip Sarwate Oct 11 '14 at 15:33
  • Now make sense. Thank you again. – ADDA Oct 14 '14 at 21:28