Введение

Форма энтропийного кодирования, используемая при сжатии данных. Арифметическое кодирование (AC) — это форма энтропийного кодирования, применяемая при сжатии данных без потерь. Обычно строка символов представляется фиксированным количеством бит на символ, как, например, в коде ASCII. При преобразовании строки в арифметический код часто используемые символы хранятся меньшим количеством бит, а редко встречающиеся — большим, что в итоге приводит к уменьшению общего количества используемых бит. Арифметическое кодирование отличается от других форм энтропийного кодирования, таких как кодирование Хаффмана, тем, что вместо разделения входных данных на отдельные символы и замены каждого кодом, оно кодирует всё сообщение в одно число — дробь произвольной точности q, где 0.0 ≤ q < 1.0. Информация представляется в виде диапазона, определяемого двумя числами. Недавнее семейство энтропийных кодировщиков, называемое асимметричными численными системами, обеспечивает более быструю реализацию благодаря непосредственной работе с одним натуральным числом, представляющим текущую информацию.

Равные вероятности

В самом простом случае вероятность появления каждого символа одинакова. Например, рассмотрим набор из трех символов, A, B и C, каждый из которых равновероятен. Кодирование символов по одному потребует 2 бита на символ, что неэффективно: одна из возможных комбинаций битов не используется. То есть, символы A, B и C могут быть закодированы соответственно как 00, 01 и 10, при этом 11 остаётся неиспользованным. Более эффективное решение – представить последовательность этих трех символов в виде рационального числа в троичной системе счисления, где каждая цифра соответствует символу. Например, последовательность "ABBCAB" может быть представлена как 0.0112013, а в арифметическом кодировании – как значение в интервале [0, 1). Следующий шаг – кодирование этого троичного числа с использованием двоичного числа с фиксированной точкой, обладающего достаточной точностью для его восстановления, например, 0.00101100012 – это всего 10 бит; по сравнению с наивным блочным кодированием экономится 2 бита. Это осуществимо для длинных последовательностей, поскольку существуют эффективные алгоритмы для преобразования основания чисел произвольной точности. Для декодирования значения, зная, что исходная строка имеет длину 6, можно просто преобразовать число обратно в троичную систему счисления, округлить до 6 знаков и восстановить строку.

Адаптированное арифметическое кодирование

Одним из преимуществ арифметического кодирования перед другими подобными методами сжатия данных является простота адаптации. Адаптация заключается в изменении таблиц частот (или вероятностей) в процессе обработки данных. Декодированные данные будут соответствовать исходным, если таблица частот при декодировании обновляется тем же способом и на том же шаге, что и при кодировании. Синхронизация обычно основана на комбинации символов, встречающихся в процессе кодирования и декодирования.

Асимптотическое равноразделение

Мы можем понять это интуитивно. Предположим, что источник эргодичен, тогда он обладает свойством асимптотического равнораспределения (AEP). Согласно AEP, после длинной последовательности символов, интервал почти полностью разбивается на интервалы почти одинакового размера. Точнее, для любого малого ε, для всех достаточно больших n, существуют строки S, такие что каждая строка имеет почти одинаковую вероятность P(S), и их суммарная вероятность равна 1.

Для любой такой строки S, она арифметически кодируется двоичной строкой длины n, где n – наименьшее число, такое что существует дробь вида k/2^n в интервале для P(S). Поскольку интервал для P(S) имеет размер ε, мы должны ожидать, что он содержит одну дробь вида k/2^n, когда ε = 1/2^n.

Таким образом, с высокой вероятностью, S может быть арифметически закодирован двоичной строкой длины n.

Кодирование Хаффмана

Поскольку арифметическое кодирование не сжимает данные по одному, оно может произвольно приближаться к энтропии при сжатии строк IID. В отличие от него, расширение кодирования Хаффмана для строк не достигает энтропии, если только все вероятности символов алфавита не являются степенями двойки, в этом случае как кодирование Хаффмана, так и арифметическое кодирование достигают энтропии. При наивном кодировании двоичных строк кодированием Хаффмана сжатие невозможно, даже если энтропия низкая (например, для ({0, 1}) с вероятностями {0,95, 0,05}). Кодирование Хаффмана присваивает 1 бит каждому значению, в результате чего получается код той же длины, что и входные данные. Напротив, арифметическое кодирование хорошо сжимает биты, приближаясь к оптимальному коэффициенту сжатия. Один из простых способов устранить субоптимальность кодирования Хаффмана — это конкатенация символов ("блокирование") для формирования нового алфавита, в котором каждый новый символ представляет собой последовательность исходных символов — в данном случае битов — из исходного алфавита. В приведенном выше примере, группировка последовательностей из трех символов перед кодированием приведет к новым "суперсимволам" со следующими частотами:
: 85.7%
, , : 4.5% каждый
, , : 0.24% каждый
: 0.0125%

При таком группировании кодирование Хаффмана в среднем дает 1.3 бита на каждые три символа, или 0.433 бита на символ, по сравнению с одним битом на символ при исходном кодировании, то есть сжатие. Разрешение произвольно больших последовательностей позволяет произвольно приближаться к энтропии — как и арифметическое кодирование — но требует для этого огромных кодов, поэтому это не так практично, как арифметическое кодирование для этой цели. Альтернативой является кодирование длин серий с использованием кодов Голомба-Райса на основе Хаффмана. Такой подход обеспечивает более простое и быстрое кодирование/декодирование, чем арифметическое кодирование или даже кодирование Хаффмана, поскольку последнее требует поиска в таблице. В примере {0,95, 0,05} код Голомба-Райса с четырехбитным остатком достигает коэффициента сжатия , что намного ближе к оптимальному, чем при использовании трехбитных блоков. Однако коды Голомба-Райса применимы только к входным данным Бернулли, таким как в этом примере, поэтому они не заменяют блокирование во всех случаях.

Показатели и другие технические характеристики

Каждая программная реализация арифметического кодирования обладает своим собственным коэффициентом сжатия и производительностью. Хотя коэффициенты сжатия меняются незначительно (обычно менее 1%), время выполнения кода может отличаться в 10 раз. Выбор подходящего кодировщика из списка общедоступных – непростая задача, так как производительность и коэффициент сжатия зависят также от типа данных, в особенности от размера алфавита (количества различных символов). Один из двух конкретных кодировщиков может показывать лучшую производительность для небольших алфавитов, а другой – для больших. Большинство кодировщиков имеют ограничения на размер алфавита, и многие из них специализированы для алфавитов, состоящих ровно из двух символов (0 и 1).