Given a ring $R$, this function checks whether the ring is $F$-pure, using Fedder's criterion (by applying frobeniusRoot to $I^{[p]} : I$, where $I$ is the defining ideal of $R$).
i1 : R = ZZ/5[x,y,z]/(x^2 + y*z); |
i2 : isFPure(R) o2 = true |
i3 : R = ZZ/7[x,y,z]/(x^3 + y^3 + z^3); |
i4 : isFPure(R) o4 = true |
i5 : R = ZZ/5[x,y,z]/(x^3 + y^3 + z^3); |
i6 : isFPure(R) o6 = false |
Alternatively, one may pass the defining ideal of a ring.
i7 : S = ZZ/2[x,y,z]; |
i8 : isFPure ideal(y^2 - x^3) o8 = false |
i9 : isFPure ideal(z^2 - x*y*z + x*y^2 + x^2*y) o9 = true |
The option AtOrigin controls whether $F$-purity is checked at the origin or everywhere. If its value is set to true (the default is false), it will only check $F$-purity at the origin.
i10 : R = ZZ/5[x,y,z]/((x - 1)^3 + (y - 2)^3 + z^3); |
i11 : isFPure(R) o11 = false |
i12 : isFPure(R, AtOrigin => true) o12 = true |
i13 : S = ZZ/13[x,y,z]/(x^3 + y^3 + z^3); |
i14 : isFPure(S) o14 = true |
i15 : isFPure(S, AtOrigin => true) o15 = true |
Note that there is a difference in the strategy for the local or non-local computations. In fact, checking $F$-purity globally can sometimes be faster than checking it only at the origin. If AtOrigin is set to false, then isFPure computes the frobeniusRoot of $I^{[p]} : I$, whereas if AtOrigin is set to true, it checks whether $I^{[p]} : I$ is contained in $m^{[p]}$, where $m$ is the maximal ideal generated by the variables.
The option FrobeniusRootStrategy is passed to internal frobeniusRoot calls, and specifies the strategy to be used.
The object isFPure is a method function with options.