Подтвердить что ты не робот

Алгоритм сжатия данных IEEE-754

У кого-нибудь есть рекомендация по хорошему алгоритму сжатия, который хорошо работает с значениями с плавающей запятой двойной точности? Мы обнаружили, что двоичное представление значений с плавающей запятой приводит к очень низким коэффициентам сжатия с общими программами сжатия (например, Zip, RAR, 7-Zip и т.д.).

Данные, которые нам нужно сжать, представляют собой одномерный массив из 8-байтовых значений, отсортированных в монотонно возрастающем порядке. Значения представляют температуры в Кельвине с интервалом, обычно равным 100 градусам. Количество значений варьируется от нескольких сотен до не более 64 КБ.

Разъяснения

  • Все значения в массиве различны, хотя повторение существует на уровне байтов из-за того, что представлены значения с плавающей запятой.

  • Желателен алгоритм без потерь, поскольку это научные данные. Преобразование в представление с фиксированной точкой с достаточной точностью (~ 5 десятичных знаков) может быть приемлемым при условии значительного улучшения эффективности хранения.

Обновление

Нашел интересную статью по этому вопросу. Не уверен, насколько применим подход к моим требованиям.

http://users.ices.utexas.edu/~burtscher/papers/dcc06.pdf

4b9b3361

Ответ 1

Первое, что нужно учитывать: попробуйте сжать данные, прежде чем преобразовывать их в двойную точность. Повторите свой комментарий Дэвиду Торнли, если у вашего ИК-изображения ADC нет 24 значащих бит, 32-битные поплавки должны иметь более чем достаточную точность; только ваше требование точно сохранить шум, создаваемый последующей обработкой, что является проблемой. В противном случае, возможно, было бы целесообразно обратное проектирование вашей обработки, путем определения таблицы значений, которую она генерирует, и вместо этого хранения индекса в этой таблице.

Во-вторых: если ваш алгоритм сжатия знает, что ваши данные находятся в 8-байтовых кусках, это будет намного более эффективно; это потому, что он не будет генерировать ваши самые значимые байты с наименее значимыми байтами. Как грубый метод предварительной обработки, вы могли бы попробовать префикс каждого двойника с отличительным байтом (запятая ASCII, возможно?), Прежде чем прокладывать его через байт-компрессор, такой как gzip; это должно привести к лучшему полному сжатию, даже если промежуточный поток на 12% больше. Меньше грубых, но больше усилий было бы написать собственное сжатие, адаптированное к этой задаче - возможно, используя 8-уровневое дерево для представления ожидаемых значений каждого байта в вашем двойном.

В-третьих: поскольку данные изображения сильно избыточны, некоторая форма дельта-кодирования или другое сжатие, связанное с изображением, должно сэкономить некоторое пространство. Тем не менее, это не принесет вам ужасно большой суммы, если вы потребуете сжатия без потерь, поскольку шум изображения по своей сути несжимаем. Кроме того, это не поможет вам разобраться с псевдослучайным хэшем в менее значительных битах ваших удвоений, как объяснялось выше.

Ответ 2

Все перечисленные вами кодировщики ориентированы по байтам и отбрасываются несколькими свойствами двойников. Для одного есть макет, где 12-разрядный показатель/знак не очень хорошо работает с границами байтов, для других - шумность вашего ввода. Первая часть легко обрабатывается множеством способов, вторая ограничивает эффективность любого сжатия без потерь, которое вы бросаете на него. Я думаю, что даже лучший результат будет менее чем потрясающим, я не знаю ваших данных, но я подозреваю, что вы можете рассчитывать на 25% -ную экономию, более или менее.

Сверху моей головы, и, возможно, бесполезно, потому что вы подумали обо всем в этом списке...

  • Рассматривайте поток как 64-битные целые числа и смежные значения delta-encode. Если у вас есть значения значений с одинаковым показателем, он будет эффективно обнулять его, а также, возможно, некоторые биты высокой мантиссы. Там будут переполнения, но данные по-прежнему нуждаются только в 64 бит, и операция может быть почитаема.

  • На этом этапе вы можете, возможно, попробовать грубое целочисленное предсказание и сохранить различия.

  • Если вы последовали этому предложению раньше, у вас будет почти половина значений, начинающихся с 000... и почти половина с FFF... Чтобы устранить это, поверните значение влево (ROL) на 1 бит и XOR он со всеми Fs, если текущий LSB равен 1. Обратный - это XOR с Fs, если LSB равен 0, затем ROR.

Во второй мысли просто предсказания XORing для истинных значений могут быть лучше, чем разница, потому что вам не нужно делать шаг 3. Затем

  1. Вы можете попробовать переупорядочить байты для группировки байтов с одинаковым значением вместе. Например, сначала все наиболее значимые байты и так далее. По крайней мере, вы должны получить что-то вроде массивного запуска нулей с наименьшим количеством бит шума.

  2. Запуск через общий компрессор или даже первый RLE при запуске нулей, то энтропийный кодер, например, huffman или лучше, кодирует диапазон от 7zip/LZMA.

В ваших данных есть одна хорошая вещь, она монотонна. Плохо о ваших данных: это слишком маленький набор. Сколько вы хотите сохранить, просто килобай? зачем? Эффективность сжатия будет сильно страдать, если между смежными значениями существует разница между экспонентами.

Если вы обрабатываете большое количество этих наборов данных, вам следует подумать об их сходстве, чтобы сжать их вместе лучше - возможно, чередуя их на определенном этапе. Если вы можете жить с некоторой потерей, обнуление некоторых наименее значимых байтов может быть хорошей идеей - возможно, как на исходных данных, так и на предсказании, чтобы вы не возвращали туда шум.

Ответ 3

Можете ли вы сделать дельта между смежными значениями?
Есть ли предел того, насколько значение может меняться между измерениями? Допустимо ли ограничить это изменение до некоторого максимального значения скорости (за счет введения некоторого сглаживания?)

Очевидно, что существует предел реальной точности значений от теплового датчика, нужно ли хранить 64 бита точности или лучше хранить целое число, например, 0,01-кельвинских единиц?

Если вы можете жить с некоторой дополнительной ошибкой, и увеличение относительно плавное, вам может быть лучше просто подогнать функцию к данным и сохранить только несколько членов функции.

EDIT:
Взгляните на типичный набор данных и посмотрите на диапазон различий между смежными значениями. Затем посмотрите, какую точность вам нужно представлять.

например. Если у вас максимальная разница в 1 градус между показаниями, вы можете сохранить изменения в 1/256 этого байта. Если вам нужно сохранить больший диапазон или более точную точность, используйте короткое разделение на некоторый коэффициент.
Итак, следующее чтение будет = last_reading + (float) increment/256.0

Ответ 4

Алгоритмы сжатия сохраняются при повторениях и закономерностях, а числа с плавающей запятой не работают.

Первый вопрос: можете ли вы использовать значения с плавающей запятой с одинарной точностью, что сразу даст вам 50% -ное сжатие. Несколько термометров с точностью до семи цифр, и показатель будет представлять собой температуру значительно ниже всего, что мне сказали, что вы действительно можете получить.

Если нет, можете ли вы фильтровать свои температуры, округляя их до эквивалента N цифр (скорее всего, N/.301 бит)? Это может привести к появлению достаточных закономерностей.

Если вам действительно нужно хранить 64 бита информации для каждого показания температуры, и все биты значительны и не предсказуемы из других битов, то вы фактически не можете сжать его.

Ответ 5

Если вы хотите архивировать хранилище с высокой степенью сжатия, "Листром и Изенбергом" может быть полезно "Высокопроизводительное сжатие данных с двойной точностью плавающей запятой" Burtscher и Patanaworabhan или "Быстрое и эффективное сжатие данных с плавающей запятой",

Если вам нужен более быстрый динамический доступ за счет более низкой степени сжатия, может потребоваться однократный подъемный вейвлет. Вы можете квантовать данные на меньшие целые числа, указав количество цифр для сохранения. Затем используйте дельта-кодирование с предсказательной моделью, за которой следует преобразование с Haar или более дорогое вейвлет-преобразование и арифметическое кодирование коэффициентов, превышающих заданное значение.

надеюсь, что это поможет

Здесь вы можете получить алгоритм Lindprom ZFP: https://github.com/LLNL/zfp

Ответ 6

Вы могли бы подумать о повторной кодировке ваших данных энтропийным кодером (Хаффман, Шеннон-Фано, Арифметическое кодирование). Но это даст только хорошие результаты, если у вас много повторений данных и если вы знаете, какие символы появятся с какой вероятностью.