This function looks at interesting minors of the jacobian matrix to try to verify that the ring is Rn. It is frequently much faster at giving an affirmative answer than computing the dimension of the ideal of all minors of the Jacobian. We begin with a simple example which is R1, but not R2.
i1 : R = QQ[x, y, z]/ideal(x*y-z^2); |
i2 : Rn(1, R) o2 = true |
i3 : Rn(2, R) |
Next we consider a more interesting example that is R1 but not R2, and highlight the speed differences. Note that Rn(2, R) returns nothing, as the function did not determine if the ring was Rn.
i4 : T = ZZ/101[x1,x2,x3,x4,x5,x6,x7]; |
i5 : I = ideal(x5*x6-x4*x7,x1*x6-x2*x7,x5^2-x1*x7,x4*x5-x2*x7,x4^2-x2*x6,x1*x4-x2*x5,x2*x3^3*x5+3*x2*x3^2*x7+8*x2^2*x5+3*x3*x4*x7-8*x4*x7+x6*x7,x1*x3^3*x5+3*x1*x3^2*x7+8*x1*x2*x5+3*x3*x5*x7-8*x5*x7+x7^2,x2*x3^3*x4+3*x2*x3^2*x6+8*x2^2*x4+3*x3*x4*x6-8*x4*x6+x6^2,x2^2*x3^3+3*x2*x3^2*x4+8*x2^3+3*x2*x3*x6-8*x2*x6+x4*x6,x1*x2*x3^3+3*x2*x3^2*x5+8*x1*x2^2+3*x2*x3*x7-8*x2*x7+x4*x7,x1^2*x3^3+3*x1*x3^2*x5+8*x1^2*x2+3*x1*x3*x7-8*x1*x7+x5*x7); o5 : Ideal of T |
i6 : S = T/I; |
i7 : dim S o7 = 3 |
i8 : time Rn(1, S) -- used 0.203472 seconds o8 = true |
i9 : time Rn(2, S) -- used 2.04579 seconds |
On one machine, a call of dim singularLocus R took 32.4468 seconds and returned 1. On the same machine, Rn(1, R) took only 0.153042 seconds.
The following is a (pruned) affine chart on Abelian surface (the product of elliptic curves). It is nonsingular, as our function verifies. If one does not prune it, then the dim singularLocus call takes an enormous amount of time, otherwise dim singularLocus frequently takes a similar amount of time to our function.
i10 : R = QQ[c, f, g, h]/ideal(g^3+h^3+1,f*g^3+f*h^3+f,c*g^3+c*h^3+c,f^2*g^3+f^2*h^3+f^2,c*f*g^3+c*f*h^3+c*f,c^2*g^3+c^2*h^3+c^2,f^3*g^3+f^3*h^3+f^3,c*f^2*g^3+c*f^2*h^3+c*f^2,c^2*f*g^3+c^2*f*h^3+c^2*f,c^3-f^2-c,c^3*h-f^2*h-c*h,c^3*g-f^2*g-c*g,c^3*h^2-f^2*h^2-c*h^2,c^3*g*h-f^2*g*h-c*g*h,c^3*g^2-f^2*g^2-c*g^2,c^3*h^3-f^2*h^3-c*h^3,c^3*g*h^2-f^2*g*h^2-c*g*h^2,c^3*g^2*h-f^2*g^2*h-c*g^2*h,c^3*g^3+f^2*h^3+c*h^3+f^2+c); |
i11 : dim(R) o11 = 2 |
i12 : time (dim singularLocus (R)) -- used 0.126238 seconds o12 = -1 |
i13 : time Rn(2, R) -- used 0.041347 seconds o13 = true |
i14 : time Rn(2, R) -- used 0.102062 seconds o14 = true |
i15 : time Rn(2, R) -- used 0.0940072 seconds o15 = true |
The function works by choosing interesting looking submatrices, computing their determinants, and periodically (based on a logarithmic growth setting), computing the dimension of a subideal of the Jacobian. The option Verbose can be used to see this in action.
i16 : time Rn(2, S, Verbose=>true) Rn: ring dimension =3, there are 17325 possible minors, we will compute up to 334 of them. Rn: About to enter loop Rn: Loop step, about to compute dimension. Submatrices considered: 11, and computed = 10 Rn: partial singular locus dimension computed, = 1 Rn: Loop step, about to compute dimension. Submatrices considered: 14, and computed = 12 Rn: partial singular locus dimension computed, = 1 Rn: Loop step, about to compute dimension. Submatrices considered: 18, and computed = 15 Rn: partial singular locus dimension computed, = 1 Rn: Loop step, about to compute dimension. Submatrices considered: 24, and computed = 16 Rn: partial singular locus dimension computed, = 1 Rn: Loop step, about to compute dimension. Submatrices considered: 31, and computed = 19 Rn: partial singular locus dimension computed, = 1 Rn: Loop step, about to compute dimension. Submatrices considered: 40, and computed = 22 Rn: partial singular locus dimension computed, = 1 Rn: Loop step, about to compute dimension. Submatrices considered: 52, and computed = 25 Rn: partial singular locus dimension computed, = 1 Rn: Loop step, about to compute dimension. Submatrices considered: 67, and computed = 29 Rn: partial singular locus dimension computed, = 1 Rn: Loop step, about to compute dimension. Submatrices considered: 87, and computed = 34 Rn: partial singular locus dimension computed, = 1 Rn: Loop step, about to compute dimension. Submatrices considered: 113, and computed = 46 Rn: partial singular locus dimension computed, = 1 Rn: Loop step, about to compute dimension. Submatrices considered: 147, and computed = 59 Rn: partial singular locus dimension computed, = 1 Rn: Loop step, about to compute dimension. Submatrices considered: 191, and computed = 73 Rn: partial singular locus dimension computed, = 1 Rn: Loop step, about to compute dimension. Submatrices considered: 248, and computed = 93 Rn: partial singular locus dimension computed, = 1 Rn: Loop step, about to compute dimension. Submatrices considered: 322, and computed = 118 Rn: partial singular locus dimension computed, = 1 Rn: Loop step, about to compute dimension. Submatrices considered: 334, and computed = 119 Rn: partial singular locus dimension computed, = 1 Rn: Loop completed, submatrices considered = 334, and computed = 119. singular locus dimension appears to be = 1 -- used 1.81518 seconds |
The maximum number of minors considered can be controlled by the option MaxMinors. If the user does not specify this, then the default value is given by the formula TODO. The function does not recompute determinants, so MaxMinors is only an upper bound on the number of minors computed.
i17 : time Rn(2, S, Verbose=>true, MaxMinors=>30) Rn: ring dimension =3, there are 17325 possible minors, we will compute up to 30 of them. Rn: About to enter loop Rn: Loop step, about to compute dimension. Submatrices considered: 11, and computed = 10 Rn: partial singular locus dimension computed, = 1 Rn: Loop step, about to compute dimension. Submatrices considered: 14, and computed = 11 Rn: partial singular locus dimension computed, = 1 Rn: Loop step, about to compute dimension. Submatrices considered: 18, and computed = 14 Rn: partial singular locus dimension computed, = 1 Rn: Loop step, about to compute dimension. Submatrices considered: 24, and computed = 18 Rn: partial singular locus dimension computed, = 1 Rn: Loop step, about to compute dimension. Submatrices considered: 30, and computed = 22 Rn: partial singular locus dimension computed, = 1 Rn: Loop completed, submatrices considered = 30, and computed = 22. singular locus dimension appears to be = 1 -- used 0.25585 seconds |
This function has many options which allow you to fine tune the strategy used to find interesting minors. You can pass it a HashTable specifying the strategy via the option Strategy. See LexSmallest for how to construct this HashTable. The default strategy is StrategyDefault, which seems to work well on the examples we have explored. However, caution must be taken, even in the above examples, certain strategies work well while others do not. In the Abelian surface example, LexSmallest works very well, while LexSmallestTerm does not even typically correctly identify the ring as nonsingular (this is because of the fact that there are a small number of entries with nonzero constant terms, which are selected repeatedly). However, in our first example, the LexSmallestTerm is much faster, and Random does not perform well at all.
i18 : StrategyCurrent#Random = 0; |
i19 : StrategyCurrent#LexSmallest = 100; |
i20 : StrategyCurrent#LexSmallestTerm = 0; |
i21 : time Rn(2, R, Strategy=>StrategyCurrent) -- used 0.0597335 seconds o21 = true |
i22 : time Rn(2, R, Strategy=>StrategyCurrent) -- used 0.0330881 seconds o22 = true |
i23 : time Rn(1, S, Strategy=>StrategyCurrent) -- used 0.188635 seconds o23 = true |
i24 : time Rn(1, S, Strategy=>StrategyCurrent) -- used 1.15853 seconds |
i25 : StrategyCurrent#LexSmallest = 0; |
i26 : StrategyCurrent#LexSmallestTerm = 100; |
i27 : time Rn(2, R, Strategy=>StrategyCurrent) -- used 0.808826 seconds |
i28 : time Rn(2, R, Strategy=>StrategyCurrent) -- used 0.786679 seconds |
i29 : time Rn(1, S, Strategy=>StrategyCurrent) -- used 0.0599751 seconds o29 = true |
i30 : time Rn(1, S, Strategy=>StrategyCurrent) -- used 0.0709854 seconds o30 = true |
i31 : time Rn(1, S, Strategy=>StrategyRandom) -- used 0.337982 seconds o31 = true |
i32 : time Rn(1, S, Strategy=>StrategyRandom) -- used 0.217947 seconds o32 = true |
Finally, passing the option ModP => p will do the computation after changing the coefficient ring to ZZ/p.