@@ -573,6 +573,8 @@ Base.iszero(::SignChange) = false
573
573
MA. scaling_convert (:: Type , s:: SignChange ) = s
574
574
Base.:* (s:: SignChange , α:: Real ) = SignChange (s. sign * α, s. Δ)
575
575
Base.:* (α:: Real , s:: SignChange ) = SignChange (α * s. sign, s. Δ)
576
+ # Base.convert(::Type{SignChange{T}}, s::SignChange) where {T} = SignChange{T}(s.sign, s.Δ)
577
+ # Base.:+(a::SignChange, b::SignChange) = convert(SignCount, a) + b
576
578
577
579
struct SignCount
578
580
unknown:: Int
@@ -593,6 +595,18 @@ function _sign(c::SignCount)
593
595
end
594
596
end
595
597
598
+ function Base.:* (α, a:: SignCount )
599
+ if α > 0
600
+ return a
601
+ elseif α < 0
602
+ return SignCount (a. unknown, a. negative, a. positive)
603
+ else
604
+ error (" Cannot multiply `SignCount`` with `$α `" )
605
+ end
606
+ end
607
+
608
+ Base.:* (a:: SignCount , α) = α * a
609
+
596
610
function Base.:+ (a:: SignCount , b:: SignCount )
597
611
return SignCount (
598
612
a. unknown + b. unknown,
@@ -602,16 +616,16 @@ function Base.:+(a::SignCount, b::SignCount)
602
616
end
603
617
604
618
function Base.:+ (c:: SignCount , a:: SignChange{Missing} )
605
- @assert c. unknown >= - a. Δ
619
+ # @assert c.unknown >= -a.Δ
606
620
return SignCount (c. unknown + a. Δ, c. positive, c. negative)
607
621
end
608
622
609
623
function Base.:+ (c:: SignCount , a:: SignChange{<:Number} )
610
624
if a. sign > 0
611
- @assert c. positive >= - a. Δ
625
+ # @assert c.positive >= -a.Δ
612
626
return SignCount (c. unknown, c. positive + a. Δ, c. negative)
613
627
elseif a. sign < 0
614
- @assert c. negative >= - a. Δ
628
+ # @assert c.negative >= -a.Δ
615
629
return SignCount (c. unknown, c. positive, c. negative + a. Δ)
616
630
elseif iszero (a. sign)
617
631
error (
@@ -624,26 +638,16 @@ end
624
638
625
639
Base. convert (:: Type{SignCount} , Δ:: SignChange ) = SignCount () + Δ
626
640
627
- function increase (cache, counter, generator_sign, monos, mult)
628
- for a in monos
629
- for b in monos
630
- MA. operate_to! (
631
- cache,
632
- * ,
633
- MB. algebra_element (mult),
634
- MB. algebra_element (a),
635
- MB. algebra_element (b),
636
- )
637
- MA. operate! (
638
- SA. UnsafeAddMul (* ),
639
- counter,
640
- _term_constant_monomial (
641
- SignChange ((a != b) ? missing : generator_sign, 1 ),
642
- mult,
643
- ),
644
- cache,
645
- )
646
- end
641
+ struct SignGram{T,B}
642
+ sign:: T
643
+ basis:: B
644
+ end
645
+ SA. basis (g:: SignGram ) = g. basis
646
+ function Base. getindex (g:: SignGram , i, j)
647
+ if i == j
648
+ return SignChange (g. sign, 1 )
649
+ else
650
+ return SignChange (missing , 2 )
647
651
end
648
652
end
649
653
@@ -708,7 +712,8 @@ function post_filter(
708
712
_DictCoefficients (Dict {MP.monomial_type(typeof(poly)),SignCount} ()),
709
713
MB. implicit_basis (SA. basis (poly)),
710
714
)
711
- cache = zero (Float64, MB. algebra (MB. implicit_basis (SA. basis (poly))))
715
+ cache = zero (SignCount, MB. algebra (MB. implicit_basis (SA. basis (poly))))
716
+ cache2 = zero (SignCount, MB. algebra (MB. implicit_basis (SA. basis (poly))))
712
717
for (mono, v) in SA. nonzero_pairs (SA. coeffs (poly))
713
718
MA. operate! (
714
719
SA. UnsafeAdd (),
@@ -717,29 +722,21 @@ function post_filter(
717
722
)
718
723
end
719
724
for (mult, gram_monos) in zip (generators, multipliers_gram_monos)
720
- for (mono, v) in SA. nonzero_pairs (SA. coeffs (mult))
721
- increase (
722
- cache,
723
- counter,
724
- - _sign (v),
725
- gram_monos,
726
- SA. basis (mult)[mono],
727
- )
728
- end
725
+ MA. operate_to! (cache, copy, SA. QuadraticForm (SignGram (- 1 , gram_monos)))
726
+ MA. operate! (SA. UnsafeAddMul (* ), counter, mult, cache)
729
727
end
730
- function decrease (sign, a, b, c )
728
+ function decrease (sign, a, b, generator )
731
729
MA. operate_to! (
732
730
cache,
733
731
* ,
734
- MB . algebra_element ( a),
732
+ _term ( SignChange ( 1 , - 1 ), a),
735
733
MB. algebra_element (b),
736
- MB. algebra_element (c),
737
734
)
738
735
MA. operate! (
739
736
SA. UnsafeAddMul (* ),
740
737
counter,
741
- _term_constant_monomial (SignChange (sign, - 1 ), a),
742
738
cache,
739
+ generator,
743
740
)
744
741
for mono in SA. supp (cache)
745
742
count = SA. coeffs (counter)[SA. basis (counter)[mono]]
@@ -765,36 +762,38 @@ function post_filter(
765
762
end
766
763
keep[i][j] = false
767
764
a = multipliers_gram_monos[i][j]
768
- for (k, v) in SA. nonzero_pairs (SA. coeffs (generators[i]))
769
- mono = SA. basis (generators[i])[k]
770
- sign = - _sign (v)
771
- decrease (sign, mono, a, a)
772
- for (j, b) in enumerate (multipliers_gram_monos[i])
773
- if keep[i][j]
774
- decrease (missing , mono, a, b)
775
- decrease (missing , mono, b, a)
776
- end
765
+ decrease (- 1 , a, a, generators[i])
766
+ for (k, b) in enumerate (multipliers_gram_monos[i])
767
+ if keep[i][k]
768
+ decrease (missing , a, b, generators[i])
769
+ decrease (missing , b, a, generators[i])
777
770
end
778
771
end
779
772
end
780
773
for i in eachindex (generators)
781
- for k in SA. supp (generators[i])
782
- for (j, mono) in enumerate (multipliers_gram_monos[i])
783
- MA. operate_to! (
784
- cache,
785
- * ,
786
- MB. algebra_element (k),
787
- MB. algebra_element (mono),
788
- MB. algebra_element (mono),
774
+ for (j, mono) in enumerate (multipliers_gram_monos[i])
775
+ MA. operate_to! (
776
+ cache,
777
+ * ,
778
+ # Dummy coef to help convert to `SignCount` which is the `eltype` of `cache`
779
+ _term (SignChange (1 , 1 ), mono),
780
+ MB. algebra_element (mono),
781
+ )
782
+ # The `eltype` of `cache` is `SignCount`
783
+ # so there is no risk of term cancellation
784
+ MA. operate_to! (
785
+ cache2,
786
+ * ,
787
+ cache,
788
+ generators[i],
789
+ )
790
+ for w in SA. supp (cache)
791
+ if ismissing (
792
+ _sign (SA. coeffs (counter)[SA. basis (counter)[w]]),
789
793
)
790
- for w in SA. supp (cache)
791
- if ismissing (
792
- _sign (SA. coeffs (counter)[SA. basis (counter)[w]]),
793
- )
794
- push! (get! (back, w, Tuple{Int,Int}[]), (i, j))
795
- else
796
- delete (i, j)
797
- end
794
+ push! (get! (back, w, Tuple{Int,Int}[]), (i, j))
795
+ else
796
+ delete (i, j)
798
797
end
799
798
end
800
799
end
0 commit comments