Алгоритм определения ошибки

Основная
литература:

  1. Скляр
    Б. Цифровая связь. 
    М., Санкт-П, Киев: Изд. дом «Вильямс»,
    2003.

  2. Передача
    дискретных сообщений: Учебник для ВУЗов
    / В. П. Шувалов, Н. В. Захарченко, В. О.
    Шварцман и др.; Под ред. В. П. Шувалова.
    – М.: Радио и связь, 1990 — 464 с.

Дополнительная
литература:

  1. Макаров
    А.А., Прибылов В.П. Помехоустойчивое
    кодирование: Монография/СибГУТИ —
    Новосибирск, 2005

  2. Захарченко
    И.Б. и др. Основы передачи дискретных
    сообщений. -М.: Радио и связь, 1990.

  3. Мирманов
    А.Б. Курс лекций по дисциплине «Технология
    цифровой связи» — Астана: КазАТУ, 2009.
    (электронный)

Ключевые
слова:

Циклический код, синдром ошибки, полином,
базис.

Рассматриваемые
вопросы:

    1. Понятие
      циклического кода.

    2. Действия
      над многочленами при формировании
      комбинаций.

    3. Алгоритм
      получения разрешенной кодовой комбинации
      циклического кода из комбинации
      простого кода.

    4. Формирование
      базиса (производящей матрицы) циклического
      кода.

    5. Построение
      кодера циклического кода.

    6. Построение
      формирователя остатка циклического
      кода.

    7. Структурная
      схема кодера циклического кода.

    8. Определение
      ошибочного разряда в ЦК.

    9. Алгоритм
      определения ошибки.

    10. Выбор
      образующего полинома.

Тезисы к лекции

Циклический
код

Широкое
распространение на практике получил
класс линейных кодов, которые называются
циклическими.
Данное название происходит от основного
свойства

этих кодов: если некоторая кодовая
комбинация принадлежит циклическому
коду, то комбинация, полученная циклической
перестановкой исходной комбинации
(циклическим сдвигом), также принадлежит
данному коду.

.

Вторым
свойством всех разрешенных комбинаций
циклических кодов является их делимость
без остатка на некоторый выбранный
полином, называемый производящим.

Синдромом
ошибки
в
этих кодах является наличие остатка от
деления принятой кодовой комбинации
на производящий полином.

В
теории циклических кодов кодовые
комбинации обычно представляются в
виде полинома. Так, n-элементную кодовую
комбинацию можно описать полиномом
(n-1) степени, в виде


(7.1)

где
ai={0,1},
причем ai=0
соответствуют нулевым элементам
комбинации, а ai=1
— ненулевым.

Действия
над многочленами

При
формировании комбинаций циклического
кода часто используют операции сложения
многочленов и деления одного многочлена
на другой.

,

Поскольку
.

Следует
отметить, что действия над коэффициентами
полинома (сложение и умножение)
производятся по модулю 2.

Деление
выполняется, как обычно, только вычитание
заменяется суммированием по модулю
два.

Отметим,
что запись кодовой комбинации в виде
многочлена, не всегда определяет длину
кодовой комбинации.

Алгоритм
получения разрешенной кодовой комбинации
циклического кода из комбинации простого
кода

Пусть
задан полином
,
определяющий корректирующую способность
кода и число проверочных разрядовr,
а также исходная комбинация простого
k-элементного кода в виде многочлена
.

Требуется
определить разрешенную кодовую комбинацию
циклического кода (n, k).

  1. Умножаем
    многочлен исходной кодовой комбинации
    на

  1. Определяем
    проверочные разряды, дополняющие
    исходную информационную комбинацию
    до разрешенной, как остаток от деления,
    полученного в предыдущем пункте
    произведения на образующий полином

  1. Окончательно
    разрешенная кодовая комбинация
    циклического кода определится так

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

свидетельствует о том, что принятая
комбинация содержит ошибки. По виду
остатка (синдрома) можно в некоторых
случаях также сделать вывод о характере
ошибки, ее местоположении и исправить
ошибку.

Формирование
базиса (производящей матрицы) циклического
кода

Формирование
базиса циклического кода возможно как
минимум двумя путями.

Вариант
первый.

  1. Составить
    единичную матрицу для простого исходного
    кода.

  2. Определить
    для каждой кодовой комбинации исходного
    кода группу проверочных элементов и
    дописать их в соответствующие строки
    матрицы.

Полученная
матрица и будет базисом циклического
кода. Причем, в данном случае, разрешенные
комбинации заведомо разделимы (т.е.
информационные и проверочные элементы
однозначно определены).

Вариант
второй.

  1. Дописать
    слева от КК, соответствующей образующему
    полиному циклического кода нули так,
    чтобы длина разрешенной кодовой
    комбинации равнялась n.

  2. Получить
    остальные разрешенные кодовые КК
    базиса, используя циклический сдвиг
    исходной. (В базисе должно быть k –
    строк). В данном случае код будет
    неразделимым.

Получив
базис ЦК,
можно получить все
разрешенные

комбинации, проводя сложение по модулю
2 кодовых комбинаций базиса в различных
сочетаниях и плюс
нулевая
.

Построение
кодера циклического кода

Разрешенная
комбинация циклического кода
образуется из комбинации простого
(исходного) кода путем умножения ее наи
прибавления остаткаR(x)
от деления
на
образующий полином.

  1. Умножение
    полинома на одночлен

    эквивалентно добавлению к двоичной
    последовательности соответствующейG(x)
    , r — нулей справа. Для реализации операции
    добавления нулей используется r-разрядный
    регистр задержки.

  2. Процедура
    деления одного двоичного числа на
    другое сводится к последовательному
    сложению по mod2
    делителя с соответствующими членами
    делимого, затем с двоичным числом,
    полученным в результате первого
    сложения, далее с результатом второго
    сложения и т.д., пока число членов
    результирующего двоичного числа не
    станет меньше числа членов делителя.
    Это двоичное число и будет остатком
    .

Построение
формирователя остатка циклического
кода

Структура
устройства осуществляющего деление на
полином полностью определяется видом
этого полинома. Существуют правила
позволяющие провести построение
однозначно.

Сформулируем
правила
построения ФПГ
.

  1. Число
    ячеек памяти равно степени образующего
    полинома r.

  2. Число
    сумматоров на единицу меньше веса
    кодирующей комбинации образующего
    полинома.

  3. Место
    установки сумматоров определяется
    видом образующего полинома.

Сумматоры
ставят после каждой ячейки памяти,
(начиная с нулевой) для которой существует
ненулевой член полинома. Не ставят после
ячейки для которой в полиноме нет
соответствующего члена и после ячейки
старшего разряда.

4.
В цепь обратной связи необходимо
поставить ключ, обеспечивающий правильный
ввод исходных элементов и вывод
результатов деления.

Структурная
схема кодера циклического кода

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

Работа
схемы
для
кодера (n,
k)

1.
На первом этапе К1
замкнут К2
– разомкнут.
Идет одновременное заполнение регистров
задержки и сдвига информационными
элементами (старший вперед!) и через k-1
тактов
старший разряд в последней
ячейке
(под номером k-1)

2.
Во время k-го
такта К2
замыкается, а К1
– размыкается с этого момента в ФПГ
формируется остаток. Одновременно из
РЗ на выход выталкивается задержание
информационные разряды.

За
k
тактов (с k
по n
включительно) в линию уйдут все k
-информационных элемента. К этому времени
в ФПГ сформируется остаток

3.
К2
– размыкается, К1
– замыкается, и в след за информационными
в линию уйдут элементы проверочной
группы.

4.
Одновременно идет заполнение регистров
новой комбинацией.

Определение
ошибочного разряда в ЦК

Пусть
А(х)
— многочлен соответствующий переданной
кодовой комбинации. Н(х)
— многочлен соответствующей принятой
кодовой комбинацией.

Тогда
сложение данных многочленов по модулю
два даст многочлен ошибки.

E(x)=A(x)H(x)

При
однократной ошибке Е(х)
будет содержать только один единственный
член соответствующий ошибочному разряду.

Остаток
– полученный от деления принятого
многочлена H(x)
на производящей Pr(x)
равен остатку, полученному при делении
соответствующего многочлена ошибок
E(x)
на Pr(x)

При
этом ошибке в каждом разряде будет
соответствовать свой остаток R(x)
(он же синдром), а значит, получив синдром
можно однозначно определить место
ошибочного разряда.

Алгоритм
определения ошибки

Пусть
имеем n-элементные комбинации (n = k + r)
тогда:

1.
Получаем остаток от деления Е(х)
соответствующего ошибке в старшем
разряде, на образующей поленом Pr(x)

2.
Делим полученный полином Н(х)
на Pr(x)
и получаем текущий остаток R(x).

3.
Сравниваем R0(x)
и R(x).


если они равны, то ошибка произошла в
старшем разряде.


если «нет», то увеличиваем степень
принятого полинома на Х и снова проводим
деления

4.
Опять сравниваем полученный остаток с
R0(x)


если они равны, то ошибки во втором
разряде.


если нет, то умножаем Н(х)х2
и повторяем эти операции до тех пор,
пока R(X) не будет равен R0(x).

Ошибка
будет в разряде соответствующем числу
на которое повышена степень Н(х) плюс
один.

Выбор
образующего полинома

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

mi(x),
являющихся простыми сомножителями (то
есть делящимся без остатка лишь на себя
и на 1) бинома xn+
1:

P(x)=m1(x)*
m
3(x)…mj(x),
(7.2)

где
j = d0
2
=
( 2tu.ош+1)
– 2 = 2
tи.ош
– 1
.

Существуют
специальные таблицы минимальных
многочленов, одна из которых приведена
ниже. Кроме образующего полинома
необходимо найти и количество проверочных
разрядов r.
Оно определяется из следующего свойства
циклических кодов
:
для любых значений l
и tи.ош
существует циклический код длины n
=
2l
– 1
, исправляющий
все ошибки кратности tи.ош
и менее, и содержащий не более
проверочных элементов.

Так
как
,
то
откуда
.

Очевидно,
что для уменьшения времени передачи
кодовых комбинаций, r
следует выбирать как можно меньше.

После
определения количества проверочных
разрядов r,
вычисления образующего полинома удобно
осуществить, пользуясь таблицей
минимальных многочленов, представленной
в следующем виде:

Таблица
7.1 — Выбор образующего полинома

J=2tи.ош
-1

Вид
минимальных многочленов для

1

x2+x+1

x3+x+1

x4+x+1

x5+x+1

x6+x+1

x7+x+1

3

x4+x3+x2+x+1

x5+x4+x3+x2+1

x6+x4+x2+x+1

x7+x3+x2+x+1

5

x5+x4+x2+x+1

x6+x5+x2+x+1

x7+x4+x3+x2+1

7

x6+x3+1

х7+x6+x5+x4+x2+x+1

Определяя
образующий полином, нужно из столбца
для соответствующего соотношения
выписать все многочлены, начиная с
верхней строки до нижней с номером
j=2tи.ош–1
включительно. После этого следует
перемножить выбранные минимальные
многочлены в соответствии с (7.2).

Контрольные
вопросы по теме:

  1. Назовите
    основные свойства циклических кодов.

  2. Запишите
    полином в двоичном виде x6+x5+x2+x+1.

  3. Запишите
    полином, соответствующий двоичной
    записи 100111.

  4. Получите
    остаток от деления полинома
    х7+x6+x5+x4+x2+x+1
    на x2+x+1.

  5. Как
    получают разрешенные комбинации при
    циклическом кодировании.

  6. Нарисуйте
    кодер для циклического кода, порождаемого
    полиномом x5+x+1.
    Поясните принцип работы кодера.

  7. По
    какому признаку обнаруживают ошибку
    в принятой кодовой комбинации.

  8. Каков
    алгоритм определения ошибочного разряда
    в комбинации циклического кода.

  9. Нарисуйте
    структурную схему декодера, обеспечивающего
    обнаружение ошибок для кода (7,4) при
    производящем полиноме x3+x+1.
    Поясните принцип его работы.

  10. Нарисуйте
    структурную схему декодера, обеспечивающего
    исправление однократной ошибки для
    кода (7,4) при производящем полиноме
    x3+x+1.
    Поясните принцип его работы.

  11. Как
    выбирается образующий (производящий)
    полином.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]

  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #

Введение

В данной статье рассказывается о простом алгоритме поиска ошибок в коде MQL. Часто после написания
программы возникают проблемы при компиляции, вызванные ошибками в коде. Это
могут быть самые различные ошибки, но в любом случае возникает необходимость
оперативного обнаружения участка кода, где допущена ошибка.

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

Концепция

Написать достаточно большой код без единой ошибки – весьма приятно. Но, к
сожалению, так выходит не всегда. Есть даже шутка, что ни одна программа не
была написана без единой ошибки. Я не рассматриваю здесь ошибки, которые
приводят к неверному исполнению кода. Здесь пойдёт речь об ошибках, из-за
которых становится невозможной компиляция.

Весьма распространённые ошибки – вставка лишней скобки в сложном условии,
нехватка скобки, не выставление двоеточия, запятой (при объявлении переменных)
и т.д. Часто при компиляции мы можем сразу увидеть, в какой строке допущена
подобная ошибка. Но бывают и случаи, когда найти такую ошибку не так просто. Ни
компилятор, ни зоркий глаз нам не могут помочь сходу найти ошибку. В
таких случаях, как правило, начинающие (и не очень) программисты начинают
«обходить» весь код, пытаясь визуально определить ошибку. И снова, и
снова, пока нервы не иссякнут, и не будет сказано «проще заново написать!».

Однако MQL, как и
другие языки программирования, предлагает потрясающий инструмент –
комментирование. Используя его можно «убирать», «отключать»
какие-то участки кода. Обычно комментирование используют именно для вставки
каких-то комментариев, или же отключения неиспользуемых участков кода. Комментирование
можно также успешно применять и при поиске ошибок.

Алгоритм поиска ошибок

Поиск ошибок обычно сводится к определению участка кода, где допущена
ошибка, а затем, в этом участке, визуально находится ошибка. Думаю, вряд ли кто-то
будет сомневаться в том, что исследовать «на глаз» 5-10 строчек кода
проще и быстрей, чем 100-500.

При использовании комментирования задача предельно проста. Сначала
нужно закомментировать различные участки кода (иногда чуть ли не весь код), тем
самым «отключив» его. Затем, по очереди комментирование снимается с
этих участков кода. После очередного снятия комментирования совершается
попытка компиляции. Если компиляция прошла успешно – ошибка не в этом участке
кода. Затем открывается следующий участок кода и т.д. Когда находится проблемный
участок кода, визуально ищется ошибка, затем устраняется. Опять происходит попытка
компиляции. Если всё прошло успешно, — ошибка устранена.

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

Весьма важно правильно определять участки кода, которые необходимо
комментировать. Если это условие (или иная логическая конструкция) – то оно
должно комментироваться полно. Если комментируется участок кода, где
объявляются переменные, важно, чтобы не был открыт участок, где происходит
обращение к этим переменным. Иначе говоря, комментирование должно применяться
по логике программирования. Несоблюдения такого подхода приводит к
возникновению новых, вводящих в заблуждение, ошибок при компиляции.

Пример

Приведу пример практического поиска ошибки в коде. Допустим, у нас есть некоторый код:

#property copyright ""
#property link      ""
 
extern int Level1=6;
extern int Level2=2;
 
extern double Lots=0.1;
extern int TP=7;
extern int SL=5000;
extern int Profit_stop=10;
 
int start()
  {


   int pos_sell=0;
 for (int i_op_sell=OrdersTotal()-1; i_op_sell>=0; i_op_sell--) 
 { 
  if (!OrderSelect(i_op_sell,SELECT_BY_POS,MODE_TRADES)) break; 
  if (Symbol()==OrderSymbol()&&(OrderType()==OP_SELLSTOP||OrderType()==OP_SELL)&&(OrderComment()=="sar_ao"))
  {
   pos_sell=1;  break;   
  } 
 }
    
   int pos_buy=0;
 for (int i_op_buy=OrdersTotal()-1; i_op_buy>=0; i_op_buy--) 
 { 
  if (!OrderSelect(i_op_buy,SELECT_BY_POS,MODE_TRADES)) break; 
  if (Symbol()==OrderSymbol()&&(OrderType()==OP_BUYSTOP||OrderType()==OP_BUY)&&(OrderComment()=="sar_ao"))
  {
   pos_buy=1;  break;   
  } 
 }
     


 


  double stop_open; 
  for (int ia=OrdersTotal()-1; ia>=0; ia--) 
  { 
   if (!OrderSelect(ia,SELECT_BY_POS,MODE_TRADES)) break; 
   if ((OrderType()==OP_BUY)&&(Symbol()==OrderSymbol())&&(OrderComment()=="sar_ao"))
   { 
    stop_open=OrderOpenPrice(); 
    if (NormalizeDouble(Bid,Digits)-stop_open<=Profit_stop*Point) continue; 
    OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()+1*Point,OrderTakeProfit(),OrderExpiration(),CLR_NONE);  
   } 
 if ((OrderType()==OP_SELL)&&(Symbol()==OrderSymbol())&&(OrderComment()=="sar_ao"))
   { 
    stop_open=OrderOpenPrice(); 
    if (stop_open-NormalizeDouble(Ask,Digits)<=Profit_stop*Point) continue; 
    OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()-1*Point,OrderTakeProfit(),OrderExpiration(),CLR_NONE);       
   } 
  }   


   int i;   
   bool trend_UP=true,trend_DOWN=true;   

if(!pos_buy)
 {  
  for(i=Level1; i>=0; i--)
   {
   
    if(Open[i]<iSAR(NULL,0,0.02,0.1,i))
    {
     trend_UP=false; break;
    }
    
   }
 
   for(i=Level2*2; i>=0; i--)
   {    
   
    if(i>Level2)
    {
     if(iAO(NULL, 0, i+1)<=iAO(NULL, 0, i))    
     { 
      trend_UP=false; break;
     }
    }
    
    if(i<Level2)
    {
     if(iAO(NULL, 0, i+1)>=iAO(NULL, 0, i))   
     {  
      trend_UP=false; break;
     }
    }          
   
   } 
 }
 else
 {
  trend_UP=false; 
 }

if(!pos_sell)
 { 
   for(i=Level1; i>=0; i--)
  {
   {
    if(Open[i]>iSAR(NULL,0,0.02,0.1,i))
    {
     trend_DOWN=false; break;
    }
    
   }
 
   for(i=Level2*2; i>=0; i--)
   { 
          
    if(i>Level2)
    {
     if(iAO(NULL, 0, i+1)>=iAO(NULL, 0, i))   
     {  
      trend_DOWN=false; break;
     }   
    }
    
    if(i<Level2)
    {
     if(iAO(NULL, 0, i+1)<=iAO(NULL, 0, i))    
     { 
      trend_DOWN=false; break;
     } 
    } 
       
   }
   
 }
  else
 {
  trend_DOWN=false; 
 }  
 
 
  if(Open[0]>iSAR(NULL,0,0.02,0.2,0))
  {
    ObjectDelete("sell"); 
  }
  
  if(Open[0]<iSAR(NULL,0,0.02,0.2,0))
  {
    ObjectDelete("buy"); 
  } 
   
double MA_1;
MA_1=iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_SIGNAL,0);  
   if(trend_UP && MA_1<50 && Open[1]<Close[1] && !pos_buy && ObjectFind("buy") != 0)
   {   
     OrderSend(Symbol(),OP_BUY, Lots,Ask,2,Ask-SL*Point,Ask+TP*Point,"sar_ao",0,0,Blue); 
      
     ObjectCreate("buy", OBJ_ARROW, 0, Time[0], Bid);
     ObjectSet("buy", OBJPROP_STYLE, STYLE_DOT);
     ObjectSet("buy", OBJPROP_ARROWCODE, SYMBOL_ARROWUP);
     ObjectSet("buy", OBJPROP_COLOR, LightSeaGreen);
   }
   
   if(trend_DOWN && MA_1>50 && Open[1]>Close[1] && !pos_sell && ObjectFind("sell") != 0) 
   {   
      OrderSend(Symbol(),OP_SELL, Lots,Bid,2,Bid+SL*Point,Bid-TP*Point,"sar_ao",0,0,Red);   
      
      ObjectCreate("sell", OBJ_ARROW, 0, Time[0], Bid);
      ObjectSet("sell", OBJPROP_STYLE, STYLE_DOT);
      ObjectSet("sell", OBJPROP_ARROWCODE, SYMBOL_ARROWDOWN);
      ObjectSet("sell", OBJPROP_COLOR, Red);  
   }
   
 


   return(0);
  }

При попытке его компиляции мы видим сообщение об ошибке:

Оперативно определить участок кода, где допущена ошибка, не представляется
возможным. Прибегаем к комментированию. Комментируем все логические
конструкции:

#property copyright ""
#property link      ""
 
extern int Level1=6;
extern int Level2=2;
 
extern double Lots=0.1;
extern int TP=7;
extern int SL=5000;
extern int Profit_stop=10;
 
int start()
  {
  
 

 
 


 

 
  
double MA_1;
MA_1=iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_SIGNAL,0); 
 

  
  


   return(0);
  }

Легко можно убедиться, что такой код компилируется без проблем. Значит, участок кода, где допущена ошибка «скрыт». По очереди открываем участки кода /* … */, пытаемся откомпилировать.

Компиляция будет происходить благополучно, пока мы не дойдём до участка кода:

 
 
if(!pos_sell)
 { 
   for(i=Level1; i>=0; i--)
  {
   {
    if(Open[i]>iSAR(NULL,0,0.02,0.1,i))
    {
     trend_DOWN=false; break;
    }
    
   }
 
   for(i=Level2*2; i>=0; i--)
   { 
          
    if(i>Level2)
    {
     if(iAO(NULL, 0, i+1)>=iAO(NULL, 0, i))   
     {  
      trend_DOWN=false; break;
     }   
    }
    
    if(i<Level2)
    {
     if(iAO(NULL, 0, i+1)<=iAO(NULL, 0, i))    
     { 
      trend_DOWN=false; break;
     } 
    } 
       
   }
   
 }
  else
 {
  trend_DOWN=false; 
 }

Следовательно, ошибка именно в этой логической конструкции. При детальном «осмотре» данного участка кода, можно увидеть, что поставлена лишняя фигурная скобка в данной конструкции:

   for(i=Level1; i>=0; i--)
  {
   {
    if(Open[i]>iSAR(NULL,0,0.02,0.1,i))
    {
     trend_DOWN=false; break;
    }
    
   }

Если убрать её, код благополучно откомпилируется.

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

Заключение

На практическом примере было показано, как именно используется данный алгоритм
поиска ошибок. В данном примере используется весьма немаленький код (194 строки),
и на его «обход» могло бы уйти достаточно много времени. Именно
возможность комментирования экономит достаточно много времени у многих
программистов, которые сталкиваются с задачей поиска ошибок.

Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.

5.1. Понятие о корректирующих кодах

5.2. Циклические коды

5.3. Выбор образующего полинома циклического кода

От СПДС обычно требуется не только передавать сообщения с заданной скоростью передачи информации, но и обеспечивать при этом требуемую достоверность.

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

Помехи, действующие в канале, как известно, приводят к возникновению ошибок. Исходная вероятность ошибки в каналах связи обычно не позволяет достичь высокой степени достоверности без применения дополнительных мероприятий. К таким мероприятиям, обеспечивающим защиту от ошибок, относят применения корректирующих кодов.

В общей структурной схеме СПДС задачу защиты от ошибок выполняет кодер и декодер канала, который иногда называют УЗО.

5.1. Понятие о корректирующих кодах

Пусть имеется источник сообщений с объемом алфавита К.

Поставим в соответствие каждому сообщению n — элементную двоичную последовательность. Всего последовательностей из n — элементов может быть .

Если , то все последовательности (или кодовые комбинации) будут использоваться для кодирования сообщений, т.е. будут разрешенными.

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

Для того, что бы код мог обнаруживать и исправлять ошибки необходимо выполнение условия , при этом неиспользуемые для передачи комбинации (N0-K) называют запрещенными.

Появление ошибки в кодовой комбинации будет обнаружено, если передаваемая разрешенная комбинация перейдет в одну из запрещенных.

Расстояние Хемминга – характеризует степень различия кодовых комбинаций и определяется числом несовпадающих в них разрядов.

Перебрав все возможные пары разрешенных комбинаций рассматриваемого кода можно найти минимальное расстояние Хемминга d0.

Минимальное расстояние d0 — называется кодовым расстоянием

Кодовое расстояние определяет способность кода обнаруживать и исправлять ошибки.

У простого кода d0=1 – он не обнаруживает и не исправляет ошибки. Так как любая ошибка переводит одну разрешенную комбинацию в другую.

В общем случае справедливы следующие соотношения

– для обнаруживающей способности

– для исправляющей способности

Линейные коды

Двоичный блочный код является линейным если сумма по модулю 2 двух кодовых слов является также кодовым словом.

Линейные коды также называют групповыми.

Введем понятия группы.

Множество элементов с определенной на нем групповой операцией называется группой, если выполняется следующие условия:

1. Замкнутость gig j= gk G в результате операции с двумя элементами группы получается третий, так же принадлежащий этой группе.
2. Ассоциативность (сочетательность) (gigj) gk = gi (gj gk)
3. Наличие нейтрального элемента gj e = gj
4. Наличие обратного элемента. gi (gi)-1= e

Если выполняется условие gi gj = gj gi, то группа называется коммутативной.

Множество кодовых комбинаций n-элементного кода является замкнутой группой с заданной групповой операцией сложение по модулю 2.

Поэтому используя свойство замкнутости относительно операции 2, множество всех элементов можно задать не перечислением всех элементов, а производящей матрицей.

Все остальные элементы, кроме 0, могут быть получены путем сложения по модулю 2 строк производящей матрицы в различных сочетаниях.

В общем случае строки производящей матрицы могут быть любыми линейно независимыми, но проще и удобнее брать в качестве производящей матрицы – единичную.

5.2. Циклические коды

Широкое распространение на практике получил класс линейных кодов, которые называются циклическими. Данное название происходит от основного свойства этих кодов:

если некоторая кодовая комбинация принадлежит циклическому коду, то комбинация полученная циклической перестановкой исходной комбинации (циклическим сдвигом), также принадлежит данному коду.

.

Вторым свойством всех разрешенных комбинаций циклических кодов является их делимость без остатка на некоторый выбранный полином, называемый производящим.

Синдромом ошибки в этих кодах является наличие остатка от деления принятой кодовой комбинации на производящий полином.

Эти свойства используются при построении кодов, кодирующих и декодирующих устройств, а также при обнаружении и исправлении ошибок.

Представление кодовой комбинации в виде многочлена

Описание циклических кодов и их построение удобно проводить с помощью многочленов (или полиномов).

В теории циклических кодов кодовые комбинации обычно представляются в виде полинома. Так, n-элементную кодовую комбинацию можно описать полиномом (n-1) степени, в виде

.

где ={0,1}, причем = 0 соответствуют нулевым элементам комбинации, а = 1 — ненулевым.

Запишем полиномы для конкретных 4-элементных комбинаций

Действия над многочленами

При формировании комбинаций циклического кода часто используют операции сложения многочленов и деления одного многочлена на другой. Так,

,

поскольку .

Следует отметить, что действия над коэффициентами полинома (сложение и умножение) производятся по модулю 2.

Рассмотрим операцию деления на следующем примере:

Деление выполняется, как обычно, только вычитание заменяется суммированием по модулю два.

Отметим, что запись кодовой комбинации в виде многочлена, не всегда определяет длину кодовой комбинации. Например, при n = 5, многочлену соответствует кодовая комбинация 00011.

Алгоритм получения разрешенной кодовой комбинации циклического кода из комбинации простого кода

Пусть задан полином , определяющий корректирующую способность кода и число проверочных разрядов r, а также исходная комбинация простого k-элементного кода в виде многочлена .

Требуется определить разрешенную кодовую комбинацию циклического кода (n, k).

  • Умножаем многочлен исходной кодовой комбинации на

  • Определяем проверочные разряды, дополняющие исходную информационную комбинацию до разрешенной, как остаток от деления полученного в предыдущем пункте произведения на образующий полином

  • Окончательно разрешенная кодовая комбинация циклического кода определится так

Для обнаружения ошибок в принятой кодовой комбинации достаточно поделить ее на производящий полином. Если принятая комбинация — разрешенная, то остаток от деления будет нулевым. Ненулевой остаток свидетельствует о том, что принятая комбинация содержит ошибки. По виду остатка (синдрома) можно в некоторых случаях также сделать вывод о характере ошибки, ее местоположении и исправить ошибку.

Формирование базиса (производящей матрицы) циклического кода

Формирование базиса циклического кода возможно как минимум двумя путями.

Вариант первый.

  1. Составить единичную матрицу для простого исходного кода.
  2. Определить для каждой кодовой комбинации исходного кода группу проверочных элементов и дописать их в соответствующие строки матрицы.

Полученная матрица и будет базисом циклического кода. Причем, в данном случае, разрешенные комбинации заведомо разделимы (т.е. информационные и проверочные элементы однозначно определены).

Вариант второй.

    1. Дописать слева от КК, соответствующей образующему полиному циклического кода нули так, чтобы длина разрешенной кодовой комбинации равнялась n.
  • Получить остальные разрешенные кодовые КК базиса, используя циклический сдвиг исходной. (В базисе должно быть k – строк)

В данном случае код будет неразделимым.

Получив базис ЦК, можно получить все разрешенные комбинации, проводя сложение по модулю 2 кодовых комбинаций базиса в различных сочетаниях и плюс НУЛЕВАЯ.

Циклические коды достаточно просты в реализации, обладают высокой корректирующей способностью (способностью исправлять и обнаруживать ошибки) и поэтому рекомендованы МСЭ-Т для применения в аппаратуре ПД. Согласно рекомендации V.41 в системах ПД с ОС рекомендуется применять код с производящим полиномом

Построение кодера циклического кода

Рассмотрим код (9,5) образованный полиномом

.

Разрешенная комбинация циклического кода образуется из комбинации простого (исходного) кода путем умножения ее на и прибавления остатка R(x) от деления на образующий полином.

  • Умножение полинома на одночлен

эквивалентно добавлению к двоичной последовательности соответствующей G(x) , r — нулей справа.

Пусть

тогда

Для реализации операции добавления нулей используется r-разрядный регистр задержки.

  • Рассмотрим более подробно операцию деления:

Как видим из примера, процедура деления одного двоичного числа на другое сводится к последовательному сложению по mod2 делителя [10011] с соответствующими членами делимого [10101], затем с двоичным числом, полученным в результате первого сложения, далее с результатом второго сложения и т.д., пока число членов результирующего двоичного числа не станет меньше числа членов делителя.

Это двоичное число и будет остатком .

Построение формирователя остатка циклического кода

Структура устройства осуществляющего деление на полином полностью определяется видом этого полинома. Существуют правила позволяющие провести построение однозначно.

Сформулируем правила построения ФПГ.

  1. Число ячеек памяти равно степени образующего полинома r.
  2. Число сумматоров на единицу меньше веса кодирующей комбинации образующего полинома.
  3. Место установки сумматоров определяется видом образующего полинома.

Сумматоры ставят после каждой ячейки памяти, (начиная с нулевой) для которой существует НЕнулевой член полинома. Не ставят после ячейки для которой в полиноме нет соответствующего члена и после ячейки старшего разряда.

4. В цепь обратной связи необходимо поставить ключ, обеспечивающий правильный ввод исходных элементов и вывод результатов деления.

Структурная схема кодера циклического кода (9,5)

Полная структурная схема кодера приведена на следующем рисунке. Она содержит регистр задержки и рассмотренный выше формирователь проверочной группы.

Рассмотрим работу этой схемы

1. На первом этапе К1– замкнут К2 – разомкнут. Идет одновременное заполнение регистров задержки и сдвига информ. элементами (старший вперед!) и через 4 такта старший разряд в ячейке №4

2. Во время пятого такта К2 – замыкается а К1 – размыкается с этого момента в ФПГ формируется остаток. Одновременно из РЗ на выход выталкивается задержание информационные разряды.

За 5 тактов (с 5 по 9 включительно) в линию уйдут все 5-информационных элемента. К этому времени в ФПГ сформируется остаток

3. К2 – размыкается, К1 – замыкается и в след за информационными в линию уйдут элементы проверочной группы.

4. Одновременно идет заполнение регистров новой комбинацией.

Второй вариант построения кодера ЦК

Рассмотренный выше кодер очень наглядно отражает процесс деления двоичных чисел. Однако можно построить кодер содержащий меньшее число элементов т.е. более экономичный.

Устройство деления на производящий полином можно реализовать в следующем виде:

За пять тактов в ячейках будет сформирован такой же остаток от деления, что и в рассмотренном выше Формирователе проверочной группы. (ФПГ).

За эти же 5 тактов информационные разряды, выданные сразу на модулятор.

Далее в след за информационными уходят проверочные из ячеек устройств деления.

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

Окончательно структурная схема экономичного кодера выглядит так.

— На первом такте Кл.1 и Кл.3 замкнуты, информационные элементы проходят на выход кодера и одновременно формируются проверочные элементы.

— После того, как в линию уйдет пятый информационный элемент, в устройстве деления сформируются проверочные;

— на шестом такте ключи 1 и 3 размыкаются (разрываются обратная связь), а ключ 2 замыкается и в линию уходят проверочные разряды.

Ячейки при этом заполняются нулями и схема возвращается в исходное состояние.

Определение ошибочного разряда в ЦК

Пусть А(х)-многочлен соответствующий переданной кодовой комбинации.

Н(х)- многочлен соответствующей принятой кодовой комбинацией.

Тогда сложение данных многочленов по модулю два даст многочлен ошибки.

E(x)=A(x) H(x)

При однократной ошибке Е(х) будет содержать только один единственный член соответствующий ошибочному разряду.

Остаток – полученный от деления принятого многочлена H(x) на производящей Pr(x) равен остатку полученному при делении соответствующего многочлена ошибок E(x) на Pr(x)

При этом ошибке в каждом разряде будет соответствовать свой остаток R(x) (он же синдром), а значит, получив синдром можно однозначно определить место ошибочного разряда.

Алгоритм определения ошибки

Пусть имеем n-элементные комбинации (n = k + r) тогда:

1. Получаем остаток от деления Е(х) соответствующего ошибке в старшем разряде [1000000000], на образующей поленом Pr(x)

2. Делим полученный полином Н(х) на Pr(x) и получаем текущий остаток R(x).

3. Сравниваем R0(x) и R(x).

— Если они равны, то ошибка произошла в старшем разряде.

— Если «нет», то увеличиваем степень принятого полинома на Х и снова проводим деления

в) Опять сравниваем полученный остаток с R0(x)

— Если они равны, то ошибки во втором разряде.

— Если нет, то умножаем Н(х)х2 и повторяем эти операции до тех пор, пока R(X) не будет равен R0(x).

Ошибка будет в разряде соответствующем числу на которое повышена степень Н(х) плюс один.

Например: то номер ошибочного разряда 3+1=4

Пример декодирования комбинации ЦК

Положим, получена комбинация H(х)=111011010

Проанализируем её в соответствии с вышеприведенным алгоритмом.

Реализуя алгоритм определения ошибок, определим остаток от деления вектора соответствующего ошибке в старшем разряде Х8 на производяший полином P(x)=X4+X+1

X8 X2+X+1

X8+X5+X4 x4+x+1

X5+X4

X5+X2+X

X4+X2+X

X4+X+1

X2+1=R0(X)=0101

Разделим принятую комбинацию на образующий полином

Полученный на 9-м такте остаток, как видим, не равен R0(X). Значит необходимо умножить принятую комбинацию на Х и повторить деление. Однако результаты деления с 5 по 9 такты включительно будут такими же, значит необходимо продолжить деление после девятого такта до тех пор, пока в остатке не будет R0(Х). В нашем случае это произойдет на 10 такте, при повышении степени на 1. Значит ошибки во втором разряде.

Декодер циклического кода с исправлением ошибки

Если ошибка в первом разряде, то остаток R0(X)=10101 появления после девятого такта в ячейках ФПГ.

Если во втором по старшинству то после 10го;
в третьем по старшинству то после 11го;
в четвертом по старшинству то после 12го
в пятом по старшинству то после 13го
в шестом по старшинству то после 14го
в седьмом по старшинству то после 15го
в восьмом по старшинству то после 16го
в девятом по старшинству то после 17го.

На 10 такте старший разряд покидает регистр задержки и проходит через сумматор по модулю 2.

Если и этому моменту остаток в ФПГ=R0(X), то логическая 1 с выхода дешифратора поступит на второй вход сумматора и старший разряд инвертируется.

В нашем случае инвертируется второй разряд на 11 такте.

5.3. Выбор образующего полинома

Рассмотрим вопрос выбора образующего полинома, который определяет корректирующие свойства циклического кода. В теории циклических кодов показано, что образующий полином представляет собой произведение так называемых минимальных многочленов mi(x), являющихся простыми сомножителями (то есть делящимся без остатка лишь на себя и на 1) бинома xn+ 1:

P(x)=m1(x)* m3(x)…mj(x), (*)

где j = d02 =( 2tu.ош+1) – 2 = 2 tи.ош – 1.

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

для любых значений l и tи.ош существует циклический код длины n =2l – 1, исправляющий все ошибки кратности tи.ош и менее, и содержащий не более проверочных элементов.

Так как , то откуда . (**)

Очевидно, что для уменьшения времени передачи кодовых комбинаций, r следует выбирать как можно меньше. Пусть, например, длина кодовых комбинаций n = 7, кратность исправляемых ошибок tи.ош =1. Из (**) получим r = 1 . log2 ( 7+1 )=3.

После определения количества проверочных разрядов r, вычисления образующего полинома удобно осуществить, пользуясь таблицей минимальных многочленов, представленной в следующем виде:

Таблица минимальных многочленов

J=2tи.ош -1

Вид минимальных многочленов для

1

2

3

4

5

6

7

1

x2+x+1

x3+x+1

x4+x+1

x5+x+1

x6+x+1

x7+x+1

3

x4+x3+

+x2+x+1

x5+x4+

+x3+x2+1

x6+x4+

+x2+x+1

x7+x3+

+x2+x+1

5

x5+x4+

+x2+x+1

x6+x5+

+x2+x+1

x7+x4+

+x3+x2+1

7

x6+x3+1

X7+x6+x5+

+x4+x2+x+1

Определяя образующий полином, нужно из столбца для соответствующего соотношения выписать все многочлены, начиная с верхней строки до нижней с номером j=2tи.ош1 включительно. После этого следует перемножить выбранные минимальные многочлены в соответствии с (*). В частности, если r=3, tи.ош=1, j=2*1-1=1, образующий полином будет представлять собой единственный минимальный многочлен P(x)= m1(x) = x3+x+1 (первая строка, второй столбец таблицы ). Соответственно образующее число равно 1011.

Контрольные вопросы по теме:

  1. Что такое разрешенные и запрещенные кодовые комбинации.
  2. Что называется расстоянием Хемминга.
  3. Дайте понятие кодового расстояния и как его определить.
  4. Как связано кодовое расстояние с исправляющей и обнаруживающей способностью кода.
  5. Какой код называется линейным.
  6. Какое множество называется группой.
  7. Назовите основные свойства циклических кодов.
  8. Запишите полином в двоичном виде.
  9. Запишите полином, соответствующий двоичной записи 100111.
  10. Получите остаток от деления полинома на .
  11. Как получают разрешенные комбинации при циклическом кодировании.
  12. Нарисуйте кодер для циклического кода, порождаемого полиномом . Поясните принцип работы кодера.
  13. По какому признаку обнаруживают ошибку в принятой кодовой комбинации.
  14. Каков алгоритм определения ошибочного разряда в комбинации циклического кода.
  15. Нарисуйте структурную схему декодера, обеспечивающего обнаружение ошибок для кода (7,4) при производящем полиноме . Поясните принцип его работы.
  16. Нарисуйте структурную схему декодера, обеспечивающего исправление однократной ошибки для кода (7,4) при производящем полиноме . Поясните принцип его работы.
  17. Как выбирается образующий (производящий) полином?

Аннотация: Контроль по четности, CRC, алгоритм Хэмминга. Введение в коды Рида-Соломона: принципы, архитектура и реализация. Метод коррекции ошибок FEC (Forward Error Correction).

Каналы передачи данных ненадежны (шумы, наводки и т.д.), да и само оборудование обработки информации работает со сбоями. По этой причине важную роль приобретают механизмы детектирования ошибок. Ведь если ошибка обнаружена, можно осуществить повторную передачу данных и решить проблему. Если исходный код по своей длине равен полученному коду, обнаружить ошибку передачи не предоставляется возможным. Можно, конечно, передать код дважды и сравнить, но это уже двойная избыточность.

Простейшим способом обнаружения ошибок является контроль по четности. Обычно контролируется передача блока данных ( М бит). Этому блоку ставится в соответствие кодовое слово длиной N бит, причем N>M. Избыточность кода характеризуется величиной 1-M/N. Вероятность обнаружения ошибки определяется отношением M/N (чем меньше это отношение, тем выше вероятность обнаружения ошибки, но и выше избыточность).

При передаче информации она кодируется таким образом, чтобы с одной стороны характеризовать ее минимальным числом символов, а с другой – минимизировать вероятность ошибки при декодировании получателем. Для выбора типа кодирования важную роль играет так называемое расстояние Хэмминга.

Пусть А и Б — две двоичные кодовые последовательности равной длины. Расстояние Хэмминга между двумя этими кодовыми последовательностями равно числу символов, которыми они отличаются. Например, расстояние Хэмминга между кодами 00111 и 10101 равно 2.

Можно показать, что для детектирования ошибок в n битах схема кодирования требует применения кодовых слов с расстоянием Хэмминга не менее N + 1. Можно также показать, что для исправления ошибок в N битах необходима схема кодирования с расстоянием Хэмминга между кодами не менее 2N + 1. Таким образом, конструируя код, мы пытаемся обеспечить расстояние Хэмминга между возможными кодовыми последовательностями большее, чем оно может возникнуть из-за ошибок.

Широко распространены коды с одиночным битом четности. В этих кодах к каждым М бит добавляется 1 бит, значение которого определяется четностью (или нечетностью) суммы этих М бит. Так, например, для двухбитовых кодов 00, 01, 10, 11 кодами с контролем четности будут 000, 011, 101 и 110. Если в процессе передачи один бит будет передан неверно, четность кода из М+1 бита изменится.

Предположим, что частота ошибок ( BERBit Error Rate) равна р = 10-4. В этом случае вероятность передачи 8 бит с ошибкой составит 1 – (1 – p)8 = 7,9 х 10-4. Добавление бита четности позволяет детектировать любую ошибку в одном из переданных битах. Здесь вероятность ошибки в одном из 9 битов равна 9p(1 – p)8. Вероятность же реализации необнаруженной ошибки составит 1 – (1 – p)9 – 9p(1 – p)8 = 3,6 x 10-7. Таким образом, добавление бита четности уменьшает вероятность необнаруженной ошибки почти в 1000 раз. Использование одного бита четности типично для асинхронного метода передачи. В синхронных каналах чаще используется вычисление и передача битов четности как
для строк, так и для столбцов передаваемого массива данных. Такая схема позволяет не только регистрировать, но и исправлять ошибки в одном из битов переданного блока.

Контроль по четности достаточно эффективен для выявления одиночных и множественных ошибок в условиях, когда они являются независимыми. При возникновении ошибок в кластерах бит метод контроля четности неэффективен, и тогда предпочтительнее метод вычисления циклических сумм ( CRCCyclic Redundancy Check). В этом методе передаваемый кадр делится на специально подобранный образующий полином. Дополнение остатка от деления и является контрольной суммой.

В Ethernet вычисление CRC производится аппаратно. На
рис.
4.1 показан пример реализации аппаратного расчета CRC для образующего полинома R(x) = 1 + x2 + x3 + x5 + x7. В этой схеме входной код приходит слева.

Схема реализации расчета CRC

Рис.
4.1.
Схема реализации расчета CRC

Эффективность CRC для обнаружения ошибок на многие порядки выше простого контроля четности. В настоящее время стандартизовано несколько типов образующих полиномов. Для оценочных целей можно считать, что вероятность невыявления ошибки в случае использования CRC, если ошибка на самом деле имеет место, равна (1/2)r, где r — степень образующего полинома.

Таблица
4.1.

CRC -12 x12 + x11 + x3 + x2 + x1 + 1
CRC -16 x16 + x15 + x2 + 1
CRC -CCITT x16 + x12 + x5 + 1

4.1. Алгоритмы коррекции ошибок

Исправлять ошибки труднее, чем их детектировать или предотвращать. Процедура коррекции ошибок предполагает два совмещеных процесса: обнаружение ошибки и определение места (идентификации сообщения и позиции в сообщении). После решения этих двух задач исправление тривиально — надо инвертировать значение ошибочного бита. В наземных каналах связи, где вероятность ошибки невелика, обычно используется метод детектирования ошибок и повторной пересылки фрагмента, содержащего дефект. Для спутниковых каналов с типичными для них большими задержками системы коррекции ошибок становятся привлекательными. Здесь используют коды Хэмминга или коды свертки.

Код Хэмминга представляет собой блочный код, который позволяет выявить и исправить ошибочно переданный бит в пределах переданного блока. Обычно код Хэмминга характеризуется двумя целыми числами, например, (11,7), используемыми при передаче 7-битных ASCII-кодов. Такая запись говорит, что при передаче 7-битного кода используется 4 контрольных бита (7 + 4 = 11). При этом предполагается, что имела место ошибка в одном бите и что ошибка в двух или более битах существенно менее вероятна. С учетом этого исправление ошибки осуществляется с определенной вероятностью. Например, пусть возможны следующие правильные коды (все они, кроме первого и последнего, отстоят друг от друга на расстояние Хэмминга 4):

00000000

11110000

00001111

11111111

При получении кода 00000111 нетрудно предположить, что правильное значение полученного кода равно 00001111. Другие коды отстоят от полученного на большее расстояние Хэмминга.

Рассмотрим пример передачи кода буквы s = 0x073 = 1110011 с использованием кода Хэмминга (11,7). Таблица 4.2.

Таблица
4.2.

Позиция бита 11 10 9 8 7 6 5 4 3 2 1
Значение бита 1 1 1 * 0 0 1 * 1 * *

Символами * помечены четыре позиции, где должны размещаться контрольные биты. Эти позиции определяются целой степенью 2 (1, 2, 4, 8 и т.д.). Контрольная сумма формируется путем выполнения операции XoR (исключающее ИЛИ) над кодами позиций ненулевых битов. В данном случае это 11, 10, 9, 5 и 3. Вычислим контрольную сумму:

11= 1011
10= 1010
09= 1001
05= 0101
03= 0011
Sigma= 1110

Таким образом, приемник получит код

Позиция бита 11 10 9 8 7 6 5 4 3 2 1
Значение бита 1 1 1 1 0 0 1 1 1 1 0

Просуммируем снова коды позиций ненулевых битов и получим нуль;

11= 1011
10= 1010
09= 1001
08= 1000
05= 0101
04= 0100
03= 0011
02= 0010
Sigma= 0000

Ну а теперь рассмотрим два случая ошибок в одном из битов посылки, например в бите 7 (1 вместо 0) и в бите 5 (0 вместо 1). Просуммируем коды позиций ненулевых битов еще раз:

Таблица
4.3.

11= 1011
10= 1010
09= 1001
08= 1000
07= 0111
05= 0101
04= 0100
03= 0011
02= 0010
Sigma= 0111
11= 1011
10= 1010
09= 1001
08= 1000
04= 0100
03= 0011
02= 0010
Sigma= 0001

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

В общем случае код имеет N = M + C бит и предполагается, что не более чем один бит в коде может иметь ошибку. Тогда возможно N+1 состояние кода (правильное состояние и n ошибочных). Пусть М = 4, а N = 7, тогда слово-сообщение будет иметь вид: M4, M3, M2, C3, M1, C2, C1. Теперь попытаемся вычислить значения С1, С2, С3. Для этого используются уравнения, где все операции представляют собой сложение по модулю 2:

С1 = М1 + М2 + М4
С2 = М1 + М3 + М4
С3 = М2 + М3 + М4

Для определения того, доставлено ли сообщение без ошибок, вычисляем следующие выражения (сложение по модулю 2):

С11 = С1 + М4 + М2 + М1
С12 = С2 + М4 + М3 + М1
С13 = С3 + М4 + М3 + М2

Результат вычисления интерпретируется следующим образом:

Таблица
4.4.

C11 C12 C13 Значение
1 2 4 Позиция бит
0 0 0 Ошибок нет
0 0 1 Бит С3 неверен
0 1 0 Бит С2 неверен
0 1 1 Бит M3 неверен
1 0 0 Бит С1 неверен
1 0 1 Бит M2 неверен
1 1 0 Бит M1 неверен
1 1 1 Бит M4 неверен

Описанная схема легко переносится на любое число n и М.

Число возможных кодовых комбинаций М помехоустойчивого кода делится на n классов, где N — число разрешенных кодов. Разделение на классы осуществляется так, чтобы в каждый класс вошел один разрешенный код и ближайшие к нему (по расстоянию Хэмминга ) запрещенные коды. В процессе приема данных определяется, к какому классу принадлежит пришедший код. Если код принят с ошибкой, он заменяется ближайшим разрешенным кодом. При этом предполагается, что кратность ошибки не более qm.

В теории кодирования существуют следующие оценки максимального числа N n -разрядных кодов с расстоянием D.

d=1 n=2n
d=2 n=2n-1
d=3 N 2n/(1 + n)
d = 2q + 1 (для кода Хэмминга это неравенство превращается в равенство)

В случае кода Хэмминга первые k разрядов используются в качестве информационных, причем

K = n – log(n + 1), откуда следует (логарифм по основанию 2), что k может принимать значения 0, 1, 4, 11, 26, 57 и т.д., это и определяет соответствующие коды Хэмминга (3,1); (7,4); (15,11); (31,26); (63,57) и т.д.

Обобщением кодов Хэмминга являются циклические коды BCH (Bose-Chadhuri-hocquenghem). Эти коды имеют широкий выбор длин и возможностей исправления ошибок.

Одной из старейших схем коррекции ошибок является двух-и трехмерная позиционная схема (
рис.
4.2). Для каждого байта вычисляется бит четности (бит <Ч>, направление Х). Для каждого столбца также вычисляется бит четности (направление Y. Производится вычисление битов четности для комбинаций битов с координатами (X,Y) (направление Z, слои с 1 до N ). Если при транспортировке будет искажен один бит, он может быть найден и исправлен по неверным битам четности X и Y. Если же произошло две ошибки в одной из плоскостей, битов четности данной плоскости недостаточно. Здесь поможет плоскость битов четности N+1.
Таким образом, на 512 передаваемых байтов данных пересылается около 200 бит четности.

Позиционная схема коррекции ошибок

Рис.
4.2.
Позиционная схема коррекции ошибок

Способы поиска ошибок

Как выявлять ошибки в алгоритме

Выявление ошибок в алгоритме возможно при помощи двух способов:

1. Использование ParamDebug

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

Рисунок 1 – Отладочная таблица

Например, выведем значения индикатора «Полосы Боллинджера» для проверки в отладочную таблицу. При наведении на какой-либо бар, в таблице выведется текущее значение индикатора на этом баре.

Рисунок 2 – Проверка значений через ParamDebug

Также, чтобы убедиться в правильности расчетов, значения в отладочной таблице данного индикатора можно сравнить со значениями готового индикатора (при его наличии) в TradingView.

Если в итоге значения с ParamDebug не сходятся, то можно в TradingView посмотреть код данного индикатора, разбить его на части и выводить промежуточные значения в TradingView. (Рисунок 4)

Процесс проверки:
1. Открываем код индикатора и делаем его копию, чтобы появилась возможность его редактировать.

Рисунок 5 – Копия кода индикатора

2. Изменяем код, например, хотим проверить значения переменной «dev» с нашим значением в ParamDebug. Значения «dev» выводится с помощью функции plot, как показано на рисунке ниже.

Рисунок 6 – Вывод значений

Таким образом, можно сравнивать промежуточные значения кода с промежуточными значениями в TradingView для проверки правильности расчетов.

Это один из вариантов проверки. Также можно сравнить значения с помощью Excel таблицы, если ТЗ в таблице и есть форма расчетов для проверки, например для расчета индикатора «Коэффициента корреляции» (рисунок 7).

Рисунок 7 – Проверка значений через Excel таблицу

Процесс проверки через Excel таблицу:

  1. Открываем график двух инструментов, например (BTCUSDT и BNBUSDT);
  2. Подставляем значения закрытой свечи (кол-во зависит от периода расчета) этих двух инструментов в таблицу;
  3. Сверяем значения xi, yi, xi*yi, x2, y2 со значениями, выведенными в ParamDebug.

Бывают такие ситуации, когда при проверке выше указанными способами, промежуточные и итоговые значения совпадают, но алгоритм не правильно работает. Один из вариантов ошибки, это использование глобальной переменной, которая принимает какие-то значения в методе при определенном условии, но при вызове функции с другим параметром, алгоритм не срабатывает. Данную ошибку можно найти при помощи покрытия разных участков кода ParamDebug и использовании отладки в Visual Studio.

Например, у нас есть несколько объектов класса и функция, принимающая данные объекты, которая вызывается каждый бар.

В данном случае, при таймфрейме 1 и 5 минут, переменная _date будет перезаписываться каждую минуту и расчет будет верным только для 1 минуты, а для 5 минуты условие никогда не будет true. Таким образом, алгоритм будет рассчитывать только для 1 минуты. Исправить это можно, если переменную _date вынести в класс, чтобы каждый объект сохранял информацию по тому таймфрейму, который ему ранее присвоился.
Таким образом, глобальные переменные, используемые в расчетах функциях, принимающие разные таймфреймы, переносить в класс.

2. Использование модуля для отладки кода через Visual Studio

Данный способ позволяет тестировать/проверять значения с помощью break points в Visual Studio. Можно комбинировать с выше описанными способами проверки.
Отладка скрипта через Visual Studio

Рисунок 8 — отладка в Visual Studio

Подключение модуля для отладки показано будет в другой статье.

Check List:

  1. Покрыть код ParamDebug, где требуется проверить правильность работы алгоритма
  2. Сравнить значения с TradingView (при наличии существующего скрипта) и разбить код на части, выводить промежуточные значения
  3. Использовать Excel (если есть расчеты)
  4. Debug в Visual Studio

Пример поиска ошибка через ParamDebug или отладки в Visual Studio:

Данное покрытие кода позволяет просмотреть разные участки кода, которые будут выполняться. Если на отладочной таблице в ETS будет видно, к примеру, ParamDebug(«Test», 1) и не видно ParamDebug(«Test», 2), это означает, что номер бара меньше указанного значения. Таким способом, покрывая ParamDebug можно идти в глубину кода и просматривать, в какие моменты код срабатывает или нет.

Check List ParamDebug/отладка в Visual Studio:

  1. Покрыть те участки кода, где необходимо посмотреть исполнения кода;
  2. Если выполняется код до функции, но функция пропускается, то углубляться в данную функцию и покрывать ее ParamDebug;
  3. Также углублять в подфункции (при наличии);
  4. Просматривать значения переменных, при которых не выполняется код;
  5. Сравнивать значения выше указанными способами (Excel, TradingView).

Check List Excel:

  1. Заполнять таблицу необходимыми значениями при расчетах;
  2. Разбивать формулу расчета на части;
  3. Сверять значения каждой части формулы с полученными.

Check List TradingView (при наличии готового кода):

  1. Найти индикатор;
  2. Скопировать скрипт, чтобы в дальнейшем изменять;
  3. Разбить алгоритм на части;
  4. Выводить промежуточные значения на график и сверять со своими промежуточными.

Все возможности открывает платформа ETS.

Понравилась статья? Поделить с друзьями:

Не пропустите эти материалы по теме:

  • Яндекс еда ошибка привязки карты
  • Алгоритм обратного распространения ошибки это
  • Акцентологическая норма примеры ошибок
  • Алгоритм обратного распространения ошибки простыми словами
  • Акцентные ошибки это

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии