Чи існує узагальнення кодування Хаффмана до арифметичного кодування?


11

Намагаючись зрозуміти зв’язки між кодуванням Хаффмана, арифметичним кодуванням і кодуванням діапазону, я почав думати про недоліки кодування Хаффмана, пов'язані з проблемою дробового розфасування бітів .

Тобто, припустимо, що у вас є 240 можливих значень для символу, і потрібно, щоб кодувати це в біти, ви застрягли б з 8 бітами на символ, навіть якщо вам не потрібно "повне" 8, оскільки 8 може виражати 256 можливих значень на символ. Вирішення цієї проблеми - це те, що я бачив, іменується "дробова розрядна упаковка", де ви можете "битсифтинг" неможливістю двох, використовуючи множення. Так само, як множення повноважень на два зміщується, x * 2 == x << 1і x * 4 == x << 2так далі для всіх потужностей по дві, так і ви можете "переключитися" на не-потужність-2 шляхом множення замість цього і упакувати в дробові символи розміру біт .

Проблема аналогічна кодуванню Хаффмана: ви закінчуєте коди, які мають бути не дробово-бітовими розмірами, і, отже, ця неефективність упаковки. Однак ви не можете просто використовувати розчин фракітональної бітової упаковки, оскільки це рішення передбачає символи фіксованого розміру.

Питання полягає в тому, чи існують якісь документи чи рішення для вдосконалення кодування Хаффмана, що має подібну ідею до дробового розфасовки, щоб досягти чогось подібного до арифметичного кодування? (або будь-які результати, навпаки).


1
Арифметичне кодування вже є оптимальним. Вдосконалювати її не потрібно.
Yuval Filmus

@YuvalFilmus Так, я мав на увазі, як покращити кодування Хаффмана, щоб зрівняти його з арифметичним кодуванням.
Realz Slaw

1
Як і пропозиція, ви можете знайти кодування асиметричної чисельної системи (ANS) простіше зрозуміти, ніж арифметичне кодування. Зокрема, трохи простіше розглянути цю формулювання як "дробову упаковку бітів".
Псевдонім

@ Псевдонім Я знайшов цю сторінку, яка, здається, зв’язує rANS і Хаффман Кодування. Не можу сказати, що я це ще зрозумів, але думаю, що цього достатньо. Якщо ви зробите коментар, відповідь я прийму.
Realz Slaw

@YuvalFilmus Я сподіваюся, що я зробив випадок, що арифметичне кодування потребує вдосконалення, а ANS - це покращення.
Псевдонім

Відповіді:


13

Давайте розглянемо дещо інший спосіб мислення про кодування Хаффмана.

Припустимо, у вас є алфавіт із трьох символів, A, B і C, з ймовірностями 0,5, 0,25 та 0,25. Оскільки ймовірності - це всі зворотні сили двох, у цього є код Хаффмана, який є оптимальним (тобто він ідентичний арифметичному кодуванню). Для цього прикладу ми будемо використовувати канонічний код 0, 10, 11.

Припустимо, наша держава - це велике ціле число, яке ми будемо називати . Ви можете думати про кодування як функцію, яка приймає поточний стан, і символ для кодування, і повертає новий стан:s

encode(s,A)=2sencode(s,B)=4s+2encode(s,C)=4s+3

Отже, почнемо зі стану 11 (який у двійковому значенні 1011), кодуємо символ B. Новий стан - 46, що становить 101110 у двійковому. Як бачимо, це "старий" стан із послідовністю 10, доданою до кінця. Ми по суті "виводимо" бітову послідовність 10.

Все йде нормально.

Тепер подумайте на хвилинку про те, як працює арифметичне кодування. Якщо розмістити ймовірності над загальним знаменником, символ A насправді представляє діапазон , символ B являє собою діапазон і символ C являє собою діапазон .[04,24)[24,34)[34,44)

В основному те, що ми робимо тут, - це множення всього на спільний знаменник. Уявіть, що стан насправді був у базі 4. Кодування символу B справді виводить цифру 2 у цій базі, а кодування символу C - виводить цифру 3 у цій базі.

Однак символ A трохи інший, тому що це не ціла цифра в базі 4.

Натомість ми можемо розглядати алфавіт як набір символів A_0, A_1, B, C з однаковою ймовірністю. Знову ж таки, оптимальний код Хаффмана 00, 01, 10, 11. Або, знову ж таки, ми можемо подумати про це в базі 4. Для кодування символу просто робимо:

encode(s,A0)=4s+0encode(s,A1)=4s+1encode(s,B)=4s+2encode(s,C)=4s+3

Отже, тепер зрозуміло, як кодувати символи B і C, але кодувати символ A, у нас є вибір. Які з та ми повинні використовувати?A 1A0A1

Тепер ось розумна думка: ми крадемо один біт інформації зі стану :s

s=s2
i=smod2

а потім .encode(s,Ai)

Використовуючи наш попередній приклад, , ми знаходимо, що і , а потім . Новий стан - 10101 у двійковій.s=11s=5i=1encode(5,A1)=4×5+1=21

Тепер це не дає точно такий же бітовий вихід, як кодування Хаффмана, але він генерує вихід, який має ту саму довжину. І я сподіваюся, що ви можете побачити, що це також унікально розширюється. Щоб розшифрувати символ, ми беремо залишок, поділившись на 4. Якщо значення дорівнює 2 або 3, то символ - B або C відповідно. Якщо це 0 або 1, то символом є A, і ми можемо повернути біт інформації назад, помноживши стан на 2 і додавши або 0, або 1.

Приємним у цьому підході є те, що він природно поширюється на дробове бітове кодування, коли чисельник та / або знаменник ймовірностей не мають сили двох. Припустимо, у нас є два символи, A і B, де ймовірність A дорівнює а ймовірність B - . Тоді ми можемо кодувати символ за допомогою:3525

encode(s,A0)=5s+0encode(s,A1)=5s+1encode(s,A2)=5s+2encode(s,B0)=5s+3encode(s,B1)=5s+4

Для кодування символу A беремо і , а потім .s=s3i=smod3encode(s,Ai)

Це еквівалентно арифметичному кодуванню. Це насправді сімейство методів, відомих як Асиметричні чисельні системи , і було розроблено протягом останніх кількох років Яреком Дудою. Значення імені повинно бути очевидним: щоб кодувати символ з вірогідністю , ви концептуально вкрали цифру базового p із стану, а потім додали цифру базового q. Асиметрія походить від трактування стану як цифри у двох різних основах.pq

Причина, чому це сімейство методів кодування, полягає в тому, що те, що ми бачили тут, непрактично саме по собі; йому потрібні деякі модифікації для вирішення того факту, що ви, мабуть, не маєте безмежно точних цілих чисел для ефективного маніпулювання змінною стану, і є різні способи, яким ви можете цього досягти. Арифметичне кодування, звичайно, має аналогічне питання з точністю до свого стану.

Практичні варіанти включають rANS ("r" означає "співвідношення") і tANS ("керований таблицею").

ANS має кілька цікавих переваг перед арифметичним кодуванням, як практичним, так і теоретичним:

  • На відміну від арифметичного кодування, "стан" - це одне слово, а не пара слів.
  • Мало того, що кодер ANS та його відповідний декодер мають однакові стани, і їх операції є абсолютно симетричними. Це викликає деякі цікаві можливості, наприклад, ви можете переплутати різні потоки закодованих символів і все ідеально синхронізується.
  • Звичайно, для практичних реалізацій потрібно "виводити" інформацію, а не просто збирати її у велике ціле число, яке потрібно записати наприкінці. Однак розмір "виводу" можна налаштувати взамін на (як правило, скромні) втрати на стиснення. Тож, коли арифметичні кодери повинні виводити трохи за один раз, ANS може виводити байт або nybble за один раз. Це дає вам прямий компроміс між швидкістю та стисненням.
  • Здається, що на апаратному забезпеченні поточного покоління воно настільки ж швидко, як і двійкове арифметичне кодування, і, отже, є конкурентоспроможною кодування Хаффмана. Це робить його набагато швидшим, ніж арифметичне кодування великого алфавіту та його варіанти (наприклад, кодування діапазону).
  • Це, мабуть, не є патентом.

Я не думаю, що коли-небудь знову буду робити арифметичне кодування.


4
Тепер це найясніше пояснення кодування ANS, яке я коли-небудь бачив.
Майкл Deardeuff

2

Як простий приклад, якби у вас було три символи з вірогідністю 1/3 кожного, оптимальне кодування Хаффмана використовувало б три символи 0, 10 та 11 із середнім значенням 5/3 біт.

Є 243 символи, створені об'єднанням 5 вихідних символів, кожен з імовірністю 1/243. Що набагато ближче до 1/256. Оптимальне кодування Хаффмана буде кодувати 13 з цих груп у 7 бітах і 230 груп у 8 бітах, в середньому 7,9465 біт на групу або 1,5893 біта на оригінальний символ, що зменшується від 1,6667 біт для вихідного кодування Хаффмана, а арифметичне кодування займає 1,5850 біт.

Тож теоретично ви могли просто поєднати два символи кожен у один більший символ, або три символи кожен у один більший символ, і використовувати кодування Хуфмана для комбінацій.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.