###################################################################### ## RecTILINGS: Save this file as RecTILINGS to use it, # # stay in the # ## same directory, get into Maple (by typing: maple ) # ## and then type: read RecTILINGS: # ## Then follow the instructions given there # ## # ## Written by Doron Zeilberger, Rutgers University , # ## zeilberg at math dot rutgers dot edu. # ###################################################################### with(combinat): Digits:=100: print(`First Written: Dec. 2005: tested for Maple 10 `): print(`Version of Dec. , 2005: `): print(): print(`This is RecTILINGS, A Maple package`): print(`accompanying Shalsoh B. Ekhad and Doron Zeilberger's article: `): print(`"Automatic CounTilings" `): print(): print(`The most current version is available on WWW at:`): print(` http://www.math.rutgers.edu/~zeilberg/tokhniot/RecTILINGS .`): print(`Please report all bugs to: zeilberg at math dot rutgers dot edu .`): print(): print(`For general help, and a list of the MAIN functions,`): print(` type "ezra();". For specific help type "ezra(procedure_name);" `): print(`For a list of the supporting functions type: ezra1();`): print(): ezra1:=proc() if args=NULL then print(` The supporting procedures are: Asy1`): print(` DS, EqG, EqGt, Growth1, KmnF, KZmn, Red, Sefer, SeferW, Zmn , Zinn`): print(`For help with a specific procedure, type "ezra(procedure_name);"`): else ezra(args): fi: end: ezra:=proc() if args=NULL then print(` RecTILINGS: A Maple package for counting tilings `): print(`of rectangles by any set of rectangular tiles`): print(`of arbitrary sizes`): print(`The MAIN procedures are`): print(` AaveT, Astat,AstatV, AstatVs, GF1, GF1t, Sidra, SidraW , Sipur, SipurW `): elif nargs=1 and args[1]=AaveT then print(`AaveT(k,ListOfTiles): Given a postive integer k and a symbol n`): print(`The list of asymptotic averages (divided by n) of the number of tiles`): print(`of tiling a k by n rectangular board by the tiles in`): print(`the list of rectangular tiles Tiles ([a,b] means a b by a rectangle)`): print(`followed by the average total number of total number of tiles (divided by n)`): print(`For example, try: AaveT(2,[[1,2],[2,1]]) `): elif nargs=1 and args[1]=Aitken then print(`Aitken(L): The conjectured limit of the sequence L`): print(`from its three last elements, using Aitken's fromula`): print(`For example, try: Aitken([3.1,3.01,3.001]);`): elif nargs=1 and args[1]=Astat then print(`Astat(k,ListOfTiles,n): Given a postive integer k and a symbol n`): print(` and given a List of rectangular Tiles`): print(`ListOfTiles`): print(`returns: (1) The lists of for the`): print(`asymptotics (in n) for pairs [average,variance] for the`): print(`r.v. number of tiles of type ListOfTiles[i], in a random tiling by the rectangular tiles`): print(`of Tiles (in order), followed by the pair [av,variance] for the`): print(`Total number of tiles, followed by the asympto. correlation`): print(`matrix for example try:`): print(`Astat(4,[[1,2],[2,1]],n):`): elif nargs=1 and args[1]=AstatV then print(`AstatV(k,ListOfTiles,n): Verbose version of Astat (q.v.) `): print(`For example, try:`): print(`AstatV(4,[[1,2],[2,1]],n):`): elif nargs=1 and args[1]=AstatVs then print(`AstatVs(K,ListOfTiles,n): AstatV(k,ListOfTiles,n) for k from 1 to K `): print(`For example, try:`): print(`AstatVs(4,[[1,2],[2,1]],n):`): elif nargs=1 and args[1]=Asy1 then print(`Asy1(f,t,n): the Asymptotics of the coeff. of the rational function f`): print(`try for example: Asy1(1/(1-t-t^2),t,n);`): elif nargs=1 and args[1]=DS then print(`D(v): the distingushed Square followed by the number of`): print(`available squares below`): print(`For example, try: DS([0,0,0,0]);`): elif nargs=1 and args[1]=EqG then print(`EqG(v,A,t,H,Tiles): the equation for A[v] in terms of H[Tiles]`): print(`where Tiles is the set of rectangular tiles`): print(`For example, try: EqG([0,0],A,t,H,{[1,2],[2,1]});`): elif nargs=1 and args[1]=EqtG then print(`EqtG(v,A,t,Tiles): the equation for A[v]`): print(`where Tiles is the set of rectangular tiles`): print(`For example, try: EqtG([0,0],A,t,{[1,2],[2,1]});`): elif nargs=1 and args[1]=GF1 then print(`GF1(k,t,H,Tiles): Given a positive integer k, a variable t`): print(`A letter H, and a set of pos. integer-pairs Tiles`): print(`outputs the rational function in t`): print(`whose general coeff. (of t^n) is the weight-enumeator of the set`): print(`of tilings of an n by k rectangle by `): print(`tiles drawn from the set of rectangular tiles, Tiles, given as`): print(`a set of pairs [a,b] (representing an a by b rectangle)`): print(` a is the vertical dimension and b is the horizontal dimension `): print(`The weight of a tiling is the product of H[a,b]'s `): print(`For example, try: GF1(2,t,H,{[1,2],[2,1]});`): elif nargs=1 and args[1]=GF1t then print(`GF1t(k,t,Tiles): Given a positive integer k, a variable t`): print(`and a set of pos. integer-pairs Tiles`): print(`outputs the rational function in t`): print(`whose general coeff. (of t^n) is the number `): print(`of tilings of an n by k rectangle by `): print(`tiles drawn from the set of rectangular tiles, Tiles, given as`): print(`a set of pairs [a,b] (representing an a by b rectangle)`): print(` a is the vertical dimension and b is the horizontal dimension `): print(`For example, try: GF1t(2,t,{[1,2],[2,1]});`): elif nargs=1 and args[1]=Growth1 then print(`Growth1(f,t): the growth of the coeff. of the rational function f`): print(`try for example: Growth1(1/(1-t-t^2),t);`): elif nargs=1 and args[1]=KmnF then print(`KmnF(m,n,z): The Kasteleyn polynomial for tiling`): print(`an m by n board by domino tiles computed`): print(`according to Kasteleyn's fromula as it appears in`): print(`his paper "The statistics of Dimers on a Lattice I...."`): print(`Physica 27 (1961) Eq. (13) p. 1215`): print(`Using Floating point`): print(`For example, try: KmnF(3,4,z);`): elif nargs=1 and args[1]=KZmn then print(`KZmn(m,n,z): The Kasteleyn polynomial for an m by n board `): print(`For example, try: KZmn(3,2,z);`): elif nargs=1 and args[1]=Red then print(`Red(v): the reduction of a vector`): print(`For example, try: Red([-1,-1,-2,-2] `); elif nargs=1 and args[1]=Sefer then print(`Sefer(t,K,N,L1,L2) : All the Sipurs for Tiles`): print(`ALL the non-empty subsets of tiles of dimensions<=L1`): print(`of cardinality L2 `): print(`For example, try: Sefer(t,2,10,2,2);`): elif nargs=1 and args[1]=SeferW then print(`SeferW(t,H,K,N,L1,L2) : All the SipurWs for Tiles`): print(`ALL the non-empty subsets of tiles of dimensions<=L1`): print(`of cardinality L2 `): print(`For example, try: SeferW(t,H,2,10,2,2);`): elif nargs=1 and args[1]=Sidra then print(`Sidra(k,Tiles,N): the first N+1 terms in the`): print(`enumerating sequence for the number of tilings `): print(`of an n by k rectangle using tiles from the set`): print(`or Rectangular tiles Tiles {[a,b]} where`): print(`[a,b] stands for an a by b rectangular tile`): print(` For example, try: Sidra(2,{[1,2],[2,1]},20); `): elif nargs=1 and args[1]=SidraW then print(`SidraW(k,H,Tiles,N): the first N+1 terms in the`): print(`weight-enumerating sequence for the number of tilings `): print(`of an n by k rectangle using tiles from the set`): print(`or Rectangular tiles Tiles {[a,b]} where`): print(`[a,b] stands for an a by b rectangular tile`): print(` and the corresponding weight is H[a,b]`): print(` For example, try: SidraW(2,H,{[1,2],[2,1]},20); `): elif nargs=1 and args[1]=Sipur then print(`Sipur(Tiles,t,K,N): Tells the story for the`); print(`enumeration of rectangular boards of width up to K`): print(`using the rectangular tiles Tiles. t is the variable for`): print(`the length of the board `): print(`N is a positive integer for the lengths of the`): print(`desired beginnings for the enumetaring sequence`): print(`Sipur({[1,2],[2,1]},t,4,10);`): elif nargs=1 and args[1]=SipurW then print(`SipurW(Tiles,t,H,K,N): Tells the story for the`); print(`enumeration of rectangular boards of width up to K`): print(`using the rectangular tiles Tiles. t is the variable for`): print(`the length of the board and H is a symbol for the`): print(`indexed variables H[a,b] accounting for the tile-types`): print(`N is a positive integer for the lengths of the`): print(`desired beginnings for the enumetaring sequence`): print(`SipurW({[1,2],[2,1]},t,H,4,10);`): elif nargs=1 and args[1]=Zinn then print(`Zinn(resh,n): Given a list resh, conjectures mu and theta`): print(`such that resh[i]=mu^n*n^theta`): print(`For example, try: Zinn(Sidra(6,{[1,2],[2,1]},40),39);`): elif nargs=1 and args[1]=Zmn then print(`Zmn(m,n,H,Tiles): the weight-enumerator of all tilings of`): print(`an m by n rectangle with rectangular tiles from the`): print(`set Tiles, for example, try:`): print(`Zmn(2,2,H,{[1,2],[2,1]});`): else print(`There is no such thing as`, args): fi: end: ###Begin General Rectangular Tiles #Red(v): the reduction of a vector Red:=proc(v) local i,m: m:=max(op(v)): [seq(v[i]-m,i=1..nops(v))]: end: #DS(v): the distinguished square, and the number of squares #below it DS:=proc(v) local m,i,k: m:=min(op(v)): for i from 1 while v[i]<>m do od: for k from 1 to nops(v)-i while v[i+k]=m do od: i,k: end: #GF1t(k,t,Tiles): the generating function for tilings of an n by k #rectangle by rectangular tiles from the set Tiles, given as #pairs [a,b] (an a by b rectangle) #For example, try: GF1t(2,t,{2},{2}); GF1t:=proc(k,t,Tiles) local eq,OldVar,A,NewVar,gu,var,i: option remember: OldVar:={}: NewVar:={[0$k]}: eq:={}: while NewVar<>{} do gu:=EqtG(NewVar[1],A,t,Tiles): OldVar:=OldVar union {NewVar[1]}: NewVar:=NewVar minus {NewVar[1]}: eq:=eq union {gu[1]}: NewVar:=NewVar union (gu[2] minus OldVar): od: var:={seq(A[op(OldVar[i])],i=1..nops(OldVar))}: var:=solve(eq,var): normal(subs(t=t^(1/k),normal(subs(var,A[0$k])))): end: #EqtG(v,A,t,Tiles): the equation for A[v] in terms of t #where Tiles is the set of rectangular tiles #For example, try: EqtG([0,0],A,t,{[1,2],[2,1]}); EqtG:=proc(v,A,t,Tiles) local gu,i,k,i1,eq,v1,i2,var,a,b,tile: gu:=DS(v):i:=gu[1]: k:=gu[2]: eq:=A[op(v)]: var:={}: for i1 from 1 to nops(Tiles) do tile:=Tiles[i1]: a:=tile[2]: b:=tile[1]: if b<=k then v1:=Red([op(1..i-1,v),seq(v[i2]+a,i2=i..i+b-1), op(i+b..nops(v),v)]): var:=var union {v1}: eq:=eq-t^(a*b)*A[op(v1)]: var:=var union {v1}: fi: od: if v=[0$nops(v)] then eq:=eq-1: fi: eq,var: end: #EqG(v,A,t,H,Tiles): the equation for A[v] in terms of H[Tiles] #where Tiles is the set of rectangular tiles #For example, try: EqG([0,0],A,t,H,{[1,2],[2,1]}); EqG:=proc(v,A,t,H,Tiles) local gu,i,k,i1,eq,v1,i2,var,a,b,tile: gu:=DS(v):i:=gu[1]: k:=gu[2]: eq:=A[op(v)]: var:={}: for i1 from 1 to nops(Tiles) do tile:=Tiles[i1]: a:=tile[2]: b:=tile[1]: if b<=k then v1:=Red([op(1..i-1,v),seq(v[i2]+a,i2=i..i+b-1), op(i+b..nops(v),v)]): var:=var union {v1}: eq:=eq-t^(a*b)*H[op(tile)]*A[op(v1)]: var:=var union {v1}: fi: od: if v=[0$nops(v)] then eq:=eq-1: fi: eq,var: end: #GF1(k,t,H,Tiles): the generating function for tilings of an n by k #rectangle by rectangular tiles from the set Tiles, given as #pairs [a,b] (an a by b rectangle) #The weight of a tiling is the product of H[op(tile)]'s and t^n #For example, try: GF1(2,t,H,{[1,2],[2,1]}); GF1:=proc(k,t,H,Tiles) local eq,OldVar,A,NewVar,gu,var,i: option remember: OldVar:={}: NewVar:={[0$k]}: eq:={}: while NewVar<>{} do gu:=EqG(NewVar[1],A,t,H,Tiles): OldVar:=OldVar union {NewVar[1]}: NewVar:=NewVar minus {NewVar[1]}: eq:=eq union {gu[1]}: NewVar:=NewVar union (gu[2] minus OldVar): od: var:={seq(A[op(OldVar[i])],i=1..nops(OldVar))}: var:=solve(eq,var): normal(subs(t=t^(1/k),normal(subs(var,A[0$k])))): end: #Sidra(k,Tiles,N): the first N+1 terms in the #enumerating sequence for the number of tilings using #of an n by k rectangle using tiles from the set #or Rectangular tiles Tiles {[a,b]} where #[a,b] stands for an a by b rectangular tile #For example, try: Sidra(2,{[1,2],[2,1]},20); Sidra:=proc(k,Tiles,N) local gu,t,i: gu:=GF1t(k,t,Tiles): [seq(coeff(taylor(gu,t=0,N+1),t,i),i=0..N)]: end: #Zmn(m,n,H,Tiles): the weight-enumerator of all tilings of #an m by n rectangle with rectangular tiles from the #set Tiles, for example, try: #Zmn(2,2,H,{[1,2],[2,1]}); Zmn:=proc(m,n,H,Tiles) local lu,t: lu:=GF1(m,t,H,Tiles): lu:=taylor(lu,t=0,n+1): lu:=sort(expand(coeff(lu,t,n))): end: #KZmn(m,n,z): The Kastelyan polynomial #For example, try: KZmn(2,4,z); KZmn:=proc(m,n,z) local H,gu: gu:=subs({H[1,2]=1,H[2,1]=z},Zmn(m,n,H,{[1,2],[2,1]})): gu:=subs(z=sqrt(z),gu); end: #Growth1(f,t): the growth of the coeff. of the rational function f #try for example: Growth1(1/(1-t-t^2),t); Growth1:=proc(f,t) local i,aluf,ku,shi,P: P:=denom(normal(f)): if degree(P,t)=0 then RETURN(FAIL): fi: ku:={fsolve(P,t)}: aluf:=ku[1]: shi:=abs(aluf): for i from 2 to nops(ku) do if abs(ku[i])0 do od: k: end: #Asy1(f,t,n): the Asymptotics of the coeff. of the rational function f #try for example: Asy1(1/(1-t-t^2),t,n); Asy1:=proc(f,t,n) local i,aluf,ku,shi,P,Q,f1: f1:=normal(f): Q:=numer(f1): P:=denom(f1): ku:={fsolve(P,t)}: aluf:=ku[1]: shi:=abs(aluf): for i from 2 to nops(ku) do if abs(ku[i])10^(-L-1) then gu:=gu+evalf(coeff(f,n,i),L)*n^i: fi: od: gu: end: Trim1:=proc(f,n,L) Trim2(coeff(f,I,1),n,L)*I+ Trim2(coeff(f,I,0),n,L): end: #Amoment(F,t,VarList,i,k,n): The asymptotic k^th moment about the #mean of the r.v. corresponding to the i^th entry in VarList #where F is a rational function in t whose coeffs. of t^n are #weight-enumerators according to statistics represented by VarList #For example (assuming that you have CountTilings), to get #the asymtotic (in n) variance of the number of horizontal tiles #in a domino-tiling of a 4 by n board, type: #Amoment(GF1(4,t,H,{[1,2],[2,1]}),t,[H[1,2],H[2,1]],1,2,n): Amoment:=proc(F,t,VarList,i,k,n) local gu,j,lu,mu,i1: gu:=[seq(AsyM(F,t,VarList,[0$(i-1),j,0$(nops(VarList)-i)],n),j=1..k)]: mu:=gu[1]: lu:=(-1)^k*mu^k: for i1 from 1 to k do lu:=lu+(-1)^(k-i1)*binomial(k,i1)*mu^(k-i1)*gu[i1]: od: Trim1(expand(lu),n,40): end: #Akurtois(F,t,VarList,i,k,n): The asymptotic Kurtosis #of the r.v. corresponding to the i^th entry in VarList #where F is a rational function in t whose coeffs. of t^n are #weight-enumerators according to statistics represented by VarList #For example (assuming that you have CountTilings), to get #the asymtotic (in n) Kurtosis of the number of horizontal tiles #in a domino-tiling of a 4 by n board, type: #AKurtosis(GF1(4,t,H,{[1,2],[2,1]}),t,[H[1,2],H[2,1]],1,n): Akurtosis:=proc(F,t,VarList,i,n) local m2,m4: m2:=Amoment(F,t,VarList,i,2,n): m4:=Amoment(F,t,VarList,i,4,n): Trim1(normal(coeff(m4,n,degree(m4,n))*n^degree(m4,n)/ (coeff(m2,n,degree(m2,n))*n^degree(m2,n))^2),n,40): end: #Aaverage(F,t,VarList,i,n): The asymptotic expectation #of the r.v. corresponding to the i^th entry in VarList #where F is a rational function in t whose coeffs. of t^n are #weight-enumerators according to statistics represented by VarList #For example (assuming that you have CountTilings), to get #the asymptotic (in n) average of the number of horizontal tiles #in a domino-tiling of a 4 by n board, type: #Aaverage(GF1(4,t,H,{[1,2],[2,1]}),t,[H[1,2],H[2,1]],1,n): Aaverage:=proc(F,t,VarList,i,n) : Trim1(AsyM(F,t,VarList,[0$(i-1),1,0$(nops(VarList)-i)],n),n,40): end: #Cov(F,VarList,i,j): Given a polynomial F in the variable-list VarList #finds the covariance between the r.v. associated with VarList[i] and #VarList[j]. For example, try: #Cov(x+y^2,[x,y],1,1): Cov:=proc(F,VarList,i,j) local x,y,gu,av1,av2,var1,var2,lu,i1: x:=VarList[i]: y:=VarList[j]: lu:={seq(VarList[i1]=1,i1=1..nops(VarList))}: gu:=subs(lu,y*diff(x*diff(F,x),y))/subs(lu,F): av1:=subs(lu,x*diff(F,x))/subs(lu,F): av2:=subs(lu,y*diff(F,y))/subs(lu,F): var1:=expand(subs(lu,x*diff(x*diff(F,x),x))/subs(lu,F)-av1^2): var2:=expand(subs(lu,y*diff(y*diff(F,y),y))/subs(lu,F)-av2^2): normal((gu-av1*av2)/sqrt(var1*var2)): end: #Acovariance(F,t,VarList,i,j,n): The asymptotic covariance #of the r.v. corresponding to the i^th entry in VarList #and the j^th entry (1<=i