%hide %latex \parindent 0pt \setlength{\parskip}{\baselineskip} \LARGE{\textbf{\underline{Bildübertragung}}} \normalsize Das Programm simuliert die Übertragung der Farbwerte eines Bildes. \\ Für jeden Punkt wird ein RGB-Wert übertragen, der aus 24 Bit besteht. Realistische Fehlerraten liegen unterhalb von 5\%. \\ (Diesen Wert hatte die NASA um 1980 bei den Voyager-Missionen) Zur Wahl stehen für die Übertragung folgende Kodierungen: \begin{itemize} \item $H_7$ - [7,4,3]-Hamming-Code \item $H_8$ - [8,4,4]-Hamming-Code (Erweiterung von $H_7$) \item $G_{23}$ - [23,12,7]-Binary-Golay-Code \item $G_{24}$ - [24,12,8]-Binary-Golay-Code (Erweiterung von $G_{23}$) \end{itemize} Rot umkreiste Punkte weisen in mindestens einem Wort mehr Fehler auf, als der Code erkennen kann. --------------------------------- nächstes Feld ------------------------------------ %hide # Konstanten rows = 5 columns = 6 #################################################################### # DEFINITIONEN UND VORBERECHNUNGEN # #################################################################### H7 = HammingCode(3,GF(2)) H8 = H7.extended_code() G23 = BinaryGolayCode() G24 = ExtendedBinaryGolayCode() vecListH7 = [] vecListH8 = [] vecListG23 = [] vecListG24 = [] genMatH7 = H7.gen_mat() genMatH8 = H8.gen_mat() genMatG23 = G23.gen_mat() genMatG24 = G24.gen_mat() # Berechnung aller Codewörter zu G23/G24 for i in range(4096): # i -> String des Wertes von i in Dual mit garantiert 12 Zeichen binString = "".join( [str(( i >> z ) & 1 ) for z in range(11, -1, -1)] ) v = vector(GF(2),[binString[i] for i in range(12)]) vecListG23.append ( v * genMatG23 ) vecListG24.append ( v * genMatG24 ) # Berechnung aller Codewörter zu H7/H8 for i in range(16): # i -> String des Wertes von i in Dual mit garantiert 4 Zeichen binString = "".join( [str(( i >> z ) & 1 ) for z in range(3, -1, -1)] ) v = vector(GF(2),[binString[j] for j in range(4)]) vecListH7.append ( v * genMatH7 ) vecListH8.append ( v * genMatH8 ) #################################################################### # Statische Grafikelemente baseGraphix = text("Original" , ( 2.5, 5), rgbcolor='#000000') baseGraphix += text("Empfangen", ( 9.5, 5), rgbcolor='#000000') baseGraphix += text("Ausgabe" , (16.5, 5), rgbcolor='#000000') # Original-Daten original = [[[] for i in range(columns)] for j in range(rows)] originalMat04 = [[[] for i in range(columns)] for j in range(rows)] originalMat12 = [[[] for i in range(columns)] for j in range(rows)] # Kodierungen mit Dimension 4 M04 = MatrixSpace ( GF(2), 6, 4 ) encodedMatH7 = [[[] for i in range(columns)] for j in range(rows)] encodedMatH8 = [[[] for i in range(columns)] for j in range(rows)] # Kodierungen mit Dimension 12 M12 = MatrixSpace ( GF(2), 2,12 ) encodedMatG23 = [[[] for i in range(columns)] for j in range(rows)] encodedMatG24 = [[[] for i in range(columns)] for j in range(rows)] for i in range (rows): for j in range(columns): # Farbwerte für die Punkte als RGB-String original[i][j] = '#%02x%02x%02x' % ( (j+2)*32, (j+2)*32, (j+2)*32 ) baseGraphix += point([j,i], rgbcolor = original[i][j], pointsize = 250 ) # RGB-String -> Zeichenweise in Dual übertragen. (Jedes Zeichen nutzt 4 Bit) binString = '' for c in original[i][j][1:]: binString += "".join( [str( (int(c,16) >> z) & 1 ) for z in range(3, -1, -1)] ) # Originalfarbwerte in Matrizenform originalMat04[i][j] = M04([binString[k] for k in range(len(binString))]) originalMat12[i][j] = M12([binString[k] for k in range(len(binString))]) # Farbwerte in Matrizenform codieren. encodedMatH7 [i][j] = originalMat04[i][j] * genMatH7 encodedMatH8 [i][j] = originalMat04[i][j] * genMatH8 encodedMatG23[i][j] = originalMat12[i][j] * genMatG23 encodedMatG24[i][j] = originalMat12[i][j] * genMatG24 #################################################################### def getRandomBit( errorRate ): """ 0 oder 1 abhängig von der Fehlerrate. INPUT: errorRate - Wahrscheinlichkeit für eine 1 OUTPUT: 0 - Zufallswert > errorRate 1 - Zufallswert <= errorRate EXAMPLE: sage: getRandomBit (100) 1 """ if randint(1,100) <= errorRate: return 1 else: return 0 def corrupt ( A, errorRate ): """ Verfälscht die Matrix A stellenweise mit einer Wahrscheinlichkeit von errorRate. INPUT: A - mxn Matrix mit Elementen aus GF(2) errorRate - Wahrscheinlichkeit für einen Bitfehler OUTPUT: Die verfälschte Matrix A """ M = MatrixSpace ( GF(2), len(A.rows()), len(A.columns()) ) size = len(A.rows()) * len(A.columns()) B = M([getRandomBit(errorRate) for i in range(size)]) return A+B #################################################################### def matrixToColor ( matrix, codeID ): """ Stellt aus der Matrix einen RGB-String her. INPUT: matrix - Matrix mit 24 Bit codeID - Bezeichnung der verwendeten Kodierung OUTPUT: RGB-String """ if codeID == 'H7' or codeID == 'H8': colorString = '#' for v in matrix.rows(): tempString = '' for j in [0,1,2,4]: tempString += str(v[j]) colorString += hex(int(tempString,2))[2:] return colorString if codeID == 'G23' or codeID == 'G24': colorString = '#' for v in matrix.rows(): for j in range(3): tempString = '' for k in range(4): tempString += str(v[4*j + k]) colorString += hex(int(tempString,2))[2:] return colorString return '' #################################################################### def getCorrectedElement( v, vecList, codeMinDist ): """ Sucht aus der Vektorliste den Vektor mit dem geringsten Abstand zum Vektor v. INPUT: v - Vektor vecList - Vektorliste codeMinDist - Mindestabstand des aktuellen Codes OUTPUT: Vektor aus vecList, der v am ähnlichsten ist. """ minVec = v minDist = 25 for w in vecList: dist = hamming_weight(v-w) if dist <= floor((codeMinDist-1)/2): return w if dist <= minDist: minVec = w minDist = dist return minVec def correct( A, codeID, minDist, checkMat, checkRowsCount ): """ Versucht die Fehler in A zu berichtigen. INPUT: A - fehlerhafte Matrix codeID - die aktuelle Kodierung minDist - Mindestabstand checkMat - Kontrollmatrix checkRowsCount - Anzahl der Zeilen der Kontrollmatrix OUTPUT: Korrigierte Matrix B """ lenARows = 0 lenACols = 0 if codeID == 'H7': vecList = vecListH7 lenARows = 6 lenACols = 7 if codeID == 'H8': vecList = vecListH8 lenARows = 6 lenACols = 8 if codeID == 'G23': vecList = vecListG23 lenARows = 2 lenACols = 23 if codeID == 'G24': vecList = vecListG24 lenARows = 2 lenACols = 24 tempList = [] for v in A.rows(): if checkMat*v == vector([0 for j in range(checkRowsCount)] ): # Wenn es ein Codewort ist tempList.append ( v ) else: # sonst w = getCorrectedElement( v, vecList, minDist ) tempList.append ( w ) M = MatrixSpace ( GF(2), lenARows, lenACols ) B = M(tempList) return B #################################################################### # INTERFACE # #################################################################### @interact def visualisierung( codeID = selector(['H7','H8','G23','G24'], nrows=1, label='Code' ), errorRate = slider(0,49,1,5,'Fehlerrate [%]') ): # Reinitialisieren der Grafik g = baseGraphix # Variablen zur Fehlerauswertung countRawErrors = 0 countIDedErrors = 0 countFinalErrors = 0 if codeID == 'H7': C = H7 encodedMat = encodedMatH7 checkMat = H7.check_mat() checkRowsCount = 3 minDist = 3 numberOfTotalBits = 1260 if codeID == 'H8': C = H8 encodedMat = encodedMatH8 checkMat = H8.check_mat() checkRowsCount = len(checkMat.rows()) minDist = 4 numberOfTotalBits = 1440 if codeID == 'G23': C = G23 encodedMat = encodedMatG23 checkMat = G23.check_mat() checkRowsCount = 11 minDist = 7 numberOfTotalBits = 1380 if codeID == 'G24': C = G24 encodedMat = encodedMatG24 checkMat = G24.check_mat() checkRowsCount = 12 minDist = 8 numberOfTotalBits = 1440 # Durchläuft alle Punkte for i in range (rows): for j in range(columns): # Codierte Matrix wird verfälscht corruptedMat = corrupt ( encodedMat[i][j], errorRate ) # Verfälschter Punkt wird hinzugefügt color = matrixToColor ( corruptedMat, codeID ) g += point([j+1*columns+1,i], rgbcolor = color , pointsize = 250 ) # Fehler werden ausgewertet. Eine Zeile entspricht einem Wort. errorMat = encodedMat[i][j] - corruptedMat for word in errorMat.rows(): localRawError = hamming_weight ( word ) countRawErrors += localRawError # Wort enthält zu viele Fehler if localRawError >= minDist: g += circle([j+1*columns+1,i], 0.5, rgbcolor='#FF0000') # Fehler sind erkennbar if localRawError < minDist: countIDedErrors += localRawError # Verfälschte Matrix wird korrigiert. correctedMat = correct ( corruptedMat, codeID, minDist, checkMat, checkRowsCount ) # Korrigierter Punkt wird hinzugefügt. color = matrixToColor ( correctedMat, codeID ) g += point([j+2*columns+2,i], rgbcolor = color, pointsize = 250 ) # Fehler werden ausgewertet. Eine Zeile entspricht einem Wort. errorMat = encodedMat[i][j] - correctedMat for word in errorMat.rows(): countFinalErrors += hamming_weight ( word ) g.show( frame = False, axes=False, figsize=[12,2.5], xmin=-1, xmax=4*columns+3, ymin=-1, ymax=5) # Berechnung von Statistiken für die anschließende HTML-Anzeige rawErrorRate = (countRawErrors / numberOfTotalBits) * 100 IDedErrorRate = 0 if countRawErrors != 0: IDedErrorRate = (countIDedErrors / countRawErrors ) * 100 finalErrorRate = (countFinalErrors / numberOfTotalBits) * 100 # HTML-Anzeige html('') html('') html(' ') html(' ') html(' ') html('') html('') html(' ') html(' ') html(' ') html('') html('') html(' ') html(' ') html(' ') html('') html('
Fehler: ' + str(countRawErrors) + ' Bit ('+ "%5.2f%%" % rawErrorRate +')
Erkannt: ' + str(countIDedErrors) + ' Bit ('+ "%5.2f%%" % IDedErrorRate +')
Nach Korrektur: ' + str(countFinalErrors) + ' Bit ('+ "%5.2f%%" % finalErrorRate +')
')