Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
Project: cocalc-sagemath-dev-slelievre
Views: 418346############################################################################# ## #W catenary-tame.gi Manuel Delgado <[email protected]> #W Pedro A. Garcia-Sanchez <[email protected]> #W Jose Morais <[email protected]> ## ## #Y Copyright 2005 by Manuel Delgado, #Y Pedro Garcia-Sanchez and Jose Joao Morais #Y We adopt the copyright regulations of GAP as detailed in the #Y copyright notice in the GAP manual. ## ############################################################################# ############################################################################# ## #F NSGPfactorizationsNC(n,l) ## ## <n> is a nonnegative integer and <l> is a list of positive integers. ## Returns a list with the different factorizations of n as a linear ## combination with elements in l. ## ############################################################################# InstallGlobalFunction( NSGPfactorizationsNC, function(n,l) local k,e1; k:=Length(l); if(n<0) then return []; fi; if(k=1) then if ((n mod l[1])=0) then return [[n /(l[1])]]; else return []; fi; fi; e1:=List([1..k],n->0); if(n=0) then return [e1]; fi; e1[1]:=1; return Union(List(NSGPfactorizationsNC(n-l[1],l),n-> n+e1), List(NSGPfactorizationsNC(n,l{[2..k]}),n->Concatenation([0],n))); end); ############################################################################# ## #F CatenaryDegreeOfNumericalSemigroup(s) ## ## Computes the catenary degree of the numerical semigroup <s>. ## ## The definition of catenary degree can be found in ## the book: ## -A. Geroldinger and F. Halter-Koch, Non-unique ## Factorizations: Algebraic, Combinatorial and ## Analytic Theory, Pure and AppliedMathematics, ## vol. 278, Chapman & Hall/CRC, 2006. ## The algorithm used appears in ## -S. T. Chapman, P. A. Garcia-Sanchez, ## D. Llena, V. Ponomarenko, and J. C. Rosales, ## The catenary and tame degree in finitely generated ## cancellative monoids, Manuscripta Mathematica 120 (2006) 253--264 ## ############################################################################# InstallGlobalFunction( CatenaryDegreeOfNumericalSemigroup, function(s) local msg, ap, candidates, rclasses; if(not(IsNumericalSemigroup(s))) then Error(s," must be a numerical semigroup.\n"); fi; msg:=MinimalGeneratingSystemOfNumericalSemigroup(s); if(msg=[1]) then return 0; #Error("The catenary degree does not make sense for ",s,"\n"); fi; ap:=AperyListOfNumericalSemigroupWRTElement(s,msg[1]); ap:=ap{[2..Length(ap)]}; # I remove the zero, # minimal generators yield conneted graphs candidates:=Union(List(msg,n->List(ap,m->m+n))); # Gn not conneted implies n=wi+minimalgenerator # thus these are the candidates rclasses:=List(candidates,n->RClassesOfSetOfFactorizations(FactorizationsIntegerWRTList(n,msg))); # from every n y obtain the connected components # they will give me the expressions of n # that yield minimal generators rclasses:=Filtered(rclasses, n->Length(n)>1); return Maximum(List(rclasses,l->Maximum(List(l,r->Minimum(List(r,Sum)))))); end); ############################################################################ ## #F This function returns true if the graph is connected an false otherwise ## ## It is part of the NumericalSGPS package just to avoid the need of using ## other graph packages only to this effect. It is used in ## CatenaryDegreeOfElementInNumericalSemigroup ## ## InstallGlobalFunction( IsConnectedGraphNCForNumericalSemigroups, function(G) local i, j, fl, n, # number of vertices uG, # undirected graph (an edge of the undirected graph may be # seen as a pair of edges of the directed graph) visit, dfs; fl := Flat(G); if fl=[] then n := Length(G); else n := Maximum(Length(G),Maximum(fl)); fi; uG := StructuralCopy(G); while Length(uG) < n do Add(uG,[]); od; for i in [1..Length(G)] do for j in G[i] do UniteSet(uG[j],[i]); od; od; visit := []; # mark the vertices an unvisited for i in [1..n] do visit[i] := 0; od; dfs := function(v) #recursive call to Depth First Search local w; visit[v] := 1; for w in uG[v] do if visit[w] = 0 then dfs(w); fi; od; end; dfs(1); if 0 in visit then return false; fi; return true; end); #======================================================================== ## #F This function is the NC version of CatenaryDegreeOfElementInNumericalSemigroup. It works ## well for numbers bigger than the Frobenius number ## DEPRECATED ##------------------------------------------------------------------------ InstallGlobalFunction(CatenaryDegreeOfElementInNumericalSemigroup_NC, function(n,s) local len, distance, Fn, V, underlyinggraph, i, weights, weightedgraph, j, dd, d, w; #---- Local functions definitions ------------------------- #========================================================== #========================================================== #Given two factorizations a and b of n, the distance between a #and b is d(a,b)=max |a-gcd(a,b)|,|b-gcd(a,b)|, where #gcd((a_1,...,a_n),(b_1,...,b_n))=(min(a_1,b_1),...,min(a_n,b_n)). #---------------------------------------------------------- distance := function(a,b) local k, gcd, i; k := Length(a); if k <> Length(b) then Error("The lengths of a and b are different.\n"); fi; gcd := []; for i in [1..k] do Add(gcd, Minimum(a[i],b[i])); od; return(Maximum(Sum(a-gcd),Sum(b-gcd))); end; ## ---- End of distance() ---- #========================================================== #---- End of Local functions definitions ------------------ #========================================================== #----------- MAIN CODE ------------------------- #---------------------------------------------------------- Fn := FactorizationsElementWRTNumericalSemigroup( n, s ); #Print("Factorizations:\n",Fn,"\n"); V := Length(Fn); if V = 1 then return 0; elif V = 2 then return distance(Fn[1],Fn[2]); fi; # compute the directed weighted graph underlyinggraph := []; for i in [2 .. V] do Add(underlyinggraph, [i..V]); od; Add(underlyinggraph, []); weights := []; weightedgraph := StructuralCopy(underlyinggraph); for i in [1..Length(weightedgraph)] do for j in [1..Length(weightedgraph[i])] do dd := distance(Fn[i],Fn[weightedgraph[i][j]]); Add(weights,dd); weightedgraph[i][j] := [weightedgraph[i][j],dd]; od; od; weights:=Set(weights); d := 0; while IsConnectedGraphNCForNumericalSemigroups(underlyinggraph) do w := weights[Length(weights)-d]; d := d+1; for i in weightedgraph do for j in i do if IsBound(j[2]) and j[2]= w then Unbind(i[Position(i,j)]); fi; od; od; for i in [1..Length(weightedgraph)] do weightedgraph[i] := Compacted(weightedgraph[i]); od; underlyinggraph := []; for i in weightedgraph do if i <> [] then Add(underlyinggraph, TransposedMatMutable(i)[1]); else Add(underlyinggraph, []); fi; od; od; return(weights[Length(weights)-d+1]); end); ## ---- End of CatenaryDegreeOfElementInNumericalSemigroup_NC() ---- #======================================================================== ## #======================================================================== ## #F This function returns the catenary cegree in a numerical semigroup S of ## a positive integer n ## #------------------------------------------------------------------------ ## InstallGlobalFunction(CatenaryDegreeOfElementInNumericalSemigroup, function(n,S) #---- Tests on the arguments ------------------------------ if not (IsNumericalSemigroup(S) and IsPosInt(n-1)) then Error(" The arguments of CatenaryDegreeOfElementInNumericalSemigroup are a nonnegativeinteger and a numerical semigroup.\n"); fi; #---- End of Tests on the arguments ----------------------- #========================================================== #----------- MAIN CODE ------------------------- #---------------------------------------------------------- if (not n in S) or (n=0) or (n in MinimalGeneratingSystemOfNumericalSemigroup(S)) then return 0; fi; return CatenaryDegreeOfSetOfFactorizations(FactorizationsElementWRTNumericalSemigroup(n,S)); end); ## ---- End of CatenaryDegreeOfElementInNumericalSemigroup() ---- ## #======================================================================== ############################################################################# ## #F TameDegreeOfElementInNumericalSemigroup(n,s) ## ## Computes the tame degre of the element <n> of the numerical semigroup <s>. ## Used for the computation of the tame degree of s, but can ## be used separately. ## ## The definition of tame degree appears in ## -A. Geroldinger and F. Halter-Koch, Non-unique ## Factorizations: Algebraic, Combinatorial and ## Analytic Theory, Pure and AppliedMathematics, ## vol. 278, Chapman & Hall/CRC, 2006. ## The algorithm used appears in ## -S. T. Chapman, P. A. Garc�a-S�nchez, ## D. Llena, V. Ponomarenko, and J. C. Rosales, ## The catenary and tame degree in finitely generated ## cancellative monoids, Manuscripta Mathematica 120 (2006) 253--264 ## ############################################################################# InstallGlobalFunction( TameDegreeOfElementInNumericalSemigroup, function(n,s) local msg, i, max, fact, mtemp, candidates, rest, distance; # distance between two factorizations distance:=function(x,y) local p,n,i,z; p:=0; n:=0; z:=x-y; for i in [1..Length(z)] do if z[i]>0 then p:=p+z[i]; else n:=n+z[i]; fi; od; return Maximum(p,-n); end; if(not(IsNumericalSemigroup(s))) then Error(s," must be a numerical semigroup.\n"); fi; msg:=MinimalGeneratingSystemOfNumericalSemigroup(s); if(msg=[1]) then Error("The tame degree does not make sense for ",s,"\n"); fi; max:=0; fact:=FactorizationsIntegerWRTList(n,msg); for i in [1..Length(msg)] do candidates:=Filtered(fact, x->x[i]=0); rest:=Filtered(fact,x->x[i]<>0); if (rest=[] or candidates=[]) then mtemp:=0; else mtemp:=Maximum(List(candidates,x->Minimum(List(rest, z->distance(x,z))))); fi; if mtemp>max then max:=mtemp; fi; od; return max; end); ############################################################################# ## #F TameDegreeOfNumericalSemigroup(s) ## ## Computes the tame degree of a numerical semigroup <s>. ## ## The definition of tame degree appears in ## -A. Geroldinger and F. Halter-Koch, Non-unique ## Factorizations: Algebraic, Combinatorial and ## Analytic Theory, Pure and AppliedMathematics, ## vol. 278, Chapman & Hall/CRC, 2006. ## The algorithm used appears in ## -S. T. Chapman, P. A. Garc�a-S�nchez, ## D. Llena, The catenary and tame degree of numerical ## monoids, Forum Math. 2007 1--13. ## ## Improved by Alfredo S�nchez-R. Navarro and P. A. Garc�a-S�nchez ## for Alfredo S�nchez-R. Navarro's PhD Thesis ## ############################################################################# InstallGlobalFunction( TameDegreeOfNumericalSemigroup, function(s) local msg, ap, candidates, rp, facts, translate; if(not(IsNumericalSemigroup(s))) then Error(s," must be a numerical semigroup.\n"); fi; translate:=function(l) #translates partitions to factorizations return List(msg, x-> Length(Positions(l,x))); end; msg:=MinimalGeneratingSystemOfNumericalSemigroup(s); #Print(msg); if(msg[1]=1) then return 0; fi; ap:=Difference(Union(Set(msg,n->AperyListOfNumericalSemigroupWRTElement(s,n))),[0]); candidates:=Set(Cartesian(ap,msg),Sum); # remove elements having in all its factorizations a common atom rp:=List(candidates, x->RestrictedPartitions(x, msg)); rp:=Filtered(rp, x->Intersection(x)=[]); facts:=List(rp, x->List(x, translate)); if facts=[] then return 0; fi; return Maximum(Set(facts,n->TameDegreeOfSetOfFactorizations(n))); end); ############################################################################# ## #F FactorizationsElementWRTNumericalSemigroup(n,s) ## ## Computes the set of factorizations ## of an element <n> as linear combinations ## with nonnegative coefficients of the minimal generators ## of the semigroup <s>. ## ############################################################################# InstallGlobalFunction(FactorizationsElementWRTNumericalSemigroup, function(n,s) local gen; if not IsNumericalSemigroup(s) then Error("The second argument must be a numerical semigroup.\n"); fi; if not (n in s) then Error("The first argument does not belong to the second.\n"); fi; #this ensures that the lenghts won't be zero gen:=MinimalGeneratingSystemOfNumericalSemigroup(s); return FactorizationsIntegerWRTList(n,gen); end); ############################################################################# ## #F LengthsOfFactorizationsElementWRTNumericalSemigroup(n,s) ## ## Computes the lengths of the set of ## factorizations of an element <n> as linear combinations ## with nonnegative coefficients of the minimal generators ## of the semigroup <s>. ## ############################################################################# InstallGlobalFunction(LengthsOfFactorizationsElementWRTNumericalSemigroup, function(n,s) local gen; if not IsNumericalSemigroup(s) then Error("The second argument must be a numerical semigroup.\n"); fi; if not (n in s) then Error("The first argument does not belong to the second.\n"); fi; #this ensures that the lenghts won't be zero gen:=MinimalGeneratingSystemOfNumericalSemigroup(s); return LengthsOfFactorizationsIntegerWRTList(n,gen); end); ############################################################################# ## #F ElasticityOfFactorizationsElementWRTNumericalSemigroup(n,s) ## ## Computes the quotient (maximum length)/(minimum lenght) of the ## factorizations of an element <n> as linear combinations ## with nonnegative coefficients of the minimal generators ## of the semigroup <s>. ## ############################################################################# InstallGlobalFunction(ElasticityOfFactorizationsElementWRTNumericalSemigroup, function(n,s) local gen,max,min,lenfact; if not IsNumericalSemigroup(s) then Error("The second argument must be a numerical semigroup.\n"); fi; if not IsPosInt(n) then Error("The first argument must be a positive integer.\n"); fi; if not (n in s) then Error("The first argument does not belong to the second.\n"); fi; #this ensures that the lengths won't be zero gen:=MinimalGeneratingSystemOfNumericalSemigroup(s); lenfact:=Set(LengthsOfFactorizationsIntegerWRTList(n,gen)); min:=Minimum(lenfact); max:=Maximum(lenfact); return max/min; end); ############################################################################# ## #F ElasticityOfNumericalSemigroup(s) ## ## Computes the supremum of the elasticities of the ## factorizations of the elements of <s>. ## From [CHM06, GHKb] this is precisely np/n1 ## with n1 the multiplicity of <s> and np the greatest ## generator. ## ############################################################################# InstallGlobalFunction(ElasticityOfNumericalSemigroup, function(s) local gen,max,min; if not IsNumericalSemigroup(s) then Error("The argument must be a numerical semigroup.\n"); fi; gen:=MinimalGeneratingSystemOfNumericalSemigroup(s); min:=Minimum(gen); max:=Maximum(gen); return max/min; end); ############################################################################# ## #F DeltaSetOfFactorizationsElementWRTNumericalSemigroup(n,s) ## ## Computes the set of differences between ## two consecutive lengths of factorizations of ## an element <n> as linear combinations ## with nonnegative coefficients of the minimal generators ## of the semigroup <s>. ## ############################################################################# InstallGlobalFunction(DeltaSetOfFactorizationsElementWRTNumericalSemigroup, function(n,s) local gen,max,min,lenfact; if not IsNumericalSemigroup(s) then Error("The second argument must be a numerical semigroup.\n"); fi; if n=0 then return []; fi; if not IsPosInt(n) then Error("The first argument must be a nonnegative integer.\n"); fi; if not (n in s) then Error("The first argument does not belong to the second.\n"); fi; #this ensures that the lenghts won't be zero gen:=MinimalGeneratingSystemOfNumericalSemigroup(s); lenfact:=LengthsOfFactorizationsIntegerWRTList(n,gen); return Set([1..(Length(lenfact)-1)], i->lenfact[i+1]-lenfact[i]); end); ############################################################################# ## #F MaximumDegreeOfElementWRTNumericalSemigroup(n,s) ## ## Computes the maximum length of the ## factorizations of an element <n> as linear combinations ## with nonnegative coefficients of the minimal generators ## of the semigroup <s>. ## ############################################################################# InstallGlobalFunction(MaximumDegreeOfElementWRTNumericalSemigroup, function(n,s) local gen; if not IsNumericalSemigroup(s) then Error("The second argument must be a numerical semigroup.\n"); fi; if n=0 then return 0; fi; if not IsPosInt(n) then Error("The first argument must be a nonnegative integer.\n"); fi; if not (n in s) then Error("The first argument does not belong to the second.\n"); fi; #this ensures that the lenghts won't be empty gen:=MinimalGeneratingSystemOfNumericalSemigroup(s); return Maximum(LengthsOfFactorizationsIntegerWRTList(n,gen)); end); ############################################################################# ## #F OmegaPrimalityOfElementInNumericalSemigroup(n,s) ## ## Computes the omega primality of an elmenent n in S, as explained in ## V. Blanco, P. A. Garc\'{\i}a-S\'anchez, A. Geroldinger, ## Semigroup-theoretical characterizations of arithmetical invariants with ## applications to numerical monoids and Krull monoids, {arXiv}:1006.4222v1. ## Current implementation optimized by C. O'Neill based on a work in progress ## by O'Neill, Pelayo and Thomas and uses ## OmegaPrimalityOfElemtListInNumericalSemgiroup ############################################################################# InstallGlobalFunction(OmegaPrimalityOfElementInNumericalSemigroup, function(n,s) return OmegaPrimalityOfElementListInNumericalSemigroup([n],s)[1]; end); ############################################################################# ## #F OmegaPrimalityOfNumericalSemigroup(s) ## ## Computes the maximum of omega primality of the minimal generators of S. ## ############################################################################# InstallGlobalFunction(OmegaPrimalityOfNumericalSemigroup, function(s) if not IsNumericalSemigroup(s) then Error("The second argument must be a numerical semigroup.\n"); fi; return Maximum(Set(MinimalGeneratingSystemOfNumericalSemigroup(s), n->OmegaPrimalityOfElementInNumericalSemigroup(n,s))); end); ############################################################################# ## #F FactorizationsIntegerWRTList(n,ls) ## ## Computes the set of factorizations ## of an integer n as linear combinations ## with nonnegative coefficients of the elements in the list of positive integers ls ## Makes use of RestrictedPartitions ############################################################################# InstallGlobalFunction(FactorizationsIntegerWRTList,function(n,ls) local translate; if not(IsListOfIntegersNS(ls) and ForAll(ls, x->IsPosInt(x))) then Error("The list must be a list of positive integers.\n"); fi; if Length(ls)<>Length(Set(ls)) then #repeated elements return NSGPfactorizationsNC(n,ls); fi; translate:=function(l) return List(ls, x-> Length(Positions(l,x))); end; return List(RestrictedPartitions(n,ls), translate); end); ############################################################################# ## #F LengthsOfFactorizationsIntegerWRTList(n,ls) ## ## Computes the lengths of the set of ## factorizations of an integer <n> as linear combinations ## with nonnegative coefficients of the elements in the list of positive integers <ls> ## ############################################################################# InstallGlobalFunction(LengthsOfFactorizationsIntegerWRTList,function(n,ls) if not(IsListOfIntegersNS(ls) and ForAll(ls, x->IsPosInt(x))) then Error("The list must be a list of positive integers.\n"); fi; return Set(RestrictedPartitions(n,ls), Length); end); ############################################################################# ## #F DeltaSetOfSetOfIntegers(ls) ## ## Computes the set of differences between ## consecutive elements in the list <ls> ## ############################################################################# InstallGlobalFunction(DeltaSetOfSetOfIntegers,function(ls) local lenfact; if not(IsListOfIntegersNS(ls)) then Error("The argument must be a nonempty list of integers.\n"); fi; lenfact:=Set(ls); return Set([1..(Length(lenfact)-1)], i->lenfact[i+1]-lenfact[i]); end); ############################################################################# ## #F CatenaryDegreeOfSetOfFactorizations(fs) ## ## Computes the catenary degree of the set of factorizations ## ############################################################################# InstallGlobalFunction(CatenaryDegreeOfSetOfFactorizations, function(fs) local cart, i , j, nfs, distance, Kruskal; # edges will be [u,w] with u,w vertices Kruskal := function(V, E) local trees, needed, v, e, i,j, nv; trees := List(V, v-> [v]); needed := []; nv:=Length(V); for e in E do i:=First([1..Length(trees)], k-> e[1] in trees[k]); j:=First([1..Length(trees)], k-> e[2] in trees[k]); if i<>j then trees[i]:=Union(trees[i], trees[j]); trees[j]:=[]; Add(needed,e); fi; if Length(needed)=nv-1 then break; fi; od; return needed; end; distance:=function(e) local p,n,i,z,x,y; x:=e[1]; y:=e[2]; p:=0; n:=0; z:=x-y; for i in [1..Length(z)] do if z[i]>0 then p:=p+z[i]; else n:=n+z[i]; fi; od; return Maximum(p,-n); end; if not(IsRectangularTable(fs) and IsListOfIntegersNS(fs[1])) then Error("The argument is not a list of factorizations.\n"); fi; if Minimum(Flat(fs))<0 then Error("Coefficients must be nonnegative integers.\n"); fi; nfs:=Length(fs); if nfs<2 then return 0; fi; cart:=[]; for i in [1..nfs] do for j in [i+1 .. nfs] do Add(cart, [fs[i], fs[j]]); od; od; Sort(cart,function(e,ee) return distance(e)<distance(ee); end); return Maximum(Set(Kruskal(fs,cart), distance)); end); ############################################################################# ## #F TameDegreeOfSetOfFactorizations(fact) ## ## Computes the tame degree of the set of factorizations ## ############################################################################# InstallGlobalFunction(TameDegreeOfSetOfFactorizations,function(fact) local distance, i, max, mtemp, candidates, rest, len; if not(IsRectangularTable(fact) and IsListOfIntegersNS(fact[1])) then Error("The argument is not a list of factorizations.\n"); fi; if Minimum(Flat(fact))<0 then Error("Coefficients must be nonnegative integers.\n"); fi; # distance between two factorizations distance:=function(x,y) local p,n,i,z; p:=0; n:=0; z:=x-y; for i in [1..Length(z)] do if z[i]>0 then p:=p+z[i]; else n:=n+z[i]; fi; od; return Maximum(p,-n); end; if Length(fact) <= 1 then return 0; fi; max:=0; len := Length(fact[1]); for i in [1..len] do candidates:=Filtered(fact, x->x[i]=0); rest:=Filtered(fact,x->x[i]<>0); if (rest=[] or candidates=[]) then mtemp:=0; else mtemp:=Maximum(List(candidates,x->Minimum(List(rest, z->distance(x,z))))); fi; if mtemp>max then max:=mtemp; fi; od; return max; end); ############################################################################# ## #F RClassesOfSetsOfFactorizations(l) ## ## Determine the set of R-classes (Chapter 7 [RGBook] of a set of factorizations ## ############################################################################# InstallGlobalFunction(RClassesOfSetOfFactorizations, function(l) local current, pos, len, colisionan, cola; if not(IsRectangularTable(l) and IsListOfIntegersNS(l[1])) then Error("The argument is not a list of factorizations.\n"); fi; if Minimum(Flat(l))<0 then Error("Coefficients must be nonnegative integers.\n"); fi; current:=List(l,n->[n]); pos :=1; len:=Length(current); while (pos<len) do colisionan:=Filtered(current{[(pos+1)..len]},k->First(Cartesian(k,current[pos]),n->n[1]*n[2]<>0)<>fail); if(colisionan<>[]) then current[pos]:=Union(current[pos],Union(colisionan)); cola:=Difference(current{[(pos+1)..len]},colisionan); current:=Concatenation(current{[1..pos]},cola); len:=Length(current); pos:=0; fi; pos:=pos+1; od; return(current); end); ######################################################## # MaximalDenumerantOfElementInNumericalSemigroup(x,s) # returns the number of factorizations of maximal length of x in # the numerical semigroup s ######################################################## InstallGlobalFunction(MaximalDenumerantOfElementInNumericalSemigroup, function(x,s) local max, fact; if not IsNumericalSemigroup(s) then Error("The second argument must be a numerical semigroup.\n"); fi; if not ( x in s ) then Error("The first argument must be an element of the second.\n"); fi; fact:=FactorizationsElementWRTNumericalSemigroup(x,s); max:=Maximum(Set(fact,Sum)); return Length(Filtered(fact, x->Sum(x)=max)); end); ######################################################## # MaximalDenumerantOfSetOfFactorizations(ls) # returns the number of factorizations of maximal length in ls ######################################################## InstallGlobalFunction(MaximalDenumerantOfSetOfFactorizations, function(ls) local max; if not(IsRectangularTable(ls) and IsListOfIntegersNS(ls[1])) then Error("The argument is not a list of factorizations.\n"); fi; if Minimum(Flat(ls))<0 then Error("Coefficients must be nonnegative integers.\n"); fi; max:=Maximum(Set(ls,Sum)); return Length(Filtered(ls, x->Sum(x)=max)); end); ######################################################## # MaximalDenumerantOfNumericalSemigroup(s) # computes the maximal denumerant of a numerical semigroup # by using de algorithm given by Bryant and Hamblin # Semigroup Forum 86 (2013), 571-582 ######################################################## InstallGlobalFunction(MaximalDenumerantOfNumericalSemigroup, function(s) local adj, ord, minord, msg, bmsg, p, m, ap, adjSi, i, Si, apb, bi, b, x, md, j, lr, bj; if(not(IsNumericalSemigroup(s)))then Error("The argument must be anumerical semigroup.\n"); fi; msg:=MinimalGeneratingSystemOfNumericalSemigroup(s); m:=MultiplicityOfNumericalSemigroup(s); ap:=AperyListOfNumericalSemigroupWRTElement(s,m); b:=BlowUpOfNumericalSemigroup(s); apb:=AperyListOfNumericalSemigroupWRTElement(b,m); bmsg:=ShallowCopy(msg-m); bmsg[1]:=m; ord:=function(x) return Maximum(LengthsOfFactorizationsIntegerWRTList(x,msg)); end; adj:=function(x) return x-ord(x)*m; end; md:=0; for i in [0..m-1] do x:=ap[i+1]; Si:=[x]; bi:=apb[i+1]+m*Minimum(LengthsOfFactorizationsIntegerWRTList(apb[i+1],bmsg)); while x<= bi do x:=x+m; if x in s then Add(Si,x); fi; od; adjSi:=Set(Si,adj); #Print(adjSi," "); lr:=[]; lr[1]:=Length(FactorizationsIntegerWRTList(adjSi[1],bmsg)); for j in [2..Length(adjSi)] do bj:=Minimum(LengthsOfFactorizationsIntegerWRTList(adjSi[j-1],bmsg))-(adjSi[j]-adjSi[j-1])/m; lr[j]:=Length(Filtered(FactorizationsIntegerWRTList(adjSi[j],bmsg), x->Sum(x)<bj)); #Print(lr[j]," "); od; #Print(Maximum(lr),"\n"); md:=Maximum(md,Maximum(lr)); od; return md; end); ######################################################## # AdjustmentOfNumericalSemigroup(s) # computes the adjustment a numerical semigroup # by using de algorithm given by Bryant and Hamblin # Semigroup Forum 86 (2013), 571-582 ######################################################## InstallGlobalFunction(AdjustmentOfNumericalSemigroup,function(s) local adj, ord, minord, msg, bmsg, p, m, ap, adjSi, i, Si, apb, bi, b, x, j, bj, adjust; if(not(IsNumericalSemigroup(s)))then Error("The argument must be anumerical semigroup.\n"); fi; msg:=MinimalGeneratingSystemOfNumericalSemigroup(s); m:=MultiplicityOfNumericalSemigroup(s); ap:=AperyListOfNumericalSemigroupWRTElement(s,m); b:=BlowUpOfNumericalSemigroup(s); apb:=AperyListOfNumericalSemigroupWRTElement(b,m); bmsg:=ShallowCopy(msg-m); bmsg[1]:=m; ord:=function(x) return Maximum(LengthsOfFactorizationsIntegerWRTList(x,msg)); end; adj:=function(x) return x-ord(x)*m; end; adjust:=[]; for i in [0..m-1] do x:=ap[i+1]; Si:=[x]; bi:=apb[i+1]+m*Minimum(LengthsOfFactorizationsIntegerWRTList(apb[i+1],bmsg)); while x<= bi do x:=x+m; if x in s then Add(Si,x); fi; od; adjSi:=Set(Si,adj); #Print(adjSi," "); adjust:=Union(adjust,adjSi); od; return adjust; end); ############################################################## # IsAdditiveNumericalSemigroup(s) # Detects if s is an additive numerical semigroup, that is, # ord(m+x)=ord(x)+1 for all x in s. For these semigroups gr_m(K[[s]]) is # Cohen-Macaulay. # We use Proposition 4.7 in Semigroup Forum 86 (2013), 571-582 ############################################################## InstallGlobalFunction(IsAdditiveNumericalSemigroup, function(s) local b,m; if(not(IsNumericalSemigroup(s)))then Error("The argument must be anumerical semigroup.\n"); fi; m:=MultiplicityOfNumericalSemigroup(s); b:=BlowUpOfNumericalSemigroup(s); return AdjustmentOfNumericalSemigroup(s) =AperyListOfNumericalSemigroupWRTElement(b,m); end); ############################################################## # IsSuperSymmetricNumericalSemigroup(s) # Detects if s is a numerical semigroup is supersymmetric, that is, # it is symmetric, additive and whenever w+w'=f+m # (with m the multiplicity and f the Frobenius number) we have # ord(w+w')=ord(w)+ord(w') ############################################################## InstallGlobalFunction(IsSuperSymmetricNumericalSemigroup,function(s) local ap,m, ord, msg, f, om; if(not(IsNumericalSemigroup(s)))then Error("The argument must be anumerical semigroup.\n"); fi; if not(IsSymmetricNumericalSemigroup(s)) then return false; fi; if not(IsAdditiveNumericalSemigroup(s)) then return false; fi; msg:=MinimalGeneratingSystemOfNumericalSemigroup(s); m:=MultiplicityOfNumericalSemigroup(s); ap:=AperyListOfNumericalSemigroupWRTElement(s,m); f:=FrobeniusNumberOfNumericalSemigroup(s); ord:=function(x) return Maximum(LengthsOfFactorizationsIntegerWRTList(x,msg)); end; ap:=Filtered(ap, x-> x<=(f+m)/2); om:=ord(f+m); return ForAll(ap, x-> om=ord(x)+ord(f+m-x)); end); ####################################################################### # BelongsToHomogenizationOfNumericalSemigroup(n,s) # checks if the pair n belongs to the homogenization of s ####################################################################### InstallGlobalFunction(BelongsToHomogenizationOfNumericalSemigroup, function(n,s) local msg; if not IsNumericalSemigroup(s) then Error("The second argument must be a numerical semigroup.\n"); fi; if not IsListOfIntegersNS(n) then Error("The first argument must be a list of integers"); fi; if n[1]<0 or n[2]<0 then return false; fi; msg:=MinimalGeneratingSystemOfNumericalSemigroup(s); return First(FactorizationsIntegerWRTList(n[2],msg), x-> Sum(x)<= n[1])<>fail; end); ####################################################################### # FactorizationsInHomogenizationOfNumericalSemigroup(n,s) # computes the set of factorizations of n with respect to generators of # the homogenization of s ####################################################################### InstallGlobalFunction(FactorizationsInHomogenizationOfNumericalSemigroup, function(n,s) local msg, fact, facthom, x, xhom; if not IsNumericalSemigroup(s) then Error("The second argument must be a numerical semigroup.\n"); fi; if not IsListOfIntegersNS(n) then Error("The first argument must be a list of integers"); fi; if n[1]<0 or n[2]<0 then return []; fi; msg:=MinimalGeneratingSystemOfNumericalSemigroup(s); fact:=Filtered(FactorizationsIntegerWRTList(n[2],msg), x-> Sum(x)<= n[1]); facthom:=[]; for x in fact do xhom:=Concatenation([n[1]-Sum(x)],x); Add(facthom,xhom); od; return facthom; end); ####################################################################### # HomogeneousBettiElementsOfNumericalSemigroup(s) # Computes the Betti elements of the Homogenization of s # uses Cox-Little-O'Shea, Chapter 8, Theorem 4 [CLOS] for finding # a system of generators of the ideal of S^h ####################################################################### InstallGlobalFunction(HomogeneousBettiElementsOfNumericalSemigroup,function( s ) local i, p, rel, rgb, msg, pol, ed, sdegree, monomial, candidates, mp; msg:=MinimalGeneratingSystemOfNumericalSemigroup(s); ed:=Length(msg); if NumSgpsCanUseSI or NumSgpsCanUseSingular or NumSgpsCanUse4ti2 then msg:=List(msg, m->[1,m]); msg:=Concatenation([[1,0]],msg); return BettiElementsOfAffineSemigroup( AffineSemigroup(msg)); fi; mp:=MinimalPresentationOfNumericalSemigroup(s); p := []; # list of exponents to monomial monomial:=function(l) local i; pol:=1; for i in [1..ed] do pol:=pol*Indeterminate(Rationals,i)^l[i]; od; return pol; end; for rel in mp do Add( p, monomial(rel[1])-monomial(rel[2])); od; rgb := ReducedGroebnerBasis( p, MonomialGrevlexOrdering() ); ## the homogenization of this is a system of genetators of the ideal of S^h ##computes the s^h degree of a pol in the semigroup ideal sdegree:=function(r) local mon; mon:=LeadingMonomialOfPolynomial(r,MonomialGrlexOrdering() ); return [Sum(List([1..ed],i->DegreeIndeterminate(mon,i))),Sum(List([1..ed],i-> msg[i]*DegreeIndeterminate(mon,i)))]; end; candidates:=List(rgb, g-> sdegree(g)); candidates:=Filtered(candidates, x-> Length(RClassesOfSetOfFactorizations( FactorizationsInHomogenizationOfNumericalSemigroup(x,s)))>1); return Set(candidates); end); #################################################################### #F HomogeneousCatenaryDegreeOfNumericalSemigroup(s) computes the ## homogeneous catenary degree of the numerical semigroup s ([GSOSN]) #################################################################### InstallGlobalFunction(HomogeneousCatenaryDegreeOfNumericalSemigroup,function( s ) local betti; if not IsNumericalSemigroup(s) then Error("The argument must be a numerical semigroup.\n"); fi; betti:=HomogeneousBettiElementsOfNumericalSemigroup(s); return Maximum(Set(betti,b-> CatenaryDegreeOfSetOfFactorizations( FactorizationsInHomogenizationOfNumericalSemigroup(b,s)))); end); ######################################## #F DenumerantElementInNumericalSemigroup(n,s) ## returns the denumerant ######################################## InstallGlobalFunction(DenumerantOfElementInNumericalSemigroup, function(x,s) local gen; if not IsNumericalSemigroup(s) then Error("The second argument must be a numerical semigroup.\n"); fi; if not ( x in s ) then return 0; fi; gen:=MinimalGeneratingSystemOfNumericalSemigroup(s); return NrRestrictedPartitions(x,gen); end); #################################################################### #F MoebiusFunctionAssociatedToNumericalSemigroup(s,x) ## Computes the value in x of Moebius function of the poset ## associated to a numerial semigroup s ## -Chappelon and Ramirez Alfonsin, Semigroup Forum 87 (2013), 313-330 #################################################################### InstallGlobalFunction(MoebiusFunctionAssociatedToNumericalSemigroup,function(s,x) local small, mu, msg, m, ap; if not(IsNumericalSemigroup(s)) then Error("The first argument must be a numerical semigroup.\n"); fi; if not(IsInt(x)) then Error("The second argument must be an integer.\n"); fi; if x<0 then return 0; fi; if x=0 then return 1; fi; if not(x in s) then return 0; fi; msg:=MinimalGeneratingSystemOfNumericalSemigroup(s); if x in msg then return -1; fi; m:=MultiplicityOfNumericalSemigroup(s); ap:=Difference(AperyListOfNumericalSemigroupWRTElement(s,m),[0]); small:=Filtered(ap, y->y<=x); #Print(small,"\n"); mu:=function(y) local sm; if y=0 then return 1; fi; if y in msg then return -1; fi; if not(y in s) then return 0;fi; sm:=Filtered(ap,z->z<=y); return -Sum(List(y-sm,mu)); end; return -Sum(List(x-small,mu)); end); ################################################################### #F AdjacentCatenaryDegreeOfSetOfFactorizations(ls) ## computes the adjacent catenary degree of the set of factorizations ls ################################################################### InstallGlobalFunction(AdjacentCatenaryDegreeOfSetOfFactorizations,function(ls) local distance, Fn, lenset, Zi, facti, i; if not(IsRectangularTable(ls) and IsListOfIntegersNS(ls[1])) then Error("The argument is not a list of factorizations.\n"); fi; # distance between two factorizations distance:=function(x,y) local p,n,i,z; p:=0; n:=0; z:=x-y; for i in [1..Length(z)] do if z[i]>0 then p:=p+z[i]; else n:=n+z[i]; fi; od; return Maximum(p,-n); end; Fn:=Set(ShallowCopy(ls)); lenset:=Set( ls, Sum ); if Length(lenset)=1 then return 0; fi; Zi:=[]; for i in lenset do facti:=Filtered( Fn, x->Sum(x)=i ); SubtractSet( Fn, facti ); Add( Zi, facti ); od; return Maximum( List( [2..Length( Zi )], t->Minimum( List( Zi[t-1], x->Minimum( List( Zi[t], y->distance( x, y ) ) ) ) ) ) ); end); ################################################################### #F EqualCatenaryDegreeOfSetOfFactorizations(ls) ## computes the equal catenary degree of of the set of factorizations ################################################################### InstallGlobalFunction(EqualCatenaryDegreeOfSetOfFactorizations,function(ls) local distance, lFni; if not(IsRectangularTable(ls) and IsListOfIntegersNS(ls[1])) then Error("The argument is not a list of factorizations.\n"); fi; # distance between two factorizations distance:=function(x,y) local p,n,i,z; p:=0; n:=0; z:=x-y; for i in [1..Length(z)] do if z[i]>0 then p:=p+z[i]; else n:=n+z[i]; fi; od; return Maximum(p,-n); end; lFni:=Set( ls, t->Sum( t ) ); return Maximum( List( lFni, y->CatenaryDegreeOfSetOfFactorizations( Filtered( ls, x->Sum( x )=y ) ) ) ); end); ################################################################### #F MonotoneCatenaryDegreeOfSetOfFactorizations(ls) ## computes the equal catenary degree of of the set of factorizations ################################################################### InstallGlobalFunction(MonotoneCatenaryDegreeOfSetOfFactorizations,function(ls) return Maximum(AdjacentCatenaryDegreeOfSetOfFactorizations(ls), EqualCatenaryDegreeOfSetOfFactorizations( ls )); end); ############################################################ #F LShapesOfNumericalSemigroup(s) ## computes the set of LShapes associated to S (see [AG-GS]) ########################################################## InstallGlobalFunction(LShapesOfNumericalSemigroup,function(s) local ap, facts, total, totalfact, new, w, z, n, ones,l, leq ; leq:=function(x,y) return ForAll(y-x, t->t>=0); end; l:=MinimalGeneratingSystemOfNumericalSemigroup(s); n:=Length(l); ap:=Set(AperyListOfNumericalSemigroupWRTElement(s, l[n])) ; ones:=List([1..n-1],_->1); total:=[[]]; for w in ap do facts:=FactorizationsIntegerWRTList(w,l{[1..n-1]}); totalfact:=[]; for z in facts do new:=Filtered(total, ll->Length(Filtered(ll, x->leq(x,z)))=Product(z+ones)-1); new:=List(new, ll->Concatenation(ll,[z])); totalfact:=Union(totalfact,new); od; total:=(totalfact); od; return total; end); ########################################################################### #F MonotonePrimitiveElementsOfNumericalSemigroup(s) ## ## Computes the sets of elements in s, such that there exists a minimal ## solution to msg*x-msg*y = 0, |x|<=|y| such that x,y are factorizations of s ## Used to compute the monotone catenary degree of the semigroup s ## ############################################################################# InstallGlobalFunction(MonotonePrimitiveElementsOfNumericalSemigroup,function(s) local l, n, facs, mat, ones, ncone, nmzcone,nmzconeproperty; if not IsNumericalSemigroup(s) then Error("The argument must be a numerical semigroup.\n"); fi; # if not IsPackageMarkedForLoading("NormalizInterface","0.0") then # Error("The package NormalizInterface is not loaded.\n"); # fi; l:=MinimalGeneratingSystemOfNumericalSemigroup(s); n:=Length(l); ones:=List([1..n],_->1); mat:=[]; mat[1]:=Concatenation(l,-l,[0]); mat[2]:=Concatenation(ones,-ones,[1]); # nmzcone:=ValueGlobal("NmzCone");#Display(mat); # ncone:=nmzcone(["equations",mat]); # nmzconeproperty:=ValueGlobal("NmzConeProperty"); # facs:=nmzconeproperty(ncone,"HilbertBasis"); facs:=HilbertBasisOfSystemOfHomogeneousEquations(mat,[]); facs:=Set(facs,m->m{[1..n]}); return Set(facs, f-> f*l); end); ########################################################################### #F EqualPrimitiveElementsOfNumericalSemigroup(s) ## ## Computes the sets of elements in s, such that there exists a minimal ## solution to msg*x-msg*y = 0, |x|=|y| such that x,y are factorizations of s ## Used to compute the equal catenary degree of the semigroup ## ############################################################################# InstallGlobalFunction(EqualPrimitiveElementsOfNumericalSemigroup,function(s) local l, n, facs, mat, ones, ncone, nmzcone,nmzconeproperty; if not IsNumericalSemigroup(s) then Error("The argument must be a numerical semigroup.\n"); fi; # if not IsPackageMarkedForLoading("NormalizInterface","0.0") then # Error("The package NormalizInterface is not loaded.\n"); # fi; l:=MinimalGeneratingSystemOfNumericalSemigroup(s); n:=Length(l); ones:=List([1..n],_->1); mat:=[]; mat[1]:=Concatenation(l,-l); mat[2]:=Concatenation(ones,-ones); # nmzcone:=ValueGlobal("NmzCone");#Display(mat); # ncone:=nmzcone(["equations",mat]); # nmzconeproperty:=ValueGlobal("NmzConeProperty"); # facs:=nmzconeproperty(ncone,"HilbertBasis"); facs:=HilbertBasisOfSystemOfHomogeneousEquations(mat,[]); facs:=Set(facs,m->m{[1..n]}); return Set(facs, f-> f*l); end); #################################################################### #F EqualCatenaryDegreeOfNumericalSemigroup(s) computes the ## adjacent catenary degree of the numerical semigroup s ## the equal catenary degree is reached in the set of primitive ## elements of s (see [PH]) #################################################################### InstallGlobalFunction(EqualCatenaryDegreeOfNumericalSemigroup,function(s) local prim, msg; if not IsNumericalSemigroup(s) then Error("The argument must be a numerical semigroup.\n"); fi; # if not IsPackageMarkedForLoading("NormalizInterface","0.0") then # Error("The package NormalizInterface is not loaded.\n"); # fi; msg:=MinimalGeneratingSystemOfNumericalSemigroup(s); prim:=EqualPrimitiveElementsOfNumericalSemigroup(s); return Maximum(Set(prim, n-> EqualCatenaryDegreeOfSetOfFactorizations( FactorizationsIntegerWRTList(n,msg)))); end); #################################################################### #F MonotoneCatenaryDegreeOfNumericalSemigroup(s) computes the ## adjacent catenary degree of the numerical semigroup s ## the monotone catenary degree is reached in the set of primitive ## elements of s (see [PH]) #################################################################### InstallGlobalFunction(MonotoneCatenaryDegreeOfNumericalSemigroup,function(s) local prim, msg; if not IsNumericalSemigroup(s) then Error("The argument must be a numerical semigroup.\n"); fi; # if not IsPackageMarkedForLoading("NormalizInterface","0.0") then # Error("The package NormalizInterface is not loaded.\n"); # fi; msg:=MinimalGeneratingSystemOfNumericalSemigroup(s); prim:=MonotonePrimitiveElementsOfNumericalSemigroup(s); return Maximum(Set(prim, n-> MonotoneCatenaryDegreeOfSetOfFactorizations( FactorizationsIntegerWRTList(n,msg)))); end); ##################################################################### ## #O FengRaoDistance(NS,r,m) ## # Computes the r-th Feng-Rao distance of the element m in the numerical semigroup NS # function originally implemented by Benjamin Heredia ## ##################################################################### InstallMethod(FengRaoDistance, "Feng-Rao distance of element in Numerical Semigroup", [IsNumericalSemigroup,IsPosInt,IsPosInt], function(s,r,m) local conductor, multiplicity, final, elementsUpToFinal, divisorsOfMany2, addOne2, posiblesOfLen2; conductor := ConductorOfNumericalSemigroup(s); multiplicity := MultiplicityOfNumericalSemigroup(s); final := Maximum([m+multiplicity-1,conductor+multiplicity-1]); # elementsUpToFinal := FirstElementsOfNumericalSemigroup(final,s); elementsUpToFinal := Intersection([0..final],FirstElementsOfNumericalSemigroup(final+r,s)); #local functions # This function gives the set of divisors of several elements divisorsOfMany2 := function(lst) return Union(List(lst, x -> DivisorsOfElementInNumericalSemigroup(s,x))); end; # addOne(s,m,lst) gives back X(m;lst) as in the notes. That is the set used # to compute the X^r(m) from X^{r-1}(m). addOne2 := function(lst) local prec, pos1, pos2; if IsEmpty(lst) then return Intersection([m..final],elementsUpToFinal); else prec := Reversed(lst)[1]; if (prec<final) then pos1 := Intersection([prec+1..final],elementsUpToFinal); else pos1 := []; fi; # pos2 := Filtered(List(lst, x -> x+multiplicity), y -> y>prec); pos2 := Filtered(lst+multiplicity, y -> y>prec); return Union(pos1,pos2); fi; end; # This functions gives back X^r(m) recursively. posiblesOfLen2 := function(r) local lst, tot; if r = 1 then return List(addOne2([]), x -> [x]); else lst := posiblesOfLen2(r-1); tot := List(lst,x -> List(addOne2(x),y -> Concatenation(x,[y]))); return Union(tot); fi; end; # end of local functions # And here it is the Feng-Rao distance return Minimum(List(posiblesOfLen2(r), d -> Length(divisorsOfMany2(d)))); end); ########################################################################### ## #O FengRaoNumber(NS,r) #O FengRaoNumber(r,NS) # returns the r-Feng Rao number of a numerical semigroup NS ##################################################################### InstallMethod(FengRaoNumber,"Feng-Rao number for a numerical semigroup", [IsNumericalSemigroup,IsPosInt], function(NS,r) local fr, m, gens, a, ne, dm, fe, aux, span, generators_for_lists_for_Feng_Rao, LIST, RES, numbers, M, divs; fr := FrobeniusNumberOfNumericalSemigroup(NS); m := 2*fr+1; gens := MinimalGeneratingSystemOfNumericalSemigroup(NS); a := MultiplicityOfNumericalSemigroup(NS); ne := gens[Length(gens)]; dm := DivisorsOfElementInNumericalSemigroup(NS,m); fe := Union(SmallElementsOfNumericalSemigroup( NS ),[fr+1..m+1+ne]); ########################################################################### ##################### local functions ########################################################################### ## computes, see remarks in [DelgadoFarranGarcia-SanchezLlena2013MC], the union of the divisors of the elements in the configuration that are not divisors of m aux := function(configuration) local u, i; u := []; for i in [2..Length(configuration)] do u := Union(u,(m-configuration[i])+fe); od; return Difference(u,fe); end; span := function(conf) local u, i; u := []; for i in [1..Length(conf)] do u := Union(u,DivisorsOfElementInNumericalSemigroup(NS,conf[i])); od; return Difference(Filtered(u,n->n>0),dm); end; ################################################################# #This function computes configurations of length r, starting in m and satisfying the property FR, among which the r-Feng Rao number of the numerical sgp NS can be computed # Besides the property FR, it uses also the fact that two configurations of the same length satisfying the property FR and having the same shadow (intersection with [m..m+ne-1] (the "ground")) have the same number of divisors # generators_for_lists_for_Feng_Rao:=function() local rho2, fr, gens, el, elts, elts0, ne, span2, salida, i, salidan, x, min, mj, Dmj_aux, divs, divlist; rho2 := MultiplicityOfNumericalSemigroup(NS); fr := FrobeniusNumberOfNumericalSemigroup(NS); gens := MinimalGeneratingSystemOfNumericalSemigroup(NS); el := FirstElementsOfNumericalSemigroup(r,NS); elts := el{[2..r]}; elts0 := Union([0],elts); elts := Intersection(elts,gens); # as the configuration is computed recursively, it suffices to work with generators ne := gens[Length(gens)]; ##################### ## computes the union of the divisors of the elements in conf that are greater than m span2 := function(conf) local fe, u, i; u := []; for i in [1..Length(conf)] do u := Union(u,Filtered(conf[i]-elts0,n -> n>=m)); od; return u; end; if r=0 then return [[]]; fi; salida := [[m]]; for i in [2..r] do salidan := []; for x in salida do min := Minimum(x[Length(x)]+rho2,m+el[i]); divlist := span2(x); for mj in [x[Length(x)]+1..min] do Dmj_aux := Set(mj - elts);#strict divisors of mj among which are those greater than m divs := Intersection(Dmj_aux,[m..mj-rho2]); if IsSubset(divlist, divs) then Append(salidan,[Difference(Union(x,[mj]),divs)]); if mj > m + ne then #This ensures that the configurations constructed have different shadows break; fi; fi; od; od; salida := salidan; od; return salida; end; ########################################################################### ##################### end of local functions ########################################################################### LIST := generators_for_lists_for_Feng_Rao(); Info(InfoNumSgps,3, "The possible configurations have been computed: ",Length(LIST),"\n"); RES := []; numbers := []; for M in LIST do divs := span(M); AddSet(numbers,Length(divs)); od; return numbers[1]; end); ################################################# ##################################################################### InstallMethod(FengRaoNumber,"Feng-Rao number for a numerical semigroup", [IsPosInt,IsNumericalSemigroup], function(r,NS) return FengRaoNumber(NS,r); end);