1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/sg-first-LDPC-code

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

LDPC Кит

Содержание

Этот репозиторий является частью проекта контроллера NAND Flash на основе LDPC.

  • В этом репозитории представлена библиотека для работы с полями Галуа и матрицами, а также библиотека для кодирования/проверки LDPC-матрицы.
  • Реализация интерфейса контроллера NAND Flash на основе LDPC находится в этом репозитории.
  • Полная документация проекта опубликована в OALib Preprint: Liu, T., Yu, H., Zhang, G., Li, Y., Zhou, M., Zhang, Z., Xin, X., Liu, S. и Ren, J. (2021). Проектирование контроллера NAND Flash на основе NB-LDPC ECC. Open Access Library PrePrints, 5, e293. doi: http://dx.doi.org/10.4236/oalib.preprints.1200293.

Обзор

За последние годы низкоденные коды проверочной суммы (Low-Density Parity-Check Codes, LDPC) получили широкое признание благодаря относительно низкой сложности кодирования/декодирования и отличной способности к исправлению ошибок. При одинаковой длине кода и скорости кодирования, производительность LDPC-кодов над полем Галуа превосходит производительность двоичных LDPC-кодов. Этот набор предназначен для решения задач аппаратного кодирования/декодирования LDPC и выполняет следующие действия:* Библиотека для вычислений над полями Галуа и операций с матрицами над этими полями, которая позволяет выполнять вычисления в полях различных порядков и с различными примитивными многочленами, а также генерировать таблицы умножения.

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

Принцип

Чтобы создать кодирующую матрицу, используются несколько малых матриц размером n x n, где диагональные элементы случайны. Эти малые матрицы располагаются в большую матрицу H таким образом, что каждая строка содержит r таких матриц, а каждый столбец — c. Схематическое представление показано ниже:

Наша кодирующая матрица основана на циклическом правом сдвиге большой матрицы H. Для этого требуется выполнение следующих шагов:

  • Случайным образом выбирается i малых матриц.
  • Для каждой выбранной малой матрицы происходит случайный циклический правый сдвиг на j позиций (циклический сдвиг — это перемещение каждого ненулевого элемента вправо до соседней позиции; если элемент уже находится справа, он перемещается обратно в начало).
  • Проверка количества четырёхциклов в матрице H. Если количество четырёхциклов минимально, эта матрица временно сохраняется. Цикл продолжается до достижения условия прекращения, которое может зависеть от конкретной ситуации. В наших экспериментах, когда число столбцов матрицы H равно 256, можно быстро найти матрицу с количеством четырёхциклов равным нулю. Поэтому условием прекращения является достижение нуля количества четырёхциклов.### Соответствующий код Заголовочный файл genH.h содержит класс-генератор HGenerator, который используется для создания кодирующей матрицы. Перед использованием необходимо установить параметры пространства имён genH для указания размера требуемой кодирующей матрицы.

Параметры включают:

  • Размер диагональных матриц diagSize
  • Количество малых матриц в каждом столбце матрицы HcNum
  • Количество малых матриц в каждой строке матрицы HrNumЗатем создается объект-генератор, который позволяет начать генерацию кодирующей матрицы. В созданном объекте диагональные элементы малых матриц равны единице. Такое начальное условие используется потому что некоторые считают, что сначала следует уменьшить количество четырёхциклических матриц в GF(2), а затем случайным образом заменять диагональные элементы на фактические элементы GF(n). Это основано на том, что возможно существуют некоторые замены от GF(n) до которых невозможно достичь минимального количества четырёхциклических матриц. Поэтому можно оптимизировать несколько различных случайных замен на основе оптимизированной GF(2) и выбрать лучший вариант. Однако в наших экспериментах при количестве столбцов матрицы H равном 256, все попытки замены быстро привели к матрице с нулевым количеством четырёхциклических матриц. Таким образом, прямая замена на GF(n) также возможна и это значительно увеличивает скорость оптимизации.Пример кода для создания кодирующей матрицы с использованием генератора:
HGenerator hg;
hg.permutationGF(); // замена на элементы GF(n)
uint usefulNum;
for(int i = 0; true; i++)
{
    if(hg.moveDetection())
        usefulNum = i;
    if(hg.tetracyclicNum == 0)
        break; // выход из цикла при достижении нулевого количества четырехциклических матриц
}
std::cout << "usefulNum" << usefulNum << std::endl;
matIO::saveMatFile("D:/result.csv", hg.getH()); // сохранение матрицы

Процесс кодирования

На основе полученной нижней треугольной кодирующей матрицы H, мы можем закодировать сообщение. Сначала необходимо разделить H следующим образом:

Затем используйте следующее уравнение для вычисления проверочных битов p1 и p2 (информационные биты — s):

Раскрыв уравнение, можно заметить, что некоторые промежуточные шаги могут быть кэшированы для ускорения выполнения. В реальном процессе кодирования требуются матрицы Φi + E · Ti + C, Ti · A, Ti · B (где i представляет обратную матрицу; в конечном поле сложение противоположных значений остается тем же значением, поэтому все минусы убраны). Поэтому эти матрицы вычисляются заранее. Соответствующий код представлен ниже:

// Вычисляем матрицы заранее
Matrix Phi_i_plus_E_Ti_C = calculatePhiETiC(i);
Matrix Ti_A = calculateTiA(i);
Matrix Ti_B = calculateTiB(i);

// Кодируем сообщение
vector<int> encodedMessage = encode(s, Phi_i_plus_E_Ti_C, Ti_A, Ti_B);

Процесс декодирования

Для декодирования сообщения используется обратная процедура. Декодирование начинается с вычисления информационных битов s из закодированного сообщения и проверочных битов p1 и p2.```cpp matrix H = matIO::ReadMatFile("D:/H(339x3070).csv", 339, 3070); // чтение кодирующей матрицы из файла cLength = H.getc(); sLength = cLength - H.getr(); uint g = H.getr() - 113; // параметр g для разделения должен быть указан вручную, здесь он равен 113 uint mg = H.getr() - g; uint nm = H.getc() - H.getr(); matrix T = H.cut(nm + g, 0, H.getc() - 1, mg - 1); matrix Ti = T.inv(); matrix E = H.cut(nm + g, mg, H.getc() - 1, H.getr() - 1); matrix B = H.cut(nm, 0, nm + g - 1, mg - 1); matrix D = H.cut(nm, mg, nm + g - 1, H.getr() - 1); matrix fi = E.dot(Ti); fi = fi.dot(B); fi = fi.add(D); matrix fii = fi.inv(); fii.dot(fi).output();

matrix C = H.cut(0, mg, nm - 1, H.getr() - 1);

// Вычисление требуемых значений
matrix fii_ETiA_C = E.dot(Ti).dot(A).add(C);
fii_ETiA_C = fii.dot(fii_ETiA_C); // Здесь ранее был оператор взятия обратной компоненты поэлементно, но так как это не влияло на результат, его убрали

matrix TiA = Ti.dot(A); // Здесь ранее был оператор взятия обратной компоненты поэлементно, но так как это не влияло на результат, его убрали
matrix TiB = Ti.dot(B); // Здесь ранее был оператор взятия обратной компоненты поэлементно, но так как это не влияло на результат, его убрали

`fii_ETiA_C`, `TiA`, `TiB` являются искомыми значениями.

Затем можно приступить к кодированию, соответствующий код представлен ниже:

```cpp
matrix sT = s.transpose(); // s — сообщение
matrix p1T = fii_ETiA_C.dot(sT);
matrix ii = TiA.dot(sT);
matrix ii2 = TiB.dot(p1T);
matrix p2T = ii.add(ii2);

p1T, p2T являются искомыми значениями.

Имея информационные биты и проверочные биты, можно получить закодированное слово:

matrix c(1, cLength);
for (uint i = 0; i < sLength; i++) // Копирование информационных битов по одному
    c.m[0][i] = s.m[0][i];
for (uint i = sLength; i < sLength + p1.getc(); i++) // Проверочный бит 1
    c.m[0][i] = p1.m[0][i - sLength];
const uint offset2 = sLength + p1.getc();
for (uint i = offset2; i < cLength; i++) // Проверочный бит 2
    c.m[0][i] = p2.m[0][i - offset2];

c является закодированным словом.Согласно литературе по LDPC-кодированию, только когда вектор ( H \cdot c^T ) (где ( T ) представляет транспонированный матричный) равен нулевому вектору, возможно правильное декодирование. Это зависит от корректности матрицы кодирования ( H ). После того, как мы сгенерируем ( H ), обычно случайным образом генерируются некоторые сообщения для кодирования, после чего вычисляется ( H \cdot c^T ) для проверки корректности данной матрицы кодирования. При наличии закодированного слова проверка может быть выполнена с помощью функции библиотеки errorCorrection::check(c, H).


Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

Описание недоступно Развернуть Свернуть
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/sg-first-LDPC-code.git
git@api.gitlife.ru:oschina-mirror/sg-first-LDPC-code.git
oschina-mirror
sg-first-LDPC-code
sg-first-LDPC-code
master