@@ -791,15 +791,51 @@ end
791
791
return is_equidimensional (pre_image_ideal (I))
792
792
end
793
793
794
- function _minimal_power_such_that (I:: Ideal , P:: PropertyType ) where {PropertyType}
794
+ @doc raw """
795
+ _minimal_power_such_that(
796
+ I::Ideal, P::PropertyType;
797
+ boundary_for_incremental_strategy::Union{Int, PosInf}=inf
798
+ ) where {PropertyType}
799
+
800
+ Find a minimal exponent `k` such that `P(I^k) == true` where `P` is
801
+ some property which can be evaluated on an ideal; return the pair
802
+ `(k, I^k)`.
803
+
804
+ By default, this is done by bisection, i.e. first we try with powers
805
+ `I^0, I^1, I^2, I^4, I^8, I^16, ...` until we obtain `P(I^k) == true`
806
+ for the first time and then downwards bisection to find the minimal
807
+ exponent with this property.
808
+
809
+ As this is prone to quickly trigger Groebner basis computations of ideals
810
+ with generators of rather high degree, we provide the keyword argument
811
+ `boundary_for_incremental_strategy`. If set to some integer value `k_lim`,
812
+ the build up phase for finding powers `J = I^(2^r)` with `P(J) == true`
813
+ is aborted, once `2^r >= k_lim` and an incremental search for the lowest
814
+ exponent is done instead.
815
+ """
816
+ function _minimal_power_such_that (
817
+ I:: Ideal , P:: PropertyType ;
818
+ boundary_for_incremental_strategy:: Union{Int, PosInf} = inf
819
+ ) where {PropertyType}
795
820
whole_ring = ideal (base_ring (I), [one (base_ring (I))])
796
821
P (whole_ring) && return (0 , whole_ring)
797
822
P (I) && return (1 , I)
798
823
I_powers = [(1 ,I)]
799
824
800
- while ! P (last (I_powers)[2 ])
825
+ # building up a cache by iterated squaring of the exponent
826
+ while 2 * last (I_powers)[1 ] < boundary_for_incremental_strategy && ! P (last (I_powers)[2 ])
801
827
push! (I_powers, (last (I_powers)[1 ]* 2 , last (I_powers)[2 ]^ 2 ))
802
828
end
829
+
830
+ # if we crossed the boundary for the build up, switch to dumb iteration
831
+ if 2 * last (I_powers)[1 ] >= boundary_for_incremental_strategy && ! P (last (I_powers)[2 ])
832
+ while true
833
+ push! (I_powers, (last (I_powers)[1 ]+ 1 , last (I_powers)[2 ]* I))
834
+ k, J = last (I_powers)
835
+ P (J) && return k, J
836
+ end
837
+ end
838
+
803
839
upper = pop! (I_powers)
804
840
lower = pop! (I_powers)
805
841
while upper[1 ]!= lower[1 ]+ 1
@@ -874,8 +910,8 @@ function order_of_vanishing(
874
910
bR = ideal (R, denominator (floc))
875
911
876
912
# The following uses ArXiv:2103.15101, Lemma 2.18 (4):
877
- num_mult = _minimal_power_such_that (J, x-> (issubset (quotient (x+ K, aR), J)))[1 ]- 1
878
- den_mult = _minimal_power_such_that (J, x-> (issubset (quotient (x+ K, bR), J)))[1 ]- 1
913
+ num_mult = _minimal_power_such_that (J, x-> (issubset (quotient (x+ K, aR), J)); boundary_for_incremental_strategy = 4 )[1 ]- 1
914
+ den_mult = _minimal_power_such_that (J, x-> (issubset (quotient (x+ K, bR), J)); boundary_for_incremental_strategy = 4 )[1 ]- 1
879
915
return num_mult - den_mult
880
916
end
881
917
0 commit comments