@@ -18,9 +18,19 @@ divides(t1::AbstractVariable, t2::AbstractVariable) = t1 == t2
18
18
Base. gcd (m1:: AbstractMonomialLike , m2:: AbstractMonomialLike ) = mapexponents (min, m1, m2)
19
19
Base. lcm (m1:: AbstractMonomialLike , m2:: AbstractMonomialLike ) = mapexponents (max, m1, m2)
20
20
21
+ struct Field end
22
+ struct UniqueFactorizationDomain end
23
+ const UFD = UniqueFactorizationDomain
24
+
25
+ algebraic_structure (:: Type{<:Union{Rational, AbstractFloat}} , :: Type{<:Union{Rational, AbstractFloat}} ) = Field ()
26
+ algebraic_structure (:: Type{<:Union{Rational, AbstractFloat}} , :: Type ) = Field ()
27
+ algebraic_structure (:: Type , :: Type{<:Union{Rational, AbstractFloat}} ) = Field ()
28
+ algebraic_structure (:: Type , :: Type ) = UFD ()
29
+
21
30
# _div(a, b) assumes that b divides a
22
- _div (a:: Union{Rational, AbstractFloat} , b) = a / b
23
- _div (a, b) = div (a, b)
31
+ _div (:: Field , a, b) = a / b
32
+ _div (:: UFD , a, b) = div (a, b)
33
+ _div (a, b) = _div (algebraic_structure (typeof (a), typeof (b)), a, b)
24
34
_div (m1:: AbstractMonomialLike , m2:: AbstractMonomialLike ) = mapexponents (- , m1, m2)
25
35
function _div (t:: AbstractTerm , m:: AbstractMonomial )
26
36
term (coefficient (t), _div (monomial (t), m))
46
56
Base. div (f:: APL , g:: Union{APL, AbstractVector{<:APL}} ; kwargs... ) = divrem (f, g; kwargs... )[1 ]
47
57
Base. rem (f:: APL , g:: Union{APL, AbstractVector{<:APL}} ; kwargs... ) = divrem (f, g; kwargs... )[2 ]
48
58
49
- # FIXME What should we do for `Rational` ?
50
- function pseudo_rem (f:: APL , g:: APL{<:Union{Rational, AbstractFloat}} , algo)
59
+ function pseudo_rem (f:: APL{S} , g:: APL{T} , algo) where {S,T}
60
+ return _pseudo_rem (algebraic_structure (S, T), f, g, algo)
61
+ end
62
+
63
+ function _pseudo_rem (:: Field , f:: APL , g:: APL , algo)
51
64
return true , rem (f, g)
52
65
end
53
66
54
- function pseudo_rem ( f:: APL , g:: APL , algo)
67
+ function _pseudo_rem ( :: UFD , f:: APL , g:: APL , algo)
55
68
ltg = leadingterm (g)
56
69
rg = removeleadingterm (g)
57
70
ltf = leadingterm (f)
@@ -73,14 +86,28 @@ function pseudo_rem(f::APL, g::APL, algo)
73
86
end
74
87
return true , f
75
88
end
89
+
76
90
function MA. promote_operation (
77
91
:: typeof (pseudo_rem),
78
92
:: Type{P} ,
79
93
:: Type{Q} ,
80
- ) where {T,S<: Union{Rational, AbstractFloat} ,P<: APL{T} ,Q<: APL{S} }
94
+ ) where {T,S,P<: APL{T} ,Q<: APL{S} }
95
+ return _promote_operation (algebraic_structure (T, S), pseudo_rem, P, Q)
96
+ end
97
+ function _promote_operation (
98
+ :: Field ,
99
+ :: typeof (pseudo_rem),
100
+ :: Type{P} ,
101
+ :: Type{Q} ,
102
+ ) where {P<: APL ,Q<: APL }
81
103
return MA. promote_operation (rem, P, Q)
82
104
end
83
- function MA. promote_operation (:: typeof (pseudo_rem), :: Type{P} , :: Type{Q} ) where {T,S,P<: APL{T} ,Q<: APL{S} }
105
+ function _promote_operation (
106
+ :: UFD ,
107
+ :: typeof (pseudo_rem),
108
+ :: Type{P} ,
109
+ :: Type{Q} ,
110
+ ) where {T,S,P<: APL{T} ,Q<: APL{S} }
84
111
U1 = MA. promote_operation (* , S, T)
85
112
U2 = MA. promote_operation (* , T, S)
86
113
# `promote_type(P, Q)` is needed for TypedPolynomials in case they use different variables
0 commit comments