0% found this document useful (0 votes)
12 views9 pages

H 5 Code

The document discusses the construction of the H5 Reed-Muller code used in the Mariner 9 Mars mission for error-corrected grayscale photography. It details the recursive process of generating Reed-Muller codes, including the mathematical foundations and properties of these codes, such as their linearity and error correction capabilities. The final H5 code is characterized as an even parity [32, 6, 16]-code, capable of correcting up to 7 errors and enabling the transmission of 64 grayscale shades.

Uploaded by

Andy Acct
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views9 pages

H 5 Code

The document discusses the construction of the H5 Reed-Muller code used in the Mariner 9 Mars mission for error-corrected grayscale photography. It details the recursive process of generating Reed-Muller codes, including the mathematical foundations and properties of these codes, such as their linearity and error correction capabilities. The final H5 code is characterized as an even parity [32, 6, 16]-code, capable of correcting up to 7 errors and enabling the transmission of 64 grayscale shades.

Uploaded by

Andy Acct
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 9

Building the H5 Reed-Muller Code used by Mariner 9

David F. Brailsford
School of Computer Science, University of Nottingham, UK.

1. Introduction
The multi-error-correcting code used on the Mariner 9 Mars missions — to deliver error-
corrected, 64-level grayscale photographs of the Martian surface — was a first-order Reed-Muller
code. These codes were discovered in the early 1950s by Irving Reed and David Muller.
From a pure mathematical standpoint the first-order Reed-Muller codes can be regarded as a sub-
set of Hadamard codes which are, in turn, generated from a recursive sequence of Hadamard
matrices making use of tensor (or ‘Kronecker’, or ‘outer’) products of matrices. It is fortunate
that, as mere computer scientists, we can join in on this party by simply taking on board the
primitive-recursive algorithm shown in section 2, for Hn . After five levels of recursion we reach
the code H5 and this is the Reed-Muller code used on Mariner 9.

1.1. The [n, k, d] notation for linear codes.


The binary codes developed in this document are all linear. This means that every codeword in
the list for some given Hn code can be added to any other codeword, to deliver a result that will
also be present in the list. This is a typical behaviour for a vector space and means that code-
words behave like vectors. Moreover, it also means that a full list of codewords can be generated
from a smaller list of representative vectors (known as the basis set) by simply forming all possi-
ble combinations of vectors from the basis set and adding them together using ⊕ (i,.e. binary
addition, or exclusive or).
In the [n, k, d ] notation the fact that square brackets are used implies that the code is linear and is
one in which n is the overall length of a codeword, k is the number of bits that are message bits
and d is the minimum distance of the code. The concept of ‘distance’, which is vital for being
able to regard codewords as vectors in a vector space, is simply the number of positions in which
the bit patterns differ. The minimum distance of a code also determines how may errors can
potentially be detected and/or corrected. For a code with distance d the number of detectable
errors is d / 2  whereas the number of correctable errors is ( d − 1 ) / 2  . Here  denotes the
‘floor’ function which causes any non integer result to be rounded down e.g. 1.5  = 1.
Note carefully that the roman Hn codes are indeed linear but, unlike the Hamming codes, they
are not perfect. As we develop the Hn codes we find that their d value is even and this fact alone
rules them out for being perfect codes; it is a necessary condition for any perfect code that d must
be odd.

2. The basis sets for the Hn


A basis set for Hn family of codes consists of:
0 ... 0 1 ... 1
{
{

2 n − 1 0s 2 n − 1 1s
together with two-fold repetitions of the codewords from the previous basis set for Hn − 1 .
-2-

So:
H0 has basis set 1
⇒ H1 has basis set 01, 11
⇒ H2 has basis set 0011, 0101, 1111
and so on.

3. Construction of H2
We will now look in detail at the construction of all the codewords for the H2 code starting from
its basis set, which is: x 1 = 0011, x 2 = 0101, x 3 = 1111. Note that the zero vector (denoted as 0
or as x 0 ) is present in all the Hn codes and consists simply of a row of n zeroes.
We now add together (via bitwise binary addition i.e. ‘exclusive or’, denoted ⊕) the basis set vec-
tors in all possible combinations, as shown below
0 (i.e. x 0 ) = 0000
x 1 = 0011
x 2 = 0101
x 3 = 1111
x 1 ⊕ x 2 = 0110
x 1 ⊕ x 3 = 1100
x 2 ⊕ x 3 = 1010
x 1 ⊕ x 2 ⊕ x 3 = 1001

It is now apparent that H2 is an even-parity code of length 4. The first 3 bits, counting from the
left, can be thought of as the message bits and the 4th bit is then the parity check. The minimum
distance between the codewords is 2 and so the code can be characterised, in [n, k, d ] notation as
a [4, 3, 2]-code. Like all codes with a single-bit parity check, its capabilities are limited to detect-
ing one error.
Another fascinating property of this code is that it embeds all of the eight possible 3-bit patterns.
Look at the codeword list again, with bit positions, starting from the left, numbered from 1
upwards. An inspection of bits 1, 2 and 4 (the “power-of-two positions”) over all eight code-
words, reveals that they form a collection (sometimes called C3 ) of all the possible 3-bit
patterns — though not in any particular order.
Finally, we note that these 4-bit codewords form a linear vector space because bitwise combina-
tion of any two of them, using the ⊕ operation, yields some other codeword in this same set. Two
of the codewords are worth a special mention: 0000 when added to any other codeword will leave
it unchanged; 1111 when added to any other codeword will deliver back the bitwise inverse of
that codeword i.e. with every bit flipped.
Readers familiar with matrix operations will note that it is not necessary to write out all the
basis-set combinations, as we have done above, in order to develop the full set of codewords. By
writing out the basis vectors (including x 0 ) as a matrix we obtain:
 0 0 0 0 
 0 0 1 1 
 0 1 0 1 
1 1 1 1 
This generator matrix can be multiplied on the left by a suitable set of vectors specifying which
members of the basis set are to be combined, via ⊕, to form any given codeword.
-3-

4. Construction of H3
The next stage along the way to H5 is to generate H3 by iterating the method of section 2 once
again, but now using the H2 basis set as the starting point. In this way we obtain :
x 1 = 00001111; x 2 = 00110011; x 3 = 01010101; x 4 = 11111111
and by noting that the 0 vector is x 0 = 00000000 on this occasion, we can once again construct all
combinations of x 1 . . . x 4 in order to generate the complete set of 16 codewords:

Codewords
 0–7 Codewords 7–16


00000000 01100110
00001111 11001100
00110011 10101010
01010101 01101001
11111111 11000011
00111100 10100101
01011010 10011001
11110000 10010110

There are no prizes for guessing that within these 16 codewords the C4 code (i.e. all the 4-bit
combinations) is embedded at bit positions 1, 2, 4, and 8.
A careful inspection of all 16 codewords reveals that this is an [8, 4, 4]-code. Therefore the num-
ber of correctable errors in any codeword will be ( d − 1 ) / 2  = 3 / 2  = 1.5  = 1. At this
stage in the Hn recursive build-up we have generated a code that is broadly similar in its capabili-
ties to those found in the [7, 4, 3] Hamming code.

5. Construction of H4
We now turn back to Section 2 once again and note that for H4 the new basis-set’s first vector
will consist of eight zeros followed by eight ones. Four other basis set vectors are obtained by
two-fold repetition of the 4 basis set vectors we used for H3 . Hence the basis set is:
0000000011111111; 0000111100001111; 0011001100110011; 0101010101010101; 1111111111111111
As ever we can supplement this basis set with a 0 vector consisting of 16 zeroes.
Exercise: Using the basis set just given, construct the full set of 32 codewords for H4 . Verify
that this forms a [16, 5, 8] linear code and that the C5 code is embedded at bit positions 1, 2, 4, 8,
and 16.
The Hamming code that is closest to H4 , in terms of codeword length, is [15, 11, 3] and this
shows us very clearly the nature of the tradeoff we are now making. H4 has 5 message bits i.e.
less than 50% of the 11 message bits the Hamming code allows. But in return H4 can correct
( d − 1 ) / 2  = 7 / 2  = 3.5  = 3. errors whereas Hamming codes can only correct 1 error.
We can now speculate that one further application of Section 2’s recursive algorithm will cer-
tainly result in fairly lengthy (32-bit) codewords but might possibly yield even more impressive
error-correction capabilities.

6. Final step: construction of H5


Exercise: Construct the basis set of 6 vectors for H5 by referring to Section 2 and making use of
the 5 basis-set vectors used for H4 . From the basis set generate the full list of 64 codewords either
"by hand" or by making use of the awk program given in Appendix 1.
-4-

The full set of 64 H5 codewords is:

Codewords 0–31 Codewords 32–63




00000000000000000000000000000000 10101010101010101010101010101010
00000000000000001111111111111111 10101010101010100101010101010101
00000000111111111111111100000000 10101010010101010101010110101010
00000000111111110000000011111111 10101010010101011010101001010101
00001111111100000000111111110000 10100101010110101010010101011010
00001111111100001111000000001111 10100101010110100101101010100101
00001111000011111111000011110000 10100101101001010101101001011010
00001111000011110000111100001111 10100101101001011010010110100101
00111100001111000011110000111100 10010110100101101001011010010110
00111100001111001100001111000011 10010110100101100110100101101001
00111100110000111100001100111100 10010110011010010110100110010110
00111100110000110011110011000011 10010110011010011001011001101001
00110011110011000011001111001100 10011001011001101001100101100110
00110011110011001100110000110011 10011001011001100110011010011001
00110011001100111100110011001100 10011001100110010110011001100110
00110011001100110011001100110011 10011001100110011001100110011001
01100110011001100110011001100110 11001100110011001100110011001100
01100110011001101001100110011001 11001100110011000011001100110011
01100110100110011001100101100110 11001100001100110011001111001100
01100110100110010110011010011001 11001100001100111100110000110011
01101001100101100110100110010110 11000011001111001100001100111100
01101001100101101001011001101001 11000011001111000011110011000011
01101001011010011001011010010110 11000011110000110011110000111100
01101001011010010110100101101001 11000011110000111100001111000011
01011010010110100101101001011010 11110000111100001111000011110000
01011010010110101010010110100101 11110000111100000000111100001111
01011010101001011010010101011010 11110000000011110000111111110000
01011010101001010101101010100101 11110000000011111111000000001111
01010101101010100101010110101010 11111111000000001111111100000000
01010101101010101010101001010101 11111111000000000000000011111111
01010101010101011010101010101010 11111111111111110000000000000000
01010101010101010101010101010101 11111111111111111111111111111111

Clearly H5 is an even parity [32, 6, 16]-code. Its six message bits (at positions 1, 2, 4, 8, 16 and
32) exactly allow for 64 grayscale shades. Moreover the codeword distance of 16 allows for up to
( 16 − 1 ) / 2  = 15 / 2  = 7.5  = 7 errors to be corrected.
Even as early as the mid-1960s Mariner 3 mission (which took photos during a Mars ’fly-by’) the
64-shade grayscale was in use. By the time Mariner 9 came along (1969–1972) it was possible to
put the spacecraft in orbit around Mars. Furthermore, better technology enabled an 18-bit scale
for each pixel. Even so these 18 bits were packaged up into three 6-bit sub-packages precisely so
that the Reed-Muller H5 6-message-bit code could still be used.

6.1. Decoding H5
It’s almost inevitable to discover that it’s far easier to invent a good code, that is robust against
various levels of noise, than it is to decode it when damaged codewords are received. Indeed
there is a general result to the effect that decoding, in the worst case, can be NP-complete i.e. you
-5-

just have to try all possibilities !


In very simple cases, such as the Hamming codes, decoding is very nearly as straightforward as
encoding because only single errors are involved. The H5 code is certainly linear and there are
some very generic ways for decoding linear codes. The drawback is that these generic methods
(often based on cosets ) can be very slow. It’s always better to try for a decoding method that is
tailored to the particularities of the encoding mechanism.
The Reed-Muller code was so named because the encoding mechanism was invented by David
Muller and the decoding mechanism (proposed by Irving Reed) involves majority logic decoding.
Embedded inside each codeword are the message bits and these bits will have an even or odd par-
ity overall. For example if the message is ‘42’ to denote the mid-gray scale of 42 (where 0 is pure
white and 63 is black) then 42 in binary is 101010 and the parity of this bit-pattern is odd. Its
weight or norm (i.e. the number of 1 bits) is 3. However, the parity of each H5 codeword is even.
Armed with this information it is possible to backtrack through the encoding algorithm, and
through all the extre information in the 26 parity check bits, to deduce what the message bits
must have been (provided that no more than 7 bits have been ‘flipped’). Finally we can multiply
the message bits we have obtained by the generator matrix to determine what the corrected trans-
mitted codeword must have been.
As message complexity increases, and even greater levels of noise immunity are demanded, there
is an increasing pressure for even faster decoding mechanisms such as Fast Fourier Transform.
Alternatively one can resort to probabilistic decoding schemes, which deliver an answer that is
‘almost certainly’ correct, rather than one that is fully deterministic.
In the awk program of Appendix I no attempt has been made to implement any form of parity-
based decoding. Quite apart from all other considerations awk scripts are not well suited to seri-
ous high-performance tasks. Instead, for testing and experimentation purposes, a very simple
‘brute force’ decoding is available, wherein some original codeword (or a corrupted version of it)
has its distance calculated from all other codewords in the list. The codeword with the smallest
distance from the test input is returned as the answer.
It’s instructive now to look back on the capabilities of Hn codes against their (approximate) Ham-
ming equivalents. The table below illustrates very clearly the tradeoff between message bits and
error-corection capabilities
Hadamard/Reed-Muller Codes Hamming Codes
H1 = [2, 2, 1] —
H2 = [4, 3, 2] [3, 1, 3]
H3 = [8, 4, 4] [7, 4, 3]
H4 = [16, 5, 8] [15, 11, 3]
H5 = [32, 6, 16] [31, 26, 3]
Looking back it is easy to see why the [32, 6, 16] Reed-Muller code was chosen by NASA and its
satellite communication sub-contractors — the Jet Propulsion Laboratory (JPL) based in
Pasadena, CA. Firstly the 32-bit overall length fitted nicely into the 32-bit word length of typical
‘mainframe’ computers of that era. Furthermore, investigations of the noise characteristics for the
portion of the radio spectrum used by Mariner 9 led communications engineers to expect that up
to 20-25% of the bits in a 32-bit message ( i.e. 7 bits, approx.) might well get corrupted during
transmission. Hence H5 ’s correction performance of up to 7 errors seemed well suited.
Although communications (and coding) technologies have improved by orders of magnitude
since the early 1970s — in exploration programs ranging from Viking to Curiosity Rover , making
possible the high-definition colour photographs we expect today — there is no doubt of Mariner
9’s pivotal importance in the history of Mars exploration.
-6-

7. Further reading
The list below gives some details of publications I have found useful. I have listed them in order
of the amount of mathematics you need in order to get to grips with what they are saying, with
the easiest listed first. All of them touch on Reed-Muller codes in one way or another, although
the SMP book gives the recursive algorithm without saying what the Hn codes are called !

SMP (1991)
Ron Haydock, Stan Dolan, and Andy Hall,
Information and Coding–The School Mathematics Project,
Cambridge University Press, 1991.
This book is one of the very few introductory texts that is accessible to those with only a High
School level of Mathematics. In places it uses its own non-standard notation (e.g "codenames"
rather than "codewords" and "basic set" rather than "basis set") so be careful. In addition it uses
the notation (n, k, d) to characterise a linear code, rather than [n, k, d]. This leads to confusion
with respect to earlier books (e.g. Welsh, Hill – see below) which both reserve round brackets for
denoting a (n, M, d)-code where M is the ‘number of messages’, as opposed to being ‘the number
of bits, (k) devoted to the message part’. Given that M is not constrained to being a power of two,
and can take on odd or even values, the (n, M, d) notation can represent non-linear codes.

Kun (2015)
Jeremy Kun, The Codes of Solomon, Reed and Muller,
https://jeremykun.com/2015/03/23/the-codes-of-solomon-reed-and-muller. March 2015
Jeremy Kun provides a very useful set of brief papers and primers on many topics, including
Coding Theory. The level of mathematics needed is about the same as that for Welsh’s book.

Welsh (1988)
Dominic Welsh, Codes and Cryptography, Oxford University Press, 1988.
Chapter 4 is especially useful. If you have had at least some exposure to University-level linear
algebra (including vector spaces and matrices) then you should be able to cope.

Hill (1983)
Raymond Hill, A First Course in Coding Theory, Oxford University Press, 1986.
Another approachable book, written at an elementary level for pure mathematicians. Computer
Scientists should be able to cope provided they have had some experience of linear algebra and
vector spaces.

Mackay (2003)
David J. C. Mackay, Information Theory Inference and Learning Algorithms,
Cambridge University Press, 2003.
(see also http://www.inference.phy.cam.ac.uk/mackay/)
David Mackay was a most talented polymath, sadly taken away from us in 2015 as a result of
cancer. He had been a champion of the move, in recent years, to LDPC (Low Density Parity
Codes) This book is at a 2nd/3rd year University-level text for keen engineers, mathematicians
and computer scientists

Reed (1954)
Irving Reed, A class of multiple-error-correcting codes and the decoding scheme,
Transactions of the IRE Professional Group on Information Theory, vol. 4, p. 38–49, 1954.
A surprisingly approachable paper, from a renowned coding theorist, setting out the earliest gen-
eral approach to majority-logic coding in the context of what we now call Reed-Muller codes.
-7-

Appendix I. This is an awk script for generating and testing the H5 code

# This is a simple AWK script to progressively develop H5


# - the Reed-Muller code used on the Mariner 9 mission
# Run this script via: awk -f testH5.awk | less
# after uncommenting the pieces you want to execute

BEGIN { print "Welcome to the H5 (Reed-Muller) test suite\n"; }

{
# basis vectors for H2
x0 = "0000"; x1 = "0011"; x2 = "0101"; x3 = "1111"
#basis vectors for H3
y0 = "00000000"; y1 = "00001111"; y3 = "00110011"; y2 = "01010101"; y4 = "11111111";
# basis vectors for H4
z0 = "0000000000000000"; z1 = "0000000011111111"; z2 = "0000111100001111";
z3 = "0011001100110011"; z4 = "0101010101010101"; z5 = "1111111111111111";
# Basis vectors for H5. Build these from concatenations of the z basis vectors for H4
w0 = conc(z0, z0); w1 = conc(z0,z5); w2 = conc(z1, z1); w3 = conc(z2, z2);
w4 = conc(z3,z3); w5 = conc(z4,z4); w6 = conc(z5,z5);
#
# H5 codewords will be built up in the array cw from all combinations of the above
# w[0-6]. Note that the 6 "message bits" in an H5 codeword (reading from the left
# and starting at 1) are at bit positions 1,2,4,8,16,32. The ordering of
# codewords in the cw array might seem arbitrary but it owes much to Pascal’s
# Triangle - which makes hand-checking easier - See assignments to "cw" below.
# The integer array "map". that now follows. points at elements in the cw array
# and reorders them so as to impose an ascending order of 6-bit message values
# i.e. increasing grayscale vals. Hence, map[0] leads to msg bits of "000000",
# map[31] to msg bits of "011111" and map[63] # delivers a msg of "111111" etc.
#
map[0] = 0; map[1] = 1; map[2] = 7; map[3] = 2; map[4] = 12; map[5] = 22; map[6] = 8;
map[7] = 3; map[8] = 16; map[9] = 26; map[10] = 42; map[11] = 32; map[12] =13;
map[13] = 23; map[14] = 9; map[15] = 4; map[16] = 19; map[17] = 29; map[18] = 45;
map[19] = 35; map[20] = 52; map[21] = 57; map[22] = 48; map[23] = 38; map[24] = 17;
map[25] = 27; map[26] = 43; map[27] = 33; map[28] = 14; map[29] = 24; map[30] = 10;
map[31] = 5; map[32] = 21; map[33] = 31; map[34] = 47; map[35] = 37; map[36] = 54;
map[37] = 59; map[38] = 50; map[39] = 40; map[40] = 56; map[41] = 61; map[42] = 63;
map[43] = 62; map[44] = 55; map[45] = 60; map[46] = 51; map[47] = 41; map[48] = 20;
map[49] = 30; map[50] = 46; map[51] = 36; map[52] = 53; map[53] = 58; map[54] = 49;
map[55] = 39; map[56] = 18; map[57] = 28; map[58] = 44; map[59] = 34; map[60] = 15;
map[61] = 25; map[62] = 11; map[63] = 6;
#
#Building up the H5 (Reed-Muller) codewords
#
#Single vectors that form the basis set
cw[0] = w0; cw[1] = w1; cw[2] = w2; cw[3] = w3; cw[4] = w4; cw[5] = w5; cw[6] = w6;
# combinatios of two basis vectors
cw[7] = rowxor(w1, w2)
cw[8] = rowxor(w1, w3)
cw[9] = rowxor(w1, w4)
cw[10] = rowxor(w1, w5)
cw[11] = rowxor(w1, w6)
cw[12] = rowxor(w2, w3)
cw[13] = rowxor(w2, w4)
cw[14] = rowxor(w2, w5)
cw[15] = rowxor(w2, w6)
cw[16] = rowxor(w3, w4)
cw[17] = rowxor(w3, w5)
cw[18] = rowxor(w3, w6)
cw[19] = rowxor(w4, w5)
cw[20] = rowxor(w4, w6)
cw[21] = rowxor(w5, w6)
# combs of 3 basis vectors
cw[22] = rowxor(cw[7], w3) # triples starting 12
-8-

cw[23] = rowxor(cw[7], w4)


cw[24] = rowxor(cw[7], w5)
cw[25] = rowxor(cw[7], w6)
cw[26] = rowxor(cw[8], w4)# triples starting 13
cw[27] = rowxor(cw[8], w5)
cw[28] = rowxor(cw[8], w6)
cw[29] = rowxor(cw[9], w5)# triples starting 14
cw[30] = rowxor(cw[9], w6)
cw[31] = rowxor(cw[10], w6)# 156
cw[32] = rowxor(cw[12], w4) # triples starting 23
cw[33] = rowxor(cw[12], w5)
cw[34] = rowxor(cw[12], w6)
cw[35] = rowxor(cw[13], w5) # triples starting 24
cw[36] = rowxor(cw[13], w6)
cw[37] = rowxor(cw[14], w6) # triples starting 25
cw[38] = rowxor(cw[16], w5) # triples starting 34
cw[39] = rowxor(cw[16], w6)
cw[40] = rowxor(cw[17], w6) #356
cw[41] = rowxor(cw[19], w6) #456
# combs of 4 basis vectors
cw[42] = rowxor(cw[22], w4)# quads starting 123
cw[43] = rowxor(cw[22], w5)
cw[44] = rowxor(cw[22], w6)
cw[45] = rowxor(cw[23], w5)# quads starting 124
cw[46] = rowxor(cw[23], w6)
cw[47] = rowxor(cw[24], w6)# 1256
cw[48] = rowxor(cw[26], w5) # quads starting 134
cw[49] = rowxor(cw[26], w6)
cw[50] = rowxor(cw[27], w6) #1356
cw[51] = rowxor(cw[29], w6) # 1456
cw[52] = rowxor(cw[32], w5) # quads starting 234
cw[53] = rowxor(cw[32], w6) #
cw[54] = rowxor(cw[33], w6) # 2356
cw[55] = rowxor(cw[35], w6) # 2456
cw[56] = rowxor(cw[38], w6) # 3456
# quintets and the final sextet
cw[57] = rowxor(cw[42], w5) # 12345
cw[58] = rowxor(cw[42], w6) # 12346
cw[59] = rowxor(cw[43], w6) # 12356
cw[60] = rowxor(cw[45], w6) # 12456
cw[61] = rowxor(cw[48], w6) # 13456
cw[62] = rowxor(cw[52], w6) # 23456
cw[63] = rowxor(cw[57], w6) #123456
#
# print out codewords in "Pascal Triangle" order
#for (k = 0; k <= 63; k++) print cw[k];
#
print ("\nHere are the H5 codewords in ascending order of message bit values \n\n");
for (j = 0; j <= 63; j++) print cw[map[j]];
# And here’s a test printout to verify that message-bit values are OK and range from
# 0-63
for (j = 0; j <= 63; j++) print msgval(cw[map[j]]);
#
# Declare a few test messages
test63 = "11111111111111111111111111111111"
test15 = "00110011001100110011001100110011" #roughly at pos15
test48 = "11001100110011001100110011001100" # roughly at 48 no damage
newtest48 = "10001100100111001100000011000100" # roughly at 48 but 5 bits damaged
test0 = "00000000000000000000000000000000" #zero vector undamaged
newtest0 = "00100001000110000001000010000001" #zero vector but damaged in 7 places
random = "10111001010001101000110001010100" # random string of 0s and 1s
# for (m = 0; m <= 63; m++) {
# print " m =" m " # dist = " norm(rowxor(cw[map[m]], newtest48))
}
x = codematch(test15, 0);
-9-

x = codematch(newtest48, 0);
x = codematch(random, 1);
# Test print of the codeword norms
#print ("\n here are the norms in order\n\n");
#for (k = 0; k <= 63; k++) print norm(cw[map[k]]);

exit

} #end of H5 program

# Various utility functions

function conc (m, n) { return m n }

# the function below is not needed on Linux awk - where xor seems to be built in
#
#function xor (a, b){
# primitive xor on single char zeroes and ones
#if ((a=="0" && b == "0) || (a == 1 && b == 1))
#return "0"
#else return "1"
#}

function rowxor (a, b) {


# bitwise xor on bit-strings
# a, b must be bitsrings of the same, non-zero, length
s = ""; len1=length(a); len2 = length(b);
if (len1 != len2) { print "string lengths unequal\n"; exit }
nbits = split(a, arr1, ""); split(b, arr2, "");
for(i = 1; i <= len1; i++) {res[i] = xor(arr1[i],arr2[i]); s = s res[i] }
return s
}

function norm (a) {


# counts number of 1s in a bit-string
nbits = split(a, arr, ""); cnt = 0;
for (j = 0; j<=nbits; j++) if (arr[j] == 1) cnt++;
return cnt
}

function msgval (m) {


# weighted addition of bit vals at posns 1,2,4,8,16,32
# to give a message/grayscale value in range 0-63
split(m, arm, "");
return (32*arm[1] + 16*arm[2] + 8*arm[4] + 4* arm[8] + 2*arm[16] + arm[32])
}

function codematch (testcode, flag) {


# finds the Hamming distance of testcode from each of the codewords in H5
# referenced via the map array. Returns position of best match i.e. smallest distance
# if "flag" is set to 0 then default behaviour is to report map position with
# smallest distance. A flag value of 1 is for diagnostic printout of all distances.
pos = 0; bestdist = 32;
for (d = 0; d <= 63; d++) {
dist = norm(rowxor(cw[map[d]], testcode));
if (dist < bestdist) {bestdist = dist; pos = d; }
{ if (flag == 1) print "grayscale = " d " dist = " dist
}
}
print "Input vector is " testcode " \nBest match is " cw[map[pos]] "
at posn/grayscale = " pos " , dist = " bestdist
return bestdist
}

END { print "\nEnd of run \n"}

You might also like