В теории информации и теории кодирования коды Рида-Соломона представляют собой группу кодов с исправлением ошибок , которые были введены Ирвингом С. Ридом и Гюставом Соломоном в 1960 году. [1] Они имеют множество применений, включая потребительские технологии, такие как мини-диски , компакт -диски , DVD-диски , диски Blu-ray , QR-коды , Data Matrix , технологии передачи данных , такие как DSL и WiMAX , системы вещания, такие как спутниковая связь, DVB и ATSC , и системы хранения данных, такие как RAID 6 .
Коды Рида–Соломона работают с блоком данных, который рассматривается как набор элементов конечного поля, называемых символами. Коды Рида–Соломона способны обнаруживать и исправлять множественные ошибки символов. Добавляя t = n − k контрольных символов к данным, код Рида–Соломона может обнаруживать (но не исправлять) любую комбинацию до t ошибочных символов или находить и исправлять до ⌊ t /2⌋ ошибочных символов в неизвестных местах. Как код стирания , он может исправлять до t стираний в местах, которые известны и предоставлены алгоритму, или он может обнаруживать и исправлять комбинации ошибок и стираний. Коды Рида–Соломона также подходят в качестве кодов исправления множественных пакетных битовых ошибок, поскольку последовательность из b + 1 последовательных битовых ошибок может повлиять не более чем на два символа размера b . Выбор t остается за разработчиком кода и может быть выбран в широких пределах.
Существует два основных типа кодов Рида-Соломона — исходный вид и вид BCH , при этом вид BCH является наиболее распространенным, поскольку декодеры вида BCH работают быстрее и требуют меньше рабочей памяти, чем декодеры исходного вида.
Коды Рида–Соломона были разработаны в 1960 году Ирвингом С. Ридом и Гюставом Соломоном , которые тогда были сотрудниками лаборатории Линкольна Массачусетского технологического института . Их основополагающая статья называлась «Полиномиальные коды над определенными конечными полями» (Reed & Solomon 1960). Первоначальная схема кодирования, описанная в статье Рида и Соломона, использовала переменный полином, основанный на кодируемом сообщении, где кодеру и декодеру известен только фиксированный набор значений (точек оценки), которые должны быть кодированы. Первоначальный теоретический декодер генерировал потенциальные полиномы, основанные на подмножествах k (длина незакодированного сообщения) из n (длина закодированного сообщения) значений полученного сообщения, выбирая наиболее популярный полином в качестве правильного, что было непрактично для всех случаев, кроме самых простых. Первоначально это было решено путем изменения исходной схемы на схему, подобную коду BCH , основанную на фиксированном полиноме, известном как кодеру, так и декодеру, но позже были разработаны практические декодеры, основанные на исходной схеме, хотя и более медленные, чем схемы BCH. Результатом этого является то, что существует два основных типа кодов Рида-Соломона: те, которые используют исходную схему кодирования, и те, которые используют схему кодирования BCH.
Также в 1960 году практический фиксированный полиномиальный декодер для кодов BCH, разработанный Дэниелом Горенштейном и Нилом Цирлером, был описан в отчете лаборатории Линкольна Массачусетского технологического института Цирлером в январе 1960 года и позднее в статье в июне 1961 года. [2] Декодер Горенштейна–Цирлера и связанная с ним работа по кодам BCH описаны в книге «Коды с коррекцией ошибок» У. Уэсли Петерсона (1961). [3] К 1963 году (или, возможно, раньше) Дж. Дж. Стоун (и другие) поняли, что коды Рида-Соломона могут использовать схему BCH с использованием фиксированного порождающего полинома, что делает такие коды особым классом кодов BCH, [4] но коды Рида-Соломона, основанные на исходной схеме кодирования, не являются классом кодов BCH, и в зависимости от набора точек оценки они даже не являются циклическими кодами .
В 1969 году Элвин Берлекэмп и Джеймс Мэсси разработали усовершенствованный декодер схемы BCH , который с тех пор известен как алгоритм декодирования Берлекэмпа–Месси .
В 1975 году Ясуо Сугияма разработал еще один улучшенный декодер схемы BCH, основанный на расширенном алгоритме Евклида . [5]
В 1977 году коды Рида–Соломона были реализованы в программе Voyager в виде конкатенированных кодов исправления ошибок . Первое коммерческое применение в массовых потребительских товарах появилось в 1982 году с компакт-диском , где использовались два перемежающихся кода Рида–Соломона. Сегодня коды Рида–Соломона широко используются в цифровых устройствах хранения данных и стандартах цифровой связи , хотя их постепенно заменяют кодами Бозе–Чоудхури–Хоквингема (BCH) . Например, коды Рида–Соломона используются в стандарте цифрового видеовещания (DVB) DVB-S в сочетании со свёрточным внутренним кодом , но коды BCH используются с LDPC в его преемнике DVB-S2 .
В 1986 году была разработана оригинальная схема декодера, известная как алгоритм Берлекэмпа–Уэлча .
В 1996 году Мадху Судан и другие разработали вариации оригинальных схем декодеров, называемых декодерами списков или программными декодерами, и работа над этими типами декодеров продолжается – см. Алгоритм декодирования списков Гурусвами–Судана .
В 2002 году Шухонг Гао разработал еще одну оригинальную схему декодера, основанную на расширенном алгоритме Евклида . [6]
Кодирование Рида-Соломона очень широко используется в системах массового хранения данных для исправления пакетных ошибок, связанных с дефектами носителей.
Кодирование Рида-Соломона является ключевым компонентом компакт- диска . Это было первое использование сильного кодирования с исправлением ошибок в массовом потребительском продукте, а DAT и DVD используют похожие схемы. В CD два слоя кодирования Рида-Соломона, разделенные 28-канальным сверточным перемежителем, дают схему, называемую перекрестно-перемежаемым кодированием Рида-Соломона ( CIRC ). Первым элементом декодера CIRC является относительно слабый внутренний (32,28) код Рида-Соломона, сокращенный от (255,251) кода с 8-битными символами. Этот код может исправлять до 2 ошибок байта на 32-байтовый блок. Что еще более важно, он помечает как стирания любые неисправимые блоки, т. е. блоки с ошибками более 2 байтов. Декодированные 28-байтовые блоки с индикацией стирания затем распространяются деперемежителем на различные блоки внешнего кода (28,24). Благодаря деинтерливингу стертый 28-байтовый блок внутреннего кода становится одним стертым байтом в каждом из 28 внешних кодовых блоков. Внешний код легко исправляет это, поскольку он может обрабатывать до 4 таких стираний на блок.
Результатом является CIRC, который может полностью исправить пакеты ошибок до 4000 бит, или около 2,5 мм на поверхности диска. Этот код настолько силен, что большинство ошибок воспроизведения компакт-дисков почти наверняка вызваны ошибками трекинга, которые заставляют лазер перескакивать с одной дорожки на другую, а не неисправимыми пакетами ошибок. [7]
DVD-диски используют похожую схему, но с гораздо большими блоками, внутренним кодом (208 192) и внешним кодом (182 172).
Исправление ошибок Рида-Соломона также используется в файлах parchive , которые обычно публикуются вместе с мультимедийными файлами в USENET . Распределенная служба онлайн-хранилища Wuala (прекращена в 2015 году) также использовала алгоритм Рида-Соломона при разбиении файлов.
Почти все двумерные штрихкоды, такие как PDF-417 , MaxiCode , Datamatrix , QR Code и Aztec Code , используют коррекцию ошибок Рида-Соломона, чтобы обеспечить правильное считывание, даже если часть штрихкода повреждена. Когда сканер штрихкода не может распознать символ штрихкода, он будет считать его стиранием.
Кодирование Рида-Соломона менее распространено в одномерных штрихкодах, но используется в символике PostBar .
Специализированные формы кодов Рида-Соломона, в частности, коды Коши -RS и Вандермонда -RS, могут использоваться для преодоления ненадежной природы передачи данных по каналам стирания . Процесс кодирования предполагает код RS( N , K ), который приводит к генерации N кодовых слов длиной N символов, каждое из которых хранит K символов данных, которые затем отправляются по каналу стирания.
Любая комбинация из K кодовых слов, полученных на другом конце, достаточна для реконструкции всех N кодовых слов. Скорость кода обычно устанавливается на уровне 1/2, если только вероятность стирания канала не может быть адекватно смоделирована и не оказывается меньше. В заключение, N обычно равно 2 K , что означает, что для реконструкции всех отправленных кодовых слов необходимо получить не менее половины всех отправленных кодовых слов.
Коды Рида-Соломона также используются в системах xDSL и спецификациях протокола космической связи CCSDS как форма прямой коррекции ошибок .
Одним из важных применений кодирования Рида-Соломона было кодирование цифровых изображений, отправленных программой «Вояджер» .
Voyager представил кодирование Рида-Соломона, соединенное со сверточными кодами , — практика, которая с тех пор получила широкое распространение в дальнем космосе и спутниковой связи (например, прямое цифровое вещание).
Декодеры Витерби склонны выдавать ошибки короткими пачками. Исправление этих пачками ошибок лучше всего выполняется короткими или упрощенными кодами Рида-Соломона.
Современные версии конкатенированного сверточного кодирования с декодированием Рида-Соломона/Витерби использовались и используются в миссиях Mars Pathfinder , Galileo , Mars Exploration Rover и Cassini , где они работают в пределах примерно 1–1,5 дБ от конечного предела — пропускной способности Шеннона .
Эти конкатенированные коды теперь заменяются более мощными турбокодами :
Код Рида–Соломона на самом деле является семейством кодов, где каждый код характеризуется тремя параметрами: размером алфавита , длиной блока и длиной сообщения , при этом . Набор символов алфавита интерпретируется как конечное поле порядка и, таким образом, должен быть степенью простого числа . В наиболее полезных параметризациях кода Рида–Соломона длина блока обычно является некоторой константой, кратной длине сообщения, то есть скорость является некоторой константой, и, кроме того, длина блока равна или на единицу меньше размера алфавита, то есть или . [ необходима цитата ]
Существуют различные процедуры кодирования для кода Рида–Соломона, и, таким образом, существуют различные способы описания набора всех кодовых слов. В первоначальном представлении Рида и Соломона (1960) каждое кодовое слово кода Рида–Соломона представляет собой последовательность значений функции полинома степени меньше . Чтобы получить кодовое слово кода Рида–Соломона, символы сообщения (каждый в пределах алфавита размером q) рассматриваются как коэффициенты полинома степени меньше k , над конечным полем с элементами. В свою очередь, полином p оценивается в n ≤ q различных точках поля F , а последовательность значений является соответствующим кодовым словом. Обычный выбор для набора точек оценки включает {0, 1, 2, ..., n - 1}, {0, 1, α , α 2 , ..., α n −2 } или для n < q , { 1 , α , α 2 , ..., α n −1 }, ... , где α является примитивным элементом F .
Формально набор кодовых слов кода Рида–Соломона определяется следующим образом: Поскольку любые два различных полинома степени меньше согласуются в большинстве точек, это означает, что любые два кодовых слова кода Рида–Соломона не согласуются по крайней мере в позициях. Более того, существуют два полинома, которые согласуются в точках, но не равны, и, таким образом, расстояние кода Рида–Соломона равно в точности . Тогда относительное расстояние равно , где — скорость. Этот компромисс между относительным расстоянием и скоростью является асимптотически оптимальным, поскольку по границе Синглтона каждый код удовлетворяет . Будучи кодом, который достигает этого оптимального компромисса , код Рида–Соломона принадлежит к классу кодов, разделяемых на максимальном расстоянии .
В то время как число различных многочленов степени меньше k и число различных сообщений оба равны , и, таким образом, каждое сообщение может быть однозначно отображено в такой многочлен, существуют различные способы выполнения этого кодирования. Первоначальная конструкция Рида и Соломона (1960) интерпретирует сообщение x как коэффициенты многочлена p , тогда как последующие конструкции интерпретируют сообщение как значения многочлена в первых k точках и получают многочлен p путем интерполяции этих значений с многочленом степени меньше k . Последняя процедура кодирования, хотя и немного менее эффективна, имеет то преимущество, что она приводит к систематическому коду , то есть исходное сообщение всегда содержится как подпоследовательность кодового слова.
В оригинальной конструкции Рида и Соломона (1960) сообщение отображается в полином с Кодовое слово получается путем оценки в различных точках поля . Таким образом, классическая функция кодирования для кода Рида–Соломона определяется следующим образом: Эта функция является линейным отображением , то есть она удовлетворяет для следующей -матрицы с элементами из :
Эта матрица является матрицей Вандермонда над . Другими словами, код Рида–Соломона является линейным кодом , и в классической процедуре кодирования его порождающая матрица равна .
Существуют альтернативные процедуры кодирования, которые производят систематический код Рида–Соломона. Один метод использует интерполяцию Лагранжа для вычисления полинома, такого что Тогда оценивается в других точках .
Эта функция является линейным отображением. Чтобы сгенерировать соответствующую систематическую кодирующую матрицу G, умножьте матрицу Вандермонда A на обратную левую квадратную подматрицу A.
для следующей -матрицы с элементами из :
Дискретное преобразование Фурье по сути то же самое, что и процедура кодирования; оно использует генераторный полином для отображения набора точек оценки в значения сообщения, как показано выше:
Обратное преобразование Фурье можно использовать для преобразования безошибочного набора значений сообщения n < q обратно в кодирующий полином из k коэффициентов, с тем ограничением, что для того, чтобы это работало, набор точек оценки, используемых для кодирования сообщения, должен быть набором возрастающих степеней α :
Однако интерполяция Лагранжа выполняет то же самое преобразование без ограничений на набор точек оценки или требования безошибочного набора значений сообщения и используется для систематического кодирования и на одном из этапов декодера Гао.
В этом представлении сообщение интерпретируется как коэффициенты полинома . Отправитель вычисляет связанный полином степени , где и отправляет полином . Полином строится путем умножения полинома сообщения , имеющего степень , на порождающий полином степени , которая известна как отправителю, так и получателю. Порождающий полином определяется как полином, корни которого являются последовательными степенями примитива поля Галуа
Для «узкосмыслового кода» .
Процедуру кодирования для представления BCH кодов Рида–Соломона можно модифицировать, чтобы получить систематическую процедуру кодирования , в которой каждое кодовое слово содержит сообщение в качестве префикса и просто добавляет символы исправления ошибок в качестве суффикса. Здесь вместо отправки кодер строит переданный полином таким образом, что коэффициенты наибольших мономов равны соответствующим коэффициентам , а коэффициенты низшего порядка выбираются точно таким образом, что становятся делимыми на . Тогда коэффициенты являются подпоследовательностью коэффициентов . Чтобы получить код, который является в целом систематическим, мы строим полином сообщения , интерпретируя сообщение как последовательность его коэффициентов.
Формально, построение выполняется путем умножения на , чтобы освободить место для контрольных символов, деления этого произведения на , чтобы найти остаток, а затем компенсации этого остатка путем его вычитания. Контрольные символы создаются путем вычисления остатка :
Остаток имеет степень не более , тогда как коэффициенты в полиноме равны нулю. Поэтому следующее определение кодового слова обладает тем свойством, что первые коэффициенты идентичны коэффициентам :
В результате кодовые слова действительно являются элементами , то есть они делятся на порождающий полином : [10]
Код Рида–Соломона — это код [ n , k , n − k +1]; другими словами, это линейный блочный код длины n (над F ) с размерностью k и минимальным расстоянием Хэмминга. Код Рида–Соломона оптимален в том смысле, что минимальное расстояние имеет максимально возможное значение для линейного кода размера ( n , k ); это известно как граница Синглтона . Такой код также называется кодом с максимальным расстоянием разделения (MDS) .
Способность кода Рида–Соломона исправлять ошибки определяется его минимальным расстоянием или, что эквивалентно, мерой избыточности в блоке. Если расположение ошибочных символов заранее неизвестно, то код Рида–Соломона может исправить до ошибочных символов, т. е. он может исправить половину ошибок, чем избыточных символов, добавленных в блок. Иногда расположение ошибок известно заранее (например, «побочная информация» в отношениях сигнал/шум демодулятора ) — их называют стираниями . Код Рида–Соломона (как и любой код MDS ) способен исправить вдвое больше стираний, чем ошибок, и любая комбинация ошибок и стираний может быть исправлена, пока выполняется соотношение 2 E + S ≤ n − k , где — количество ошибок, а — количество стираний в блоке.
Теоретическая граница ошибки может быть описана с помощью следующей формулы для канала AWGN для FSK : [11] и для других схем модуляции: где , , , — частота ошибок символов в случае некодированного AWGN, а — порядок модуляции.
Для практического использования кодов Рида–Соломона обычно используют конечное поле с элементами. В этом случае каждый символ может быть представлен как -битное значение. Отправитель отправляет точки данных в виде закодированных блоков, а количество символов в закодированном блоке равно . Таким образом, код Рида–Соломона, работающий с 8-битными символами, имеет символов на блок. (Это очень популярное значение из-за распространенности байт-ориентированных компьютерных систем.) Количество , с , символов данных в блоке является параметром проектирования. Обычно используемый код кодирует восьмибитные символы данных плюс 32 восьмибитных символа четности в -символьном блоке; это обозначается как код и способно исправлять до 16 ошибок символов на блок.
Свойства кода Рида-Соломона, рассмотренные выше, делают их особенно подходящими для приложений, где ошибки происходят пачками . Это связано с тем, что для кода не имеет значения, сколько бит в символе содержат ошибку — если несколько бит в символе повреждены, это считается только одной ошибкой. И наоборот, если поток данных не характеризуется пачками ошибок или выпадениями, а случайными ошибками в одном бите, код Рида-Соломона обычно является плохим выбором по сравнению с двоичным кодом.
Код Рида–Соломона, как и сверточный код , является прозрачным кодом. Это означает, что если символы канала были инвертированы где-то по линии, декодеры все равно будут работать. Результатом будет инверсия исходных данных. Однако код Рида–Соломона теряет свою прозрачность, когда код укорачивается ( см. «Примечания» в конце этого раздела ). «Отсутствующие» биты в укороченном коде должны быть заполнены либо нулями, либо единицами, в зависимости от того, дополняются данные или нет. (Другими словами, если символы инвертированы, то заполнение нулями должно быть инвертировано в заполнение единицами.) По этой причине обязательно, чтобы смысл данных (т. е. истинный или дополненный) был разрешен до декодирования Рида–Соломона.
Является ли код Рида–Соломона циклическим или нет, зависит от тонких деталей конструкции. В исходном представлении Рида и Соломона, где кодовые слова являются значениями многочлена, можно выбрать последовательность точек оценки таким образом, чтобы сделать код циклическим. В частности, если является примитивным корнем поля , то по определению все ненулевые элементы принимают вид для , где . Каждый многочлен над порождает кодовое слово . Поскольку функция также является многочленом той же степени, эта функция порождает кодовое слово ; поскольку выполняется , это кодовое слово является циклическим левым сдвигом исходного кодового слова, полученного из . Таким образом, выбор последовательности степеней примитивных корней в качестве точек оценки делает исходное представление кода Рида–Соломона циклическим . Коды Рида–Соломона в представлении БЧХ всегда циклические , поскольку коды БЧХ являются циклическими .
Разработчики не обязаны использовать «естественные» размеры блоков кода Рида–Соломона. Метод, известный как «сокращение», может создать меньший код любого желаемого размера из большего кода. Например, широко используемый код (255,223) может быть преобразован в код (160,128) путем заполнения неиспользуемой части исходного блока 95 двоичными нулями и не передачи их. В декодере та же часть блока загружается локально двоичными нулями.
QR-код версии 3 (29×29) использует чередующиеся блоки. Сообщение содержит 26 байтов данных и закодировано с использованием двух блоков кода Рида-Соломона. Каждый блок представляет собой код Рида-Соломона (255,233), сокращенный до кода (35,13).
Теорема Дельсарта–Геталса–Зейделя [12] иллюстрирует пример применения укороченных кодов Рида–Соломона. Параллельно с укорочением, метод, известный как прокалывание, позволяет опустить некоторые закодированные символы четности.
Декодеры, описанные в этом разделе, используют представление BCH кодового слова как последовательности коэффициентов. Они используют фиксированный генераторный полином, известный как кодеру, так и декодеру.
Дэниел Горенштейн и Нил Цирлер разработали декодер, который был описан Цирлером в отчете лаборатории Линкольна Массачусетского технологического института в январе 1960 года, а затем в статье в июне 1961 года. [13] Декодер Горенштейна–Цирлера и связанная с ним работа по кодам BCH описаны в книге « Коды с исправлением ошибок» У. Уэсли Петерсона (1961). [14]
Передаваемое сообщение рассматривается как коэффициенты полинома s ( x ):
В результате процедуры кодирования Рида-Соломона s ( x ) делится на порождающий полином g ( x ): где α — примитивный элемент.
Поскольку s ( x ) является кратным генератору g ( x ), то отсюда следует, что он «наследует» все его корни. Следовательно,
Переданный полином искажается при передаче полиномом ошибки e ( x ) для получения полученного полинома r ( x ).
Коэффициент e i будет равен нулю, если нет ошибки в этой степени x и ненулевой, если есть ошибка. Если есть ν ошибок в различных степенях i k от x , то
Цель декодера — найти количество ошибок ( ν ), позиции ошибок ( ik ) и значения ошибок в этих позициях ( eik ) . Из них можно вычислить e ( x ) и вычесть из r ( x ), чтобы получить изначально отправленное сообщение s ( x ).
Декодер начинает с оценки полинома, полученного в точках . Мы называем результаты этой оценки «синдромами», S j . Они определяются как: Обратите внимание, что поскольку имеет корни в , как показано в предыдущем разделе.
Преимущество рассмотрения синдромов в том, что полином сообщения выпадает. Другими словами, синдромы относятся только к ошибке и не зависят от фактического содержания передаваемого сообщения. Если все синдромы равны нулю, алгоритм останавливается здесь и сообщает, что сообщение не было повреждено при передаче.
Для удобства определим локаторы ошибок X k и значения ошибок Y k как:
Тогда синдромы можно записать в терминах этих локаторов ошибок и значений ошибок как
Это определение значений синдрома эквивалентно предыдущему, поскольку .
Синдромы дают систему из n − k ≥ 2 ν уравнений с 2 ν неизвестными, но эта система уравнений нелинейна относительно X k и не имеет очевидного решения. Однако, если бы X k были известны (см. ниже), то уравнения синдрома дают линейную систему уравнений, которая может быть легко решена относительно значений ошибок Y k .
Следовательно, проблема заключается в нахождении X k , поскольку тогда была бы известна самая левая матрица, и обе стороны уравнения можно было бы умножить на ее обратную, получив Y k
В варианте этого алгоритма, где местоположения ошибок уже известны (когда он используется как код стирания ), это конец. Места ошибок ( X k ) уже известны каким-то другим способом (например, в передаче FM участки, где битовый поток был нечетким или преодолен помехами, вероятностно определяются из частотного анализа). В этом сценарии можно исправить до ошибок.
Остальная часть алгоритма служит для обнаружения ошибок и потребует значения синдрома до , а не только используемые до сих пор. Вот почему необходимо добавить в два раза больше символов исправления ошибок, чем можно исправить, не зная их местоположения.
Существует линейное рекуррентное соотношение, которое порождает систему линейных уравнений. Решение этих уравнений определяет эти местоположения ошибок X k .
Определим полином локатора ошибок Λ( x ) как
Нули Λ( x ) являются обратными величинами . Это следует из приведенной выше конструкции записи произведения, поскольку если то один из умноженных членов будет равен нулю , что делает весь многочлен равным нулю.
Пусть будет любым целым числом, таким что . Умножьте обе части на , и они все равно будут равны нулю.
Суммируем для k = 1 до ν , и результат все равно будет равен нулю.
Соберите каждый член в отдельную сумму.
Извлеките постоянные значения, на которые не влияет суммирование.
Эти суммирования теперь эквивалентны значениям синдрома, которые мы знаем и можем подставить! Таким образом, это сводится к
Вычитание из обеих сторон дает
Напомним, что j было выбрано как любое целое число от 1 до v включительно, и эта эквивалентность верна для любых и всех таких значений. Следовательно, у нас есть v линейных уравнений, а не только одно. Эта система линейных уравнений может быть решена для коэффициентов Λ i полинома местоположения ошибки: Вышеизложенное предполагает, что декодер знает количество ошибок ν , но это количество еще не определено. Декодер PGZ не определяет ν напрямую, а ищет его, пробуя последовательные значения. Декодер сначала предполагает наибольшее значение для пробного ν и устанавливает линейную систему для этого значения. Если уравнения могут быть решены (т. е. определитель матрицы не равен нулю), то это пробное значение является количеством ошибок. Если линейная система не может быть решена, то пробное ν уменьшается на единицу, и рассматривается следующая меньшая система. (Gill nd, стр. 35)
Используйте коэффициенты Λ i, найденные на последнем шаге, для построения полинома местоположения ошибки. Корни полинома местоположения ошибки можно найти с помощью исчерпывающего поиска. Локаторы ошибок X k являются обратными величинами этих корней. Порядок коэффициентов полинома местоположения ошибки можно изменить на обратный, в этом случае корни этого обращенного полинома являются локаторами ошибок (а не их обратными величинами ). Поиск Чиена является эффективной реализацией этого шага.
Как только локаторы ошибок X k известны, можно определить значения ошибок. Это можно сделать прямым решением для Y k в матрице уравнений ошибок, приведенной выше, или с помощью алгоритма Форни .
Рассчитайте i k , взяв логарифмическое основание X k . Обычно это делается с помощью предварительно вычисленной таблицы поиска.
Наконец, e ( x ) генерируется из i k и e i k , а затем вычитается из r ( x ), чтобы получить первоначально отправленное сообщение s ( x ) с исправленными ошибками.
Рассмотрим код Рида–Соломона, определенный в GF (929) с α = 3 и t = 4 (он используется в штрихкодах PDF417 ) для кода RS(7,3). Генераторный полином равен Если полином сообщения равен p ( x ) = 3 x 2 + 2 x + 1 , то систематическое кодовое слово кодируется следующим образом. Ошибки при передаче могут привести к тому, что вместо этого будет получено это. Синдромы вычисляются путем оценки r в степенях α .
Используя метод исключения Гаусса :
Коэффициенты можно поменять местами, чтобы получить корни с положительными показателями, но обычно это не используется:
с логарифмом корней, соответствующих местоположениям ошибок (справа налево, местоположение 0 — последний член кодового слова).
Для расчета значений ошибок применим алгоритм Форни .
Вычитание из полученного полинома r ( x ) воспроизводит исходное кодовое слово s .
Алгоритм Берлекэмпа–Месси представляет собой альтернативную итеративную процедуру поиска полинома локатора ошибок. Во время каждой итерации он вычисляет расхождение на основе текущего экземпляра Λ( x ) с предполагаемым числом ошибок e : и затем корректирует Λ( x ) и e так, чтобы пересчитанное Δ было равно нулю. Статья Алгоритм Берлекэмпа–Месси содержит подробное описание процедуры. В следующем примере C ( x ) используется для представления Λ( x ).
Используя те же данные, что и в примере Петерсона-Горенштейна-Цирлера выше:
Конечное значение C — это полином локатора ошибок Λ( x ).
Другой итерационный метод вычисления как полинома локатора ошибок, так и полинома значения ошибки основан на адаптации Сугиямы расширенного алгоритма Евклида .
Определим S ( x ), Λ( x ) и Ω( x ) для t -синдромов и e- ошибок:
Ключевое уравнение:
Для t = 6 и e = 3:
Средние члены равны нулю из-за связи между Λ и синдромами.
Расширенный алгоритм Евклида может найти ряд полиномов вида
где степень R уменьшается с ростом i . Как только степень R i ( x ) < t /2, тогда
B ( x ) и Q ( x ) не нужно сохранять, поэтому алгоритм становится таким:
R −1 := x t R 0 := S ( x ) A −1 := 0 A 0 := 1 i := 0 пока степень R i ≥ t /2 i := i + 1 Q := R i -2 / R i -1 R i := R i -2 - Q R i -1 A i := A i -2 - Q A i -1
чтобы установить член младшего порядка Λ( x ) равным 1, разделите Λ( x ) и Ω( x ) на A i (0):
A i (0) — постоянный (низшего порядка) член A i .
Используя те же данные, что и в примере Петерсона–Горенштейна–Цирлера выше:
Для декодирования можно использовать дискретное преобразование Фурье. [15] Чтобы избежать конфликта с названиями синдромов, пусть c ( x ) = s ( x ) закодированное кодовое слово. r ( x ) и e ( x ) такие же, как указано выше. Определим C ( x ), E ( x ) и R ( x ) как дискретные преобразования Фурье c ( x ), e ( x ) и r ( x ). Поскольку r ( x ) = c ( x ) + e ( x ), и поскольку дискретное преобразование Фурье является линейным оператором, R ( x ) = C ( x ) + E ( x ).
Преобразуем r ( x ) в R ( x ) с помощью дискретного преобразования Фурье. Поскольку расчет для дискретного преобразования Фурье такой же, как расчет для синдромов, коэффициенты t R ( x ) и E ( x ) такие же, как и у синдромов:
Используйте сквозные синдромы (они одинаковы) и сгенерируйте полином локатора ошибок, используя методы любого из вышеперечисленных декодеров.
Пусть v = количество ошибок. Сгенерируйте E ( x ) с использованием известных коэффициентов , полинома локатора ошибок и этих формул
Затем вычисляем C ( x ) = R ( x ) − E ( x ) и выполняем обратное преобразование (полиномиальную интерполяцию) C ( x ), чтобы получить c ( x ).
Граница Синглтона утверждает, что минимальное расстояние d линейного блочного кода размера ( n , k ) ограничено сверху n − k + 1 . Расстояние d обычно понималось как ограничение возможности исправления ошибок до ⌊( d −1) / 2⌋ . Код Рида-Соломона достигает этой границы с равенством и, таким образом, может исправить до ⌊( n − k ) / 2⌋ ошибок. Однако эта граница исправления ошибок не является точной.
В 1999 году Мадху Судан и Венкатесан Гурусвами из Массачусетского технологического института опубликовали статью «Улучшенное декодирование кодов Рида–Соломона и алгебро-геометрических кодов», в которой был представлен алгоритм, позволяющий исправлять ошибки, превышающие половину минимального расстояния кода. [16] Он применим к кодам Рида–Соломона и, в более общем смысле, к алгебро-геометрическим кодам . Этот алгоритм создает список кодовых слов (это алгоритм декодирования списков ) и основан на интерполяции и факторизации полиномов над и его расширениях.
В 2023 году, основываясь на трех захватывающих работах, [17] [18] [19] теоретики кодирования показали, что коды Рида-Соломона, определенные по случайным точкам оценки, могут фактически достигать емкости декодирования списков (до n − k ошибок) над алфавитами линейного размера с высокой вероятностью. Однако этот результат является комбинаторным, а не алгоритмическим.
Алгебраические методы декодирования, описанные выше, являются методами жесткого решения, что означает, что для каждого символа принимается жесткое решение о его значении. Например, декодер может связать с каждым символом дополнительное значение, соответствующее уверенности демодулятора канала в правильности символа. Появление LDPC и турбокодов , которые используют методы декодирования с итерационным мягким решением распространения убеждения для достижения производительности исправления ошибок, близкой к теоретическому пределу , стимулировало интерес к применению декодирования с мягким решением к обычным алгебраическим кодам. В 2003 году Ральф Кеттер и Александр Варди представили полиномиальный алгоритм мягкого решения алгебраического списка-декодирования для кодов Рида-Соломона, который был основан на работе Судана и Гурусвами. [20] В 2016 году Стивен Дж. Франке и Джозеф Х. Тейлор опубликовали новый декодер с мягким решением. [21]
Здесь мы представляем простую реализацию кодера на языке MATLAB .
закодированная функция = rsEncoder ( msg, m, prim_poly, n, k ) % RSENCODER Кодировать сообщение с помощью алгоритма Рида-Соломона % m — количество бит на символ % prim_poly: Примитивный многочлен p(x). То есть для DM это 301 % k — размер сообщения % n — общий размер (k+избыточный) % Пример: msg = uint8('Test') % enc_msg = rsEncoder(msg, 8, 301, 12, numel(msg)); % Получить альфу альфа = gf ( 2 , m , prim_poly ); % Получить порождающий полином Рида-Соломона g(x) g_x = genpoly ( k , n , альфа ); % Умножьте информацию на X^(nk) или просто допишите нули в конце, чтобы % освободить место для добавления избыточной информации msg_padded = gf ([ нули сообщения ( 1 , n - k )], m , prim_poly ); % Получить остаток от деления расширенного сообщения на % Генерирующий полином Рида-Соломона g(x) [ ~ , остаток ] = deconv ( msg_padded , g_x ); % Теперь верните сообщение с избыточной информацией закодировано = msg_padded - остаток ; конец% Найдите порождающий полином Рида-Соломона g(x), кстати, это% то же самое, что и функция rsgenpoly в matlabфункция g = genpoly ( k, n, alpha ) г = 1 ; % Умножение на поле Галуа — это просто свертка для k = mod ( 1 : n - k , n ) g = conv ( g , [ 1 альфа .^ ( k )]); конецконец
Теперь расшифровка:
функция [декодировано, error_pos, error_mag, g, S] = rsDecoder ( закодировано, m, prim_poly, n, k ) % RSDECODER Декодирует сообщение, закодированное в кодировке Рида-Соломона. % Пример: % [dec, ~, ~, ~, ~] = rsDecoder(enc_msg, 8, 301, 12, numel(msg)) max_errors = floor (( n - k ) / 2 ); orig_vals = закодировано . x ; % Инициализируем вектор ошибки ошибки = нули ( 1 , n ); г = []; С = []; % Получить альфу альфа = gf ( 2 , m , prim_poly ); % Найти синдромы (Проверить, делится ли сообщение генератором % полином результат равен нулю) Synd = поливалентный ( закодированный , альфа .^ ( 1 : n - k )); Синдромы = обрезка ( Synd ); % Если все синдромы равны нулю (совершенно делятся), то ошибок нет. если пусто ( Синдромы . x ) декодировано = orig_vals ( 1 : k ); ошибка_поз = []; error_mag = []; г = []; С = Синд ; возвращаться ; конец % Подготовка к евклидову алгоритму (используется для поиска ошибки, локализующей % полиномы) r0 = [ 1 , нули ( 1 , 2 * max_errors )]; r0 = gf ( r0 , m , prim_poly ); r0 = trim ( r0 ); размер_r0 = длина ( r0 ); r1 = Синдромы ; f0 = gf ([ нули ( 1 , size_r0 - 1 ) 1 ], m , prim_poly ); f1 = gf ( нули ( 1 , size_r0 ), m , prim_poly ); г0 = ф1 ; г1 = ф0 ; % Выполнить евклидов алгоритм на полиномах r0(x) и синдромах(x) в % порядок нахождения полинома локализации ошибок в то время как правда % Выполнить деление в столбик [ частное , остаток ] = deconv ( r0 , r1 ); % Добавьте несколько нулей частное = прокладка ( частное , длина ( g1 )); % Найти частное*g1 и дополнить c = conv ( частное , g1 ); с = обрезка ( с ); c = площадка ( c , длина ( g0 )); % Обновить g как g0-частное*g1 г = г0 - с ; % Проверить, меньше ли степень остатка (x), чем max_errors если все ( остаток ( 1 : конец - max_errors ) == 0 ) перерыв ; конец % Обновить r0, r1, g0, g1 и удалить начальные нули r0 = обрезка ( r1 ); r1 = обрезка ( остаток ); г0 = г1 ; г1 = г ; конец % Удалить начальные нули г = обрезка ( г ); % Найдите нули полинома ошибки на этом поле Галуа evalPoly = поливалентный ( g , альфа .^ ( n - 1 : - 1 : 0 )); error_pos = gf ( find ( evalPoly == 0 ), m ); % Если позиция ошибки не найдена, мы возвращаем полученную работу, потому что % по сути ничего не можем сделать и возвращаем полученное сообщение если пусто ( error_pos ) декодировано = orig_vals ( 1 : k ); error_mag = []; возвращаться ; конец % Подготовьте линейную систему для решения полинома ошибки и найдите ошибку % величины size_error = длина ( error_pos ); Syndrome_Vals = Синдромы . x ; b (:, 1 ) = Значения_синдрома ( 1 : ошибка_размера ); для idx = 1 : size_error e = альфа .^ ( idx * ( n - error_pos . x )); ошибка = е . х ; er ( idx , :) = err ; конец % Решить линейную систему error_mag = ( gf ( er , m , prim_poly ) \ gf ( b , m , prim_poly )) ' ; % Поместить величину ошибки в вектор ошибки ошибки ( полож_ошибки . x ) = величина_ошибки . x ; % Привести этот вектор к полю Галуа ошибки_гф = гф ( ошибки , м , первичный_поли ); % Теперь, чтобы исправить ошибки, просто добавьте закодированный код декодированный_gf = закодированный ( 1 : k ) + ошибки_gf ( 1 : k ); декодировано = декодировано_gf . x ; конец% Удалить начальные нули из массива Галуафункция gt = обрезка ( g ) гх = г . х ; gt = gf ( gx ( find ( gx , 1 ) : end ) , g.m , g.prim_poly ) ; конец% Добавить начальные нулифункция xpad = pad ( x, k ) len = длина ( x ); если len < k xpad = [ нули ( 1 , k - len ) x ]; конецконец
Декодеры, описанные в этом разделе, используют исходный вид Рида-Соломона кодового слова как последовательность полиномиальных значений, где полином основан на сообщении, которое должно быть закодировано. Один и тот же набор фиксированных значений используется кодером и декодером, и декодер восстанавливает кодирующий полином (и, опционально, полином обнаружения ошибок) из полученного сообщения.
Рид и Соломон (1960) описали теоретический декодер, который исправлял ошибки, находя наиболее популярный многочлен сообщения. Декодер знает только набор значений и какой метод кодирования использовался для генерации последовательности значений кодового слова. Исходное сообщение, многочлен и любые ошибки неизвестны. Процедура декодирования может использовать метод, подобный интерполяции Лагранжа на различных подмножествах из n значений кодового слова, взятых по k за раз, для многократного создания потенциальных многочленов, пока не будет создано достаточное количество соответствующих многочленов для разумного устранения любых ошибок в полученном кодовом слове. После определения многочлена любые ошибки в кодовом слове могут быть исправлены путем пересчета соответствующих значений кодового слова. К сожалению, во всех случаях, кроме самых простых, существует слишком много подмножеств, поэтому алгоритм непрактичен. Количество подмножеств равно биномиальному коэффициенту , , а количество подмножеств неосуществимо даже для скромных кодов. Для кода, который может исправить 3 ошибки, наивный теоретический декодер должен будет проверить 359 миллиардов подмножеств.
В 1986 году был разработан декодер, известный как алгоритм Берлекэмпа–Уэлча , который способен восстановить исходный полином сообщения, а также полином «локатора» ошибок, который выдает нули для входных значений, соответствующих ошибкам, со сложностью по времени , где — количество значений в сообщении. Затем восстановленный полином используется для восстановления (пересчета по мере необходимости) исходного сообщения.
Используя RS(7,3), GF(929) и набор точек оценки a i = i − 1
Если полином сообщения равен
Кодовое слово -
Ошибки при передаче могут привести к получению этого сообщения.
Ключевые уравнения:
Предположим максимальное количество ошибок: e = 2. Ключевые уравнения принимают вид:
Используя метод исключения Гаусса :
Пересчитайте P(x), где E(x) = 0: {2, 3}, чтобы исправить b, получив в результате исправленное кодовое слово:
В 2002 году Шухонг Гао разработал улучшенный декодер на основе расширенного алгоритма Евклида. [6]
Используя те же данные, что и в примере Берлекэмпа Уэлча выше:
Разделите Q ( x ) и E ( x ) на наиболее значимый коэффициент E ( x ) = 708. (Необязательно)
Пересчитайте P ( x ) , где E ( x ) = 0 : {2, 3}, чтобы исправить b, получив в результате исправленное кодовое слово: