#shifts the index by N dshift:=proc(E,N,n) local newE; newE:=subs(n=n+N,E); end: #picks out undefined functions and their shifts in an expression whatfun2:=proc(E,n) local i,s,sid; s:={NULL}; sid:=[op(indets(E,`indexed`))]; for i from 1 to nops(sid) do if not(type(op(0,sid[i]),`procedure`)) then s:={op(s),sid[i]}; fi; od; [op(s)]; end: #maxshift determines the maximum shift in T maxshift:=proc(T,n) local ulist; ulist:=whatfun2(T,n); ulist:={seq(op(ulist[i])-n,i=1..nops(ulist))}; max(op(ulist)); end: #minshift determines the minimum shift in T minshift:=proc(T,n) local ulist; ulist:=whatfun2(T,n); ulist:={seq(op(ulist[i])-n,i=1..nops(ulist))}; min(op(ulist)); end: #picks out undefined functions in an expression whatfun:=proc(E,n) local i,s,sid; s:={NULL}; sid:=[op(indets(E,`indexed`))]; for i from 1 to nops(sid) do if not(type(op(0,sid[i]),`procedure`)) then s:={op(s),op(0,sid[i])[n]}; fi; od; [op(s)]; end: SUMalg:=proc(EE,n) local Glist,Tlist,M,shiftlist,Elist,N,u,E,functionset,nset,k,sumnset; E:=expand(EE); #convert E to a list if not(whattype(E)=`+`) then Elist:=[E]; else Elist:=convert(E,`list`); fi; #determine the unknown functions u:=whatfun(E,n); #maxshift in E N:=maxshift(E,n); #remove terms which have no functional dependence to be summed directly functionset:=[seq(seq(dshift(u[r],j,n),j=0..N),r=1..nops(u))]; nset:={NULL}; for k in Elist do if not(has(k,functionset)) then nset:={op(nset),k}; fi; od; nset:=expand(convert(nset,`+`)); sumnset:=sum(nset,n); E:=expand(eval(E-nset)); if not(whattype(E)=`+`) then Elist:=[E]; else Elist:=convert(E,`list`); fi; M:=nops(Elist); shiftlist:=[seq(minshift(Elist[i],n),i=1..nops(Elist))]; Glist:=[seq(dshift(Elist[i],-shiftlist[i],n),i=1..M)]; Tlist:=[seq(add(dshift(Elist[i],-j,n),j=0..shiftlist[i]-1),i=1..M)]; convert(Tlist,`+`)+sum(expand(convert(Glist,`+`)),n) end: #ouputs the expression G modulo total differences DifferenceMod:=proc(G,n) local i,sumpart,Glist; Glist:=[op(SUMalg(G,n))]; sumpart:=0; for i from 1 to nops(Glist) do if has(Glist[i],`sum`) then sumpart:=op(1,Glist[i]); fi; od; sumpart; end: