#This is my first draft for the final project of this year's Experimental math class. Right now it consists of a list of programs which help me randomly create codes, compute their weight enumerators, and find the value of p so that W_C(p)=1.5. The hope is to try to get a handle on when codes have their weight enumerators go from being very small to very large. Tom has also provided some help, writing some more efficient code in C. Finally I would note that after playing with this for a bit, I noticed that random codes looked normall distributed about the mean (in terms of weight distribution), but this probably isn't the case for all codes so I need to start looking at some famous families of codes, not just random ones. Help:=proc(): print(``): end: #span(L) inputs a list of vectors and computes their span over $\F_2^n$ span:=proc(L) local n,x,i,d: option remember: if nops(L)=0 then RETURN(FAIL): fi: d:=nops(L[1]): if nops(L)=1 then RETURN({[0$d],L[1]}): fi: n:=nops(L): {seq(L[n]+x mod 2,x in span([seq(L[i],i=1..n-1)])),op(span([seq(L[i],i=1..n-1)]))}: end: #worthless program because maple adds lists vecadd:=proc(x,y) local i: if nops(x)<>nops(y) then RETURN(FAIL): fi: [seq(x[i]+y[i] mod 2,i=1..nops(x))]: end: #Returns the weight of a vector x in \F_2^n (i.e. the number of 1's) wt:=proc(x) local i: add(x[i],i=1..nops(x)): end: #Inputs a list of vectors L and computes the minimum distance in their #linear span distance:=proc(L) local c,C: C:=span(L): min({seq(wt(c), c in C)} minus {0}): end: #d returns the minimal nonzero degree of a polynomial f in the variable p #i.e. d(1+p^5+10p^10)=5 (This is used with the Weight enumerator to find distance) d:=proc(f,p) local i: if degree(f,p)<0 then RETURN(FAIL): fi: for i from 1 to degree(f,p) do if coeff(f,p,i)<> 0 then RETURN(i): fi: od: FAIL: end: WSpan:=proc(S,x) local A,WE,s: WE:=0: with(combinat): for A in powerset(S) do WE:=WE+x^wt(add(s, s in A) mod 2): od: WE: end: #W(S,x) computes the weight enumerator of a set S W(S,x)=\sum_{s in S} x^wt(s) W:=proc(S,x,y:=1) local s,n: n:=nops(S[1]): add( y^n*(x/y)^wt(s),s in S): end: #rando generates a random code with vectors of length n and approximately of rank k by #generating k random vectors in \F_2^n and then taking their span rando:=proc(n,k) local ra, S,i,j: ra:=rand(0..1): S:={seq([seq(ra(),j=1..n)],i=1..k)}: span(S): end: RandW:=proc(n,k,x) local ra,S: ra:=rand(0..1): S:={seq([seq(ra(),j=1..n)],i=1..k)}: WSpan(S,x): end: #Rest returns the restriction of a code to wts b1 to b2 which is to say, removes all #codewords who do not have b1b1 then T:=T union {s}: fi: od: T: end: #Test1 generates a code of rank appx. k in F_2^n and outputs an appx. of the largest #p for which we have W(Code,p)<1.5, along with the relative distance of the code #distance/n Test1:=proc(n,r) local guess,p,f,i,Code: Code:=rando(n,r): f:=W(Code,p): guess:=.5: for i from 2 to 100 do if subs(p=guess,f)<1.5 then guess:=guess+2^(-i): else guess:=guess-2^(-i): fi: od: [d(f,p)/n,guess]: end: #Test runs Test1 N times and then returns the min/max relative distances and p's Test:=proc(n,r,N) local p,i, maxd,minp,mind,result: minp:=1: maxd:=0: mind:=n: for i from 1 to N do result:=Test1(n,r): minp:=min(minp,result[1]): mind:=min(mind,result[2]): maxd:=max(maxd,result[2]): od: minp,mind,maxd: end: #Genplot runs Test1 N times and outputs the data points in a form suitable for plotting Genplot:=proc(n,r,N) local points,i: points:={}: for i from 1 to N do points:=points union{Test1(n,r)}: od: points: end: #GenplotSpread runs Genplot for all r from 1 to n/2 and outputs in a form suitable for plotting Genplotspread:=proc(n,N) local r,i,points,newdata: points:=[[],[]]: for r from 1 to n/2 do newdata:=Genplot(n,r,N): for i from 1 to nops(newdata) do points[1]:=[op(points[1]),newdata[i][1]]: points[2]:=[op(points[2]),newdata[i][2]]: od: od: points: end: Test2:=proc(n,r) local f,p,i,guess: f:=RandW(n,r,p): guess:=.5: for i from 2 to 100 do if subs(p=guess,f)<1.5 then guess:=guess+2^(-i): else guess:=guess-2^(-i): fi: od: [d(f,p)/n,guess]: end: #Genplot2 runs Test1 N times and outputs the data points in a form suitable for plotting Genplot2:=proc(n,r,N) local points,i: points:={}: for i from 1 to N do points:=points union{Test2(n,r)}: od: points: end: Genplotspread2:=proc(n,N) local r,i,points,newdata: points:=[[],[]]: for r from 1 to n/2 do newdata:=Genplot2(n,r,N): for i from 1 to nops(newdata) do points[1]:=[op(points[1]),newdata[i][1]]: points[2]:=[op(points[2]),newdata[i][2]]: od: od: points: end: