# Please do not post homework # Aurora Hiveley, 02/13/24, Assignment 8 Help:= proc(): print(` WtEnumerator(q,M,t) `): end: ## WtEnumerator activity # inputs generating matrix M, k rows with entries in GF(q)^n # calculates Sum (t^(weight(v))) over all v in C WtEnumerator := proc(q,M,t) local C,n,v: C:= LtoC(q,M): n:= nops(C[1]): add(t^(HD([0$n], v)), v in C); end: ## testing M:=[seq(RV(3,7),i=1..3)]: M1:=SFde(3,M); H:= [PCM(3,M1)]; WtEnumerator(3,M1,2); WtEnumerator(3,H,2); WtEnumerator(3,M1,3); WtEnumerator(3,H,3); WtEnumerator(3,M1,4); WtEnumerator(3,H,4); # H has larger weight than M, but the factor greater varies. # presumably varies with t, it seems as though as t increases the gap between them decreases ### stuff from class below cut ### HelpC:= proc(): print(` LtoC(q,M), HD(u,v), RV(q,n), PCM(q,M), SFde(q,M) `): end: #LtoC(q,M): inputs a list of basis vectors for our linear code over GF(q) #outputs all the codewords (the actual subset of GF(q)^n with q^k elements) LtoC:=proc(q,M) local n,k,C,c,i,M1: option remember: k:=nops(M): n:=nops(M[1]): if k=1 then RETURN({seq(i*M[1] mod q,i=0..q-1) }): fi: M1:=M[1..k-1]: C:=LtoC(q,M1): {seq(seq(c+i*M[k] mod q,i=0..q-1),c in C)}: end: #HD(u,v): The Hamming distance between two words (of the same length) HD:=proc(u,v) local i,co: co:=0: for i from 1 to nops(u) do if u[i]<>v[i] then co:=co+1: fi: od: co: end: #RV(q,n): A random word of length n in {0,1,..,q-1} RV:=proc(q,n) local ra,i: ra:=rand(0..q-1): [seq( ra(), i=1..n)]: end: PCM:= proc(q,M) local k,n,i,j,H: # error checking first n := nops(M[1]): k := nops(M): # if M[1..k,1..k] != ID(k) # dr z's version with seq since identity matrix requires linalg package if [seq( [op(1..k,M[i])], i=1..k)]<>[seq([0$(i-1),1,0$(k-i)], i=1..k)] then print(`Matrix not in standard form. Use SFde(q,M) first`); RETURN(FAIL) : fi: # build transpose with a minus sign for i from 1 to n-k do # first n - k entries for j from 1 to k do H[i,j] := -M[j][i+k] mod q: # remember M is a list of lists od: # identity matrix at the end for j from k+1 to n do if i = j-k then H[i,j] := 1 : else H[i,j] := 0: fi: od: od: seq([seq(H[i,j],j=1..n)], i=1..n-k); end: # gets a row from a matrix GetRow:=proc(M,r) local v,i,n: v:=[]; n:=nops(M[1]); for i from 1 to n do: v:=[op(v),M[r,i]]; od; return v; end; # sets a row in a matrix SetRow:=proc(M,r,v) local i,M1: M1:=copy(M); for i from 1 to nops(v) do: M1[r,i]:=v[i]; od; return M1; end; # gets a column from a matrix GetCol:=proc(M,c) local v,i,n: v:=[]; n:=nops(M); for i from 1 to n do: v:=[op(v),M[i,c]]; od; return v; end; # sets a column in a matrix SetCol:=proc(M,c,v) local i,M1: M1:=copy(M); for i from 1 to nops(v) do: M1[i,c]:=v[i]; od; return M1; end; # returns matrix M in standard form SFde:=proc(q,M) local k,n,i,j,S,rj,cj,ri: k:=nops(M); n:=nops(M[1]); S:=copy(M); for i from 1 to k do: # algorithm is iterated from 1 to k # if S_ii = 0, then we need to perform a swap: if S[i,i] = 0 then for j from i+1 to k while S[j,i] = 0 do od; # look for available row if j<=k then # swap rows rj:=GetRow(S,j); S:=SetRow(S,j, GetRow(S,i)); S:=SetRow(S,i,rj); else # look to swap columns for j from i+1 to n while S[i,j] = 0 do od; # look for available col # swap cols cj:=GetCol(S,j); S:=SetCol(S,j, GetCol(S,i)); S:=SetCol(S,i,cj); fi; fi; # scale row to have leading entry 1 ri:=GetRow(S,i); ri:=(ri*(ri[i]&^(-1) mod q)) mod q; S:=SetRow(S,i,ri); for j from 1 to k do: if j <> i then rj:=GetRow(S,j); rj:=(rj - (rj[i] * ri mod q)) mod q; S:=SetRow(S,j,rj); fi; od; od; return S; end;