Tutorial
Upcoming SlideShare
Loading in...5
×
 

Tutorial

on

  • 389 views

 

Statistics

Views

Total Views
389
Views on SlideShare
389
Embed Views
0

Actions

Likes
0
Downloads
1
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Tutorial Tutorial Document Transcript

  • Alguns c´digos lineares com o µ–pad o Notas de apoio para Teoria de C´digos o Pedro Patr´ ∗ ıcio Maio de 2006Conte´ do u1 Documenta¸˜o ca 22 Aquecendo os motores 23 Um pouco de aritm´tica (a tabuada revisitada) e 44 Matrizes e afins 55 Procedimentos 76 Polin´mios o 137 C´digos de Hamming o 168 C´digos lineares o 209 BCH 22 Referˆncias bibliogr´ficas e a 28 ∗ Departamento de Matem´tica da Universidade do Minho; pedro@math.uminho.pt a 1
  • 1 Documenta¸˜o caO MuPAD est´ dispon´ em a ıvel http://www.mupad.depara download. As vers˜es com licen¸a para estudante (gratuita) s˜o a 2.5.x para Windows (light) o c ae 3.x para Linux. Uma licen¸a de estudante pode ser pedida aqui: c https://www.mupad.org/muptan/muptan.php Espera-se que de forma tempor´ria, estas licen¸as n˜o est˜o actualmente a ser distribuidas. a c a aAconselha-se vivamente a visita e leitura de http://fuchssteiner.info/ No site do MuPAD tamb´m pode encontrar alguma documenta¸˜o. Por exemplo, a referente e ca` vers˜o 3.1 pode ser consultada aqui:a a http://research.mupad.de/doc/31/eng/index.html Por exemplo, se pretender saber como construir um corpo de Galois e manipular os seuselementos, pode usar a documenta¸˜o online dispon´ em ca ıvel http://research.mupad.de/doc/31/eng/Dom GaloisF.html O mesmo pode ser feito em rela¸˜o ` vers˜o 2.5: ca a a http://research.mupad.de/doc/25/eng/index.shtml Na p´gina da disciplina, pode tamb´m encontrar um guia muito r´pido, da autoria de W. a e aOevel e J. Gerhard. Pode ainda usar os mirrors e respectiva documenta¸˜o disponibilizados pelo Departamento de caInform´tica da Universidade do Minho a http://ftp.di.uminho.pt/pub/apps/math/MuPAD/2 Aquecendo os motoresAo inv´s do que sucede em linguagem matem´tica (pelo menos na sua forma mais vulgar), tanto e ano mupad como noutras ferramentas computacionais urge distinguir de uma forma clara o s´ımboloque atribui um valor a uma vari´vel do que inquirir sobre a igualdade entre duas express˜es. O a oprimeiro, que mais nos interessa neste momento, ´ escrito como :=. e>> x:=3; 3Se se pretender que o valor de x n˜o seja exibido, basta terminar a instru¸˜o com : em vez de ; a ca>> x:=3:>> O valor de x pode ser mostrado digitando-o:>> x; 3 2
  • Para deixar x sem m´cula, apague-se a atribui¸˜o: a ca>> delete(x);>> x x Uma fun¸˜o ´ definida do modo seguinte: ca e>> f:=x->x^8-1; x -> x^8 - 1 Torna-se simples calcular a imagem de 2 por f :>> f(2); 255 Em alternativa,>> evalp(f(x),x=2); 255 Atente agora nas diferen¸as: c>> f; x -> x^8 - 1 >> f(x); x8 - 1 Os zeros de f s˜o calculados usando a>> solve(f(x)); Caso alguma d´vida surja ao utilizador, pode usar a ajuda imersa no mupad: u>> ?solve A factoriza¸˜o de polin´mios: ca o>> factor(f(x)); (x - 1) (x + 1) (x2 + 1) (x4 + 1) O mupad tamb´m indica o n´mero de factores: e u>> nops(factor(f(x)))Surpreendido? O factor i ´ indicado usando factor(f(x))[i]. Fa¸a ent˜o um ciclo for de forma e c aa serem apresentados todos os factores (use print, em, a t´ ıtulo de exemplo, print("factor",i,"e’ ",factor(f(x))[i])). De referir que os comandos do mupad s˜o case sensitive. Por exemplo, a>> FaCtOr(f(x)); 3 View slide
  • FaCtOr(x8 - 1) ´ E claro que o polin´mio f n˜o ´ irredut´ j´ que tem factores, na sua decomposi¸˜o, que s˜o o a e ıvel a ca an˜o constantes (e n˜o nulos, diga-se de passagem, embora tal seja ´bvio). a a o>> irreducible(f(x)); FALSE3 Um pouco de aritm´tica (a tabuada revisitada) eAssuma que se pretende testar o c´digo ISBN de um livro recebido. Antes de mais, o c´digo o oISBN-10 (investigue o que se passa com o ISBN-13) ´ uma sequˆncia de 10 s´ e e ımbolos x1 x2 . . . x9 x10onde xi = 0..9, se i = 1..9, e x10 ∈ {0..9} ∪ {X}. E ´ indiferente a coloca¸˜o dos h´ ca ıfenes: estesservem apenas para separar a codifica¸˜o de certo tipo de informa¸˜o – pa´ ou l´ ca ca ıs ıngua de edi¸˜o,can´mero da editora, n´mero do livro. O s´ u u ımbolo x10 ´ de facto o respons´vel pela detec¸˜o de erros e a ca– o s´ ımbolo de verifica¸˜o. Tomando X = 10 no que se segue, estes tˆm que satisfazer ca e 10 (11 − i)xi ≡ 0 mod 11. i=1Ou doutra forma, (x1 , x2 , . . . , x10 ) · (10, 9, 8, 7, 6, 5, 4, 3, 2, 1) ≡ 0 mod 11. Por exemplo, e para simplificar, assuma recebido o suposto c´digo 989-616072-4 (de que livro? opelo menos a l´ ıngua deve tentar saber; http://www.isbn-international.org/en/identifiers/allidentifiers.html),dado como uma tabela:>> cod:=table(1=9,2=8,3=9,4=6,5=1,6=6,7=0,8=7,9=2,10=4)Fa¸a ?table para entender a sintaxe. Se preferir, pode usar o comando array: c>> cod:=array(1..10,[9,8,9,6,1,6,0,7,2,4]);Podemos definir Z11 como>> Z11:=Dom::IntegerMod(11); 10Falta-nos agora verificar se o somat´rio ´ multiplo de 11, ou seja, se i=1 ixi ≡ 0 mod 11. Antes o e´ preciso calcular a soma:e>> sum((11-i)*cod[i],i=1..10)Repare que cod[i] indica o elemento i da tabela cod. Falta agora estudar a congruˆncia mod 11 e>> sum((11-i)*cod[i],i=1..10) mod 11ou>> Z11(sum((11-i)*cod[i],i=1..10)) Se n˜o tiv´ssemos ` disposi¸˜o o comando sum ou um similar, ent˜o ter-se-ia optado, por a e a ca aexemplo, por um ciclo for. Veja a sintaxe com ?for.>> soma:=0:>> for i from 1 downto 10 dosoma:=soma+(11-i)*cod[i]end for:>> print(Z11(soma)); As mudan¸as de linha s˜o feitas por shift+return, se estiver a usar o x-mupad em linux, ou c ao mupad no Windows. 4 View slide
  • ´ E escusado referir a importˆncia que ciclos como afor i from inicio to fim <step tamanhodosalto> do .. end forrepeat .. until condi¸~o end repeat cawhile condi¸~o do .. end while caou instru¸˜es de decis˜o como co aif condi¸~o cathen ..<elif condi¸~o then ..> ca<elif condi¸~o then ..> ca<...><else ..>end iftˆm importˆncia quase vital na constru¸˜o de c´digos. e a ca o4 Matrizes e afinsO comando matrix cria uma matriz de ordem pr´-definida. A sua sintaxe ´ a seguinte: e e matrix(m, n, [[a11, a12, ...], [a21, a22, ...], ...]) O vectores coluna e linha s˜o definidos atribuindo, respectivamente, os valores n = 1 e m = 1. a>> A:=matrix(2,2,[[1,2],[2,4]]); De facto, pode-se abdicar da informa¸˜o 2,2 j´ que a matriz tem as entradas definidas expli- ca acitamente:>> A:=matrix([[1,2],[2,4]]); ´ E relevante aqui referir-se a livraria linalg de ferramentes de apoio ` ´lgebra linear. Por a aexemplo, permite-nos obter a factoriza¸˜o LU de A: ca>> linalg::factorLU(A); Os v´rios comandos desta livraria est˜o assim dispon´ a a ıveis:>> ?linalg Sendo tedioso a escrita repetitiva de linalg::comando, pode-se optar por exportar a livrariaem bloco>> export(linalg);ficando assim todos os comandos dispon´ ıveis de uma forma mais expedita.>> nullspace(A); Certamente que o leitor pˆde prever o resultado ao rever a factoriza¸˜o LU obtida mais acima. o ca´ desnecess´rio o c´lculo do determinante, mas se for incr´dulo tenteE a a e 5
  • >> det(A); Atente que a livraria foi exportada para o kernel, caso contr´rio teria que digitar a>> linalg::det(A); As entradas da matriz s˜o acedidas assim: a>> A[1,2]; 2 Considere agora os vectores-linha>> a:=matrix([1,0,3,4]);>> b:=matrix([1,2,3,4]); Vamos criar um “array” c que apenas tem como prop´sito armazenar informa¸˜o: o ca>> c:=array(1..4);Como resposta, o utilizador ´ informado que as entradas n˜o est˜o especificadas. Nada de util se e a a ´processa no ciclo seguinte:>> i:=0:while i<4 do i:=i+1: c[i]:=a[i]*b[i]:end while:eval(c); O comando eval tem como objectivo mostrar o conte´do de c. As mudan¸as de linha s˜o u c afeitas por shift+return, se estiver a usar o x-mupad em linux, ou o mupad no Windows. Em vezde um ciclo while poder-se-ia ter optando por um for:>> for i from 1 to 4 do c[i]:=a[i]*b[i]:end for:eval(c); Dom::Matrix(R) cria o dom´ ınio das matrizes cujas componentes est˜o em R. Por exemplo, a>> MatZ2:=Dom::Matrix(Dom::IntegerMod(2));cria o dom´ ´ o ınio (ou categoria) das matrizes sobre Z2 , que denomin´mos por MatZ2. E ´bvio que aa denomina¸˜o fica ao crit´rio do utilizador. N˜o se esque¸a de alguns pontos-chave, como a ca e a cclareza (se come¸ar a denominar os dom´ c ınios de forma aleat´ria, ser´ uma veradeira confus˜o o a aencontrar, posteriormente, o que pretende), nem usar termos propriet´rios do mupad (uma forma ade contornar este problema ´ usar algumas letras mai´sculas – recorde que ´ case-sensitive). e u e 1 0 1 0 1 Por exemplo, suponha que pretende definir a matriz A = enquanto matriz 0 1 0 1 1sobre Z2 . Nada mais simples:>> G:=MatZ2([[1,0,1,0,1],[0,1,0,1,1]]); Suponha agora que pretende calcular o espa¸o nulo, nG, desta matriz, e respectiva dimens˜o: c a>> nG:=linalg::nullspace(G); 6
  • >> nops(nG)O vector i dessa base pode ser chamado usando nG[i]. Uma instru¸˜o de grande utilidade ´ a de concatena¸˜o de matrizes, quer seja a de linhas ou ca e caa de colunas. Suponhamos que se prentende definir uma nova matriz A = I2 G .>> I2:=matrix::identity(2);>> I2:=coerce(I2,MatZ2);A segunda instru¸˜o tem como prop´sito transformar a matriz identidade 2 × 2, por defeito real, ca onuma sobre Z2 . Fa¸amos agora a concatena¸˜o horizontalmente: c ca>> A:=linalg::concatMatrix(I2,G); Se se pretendesse concatenar verticalmente, far-se-ia uso de linalg::stackMatrix. Explore aajuda sempre que necess´rio! a5 ProcedimentosUm procedimento ´ uma jun¸˜o de instru¸˜es que, associadas, produzem uma tarefa, e que, estando e ca coagrupadas sob uma denomina¸˜o, est˜o sujeitas a serem usadas por outras sob essa denomina¸˜o. ca a caUm exemplo:>> meumin := proc(x : Type::Real, y : Type::Real) begin if x < y then return(x); end if; y; end proc: Em certos casos, ´ necess´rio a utiliza¸˜o de outras vari´veis apenas a ser utililizadas no e a ca aprocedimento. Neste caso, ´ usado o comando local antes de begin. A instru¸˜o return e cadevolve o valor obtido no procedimento. Eis a sintaxe:>>proc(x1 <= default1> <: type1>,x2 <= default2> <: type2>, ...) <: returntype><name pname;><option option1, option2, ...;><local local1, local2, ...;><save global1, global2, ...;>beginbodyend proc Tendo criado um conjunto relevante de procedimentos, torna-se imperioso a existˆncia de uma eferramenta que permita ler os procedimentos em sess˜es futuras. Ou seja, ´ provavelmente uma o eboa ideia criar ficheiros com procedimentos que executem certas tarefas para depois, numa sess˜o ade trabalho, esse procedimento ser invocado de uma forma expedita sem que tenha que ser de novo 7
  • introduzido pelo utilizador. No caso do procedimento meumax apresentado atr´s, o autor destas alinhas procedeu da forma seguinte: (i) a sess˜o contendo apenas o procedimento foi gravada em a /home/pedro/Aulas/2004-2005/Codigos/meumax.mupad (ii) aberta uma nova sess˜o, o procedimento meumax foi carregado usando a >> read("/home/pedro/Aulas/2004-2005/Codigos/meumax.mupad") Apresentamos, de seguida, dois conjuntos de procedimentos que implementam os c´digos ISBN oe EAN-13. • ISBN COMO INSTALAR Copie, para uma directoria, os ficheiros verISBN.txt menu.txt testaisbn.txt constroiisbn.txt No MUPAD, indique o caminho para essa directoria, usando READPATH:="directoria" Por exemplo, estando os ficheiros em d:userspedroMy Documents usou-se begin{verbatim}READPATH:="d:userspedroMy Documents" Ainda no MuPAD, fa¸a c read("verISBN.txt") Optimizado para Mupad, em linux, num terminal. Testado no XMUPAD pro em linux e no MuPADlight, em Windows. verISBN.txt /* ************************************* */ /* verISBN v0.01 beta1 */ /*****************************************/ /* copyleft, pedro patricio, 2006 */ /*****************************************/ read("menu.txt"): 8
  • menu.txt/* ************************************* *//* M E N U das opcoes *//*****************************************/prima:=0:read("testaisbn.txt"):read("constroiisbn.txt"):repeat input("Prima 1 para testar o ISBN-10; 2 para calcular o digito de controlo; 3 sair " , prima):if prima=1 theninput("Indique o ISBN da forma [a,b,c,...] ",isbn):testaisbn(isbn)end_if:if prima=2 theninput("Indique o ISBN da forma [a,b,c,...] ",isbn):constroiisbn(isbn)end_if /*menu das opcoes */until prima=3 end_repeat:Seguem-se os procedimentos propriamente ditos.constroiisbn.txt/* ************************************* *//* Procedim que constroi o dig controlo*//*****************************************/constroiisbn:=proc(isbn)local i, teste, checksum;beginisbnArray:=array(1..9,isbn);teste:=0;for i from 9 downto 1 doteste:=teste+(11-i)*isbnArray[i]end_for:checksum:=-teste mod 11: /* checksum e’ o digito de controlo */if checksum=10 then /* caso em que o caracter e’ X=10 */ 9
  • print("O digito de controlo e’ X") else print(" O digito de controlo e’ ",checksum): end_if: end_proc: testaisbn.txt /* ************************************* */ /* Procedimento que testa o ISBN-10 */ /*****************************************/ testaisbn:=proc(isbn) local i, isbnArray, teste; begin isbnArray:=array(1..10,isbn); /* criar o array com o isbn */ if (isbnArray[10]=X or isbnArray[10]=x) then isbnArray[10]:=10 end_if: /* o caso em que o controlo e’ X=10 */ teste:=0; for i from 10 downto 1 do teste:=teste+(11-i)*isbnArray[i] end_for: if (teste mod 11 = 0) then print("O ISBN esta’ correcto") else print(" O ISBN esta’ incorrecto"): end_if: end_proc:• EAN-13 Aqui esta’ um exemplo de um conjunto de procedimentos que testam e controem o digito de controlo de um codigo EAN-13 verEAN v0.01 beta1 COMO INSTALAR Copie, para uma directoria, os ficheiros verEAN.txt menu.txt testaean.txt 10
  • constroiean.txtNo MUPAD, indique o caminho para essa directoria, usandoREADPATH:="directoria"::LINUX::Por exemplo, estando os ficheiros em/home/pedro/Desktopusou-se READPATH:=”/home/pedro/Desktop”::WINDOWS:: Por exemplo, estando os ficheiros emd:userspedroMy Documentsusou-seREADPATH:="d:userspedroMy Documents"Ainda no MuPAD, fa¸a cread("verEAN.txt")Optimizado para Mupad, em linux, num terminal. Testado no XMUPAD pro em linux, e noMUPAD-light em windows.verEAN.txt/* ************************************* *//* verEAN v0.01 beta1 *//*****************************************//* copyleft, pedro patricio, 2006 *//*****************************************/read("menu.txt"):menu.txt/* ************************************* *//* M E N U das opcoes *//*****************************************/prima:=0: 11
  • read("testaean.txt"):read("constroiean.txt"): /* leitura dos sub-procedimentos */repeatinput("Prima 1 para testar o EAN-13; 2 para calcular o digito de controlo; 3 sair :" , prima):if prima=1 theninput("Indique o EAN da forma [a,b,c,...] ",ean): /*entrada do ean pelo utilizador */testaean(ean)end_if:if prima=2 theninput("Indique o EAN da forma [a,b,c,...] ",ean): /*entrada do ean pelo utilizador */constroiean(ean)end_if /*menu das opcoes */until prima=3 end_repeat:constroiean.txt/* ************************************* *//* Procedim que constroi o dig controlo*//*****************************************/constroiean:=proc(ean)local i, isbn, testePAR, testeIM, checksum, eanArray;begineanArray:=array(1..12,ean); testeIM:=0; for i from 1 to 6 do testeIM:=testeIM+eanArray[2*i-1] end_for: testePAR:=0; for i from 1 to 6 do testePAR:=testePAR+3*eanArray[2*i] end_for: checksum:=-(testeIM+testePAR) mod 10: print(" O digito de controlo e’ ",checksum):end_proc:testaean.txt/* ************************************* */ 12
  • /* Procedimento que testa o EAN-13 */ /*****************************************/ testaean:=proc(ean) local i, testeIM, testePAR, teste, eanArray; begin eanArray:=array(1..13,ean); /* criar o array com o ean */ testeIM:=0; for i from 1 to 7 do testeIM:=testeIM+eanArray[2*i-1] end_for: testePAR:=0; for i from 1 to 6 do testePAR:=testePAR+3*eanArray[2*i] end_for: teste:=testeIM+testePAR: if (teste mod 10 = 0) then print("O EAN esta’ correcto") else print(" O EAN esta’ incorrecto"): end_if: end_proc: Como exerc´ ıcio, construa um procedimento hamming:=proc(numero:Type::PosInt)onde n ´ um argumento de entrada, n´mero inteiro positivo, e cujo resultado final ´ uma matriz e u e nn × (2 − 1), cuja coluna j ´ a representa¸˜o do n´mero natural j na sua escrita bin´ria. A matriz e ca u aresultante chama-se matriz de Hamming. Por exemplo,>> hamming(3);   0 0 0 1 1 1 1    0 1 1 0 0 1 1  1 0 1 0 1 0 1 Para tal, use a instru¸˜o mod que a um par de naturais faz corresponder o resto da divis˜o ca ainteira do primeiro pelo segundo. Caso ache conveniente, pode dividir o problema em dois, em que um consiste em transformara escrita decimal de um natural na sua representa¸˜o bin´ria, e o outro constr´i a matriz. ca a o6 Polin´mios oAntes de mais, fa¸amos um reset do kernel: c>> reset(); 13
  • O conjunto (mais do que isso, o anel) dos polin´mios com tantas vari´veis quantas se queira ´ o a edenotado por Dom::Polynomial. Dom::Polynomial(R, ..) cria o dom´ ınio dos polin´mios com coeficientes no anel comutativo oR, podendo a representa¸˜o ser exibida de uma forma pr´-definida. ca e Sintaxe:Dom::Polynomial( <R <, Order>>)Order pode tomar o valor LexOrder, DegreeOrder, ou DegInvLexOrder ou um elemento deDom::MonomOrdering. Default: LexOrder. Por exemplo, suponha o leitor que se quer estudar polin´mios com uma vari´vel, em que o aos coeficientes s˜o elementos de Z3 . Ou seja, o anel sob estudo ´ Z3 [x]. Mais concretamente, a epretende-se estudar o polin´mio dado por o f (x) = x2 + x + 2.Defina-se, no µ–pad, o dom´ınio Z3 [x]. Usaremos a sigla Polin3 para representar essa entidade:>> Polin3:=Dom::Polynomial(Dom::IntegerMod(3)); Para mais informa¸˜es, digite co>> ?Dom::Polynomial Para definir f , nada mais f´cil: a>> f:=Polin3(x^2+x+5); (1 mod 3) x2 + (1 mod 3) x + (2 mod 3) O polin´mio ´ irredut´ o e ıvel:>> irreducible(f); TRUE Para se calcular f (1),>> evalp(f,x=1); 1 mod 3 Temos, ent˜o, um polin´mio irredut´ a o ıvel, e portanto, Z3 [x]/(f (x)) ´ um corpo, no caso um ecorpo de Galois. Ser´ um corpo gerado pelo polin´mio x? Uma forma expedita de se verificar se a of (x) ´ primitivo ´ escrever os elementos de Z3 [x]/(f (x)) enquanto potˆncias de x. Por exemplo, e e ex3 mod f (x) ´ calculado da forma seguinte: e>> powermod(x,3,f); 2 x + 2 Para verificarmos se f (x) ´ primitivo, ou de forma equivalente, se o corpo Z3 [x]/(f (x)) ´ gerado e epor x, basta percorrer as potˆncias de x e verificar se todas, at´ certo expoente, s˜o diferentes de e e a1. Pode ser ainda de interesse apresentar todas as potˆncias modulo f (x) para c´lculos futuros: e a>> for i from 1 to 8 dot:=powermod(x,i,f);print(x^i,"elemento do corpo:",t);end for O resultado ´: e 14
  • x, "elemento do corpo:", x 2 x , "elemento do corpo:", 2 x + 1 x3 , "elemento do corpo:", 2 x + 2 x4 , "elemento do corpo:", 2 x5 , "elemento do corpo:", 2 x 6 x , "elemento do corpo:", x + 2 x7 , "elemento do corpo:", x + 1 x8 , "elemento do corpo:", 1 Poder´ ser conveniente (e certamente sˆ-lo-´) criar um procedimento que tem como entrada a e aum polin´mio (para simplificar, em Z2 [x]) primitivo p(x) e como sa´ uma tabela com a cor- o ıdarespondˆncia entre as potˆncias de x (polin´mio gerador do grupo c´ e e o ıclico) e os polin´mios de oZ2 /(p(x)). Antes de passarmos ` resolu¸˜o do problema, e portanto constru¸˜o do procedimento), a ca cavejamos qual o metodologia a ser usada na implementa¸˜o. At´ agora, tem-se usado o MuPad ca en˜o s´ como interpretador, mas tamb´m como editor (colocado ponto de vista de uma forma a o esimplista). Faremos neste caso uso de um editor de texto externo, ficando o MuPad com a fun¸˜oca 1de interpretador. Num editor de texto, crie um ficheiro, por exemplo, TabPrim.txt . Comente asinstru¸˜es de forma a que mais tarde seja f´cil a si ou outrem entender o caminho que vai sendo co atra¸ado. cTabPrim:=proc(f) local grau,tabela, i; begin grau:=degree(f): tabela:=array(1..2^grau-1): for i from 1 to 2^grau-1 do tabela[i]:=powermod(x,i,f) end_for: return(tabela): end_proc: Agora, e j´ no MuPad, o procedimento construido externamente ´ carregado com a e>> read("TabPrim.txt")Tenha aten¸˜o ao caminho (vulgo PATH) onde o seu ficheiro est´. Temos ent˜o um procedimento ca a ano kernel do sistema que, dado um polin´mio irredut´ o ıvel, constr´i uma tabela das potˆncias: o e>> Polin2:=Dom::Polynomial(Dom::IntegerMod(2)) ´ o 1 E ´bvio que lhe pode chamar o que quiser. A extens˜o .txt pode parecer despropositada, mas pode servir de aalguma ajuda em alguns SO’s no reconhecimento do tipo de ficheiro. 15
  • Dom::Polynomial(Dom::IntegerMod(2), LexOrder)>> f:=Polin2(x^4+x+1); 4 (1 mod 2) x + (1 mod 2) x + (1 mod 2)>> TabPrim(f); Se se quiser saber como se escreve x10 basta fazer>> TabPrim(f)[10] 2 x + x + 1 Mais adiante, ser´ crucial encontrar raizes de polin´mios cujos coeficientes est˜o num certo a o acorpo de Galois. Consulte Dom::GaloisField no MuPad. Considere π(x) = x4 + x + 1 ∈ Z2 [x]. Este polin´mio ´ primitivo, pelo que F = Z2 [x]/(π(x)) ´ o e eum corpo e F∗ = x Pretende-se saber que elementos de F anulam m(x) = x2 + x + 1 ∈ Z2 [x].>> // Criar um corpo de Galois usando Dom::GaloisField>> p:=a^4+a+1: // polinomio primitivo p>> F:=Dom::GaloisField(2,4,p): // corpo de Galois criado!>> PolF:=Dom::Polynomial(F); // anel dos polinomios dobre F>> m:=PolF(x^2+x+1) // o polinomio m sobre Z2: calcula-se as raizes sobre F>> solve(m=0,x); // as raizes de m>> F(a^5); A ultima instru¸˜o revela que a5 ´ uma das ra´ ´ ca e ızes. Como se escreve a outra raiz como potˆncia ede a?7 C´digos de Hamming oOs c´digos de Hamming ser˜o os primeiros com direito a implementa¸˜o. No esquema de correc¸˜o o a ca cade rros, ser´ necess´rio escrever um n´mero apresentado no sistema bin´rio no decimal. De facto, a a u ao n´mero ser´ dado ` custa de um vector (coluna) sobre Z2 . Por exemplo, o vector [1, 0, 1, 1]T u a aindica o n´mero (1011)2 . Pretende-se encontrar a representa¸˜o decimal. Para tal, recordamos u cacomo se faz tal correspondˆncia: a representa¸˜o decimal de (v1 v2 · · · vk )2 ´ e ca e k vi 2k−i . i=1No exemplo anterior, temos 1 · 23 + 0 · 22 + 1 · 21 + 1 · 20 , que no caso ´ 11. Este algoritmo ´ e efacilmente implementado. No entanto, o vector v fornecido pode ser elemento de Z2 .>> Z2:=Dom::IntegerMod(2): 16
  • >> M2:=Dom::Matrix(Z2):>> delete(i):>> v:=M2([1,0,1,1]):>> sum(v[i]*2^(4-i),i=1..4); 1 mod 2 Aqui surge um problema, j´ que o MUPAD efectua os c´lculos em Z2 . a a Para contornar esta quest˜o, transforma-se, ` medida do necess´rio, as entradas v[i] de v dado a a aem elementos de Z, fazendo uso de uma vari´vel auxiliar: a>> aux:=coerce(v[i],Dom::Integer); Assuma que usa um ciclo for. A cada passo do ciclo, a soma vai sendo calculada:>> soma:=soma+aux*2^(n-i); Ficamos, para este caso, com o ciclo seguinte:>> soma:=0 0>> for i from 1 to 4 do aux:=coerce(v[i],Dom::Integer); soma:=soma+aux*2^(4-i); end_for: print(soma); 11 Se estiver a construir um procedimento, n˜o se esque¸a de enviar o resultado para o programa a cprincipal:return(soma); Esta sec¸˜o tem como finalidade fornecer algumas ideias para a implementa¸˜o de um c´digo ca ca ode Hamming. Recorde que a correc¸˜o de erros de r ´ feita ` custa do s´ ca e a ındrome de r, ou seja, T` custa do vector coluna Hr , onde H ´ a matriz de Hamming, matriz de paridade do c´digo.a e oMais, um c´digo de Hamming ´ um c´digo perfeito corrector erros singulares. De facto, a posi¸˜o o e o ca Tdo erro em r ´ dada pela representa¸˜o decimal de Hr . Por exemplo, suponha que r recebido e catem s´ındrome [1, 0, 1, 1]T . Pelo que foi visto nas aulas te´ricas, a posi¸˜o de r com erro ´ (1011)2 , o ca eque corresponde a 11 na base 10. Note ainda que sendo H a matriz de paridade do c´digo de o 4Hamming, com 4 linhas, ent˜o tem 2 − 1 = 15 colunas. Ou seja, r ´ um vector linha com 14 a ebits, sendo que o 11◦ est´ incorrecto (segundo o esquema usado na correc¸˜o pelo vizinho mais a capr´ximo, fazendo uso da distˆncia de Hamming). o a ´ E ainda necess´rio, de forma a se poder implementar um c´digo de Hamming, construir um pro- a ocedimento hamming:=proc(numero:Type::PosInt) onde n ´ um argumento de entrada, n´mero e uinteiro positivo, e cujo resultado final ´ uma matriz n × (2n − 1), cuja coluna j ´ a representa¸˜o e e cado n´mero natural j na sua escrita bin´ria. Ou seja, uma forma f´cil de construir uma matriz u a a 17
  • de Hamming. Para tal, concentramo-nos num algoritmo que, dado um n´mero (k)10 , encontre uum vector coluna sobre Z2 , com dimens˜o fixa ` partida, cujas entradas s˜o os d´ a a a ıgitos (0 ou 1)correspondentes ` representa¸˜o bin´ria de n. Por exemplo, que a 5, fixando em 4 o n´mero de a ca a u Tlinhas do vector, tenha como resultado [0, 1, 0, 1] . Suponha, ent˜o, que se pretende construir um vector coluna v, com dimen linhas, cujas entradas as˜o os s´ a ımbolos da representa¸˜o bin´ria de q, onde dimen ≥ log2 q + 1. Aplica-se o algoritmo ca ada divis˜o: a q = q0 = 2q1 + r1 , q1 = 2q2 + r2 , . . . qn−2 = 2qn−1 + rn−1 , qn−1 = 2 ∗ 0 + rn ,onde 0 ≤ ri < 2. O vector pretendido ser´ [0, . . . , 0, rn , rn−1 , . . . , r2 , r1 ]T . a No que se segue, atribua 4 a dimen e 5 a q.>> for i from dimen downto 1 do v[i]:=Dom::IntegerMod(2)(q): q:=q div 2: end_for:>> v; +- -+ | 0 mod 2 | | | | 1 mod 2 | | | | 0 mod 2 | | | | 1 mod 2 | +- -+ O que lhe resta fazer? Construir cada coluna da matriz de Hamming, concatenando-as. Porexemplo:export(linalg):dimen:=3:q:=1: v:=M2(dimen,1):for i from dimen downto 1 do v[i]:=Dom::IntegerMod(2)(q): q:=q div 2: end_for:H:=v:for q2 from 2 to 2^dimen-1 doq:=q2:for i from dimen downto 1 do 18
  • v[i]:=Dom::IntegerMod(2)(q): q:=q div 2: end_for:H:=concatMatrix(H,v)end_for: print(H); Suponha que foi recebido por uma canal sim´trico bin´rio e a r= 1 mod 2 1 mod 2 1 mod 2 1 mod 2 1 mod 2 1 mod 2 1 mod 2onde o esquema de codifica¸˜o usado foi Hamming [7,4]. Seja H a matriz de Hamming com 3 calinhas, que pode ser obtida pelas instru¸˜es atr´s definidas. Basta-nos calcular o s´ co a ındrome de r,isto ´, HrT : e>> H*transpose(r) +- -+ | 0 mod 2 | | | | 0 mod 2 | | | | 0 mod 2 | +- -+ Assuma que previamente foi exportada a livraria linalg. Como o s´ ındrome ´ o vector nulo, esegue que r ´ palavra-c´digo. e o Suponha agora que foi recebido r= 1 mod 2 1 mod 2 1 mod 2 0 mod 2 0 mod 2 0 mod 2 1 mod 2Calcula-se o s´ ındrome de r>> s:=H*transpose(r) +- -+ | 1 mod 2 | | | | 1 mod 2 | | | | 1 mod 2 | +- -+para se concluir que n˜o ´ palavra-c´digo. Sendo o c´digo de Hamming, o processo de correc¸˜o de a e o o caerros (neste caso de um erro) fornece um algoritmo para a correc¸˜o: o s´ ca ındrome ´ a representa¸˜o e cabin´ria da posi¸˜o de r que tem o erro. Fa¸a-se uso do que inicialmente se tratou nesta sec¸˜o. a ca c ca>> soma:=0:for i from 1 to 3 do aux:=coerce(s[i],Dom::Integer); soma:=soma+aux*2^(3-i);end_for:print(soma); 7 19
  • Ou seja, o elemento r[7] est´ errado. Corrijamo-lo: a>> r[soma]:=r[soma]+Z2(1); 0 mod 28 C´digos lineares oOs c´digos de Hamming s˜o c´digos lineares em que a matriz de paridade pode ser dada por uma o a omatriz de Hamming. Estes tˆm a vantagem de serem perfeitos, embora sejam apenas correctores ede erros singulares e de os parˆmetros seguirem regras (mais) fixas. a O esquema que se ir´ seguir de correc¸˜o de erros de c´digos lineares gerais recorre aos a ca os´ ındromes. Para tal, ´ preciso calcular o n´mero de erros do c´digo linear ` custa de, por exemplo, e u o auma matriz geradora ou de uma matriz de paridade. Listam-se ent˜o os s´ a ındromes dos l´ıderes decada classe. Recebido um vector, este ´ corrig´ se o seu s´ e ıvel ındrome igualar um unico s´ ´ ındromede um l´ıderes, l´ ıder esse que ´ subtra´ ao vector recebido por forma a se efectuar a correc¸˜o. e ıdo ca Suponha que A ´ matriz geradora de um c´digo C, onde e o 1 mod 2 1 mod 2 1 mod 2 1 mod 2 0 mod 2 A= 0 mod 2 1 mod 2 1 mod 2 0 mod 2 1 mod 2Esta matriz tem caracter´ ıstica 2:>> rank(A) 2Como o c´digo ´ linear, a distˆncia m´ o e a ınima do c´digo ´ igual ao menor peso de Hamming das o epalavras-c´digo n˜o nulas. Ou seja, d(C) = minc∈C{0} w(c). As palavras c´digo n˜o nulas o a o as˜o as combina¸˜es lineares (n˜o nulas) das linhas de A. No nosso caso, row(A,1); row(A,2); a co arow(A,1)+row(A,2). Segue que a distˆncia m´ a ınima ´ 3, e portanto ´ corrector de erros singulares. e e Para se aplicar o esquema de correc¸˜o de erros, ´ ainda necess´rio calcular a matriz de pari- ca e adade. Ou seja, uma matriz com caracter´ ıstica 3 tal que AH T = 0. Ou ainda, uma matriz cujascolunas da transposta formem uma base do espa¸o nulo de A. c>> nullspace(A) -- +- -+ +- -+ +- -+ -- | | 0 mod 2 | | 1 mod 2 | | 1 mod 2 | | | | | | | | | | | | 1 mod 2 | | 0 mod 2 | | 1 mod 2 | | | | | | | | | | | | 1 mod 2 |, | 0 mod 2 |, | 0 mod 2 | | | | | | | | | | | | 0 mod 2 | | 1 mod 2 | | 0 mod 2 | | | | | | | | | | | | 0 mod 2 | | 0 mod 2 | | 1 mod 2 | | -- +- -+ +- -+ +- -+ -- Neste caso, 20
  • >> H:=concatMatrix(nullspace(A)[1],nullspace(A)[2],nullspace(A)[3]) +- -+ | 0 mod 2, 1 mod 2, 1 mod 2 | | | | 1 mod 2, 0 mod 2, 1 mod 2 | | | | 1 mod 2, 0 mod 2, 0 mod 2 | | | | 0 mod 2, 1 mod 2, 0 mod 2 | | | | 0 mod 2, 0 mod 2, 1 mod 2 | +- -+ Em casos mais complexos, ser´ preciso criar um ciclo de forma a se construir a concatena¸˜o a caiterativamente. Repare que a matriz de paridade ´ a transposta da matriz apresentada em cima. ePortanto,>> H:=transpose(H) +- -+ | 0 mod 2, 1 mod 2, 1 mod 2, 0 mod 2, 0 mod 2 | | | | 1 mod 2, 0 mod 2, 0 mod 2, 1 mod 2, 0 mod 2 | | | | 1 mod 2, 1 mod 2, 0 mod 2, 0 mod 2, 1 mod 2 | +- -+ Os l´ ıderes s˜o, visto o c´digo corrigir 1 erro, as linhas da matriz identidade I5 , e portanto os a os´ ındromes dos l´ ıderes n˜o s˜o mais que as colunas de H. a a Suponha que se recebeu por uma canal sim´trico bin´rio com ru´ o vector e a ıdo r= 1 mod 2 0 mod 2 0 mod 2 1 mod 2 0 mod 2 ındrome HrT de r:Calcula-se o s´>> H*transpose(r) +- -+ | 0 mod 2 | | | | 0 mod 2 | | | | 1 mod 2 | +- -+Como o s´ındrome n˜o ´ nulo, segue que r ∈ C. Mas o s´ a e ındrome de r ´ igular ` coluna 5 de H, que e apor sua vez ´ o s´ e ındrome da linha 5 de matriz identidade I5 . Portanto, a correc¸˜o ´ feita como ca e>> I5:=M2(matrix::identity(5)): 21
  • >> c:=r+row(I5,5) +- -+ | 1 mod 2, 0 mod 2, 0 mod 2, 1 mod 2, 1 mod 2 | +- -+9 BCHO c´digo BCH ´ um c´digo linear c´ o e o ıclico, constru´ ` custa de polin´mios sobre Z2 . O papel ıdo a oda primitividade de certos polin´mios irredut´ o ıveis ´ crucial nesta teoria. Para tal, definamos o edom´ınios dos polin´mios sobre Z2 e teste-se a primitividade de p(x) = x4 + x + 1: o>> Pol2:=Dom::Polynomial(Dom::IntegerMod(2)); Dom::Polynomial(Dom::IntegerMod(2), LexOrder)>> q:=Pol2(x^4+x+1) 4 (1 mod 2) x + (1 mod 2) x + (1 mod 2)>> fs:=2^(degree(q)) 16>> for i from 1 to fs-1 do field[i]:=powermod(x,i,q): end_for:>> field[fs]:=0:>> ftable:=table():>> for i from 1 to fs-1 do ftable[field[i]]:=x^i: end_for:>> ftable[field[fs]]:=0:>> eval(ftable); table( 0 = 0, 15 1 = x , 3 14 x + 1 = x , 3 2 13 x + x + 1 = x , 3 2 12 x + x + x + 1 = x , 3 2 11 x + x + x = x , 2 10 x + x + 1 = x , 22
  • 3 9 x + x = x , 2 8 x + 1 = x , 3 7 x + x + 1 = x , 3 2 6 x + x = x , 2 5 x + x = x , 4 x + 1 = x , 3 3 x = x , 2 2 x = x , x = x ) Vejamos como se pode escrever x3 + 1 como elemento do grupo:>> ftable[x^3+1] 14 x Fa¸amos agora uso do dom´ c ınio dos corpos de Galois implementado no MuPAD:p:=a^4+a+1:F:=Dom::GaloisField(2,4,p):PolF:=Dom::Polynomial(F) 4Assuma f (x) = x2 −1 − 1 = x15 − 1, e calcule-se a respectiva factoriza¸˜o em polin´mios irre- ca odut´ ıveis:>> f:=Pol2(x^15-1) 15 (1 mod 2) x + (1 mod 2)>> for i from 1 to (nops(factor(f))-1)/2 do print(factor(f)[2*i]); end_for; (1 mod 2) x + (1 mod 2) 2 (1 mod 2) x + (1 mod 2) x + (1 mod 2) 23
  • 4 3 (1 mod 2) x + (1 mod 2) x + (1 mod 2) 4 (1 mod 2) x + (1 mod 2) x + (1 mod 2) 4 3 (1 mod 2) x + (1 mod 2) x + (1 mod 2) Construa-se uma tabela contendo os factores irredut´ ıveis de f (x):>> for i from 1 to (nops(factor(f))-1)/2 do TabFact[i]:=factor(f)[2*i] end_for: Destes factores, vejamos de que potˆncia de α s˜o minimais aniquiladores: e afor k from 1 to nops(TabFact) do // vamos percorrer cada factor irredutivelm:=TabFact[k]:print("Polinomio: ",m," k=",k); // mensagem de controlomF:=PolF(0): // aqui comeca o algoritmo que transforma o polinomio em PolFfor i from 0 to degree(m) do mF:=mF+PolF(coeff(m,i)*x^i):end_for:for j from 1 to nops(solve(mF=0,x)) do print("solucoes: ",solve(mF=0,x)[j]) // agora temos as raizes sobre Fend_forend_for Uma r´pida an´lise aos resultados, obtemos a a>> m1:=TabFact[4]: m2:= m1: m4:=m1: m3:=TabFact[5]: m6:=m3: m5:=TabFact[2]:onde m? indica o polin´mio mi minimal aniquilador de αi . o O caso menos evidente ser´ a obten¸˜o de m5 . No entanto, fazendo a ca>> F(a^5) 2 a + achega-se ` conclus˜o que x5 ≡ x2 + x, que por sua vez anula TabFact[2]. a a O polin´mio do c´digo BCH considerando as primeiras 6 potˆncias de α ´ g(x) = x10 + x8 + o o e e 5 4 2x + x + x + x + 1:>> g:=lcm(m1,m2,m3,m4,m5,m6) 10 8 5 4(1 mod 2) x + (1 mod 2) x + (1 mod 2) x + (1 mod 2) x + 2 (1 mod 2) x + (1 mod 2) x + (1 mod 2) 24
  • A inser¸˜o de g pode ser feita directamente: ca>> g:=Pol2(x^10+x^8+x^5+x^4+x^2+x+1); 10 8 5 4(1 mod 2) x + (1 mod 2) x + (1 mod 2) x + (1 mod 2) x + 2 (1 mod 2) x + (1 mod 2) x + (1 mod 2) A codifica¸˜o de um polin´mio h(x) ´ feita fazendo h(x)g(x). Por exemplo, para h(x) = ca o ex3 + x + 1,>> h:=Pol2(x^3+x+1) 3 (1 mod 2) x + (1 mod 2) x + (1 mod 2)>> Pol2(h*g) 13 10 9 7(1 mod 2) x + (1 mod 2) x + (1 mod 2) x + (1 mod 2) x + 6 5 (1 mod 2) x + (1 mod 2) x + (1 mod 2) Assuma agora que foi recebido o polin´mio r(x) = 1 + x2 + x3 + x4 + x5 + x6 + x7 + x10 : o>> r:=Pol2(1+x^2+x^3+x^4+x^5+x^6+x^7+x^10) 10 7 6 5(1 mod 2) x + (1 mod 2) x + (1 mod 2) x + (1 mod 2) x + 4 3 2 (1 mod 2) x + (1 mod 2) x + (1 mod 2) x + (1 mod 2)O polin´mio recebido n˜o ´ palavra c´digo, j´ que g n˜o divide r: o a e o a a>> Pol2(divide(r,g,Rem)) 8 7 6 3 (1 mod 2) x + (1 mod 2) x + (1 mod 2) x + (1 mod 2) x + (1 mod 2) x O passo seguinte envolve o c´lculo dos s´ a ındromes de r(x). Para tal, iremos transformar r numpolin´mio em F[x]. o>> rF:=PolF(0): for i from 0 to degree(r) do rF:=rF+PolF(coeff(r,i)*x^i): 25
  • end_for:>> print(rF); 10 7 6 5 4 3 2 x + x + x + x + x + x + x + 1 Assumimos que r tem 3 erros. A tabela dos s´ ındromes ´ calculada assim: et:=3; syn:=array(1..2*t):for i from 1 to 2*t do syn[i]:=evalp(rF,x=F(a^i)):end_for:print(syn):e obtemos +- 3 3 2 3 2 3 2 2 3 2 -+ | a , a + a , a + a , a + a + a + 1, a + a + 1, a + a + a + 1 | +- -+ O sistema de equa¸˜es lineares que se obtem (v. aulas te´ricas), que determina os coeficientes co odo polin´mio localizador de erros E(z) tem como matriz o   a3 a3 + a2 a3 + a2  3   a + a2 a3 + a2 a3 + a2 + a + 1  a3 + a2 a3 + a2 + a + 1 a2 + a + 1que resulta deMatF:=Dom::Matrix(F)V:=MatF([[syn[1],syn[2],syn[3]],[syn[2],syn[3],syn[4]],[syn[3],syn[4],syn[5]]]) O termo independente ´ e>> b:=MatF([[syn[4]],[syn[5]],[syn[6]]]) +- -+ | 3 2 | | a + a + a + 1 | | | | 2 | | a + a + 1 | | | | 3 2 | | a + a + a + 1 | +- -+ 26
  • Verifique-se que a matriz ´ n˜o-singular: e a>> det(V) 3 2 a + a + a + 1 A unica soluc˜o ´ dada por x = V −1 b: ´ a e>> inverseLU(V) +- -+ | 3 2 3 2 3 2 | | a + a , a + a + a + 1, a + a + 1 | | | | 3 2 3 | | a + a + a + 1, a + 1, a + 1 | | | | 3 2 3 3 2 | | a + a + 1, a + 1, a + a + a | +- -+>> solucao:=inverseLU(V)*b +- -+ | 2 | | a | | | | 3 2 | | a + a + 1 | | | | 3 | | a | +- -+Vejamos a que potˆncia de α corresponde a segunda entrada do vector solu¸˜o: e ca>> ftable[x^3+x^2+1] 13 x Temos ent˜o os s´ a ındromes, e portanto temos em nosso poder o polin´mio localizador de erros oELP :sig2:=a^13sig3:=a^3 27
  • sig1:=a^2ELP:=x->x^3+sig3*x^2+sig2*x+sig Por exaust˜o, encontram-se os zeros deste polin´mio, e faz-se a correc¸˜o dos erros: a o ca>> Erro:=Pol2(0):>> for i from 0 to 14 do if F(ELP(a^i))=F(0) then print("erro na posicao ",i): Erro:=Erro+Pol2(x^i); end_if: end_for: print("e(x)=",Erro): "erro na posicao ", 0 "erro na posicao ", 5 "erro na posicao ", 12 12 5 "e(x)=", (1 mod 2) x + (1 mod 2) x + (1 mod 2)>> palavracod:=Pol2(r+Erro); 12 10 7 6(1 mod 2) x + (1 mod 2) x + (1 mod 2) x + (1 mod 2) x + 4 3 2 (1 mod 2) x + (1 mod 2) x + (1 mod 2) xReferˆncias e[1] , W.C. Huffman, V. Pless, Fundamentals of Erros-Correcting Codes, Cambridge UP, 2003.[2] R. Klima, N. Sigmon, E. Stitzinger, Applications of Abstract Algebra with MAPLE, CRC Press, 2000.[3] J. H. van Lint, Introduction to coding theory, Springer, 1999.[4] M. Majewski, MuPAD Pro Computing Essentials, Springer, 2004. 28