Fibonacci Encoding

(2024-10-29)

Go to: Home · Blog

I recently learned this cool encoding in my info theory class and wanted to share.

As a forewarning, I am a student still learning and write this as a way of processing the information as I learn it. None of this is peer-reviewed. My writing here may (and likely will) have mistakes.

Lets dive in though! First let us consider representations for a number nn. There is a greedy algorithm to produce a representation for any number given placeholders. Lets assume we have the placeholders

Py>Py1>>P2>P1=1P_y > P_{y-1} > \dots > P_2 > P_1 = 1

To represent nn we

  1. Find the largest PiP_i such that PinP_i \leq n
  2. Find the largest ciNc_i \in \mathbb{N} such that ciPinc_iP_i \leq n
  3. Put cic_i in position ii
  4. nnciPin \leftarrow n - c_iP_i and repeat (i.e subtract nn by ciPic_iP_i and go back to step 1)

For example given n=60n = 60 and typical binary placeholders 2i12^{i-1} for PiP_i, which are

P1=1,P2=2,P3=4,P4=8,P5=16Pi=2i1P_1 = 1, P_2 = 2, P_3 = 4, P_4 = 8, P_5 = 16 \dots P_i = 2^{i-1} \dots

We then step through the algorithm getting the highest placeholder P6=32P_6 = 32, which we can multiply by at most 11. This gives us a 11 in position 6. nn then becomes n=6032=28n = 60 - 32 = 28. We then get P5=16P_5 = 16, with c6=1c_6 = 1, and nn becomes n=2816=12 n = 28 - 16 = 12. We then do this again with P=4P=4 and P=3P=3 to give us:

P6P_6 P5P_5 P4P_4 P3P_3 P2P_2 P1P_1
1 1 1 1 0 0

For the base representations we always have that ci<dc_i < d for some dd-ary base since the greedy algorithm would pick the larger placeholder. This is because for a dd-ary base, dP˙i=Pi+1d \dot P_i = P_{i+1}.

Now let us consider P\vec{P} placeholders to be fibonacci. That is we start at P1=1P_1 = 1, then P2=2P_2 = 2 (to make sure we have that subsequent PP are strictly greater then previous ones), P3=3P_3 = 3, P4=5P_4 = 5, and so on following that Pi+2=Pi+1+PiP_{i+2} = P_{i+1} + P_i

That same number n=60n = 60 would be represented as

5555 3434 2121 1313 88 55 33 22 11
1 0 0 0 0 1 0 0 0

In fibonacci representation. This representation has two important properties

(1) Fibonacci representations only contains 0s and 1s. Why?

Pi+1=Pi+Pi1<2PiP_{i+1} = P_i + P_{i-1} < 2P_i

Thus, for all placeholders, since multiplying by two is always greater than the next placeholder, the greedy algorithm would have us pick that placeholder rather than multiply by 2.

(2) Fibonacci representations will never have consecutive 11s. This is because the greedy algorithm will choose the biggest possible placeholder. Thus we would always have 100100 instead of 011011.

The second property is how we will leverage this to construct fibonacci encodings, allowing us to encode a stream of integers of unknown length. We do this by

  1. Creating the fibonacci representation
  2. Reversing the order (i.e. least significant bit to most)
  3. Adding a trailing 1.

Going back to our n=60n = 60 example, the representation of 1000100010001000 would then be reversed to 000100001000100001 and then a trailing 11 is added to get us the encoding of 00010000110001000011.

We essentially encode in the base of the ratio between numbers, in this case we are encoding in the golden ratio ϕ1.618\phi \sim 1.618. Thus to encode nn we need roughly logϕnlog_\phi n bits.

This is roughly logϕnlgn1.44\frac{log_\phi n}{lg n} \sim 1.44 times more bits than in binary. However this encoding allows us to send an arbitrary amount of nn at a time, with a way of punctuating between numbers (something called a universal code).

The robustness of fibonacci comes from the fact that by flipping a bit in the stream, we mess up at most 2 numbers. Contrary to other encoding schemes like Lempel-Ziv, Elias Gamma, Elias Delta, and Elias Omega, flipping one bit has some robustness, and is able to preserve the majority of the stream of integers.

Lastly, although not planned, is the ability to convert units rather easily in this representation. Specifically from kilometers to miles and centimeters to inches. The ratio of kilometers to miles is roughly 1.611.61, in other words there are 1.611.61 kilometers in a mile; Therefore, we can shift a bit to the left to convert from miles to kilometers.

1001 0 0 (33) miles becomes 10001 0 0 0 (55) kilometers.

The ratio between centimeters to inches is roughly 2.542.54, and since 1.611.611.61 \cdot 1.61 is roughly 2.562.56, we can a bit shift twice to convert between the two.

1001 0 0 (33) inches becomes 10001 0 0 0 (88) centimeters.

This is purely a coincidence due to the fact that the ratios between these units are close to (or close to a power of) the golden ratio 1.611.61.