diff --git a/Demo.m2 b/Demo.m2 index 09a4fc0..fdd2c5c 100644 --- a/Demo.m2 +++ b/Demo.m2 @@ -101,10 +101,10 @@ isInvariant((J.gens)_(0,0),L) restart needsPackage "InvariantRing" R = QQ[x_1..x_4] -L = apply({"2134","2341"},permutationMatrix); +L = apply({[2,1,3,4],[2,3,4,1]},permutationMatrix); S4 = finiteAction(L,R) elapsedTime invariants S4 -elapsedTime invariants(S4,UseLinearAlgebra=>true) +elapsedTime invariants(S4,Strategy=>"LinearAlgebra") elapsedTime p=primaryInvariants S4 elapsedTime secondaryInvariants(p,S4) elapsedTime hironakaDecomposition(S4) @@ -159,3 +159,46 @@ M=transpose ( ) d=discriminant det M ideal d==ideal first inv + + +-- 2x2 conjugation invariants +restart +needsPackage "InvariantRing" +S = QQ[g_(1,1)..g_(2,2),t] +I = ideal((det genericMatrix(S,2,2))*t-1) +Q = S/I +A = Q[y_(1,1)..y_(2,2)] +Y = transpose genericMatrix(A,2,2) +-- generic group element +g = promote(genericMatrix(S,2,2),A) +-- act by conjugation on a 2x2 generic matrix +-- get corresponding action of 1x4 matrix of variables +G = reshape(A^1,A^4,g*Y*inverse(g)) // (vars A) +G = lift(map(A^4,A^4,G),S) + +R = QQ[x_(1,1)..x_(2,2)] +L=linearlyReductiveAction(I,G,R) +elapsedTime H=hilbertIdeal(L) +elapsedTime invariants L + + +-- 3x3 conjugation invariants +restart +needsPackage "InvariantRing" +S = QQ[g_(1,1)..g_(3,3),t] +I = ideal((det genericMatrix(S,3,3))*t-1) +Q = S/I +A = Q[y_(1,1)..y_(3,3)] +Y = transpose genericMatrix(A,3,3) +-- generic group element +g = promote(genericMatrix(S,3,3),A) +-- act by conjugation on a 2x2 generic matrix +-- get corresponding action of 1x4 matrix of variables +G = reshape(A^1,A^9,g*Y*inverse(g)) // (vars A) +G = lift(map(A^9,A^9,G),S) +R = QQ[x_(1,1)..x_(3,3)] +L=linearlyReductiveAction(I,G,R) +elapsedTime H=hilbertIdeal(L) +elapsedTime invariants(L,1) +elapsedTime invariants(L,2) +elapsedTime invariants(L,3) diff --git a/InvariantRing.m2 b/InvariantRing.m2 index b628305..1724b92 100644 --- a/InvariantRing.m2 +++ b/InvariantRing.m2 @@ -9,8 +9,8 @@ newPackage( "InvariantRing", - Version => "2.1", - Date => "July 9, 2021", + Version => "2.2", + Date => "July 8, 2022", Authors => { {Name => "Luigi Ferraro", Email => "lferraro@ttu.edu", @@ -30,7 +30,7 @@ newPackage( }, {Name => "Thomas Hawes", Email => "thomas.hawes@maths.ox.ac.uk"}, {Name => "Matthew Mastroeni", - Email => "mmastro@okstate.edu", + Email => "mmastro@iastate.edu", HomePage => "https://mnmastro.github.io/" }, {Name => "Xianglong Ni", @@ -52,43 +52,54 @@ newPackage( "volume URI" => "http://j-sag.org/Volume5/" }, AuxiliaryFiles => true, - DebuggingMode => false + DebuggingMode => false, + PackageExports => { + "Graphs" + } ) export { - "GroupAction", - "finiteAction", - "FiniteGroupAction", + -- New Types + "GroupAction", + "FiniteGroupAction", + "DiagonalAction", + "LinearlyReductiveAction", + + --FiniteGroups.m2 + "finiteAction", "group", "isAbelian", "permutationMatrix", "schreierGraph", - "words", - "cyclicFactors", - "DiagonalAction", + "words", + + --AbelianGroups.m2 + "cyclicFactors", "diagonalAction", "equivariantHilbert", "equivariantHilbertSeries", - "weights", + "weights", + + --LinearlyReductiveGroups.m2 "actionMatrix", "groupIdeal", "hilbertIdeal", - "linearlyReductiveAction", - "LinearlyReductiveAction", + "linearlyReductiveAction", + + --Invariants.m2 "action", "definingIdeal", "DegreeBound", "invariants", "invariantRing", "isInvariant", - "reynoldsOperator", - "UseLinearAlgebra", + "reynoldsOperator", "RingOfInvariants", - "UseCoefficientRing", - "UseNormaliz", - "UsePolyhedra", + "UseCoefficientRing", + + --Hawes.m2 "hironakaDecomposition", "molienSeries", "primaryInvariants", @@ -98,7 +109,6 @@ export { "PrintDegreePolynomial" } - needsPackage("Elimination") needsPackage("Normaliz") needsPackage("Polyhedra") diff --git a/InvariantRing/AbelianGroups.m2 b/InvariantRing/AbelianGroups.m2 index 6b5f9db..d0ed3f3 100644 --- a/InvariantRing/AbelianGroups.m2 +++ b/InvariantRing/AbelianGroups.m2 @@ -127,6 +127,8 @@ equivariantHilbertSeries DiagonalAction := op -> T -> ( ) ) +-- computes equivariant hilbert series as rational function +-- INPUT: T, DiagonalAction equivariantHilbertRational = T -> ( n := dim T; W1 := first weights T; @@ -143,6 +145,8 @@ equivariantHilbertRational = T -> ( Divide{1,den} ) +-- computes equivariant hilbert series up to a given degree +-- INPUT: T, DiagonalAction equivariantHilbertPartial = (T, d) -> ( if not T.cache.?equivariantHilbert then ( T.cache.equivariantHilbert = 1_(degreesRing T); diff --git a/InvariantRing/FiniteGroups.m2 b/InvariantRing/FiniteGroups.m2 index 381bd4d..3472742 100644 --- a/InvariantRing/FiniteGroups.m2 +++ b/InvariantRing/FiniteGroups.m2 @@ -46,29 +46,26 @@ numgens FiniteGroupAction := ZZ => G -> G.numgens ------------------------------------------- -isAbelian = method() +isAbelian = method(Options => true) -isAbelian FiniteGroupAction := { } >> opts -> (cacheValue (symbol isAbelian)) (G -> runHooks(FiniteGroupAction, symbol isAbelian, G) ) +isAbelian FiniteGroupAction := { } >> opts -> (cacheValue (symbol isAbelian)) ( + G -> runHooks((isAbelian, FiniteGroupAction), G) ) -addHook(FiniteGroupAction, symbol isAbelian, G -> break ( +addHook((isAbelian, FiniteGroupAction), G -> ( X := G.generators; n := #X; - if n == 1 then( - true - ) - else( - all(n - 1, i -> all(n - 1 - i, j -> (X#j)*(X#(n - 1 - i)) == (X#(n - 1 - i))*(X#j) ) ) - ) - )) + if n == 1 then true + else all(n - 1, i -> all(n - 1 - i, j -> (X#j)*(X#(n - 1 - i)) == (X#(n - 1 - i))*(X#j) ) ) + )) -generateGroup = method() +generateGroup = method(Options => true) -generateGroup FiniteGroupAction := { } >> opts -> (cacheValue (symbol generateGroup)) (G -> runHooks(FiniteGroupAction, symbol generateGroup, G) ) +generateGroup FiniteGroupAction := {} >> opts -> (cacheValue (symbol generateGroup)) (G -> runHooks((generateGroup, FiniteGroupAction), G) ) -addHook(FiniteGroupAction, symbol generateGroup, G -> break ( +addHook((generateGroup, FiniteGroupAction), G -> ( m := numgens G; n := dim G; K := coefficientRing ring G; @@ -111,40 +108,37 @@ addHook(FiniteGroupAction, symbol generateGroup, G -> break ( ------------------------------------------- -schreierGraph = method() +schreierGraph = method(Options => true) -schreierGraph FiniteGroupAction := { } >> opts -> (cacheValue (symbol schreierGraph)) (G -> runHooks(FiniteGroupAction, symbol schreierGraph, G) ) +schreierGraph FiniteGroupAction := {} >> opts -> (cacheValue (symbol schreierGraph)) (G -> runHooks((schreierGraph, FiniteGroupAction), G) ) -addHook(FiniteGroupAction, symbol schreierGraph, - G -> break (generateGroup G)_0 - ) +addHook((schreierGraph, FiniteGroupAction), G -> (generateGroup G)_0 ) ------------------------------------------- -group = method() +group = method(Options => true) -group FiniteGroupAction := { } >> opts -> (cacheValue (symbol group)) (G -> runHooks(FiniteGroupAction, symbol group, G) ) +group FiniteGroupAction := { } >> opts -> (cacheValue (symbol group)) (G -> runHooks((group, FiniteGroupAction), G) ) + +addHook((group, FiniteGroupAction), G -> keys first schreierGraph G ) -addHook(FiniteGroupAction, symbol group, - G -> break keys first schreierGraph G - ) ------------------------------------------- -words = method() +words = method(Options => true) -words FiniteGroupAction := { } >> opts -> (cacheValue (symbol words)) (G -> runHooks(FiniteGroupAction, symbol words, G) ) +words FiniteGroupAction := { } >> opts -> (cacheValue (symbol words)) (G -> runHooks((words, FiniteGroupAction), G) ) + +addHook((words, FiniteGroupAction), G -> applyValues((generateGroup G)_1, val -> first val) ) -addHook(FiniteGroupAction, symbol words, - G -> break applyValues((generateGroup G)_1, val -> first val) - ) ------------------------------------------- -relations FiniteGroupAction := { } >> opts -> (cacheValue (symbol relations)) (G -> runHooks(FiniteGroupAction, symbol relations, G) ) +relations FiniteGroupAction := { } >> opts -> (cacheValue (symbol relations)) ( + G -> runHooks((relations, FiniteGroupAction), G) ) -addHook(FiniteGroupAction, symbol relations, G -> break ( +addHook((relations, FiniteGroupAction), G -> ( relators := values last generateGroup G; W := apply(relators, r -> first r); relators = flatten apply(#W, i -> apply(drop(relators#i, 1), a -> {W#i,a} ) ); @@ -159,57 +153,43 @@ addHook(FiniteGroupAction, symbol relations, G -> break ( unique relators )) + ------------------------------------------- -permutationMatrix = method() +permutationMatrix = method(Options => {EntryMode => "one-line"}) -permutationMatrix String := Matrix => s -> ( - n := #s; - p := apply(n, i -> ( - v := value(s#i); - if v <= 0 or v > n then ( - error "permutationMatrix: Expected a string of positive integers - representing a permutation." - ) - else v - ) - ); - if #(unique p) =!= n then ( - error "permutationMatrix: Expected a string of distinct integers." - ); - matrix apply(n, i -> - apply(n, j -> if p#j - 1 == i then 1 else 0) +permutationMatrix Array := Matrix => opts -> p -> ( + if opts.EntryMode == "cycle" then permutationMatrix(max p, p) + else ( + n := max p; + if #p =!= n or set (1..n) =!= set p then ( + error "permutationMatrix: Expected a sequence of positive integers + representing a permutation." + ); + matrix apply(n, i -> apply(n, j -> if p#j - 1 == i then 1 else 0) ) ) ) -permutationMatrix (ZZ, Array) := Matrix => (n, c) -> permutationMatrix(n, {c}) - -permutationMatrix (ZZ, List) := Matrix => (n, p) -> ( - if n <= 0 then (error "permutationMatrix: Expected the first input to be a positive integer."); - if any(p, c -> not instance(c, Array) or any(c, i -> i <= 0 or i > n)) then ( - error "permutationMatrix: Expected the second input to be a list of arrays - with integer entries between 1 and the first input." +permutationMatrix (ZZ, Array) := Matrix => opts -> (n, c) -> ( + if n <= 0 then error "permutationMatrix: Expected a positive integer."; + if #c == 0 then error "permutationMatrix: Expected a nonempty array,"; + if #(set c) =!= #c or not isSubset(set c, set(1..n)) then ( + error "permutationMatrix: Expected an array of distinct integers + between 1 and the first input." ); - if any(p, c -> #(unique toList c) =!= #c) then (error "permutationMatrix: Expected each sequence in - the list to have distinct entries."); - s := new MutableHashTable from apply(n, i -> i + 1 => i + 1); - scan(p, c -> ( - k := #c; - u := hashTable pairs s; - scan(k, j -> ( - if j < k - 1 then s#(c_j) = u#(c_(j+1)) - else s#(c_j) = u#(c_0) - ) - ) + permutationMatrix new Array from apply(n, i -> + if (set c)#?(i + 1) then ( + k := position(c, j -> j == i + 1); + if k == #c - 1 then c#0 else c#(k + 1) ) - ); - s = horizontalJoin apply(values s, i -> toString i); - permutationMatrix toString s - ) - -permutationMatrix Array := Matrix => c -> permutationMatrix(max c, c) + else i + 1 + ) + ) + +permutationMatrix (ZZ, List) := Matrix => opts -> (n, p) -> product apply(p, c -> permutationMatrix(n, c) ) -permutationMatrix List := Matrix => p -> permutationMatrix(max (p/max), p) +permutationMatrix List := Matrix => opts -> p -> permutationMatrix(max (p/max), p) + diff --git a/InvariantRing/FiniteGroupsDoc.m2 b/InvariantRing/FiniteGroupsDoc.m2 index fe588e6..831f2f5 100644 --- a/InvariantRing/FiniteGroupsDoc.m2 +++ b/InvariantRing/FiniteGroupsDoc.m2 @@ -47,7 +47,7 @@ document { }, EXAMPLE { - "P = permutationMatrix toString 231", + "P = permutationMatrix [2, 3, 1]", "C3 = finiteAction(P, R)", }, } @@ -297,21 +297,22 @@ document { document { - Key => {permutationMatrix, - (permutationMatrix, String), + Key => {permutationMatrix, + (permutationMatrix, Array), (permutationMatrix, ZZ, Array), (permutationMatrix, ZZ, List), - (permutationMatrix, Array), - (permutationMatrix, List) + (permutationMatrix, List), + [permutationMatrix, EntryMode] }, Headline => "convert a one-line notation or cyclic notation of a permutation to a matrix representation", - Usage => "permutationMatrix s, permutationMatrix(n , c)", + Usage => "permutationMatrix c, \n permutationMatrix(n , c), \n permutationMatrix(n, p), \n permutationMatrix p", Inputs => { - "s" => String => {"an array or a list of arrays giving a one-line notation or cyclic notation of a permutation"}, - "n" => ZZ => {"giving the number of intergers getting permuted"}, - "c" => List => {"of arrays giving a cyclic notation of a permutation"} + "c" => Array => {"of positive integers representing a permutation in one-line notation or + representing a cyclic permutation"}, + "p" => List => {"of arrays representing a permutation as a product of cycles"}, + "n" => ZZ => {"giving the number of integers being permuted"}, }, Outputs => { Matrix => {"the matrix representation of the permutation"} @@ -324,25 +325,34 @@ document { }, EXAMPLE { - "M = permutationMatrix toString 213", + "M = permutationMatrix [2, 1, 3]", }, PARA { - "The following example converts the cyclic notation of the same transposition into a matrix representation. Without ",TT "n"," the function assumes ",TT "n"," is the largest integer that appears in your array or list of arrays." + "The following example converts the cyclic notation of the same transposition into a matrix representation." }, EXAMPLE { "M = permutationMatrix(3,[1,2])", - "M = permutationMatrix [1,2]", }, + + PARA { + "If ",TT "n"," is the largest integer that appears in your array, the value of ", TT "n", " can be omitted by + using the option ", TT "EntryMode => \"cycle\"", "." + }, + + EXAMPLE { + "M = permutationMatrix([1,2], EntryMode => \"cycle\")", + }, + PARA { "The following example converts the cyclic notation of a permutation of 4 into a matrix representation." }, EXAMPLE { "M = permutationMatrix(4,{[1,2],[3,4]})", - "M = permutationMatrix {[1,2],[3,4]}", }, } + document { Key => {(relations, FiniteGroupAction)}, Headline => "relations of a finite group", diff --git a/InvariantRing/HawesDoc.m2 b/InvariantRing/HawesDoc.m2 index 7eb558c..6f1f28b 100644 --- a/InvariantRing/HawesDoc.m2 +++ b/InvariantRing/HawesDoc.m2 @@ -37,8 +37,8 @@ document { TT "({f", SUB TT "1", TT ",...," , TT "f", SUB TT "n", TT "}, {g", SUB TT "1", TT ",...," , TT "g", SUB TT "r", TT"})", " of primary and secondary invariants such that ", - TT "R", SUP TT "G", TT "=A", TT "g", SUB TT "1", TEX "\\oplus", - TT "...", TEX "\\oplus", TT "A", TT "g", SUB TT "r", ", where ", TT "A=K[", + TT "R", SUP TT "G", TT "=A", TT "g", SUB TT "1", "$\\oplus$", + TT "...", "$\\oplus$", TT "A", TT "g", SUB TT "r", ", where ", TT "A=K[", TT "f", SUB TT "1", TT ",...," , TT "f", SUB TT "n", TT "]", " and ", TT "K", " is the field of coefficients of ", TT "R", "." @@ -63,7 +63,7 @@ document { }, PARA{ "From the output one sees that ", TT "QQ[x,y]", SUP(TT "C4"), - TT "=QQ[f", SUB(TT "1"), TT "f", SUB(TT "2"), TT "]", TEX "\\oplus", TT "QQ[f", + TT "=QQ[f", SUB(TT "1"), TT "f", SUB(TT "2"), TT "]", "$\\oplus$", TT "QQ[f", SUB(TT "1"), TT "f", SUB(TT "2"), TT "](x", SUP(TT "4"), TT "+y", SUP(TT "4"), TT ")", ", where ", TT "f", SUB(TT "1"), TT "=x", SUP(TT "2"), TT "+y", SUP(TT "2"), " and ",TT "f", SUB(TT "2"), TT "=xy", diff --git a/InvariantRing/InvariantRingDoc.m2 b/InvariantRing/InvariantRingDoc.m2 index 4b3cee7..68c5323 100644 --- a/InvariantRing/InvariantRingDoc.m2 +++ b/InvariantRing/InvariantRingDoc.m2 @@ -72,6 +72,9 @@ document { fixes a warning that appeared when computing invariants of finite groups (the authors thank N. Iammarino, T. Yu, and Q. Zhao for the fix)." + }, + {BOLD "2.2: ", "changed input of ", TO permutationMatrix, + ", minor documentation and internal code changes." } } } diff --git a/InvariantRing/Invariants.m2 b/InvariantRing/Invariants.m2 index ed81409..68e4904 100644 --- a/InvariantRing/Invariants.m2 +++ b/InvariantRing/Invariants.m2 @@ -14,8 +14,7 @@ RingOfInvariants = new Type of HashTable invariantRing = method(Options => { - Strategy => UseNormaliz, - UseLinearAlgebra => false, + Strategy => "Default", UseCoefficientRing => false, DegreeBound => infinity }) @@ -113,8 +112,7 @@ reynoldsOperator (RingElement, DiagonalAction) := RingElement => (f, D) -> sum s ------------------------------------------- invariants = method(Options => { - Strategy => UseNormaliz, - UseLinearAlgebra => false, + Strategy => "Default", UseCoefficientRing => false, DegreeBound => infinity, DegreeLimit => {}, @@ -179,11 +177,11 @@ invariants DiagonalAction := List => o -> D -> ( if r == 0 then return apply(mons, m -> sub(m, ring D) ); W1 = W1*(transpose matrix (mons/exponents/first)); - if o.Strategy == UsePolyhedra then ( + if o.Strategy == "Polyhedra" then ( if r == 1 then C = convexHull W1 else C = convexHull( 2*r*W1|(-2*r*W1) ); C = (latticePoints C)/vector; ) - else if o.Strategy == UseNormaliz then ( + else ( if r == 1 then C = (normaliz(transpose W1, "polytope"))#"gen" else C = (normaliz(transpose (2*r*W1|(-2*r*W1)), "polytope"))#"gen"; C = transpose C_(apply(r, i -> i)); @@ -246,7 +244,7 @@ manualTrim (List) := List => L -> ( ------------------------------------------- -- Computes an *additive* basis for the degree d part of the -- invariant ring following Algorithm 4.5.1 of Derksen-Kemper. -invariants (LinearlyReductiveAction, List) := List => o -> (V,d) -> ( +invariants (LinearlyReductiveAction, List) := List => o -> (V, d) -> ( M := actionMatrix V; Q := ring V; A := groupIdeal V; @@ -329,7 +327,7 @@ invariants FiniteGroupAction := List => o -> G -> ( M = reverse select(flatten entries (basis(d,R)%I),m->not zero m); if d == b+1 then break; if M === {} then break else ( - if o.UseLinearAlgebra then ( + if o.Strategy == "LinearAlgebra" then ( for f in invariants(G,d) do ( g := f % Gb; if not zero g then ( @@ -337,7 +335,8 @@ invariants FiniteGroupAction := List => o -> G -> ( Gb = forceGB ( (gens Gb) | matrix{{g}} ); ); ); - ) else ( + ) + else ( for m in M do ( f := reynoldsOperator(m,G); g := f % Gb; diff --git a/InvariantRing/InvariantsDoc.m2 b/InvariantRing/InvariantsDoc.m2 index 91957ef..0fa1ee4 100644 --- a/InvariantRing/InvariantsDoc.m2 +++ b/InvariantRing/InvariantsDoc.m2 @@ -81,7 +81,6 @@ document { Inputs => { "G" => GroupAction, "R" => PolynomialRing => {"on which the group acts"}, - Strategy => {"the strategy used to compute the invariant ring"} }, Outputs => { RingOfInvariants => {"the ring of invariants of the given group action"} @@ -137,7 +136,6 @@ document { Inputs => { "G" => GroupAction => {"a specific type of group action on a polynomial ring"}, - Strategy => {"the strategy used to compute diagonal invariants, options are UsePolyhedra or UseNormaliz."} }, Outputs => { "L" => List => {"a minimal set of generating invariants for the group action"} @@ -171,7 +169,7 @@ document { document { Key => { - (invariants, DiagonalAction) + (invariants, DiagonalAction) }, Headline => "computes the generating invariants of a group action", @@ -180,7 +178,6 @@ document { Inputs => { "D" => DiagonalAction => {"a diagonal action on a polynomial ring"}, - Strategy => {"the strategy used to compute diagonal invariants, options are UsePolyhedra or UseNormaliz."} }, Outputs => { "L" => List => {"a minimal set of generating invariants for the group action"} @@ -289,6 +286,56 @@ document { isInvariant } } + +document { + Key => { + [invariants, Strategy], [invariantRing, Strategy] + }, + Headline => "choose the strategy for computing invariants", + + PARA { + "The default strategy for computing invariants of a finite + group action uses the Reynolds operator, however + this may be slow for large groups. Using the option ", + TT "Strategy => \"LinearAlgebra\"", " uses the linear algebra + method for computing invariants of a given degree by calling ", + TO (invariants, FiniteGroupAction, ZZ), ". This may + provide a speedup at lower degrees, especially if the + user-provided generating set for the group is small." + }, + + PARA { + "The following example computes the invariants of the + symmetric group on 4 elements. Note that using + different strategies may lead to different sets of + generating invariants." + }, + + EXAMPLE { + "R = QQ[x_1..x_4]", + "L = apply({[2, 1, 3, 4], [2, 3, 4, 1]}, permutationMatrix);", + "S4 = finiteAction(L, R)", + "elapsedTime invariants S4", + "elapsedTime invariants(S4, Strategy => \"LinearAlgebra\")" + }, + + PARA { + "For a diagonal action, the computation of invariants relies on + finding integral points in a convex hull constructed + from a weight matrix. By default, the package ", TO Normaliz, + " is used for finding integral points. It is also possible + to use the package ", TO Polyhedra, " for finding integral points + by using the option ", TT "Strategy => \"Polyhedra\"", "." + }, + + SeeAlso => { + diagonalAction, + invariants, + invariantRing, + reynoldsOperator + } + + } document { Key => { @@ -298,7 +345,6 @@ document { Usage => "invariants G", Inputs => { "G" => FiniteGroupAction, - Strategy => {"the strategy used to compute diagonal invariants, options are UsePolyhedra or UseNormaliz."} }, Outputs => { "L" => List => {"a minimal set of generating invariants for the group action"} @@ -321,11 +367,11 @@ document { "The following example computes the invariants of the alternating group on 4 elements." }, - EXAMPLE { - "R = QQ[x_1..x_4]", - "L = apply({\"2314\",\"2143\"},permutationMatrix);", - "A4 = finiteAction(L,R)", - "netList invariants A4" + EXAMPLE { + "R = QQ[x_1..x_4]", + "L = apply({[2, 3, 1, 4], [2, 1, 4, 3]}, permutationMatrix);", + "A4 = finiteAction(L, R)", + "netList invariants A4" }, SeeAlso => { @@ -364,10 +410,10 @@ document { }, EXAMPLE { "R = QQ[x_1..x_4]", - "L = apply({\"2134\",\"2341\"},permutationMatrix);", - "S4 = finiteAction(L,R)", + "L = apply({[2, 1, 3, 4], [2, 3, 4, 1]}, permutationMatrix);", + "S4 = finiteAction(L, R)", "elapsedTime invariants S4", - "elapsedTime invariants(S4,DegreeBound=>4)" + "elapsedTime invariants(S4, DegreeBound => 4)" }, Caveat => { "If the value provided for this option is too small, @@ -436,55 +482,6 @@ document { } } -document { - Key => { - [invariants, UseLinearAlgebra], [invariantRing, UseLinearAlgebra], UseLinearAlgebra - }, - Headline => "strategy for computing invariants of finite groups", - Usage => "invariants G", - Inputs => {"G" => FiniteGroupAction}, - Outputs => { - "L" => List => {"a minimal set of generating invariants for the group action"} - }, - - PARA { - "This function is provided by the package ", TO InvariantRing, "." - }, - - PARA { - "This optional argument determines the strategy used to - compute generating invariants of a finite group action. - The default strategy uses the Reynolds operator, however - this may be slow for large groups. Setting this argument - to ", TO true, " uses the linear algebra method for - computing invariants of a given degree by calling ", - TO (invariants, FiniteGroupAction, ZZ), ". This may - provide a speedup at lower degrees, especially if the - user-provided generating set for the group is small." - }, - - PARA { - "The following example computes the invariants of the - symmetric group on 4 elements. Note that using - different strategies may lead to different sets of - generating invariants." - }, - - EXAMPLE { - "R = QQ[x_1..x_4]", - "L = apply({\"2134\",\"2341\"},permutationMatrix);", - "S4 = finiteAction(L,R)", - "elapsedTime invariants S4", - "elapsedTime invariants(S4,UseLinearAlgebra=>true)" - }, - - SeeAlso => { - finiteAction, - invariantRing, - isInvariant - } - } - document { Key => { (invariants, FiniteGroupAction, ZZ), @@ -497,8 +494,7 @@ document { Inputs => { "G" => FiniteGroupAction, - "d" => ZZ => {"a degree or multidegree"}, - Strategy => {"the strategy used to compute diagonal invariants, options are UsePolyhedra or UseNormaliz."} + "d" => ZZ => {"a degree or multidegree"} }, Outputs => { "L" => List => {"an additive basis for a graded component of the ring of invariants"} @@ -559,8 +555,7 @@ document { Inputs => { "V" => LinearlyReductiveAction, - "d" => ZZ => {"a degree or multidegree"}, - Strategy => {"the strategy used to compute diagonal invariants, options are UsePolyhedra or UseNormaliz."} + "d" => ZZ => {"a degree or multidegree"} }, Outputs => { "L" => List => {"an additive basis for a graded component of the ring of invariants"} @@ -616,8 +611,7 @@ document { Usage => "invariants V", Inputs => { - "V" => LinearlyReductiveAction, - Strategy => {"the strategy used to compute diagonal invariants, options are UsePolyhedra or UseNormaliz."} + "V" => LinearlyReductiveAction }, Outputs => { "L" => List => {"of invariants generating the Hilbert ideal"} @@ -842,7 +836,7 @@ document { EXAMPLE { "R = ZZ/3[x_0..x_6]", - "P = permutationMatrix toString 2345671", + "P = permutationMatrix [2, 3, 4, 5, 6, 7, 1]", "C7 = finiteAction(P, R)", "reynoldsOperator(x_0*x_1*x_2^2, C7)", }, @@ -965,16 +959,3 @@ document { }, } -document { - Key => {UseNormaliz, UsePolyhedra}, - Headline => "option for diagonal invariants", - "This option is provided by the package ", TO InvariantRing,". ", - PARA { - "The computation of diagonal invariants relies on - finding integral points in a convex hull constructed - from a weight matrix. This option selects the package - used for finding integral points. See ", - TO (invariants,DiagonalAction), - " for usage." - }, - } diff --git a/InvariantRing/LinearlyReductiveGroupsDoc.m2 b/InvariantRing/LinearlyReductiveGroupsDoc.m2 index 2ef3e75..b1a1be2 100644 --- a/InvariantRing/LinearlyReductiveGroupsDoc.m2 +++ b/InvariantRing/LinearlyReductiveGroupsDoc.m2 @@ -114,6 +114,10 @@ document { ". Heidelberg: Springer. pp 159-164"} }, + PARA { + "and works in arbitrary characteristic.", + }, + PARA { "The next example constructs a cyclic group of order 2 as a set of two affine points. Then it introduces an @@ -155,7 +159,11 @@ document { generators for the Hilbert ideal." }, Caveat => "The generators of the Hilbert ideal computed - by this function need not be invariant." + by this function need not be invariant. + + Although this method could in principle be used for any group + that can be represented as an affine variety, it tends to be + slow; other specialized methods are likely to be faster." } diff --git a/InvariantRing/Tests.m2 b/InvariantRing/Tests.m2 index a687fe3..12e6e75 100644 --- a/InvariantRing/Tests.m2 +++ b/InvariantRing/Tests.m2 @@ -278,8 +278,8 @@ R=QQ[x_1..x_4] S5=finiteAction({A,B},R) assert(#(group S5) === 120) assert(not isAbelian S5) -C=permutationMatrix toString 3124 -D=permutationMatrix toString 2143 +C=permutationMatrix [3, 1, 2, 4] +D=permutationMatrix [2, 1, 4, 3] A4=finiteAction({C,D},R) assert(#(group A4) === 12) assert(not isAbelian A4) @@ -324,8 +324,8 @@ assert(invariants D4 === {x*y,x^4+y^4}) TEST /// R = QQ[x,y,z] -r=permutationMatrix toString 312 -s=permutationMatrix toString 213 +r=permutationMatrix [3, 1, 2] +s=permutationMatrix [2, 1, 3] S3 = finiteAction({r,s},R) assert(isInvariant(x*y*z,S3)) assert(isInvariant(x+y+z,S3)) @@ -352,8 +352,8 @@ assert(value denominator H === sub((1-T)^3, ring value denominator H)) TEST /// K=GF(101) R=K[x,y,z] -r=permutationMatrix toString 312 -s=permutationMatrix toString 213 +r=permutationMatrix [3, 1, 2] +s=permutationMatrix [2, 1, 3] S3 = finiteAction({r,s},R) setRandomSeed 0 P=primaryInvariants(S3, Dade=>true)