4

Given a clocked 3-level (-1,0,+1) channel between two devices, what is the most stream-efficient way to convert a stream of bits to and from the channel representation?

The current method is to take 3 binary bits, and convert into two trits. I believe this wastes 11% of the channel capability (since 1 out of 9 possible pairs is never used). I suspect grouping might reduce this waste, but this project is using 8-bit devices, so my group sizes are restricted.

I'd like to use divmod-3, but I don't have the entire binary stream available at any one point. Is there a method for an 'incremental' divmod3 that can start at the LSB?

As an untrained guess, I speculate that there should be an approach of the form 'analyze the next 3 bits, remove one bit, change one bit' -- but I haven't been able to find something workable.

frLich
  • 163
  • 1
  • 5
  • what does "my group sizes are restricted" mean? – lijie Dec 17 '10 at 05:28
  • there seems to be effectiveness savings in grouping into larger and larger chunks (eg, 64 bits into 40 trits), but those operations would be expensive. – frLich Dec 17 '10 at 06:23

2 Answers2

2

Try to pack 11 bits (2048 codes) into 7 trits (2187 codes), you'll get less than 1% of overhead. There are several methods. First one is straightforward: the lookup table. Second is divmod-3. Third is some bit/trit mainpulation like below.

First stage: pack first 9 bits using 3-bit-to-2-trit scheme:

abc def ghi jk => mn pq rs jk (mn, pq, rs are trit pairs)

bits   trits
0ab -> ab
10a -> Za
11a -> aZ (i'll use Z is for -1 for compactness)

state ZZ will be used futher

Second stage: using more complex logic to pack 6 trits and 2 bits into 7 trits:

mn pq rs 0k -> mn pq rs k
mn pq rs 10 -> mn pq rs Z
mn pq rZ 11 -> mn pq ZZ r
mn pq r0 11 -> mn ZZ pq r
mn pq r1 11 -> ZZ mn pq r

Unused codes would be:

ZZ ZZ xx x
ZZ xx ZZ x
xx ZZ ZZ x

UPD another suitable packing relations are 19b -> 11t (~0.1% overhead), 84b -> 53t (~0,0035% overhead), but is seems to be overshoot.

Vovanium
  • 3,798
  • 17
  • 23
  • Wow. This is looking great - can you point to some background on the reasoning behind this approach? It also looks like I could reorder it a bit so I could send out 'ZZ' vs 'mn' sooner. – frLich Dec 17 '10 at 17:11
  • It seems to be empiric approach. I've seen how IEEE decimal floating point numbers made and figured out something like it. My 'algorithm' of doing this is: ensure destination codespace is enough; make mapping for as large as possible codespace subset; make the same for remainig codes. I do not know any high math behind it... – Vovanium Dec 20 '10 at 22:16
  • The current approach introduces a bias in the result; trits that include `Z` are less likely than others, as (by comparison) a larger part of the codes that include `Z` symbols remain unused. Do you have any thoughts on coding the trits in such a way that a random distribution can be preserved? – Joost Jan 18 '16 at 13:45
1

Could you pinch some ideas from http://en.wikipedia.org/wiki/Arithmetic_coding?

mcdowella
  • 19,301
  • 2
  • 19
  • 25
  • The example of three symbols with probability 1/3rd looks interesting. Is there any sort of shortcut that works with fixed probabilities - arithmetic coding seems to have a high symbol cost. – frLich Dec 17 '10 at 06:29
  • Did you end up using Arithmetic coding to attack this in the end? I'm dealing with a similar situation (bit-stream to trit-stream), and am investigating if it could be applied effectively. – Joost Jan 18 '16 at 13:38