@@ -16,6 +16,7 @@ struct PolyForm{T, M} <: Symbolic{T}
1616 sym2term:: Dict # Symbol("sin-$hash(sin(x+y))") --> sin(x+y) => sin(PolyForm(...))
1717 metadata:: M
1818end
19+ (:: PolyForm{T} )(p, d1, d2, m) where {T} = PolyForm {T, typeof(m)} (p, d1, d2, m)
1920
2021Base. hash (p:: PolyForm , u:: UInt64 ) = xor (hash (p. p, u), trunc (UInt, 0xbabacacababacaca ))
2122Base. isequal (x:: PolyForm , y:: PolyForm ) = isequal (x. p, y. p)
@@ -25,6 +26,7 @@ Base.isequal(x::PolyForm, y::PolyForm) = isequal(x.p, y.p)
2526# start over if necessary
2627const PVAR2SYM = Ref (WeakRef ())
2728const SYM2TERM = Ref (WeakRef ())
29+ clear_dicts () = (PVAR2SYM[] = WeakRef (nothing ); SYM2TERM[] = WeakRef (nothing ); nothing )
2830function get_pvar2sym ()
2931 v = PVAR2SYM[]. value
3032 if v === nothing
@@ -55,16 +57,21 @@ function mix_dicts(p, q)
5557end
5658
5759# forward gcd
58- Base. div (x:: PolyForm , y:: PolyForm ) = PolyForm (div (x. p, y. p), mix_dicts (x, y)... )
59- Base. div (x:: Integer , y:: PolyForm ) = PolyForm (div (x, y. p), y. pvar2sym, y. sym2term)
60- Base. div (x:: PolyForm , y:: Integer ) = PolyForm (div (x. p, y), x. pvar2sym, x. sym2term)
6160
62- Base. gcd (x:: PolyForm , y:: PolyForm ) = PolyForm (_gcd (x. p, y. p), mix_dicts (x, y)... )
63- Base. gcd (x:: Integer , y:: PolyForm ) = PolyForm (_gcd (x, y. p), y. pvar2sym, y. sym2term)
64- Base. gcd (x:: PolyForm , y:: Integer ) = PolyForm (_gcd (x. p, y), x. pvar2sym, x. sym2term)
61+ PF = :(PolyForm{promote_type (/ , symtype (x), symtype (y))})
62+ @eval begin
63+ Base. div (x:: PolyForm , y:: PolyForm ) = $ PF (div (x. p, y. p), mix_dicts (x, y)... )
64+ Base. div (x:: Integer , y:: PolyForm ) = $ PF (div (x, y. p), y. pvar2sym, y. sym2term)
65+ Base. div (x:: PolyForm , y:: Integer ) = $ PF (div (x. p, y), x. pvar2sym, x. sym2term)
66+
67+ Base. gcd (x:: PolyForm , y:: PolyForm ) = $ PF (_gcd (x. p, y. p), mix_dicts (x, y)... )
68+ Base. gcd (x:: Integer , y:: PolyForm ) = $ PF (_gcd (x, y. p), y. pvar2sym, y. sym2term)
69+ Base. gcd (x:: PolyForm , y:: Integer ) = $ PF (_gcd (x. p, y), x. pvar2sym, x. sym2term)
70+ end
71+
6572_isone (p:: PolyForm ) = isone (p. p)
6673
67- function polyize (x, pvar2sym, sym2term, vtype, pow)
74+ function polyize (x, pvar2sym, sym2term, vtype, pow, Fs, recurse )
6875 if istree (x)
6976 if ! (symtype (x) <: Number )
7077 error (" Cannot convert $x of symtype $(symtype (x)) into a PolyForm" )
@@ -73,19 +80,28 @@ function polyize(x, pvar2sym, sym2term, vtype, pow)
7380 op = operation (x)
7481 args = arguments (x)
7582
76- local_polyize (y) = polyize (y, pvar2sym, sym2term, vtype, pow)
83+ local_polyize (y) = polyize (y, pvar2sym, sym2term, vtype, pow, Fs, recurse )
7784
78- if op == (+ )
85+ if typeof ( + ) <: Fs && op == (+ )
7986 return sum (local_polyize, args)
80- elseif op == (* )
87+ elseif typeof ( * ) <: Fs && op == (* )
8188 return prod (local_polyize, args)
82- elseif op == (^ ) && args[2 ] isa Integer && args[2 ] > 0
89+ elseif typeof ( ^ ) <: Fs && op == (^ ) && args[2 ] isa Integer && args[2 ] > 0
8390 @assert length (args) == 2
8491 return local_polyize (args[1 ])^ (args[2 ])
8592 else
8693 # create a new symbol to store this
8794
88- name = Symbol (string (op), " -" , hash (x))
95+ y = if recurse
96+ similarterm (x,
97+ op,
98+ map (a-> PolyForm (a, pvar2sym, sym2term, vtype, Fs, recurse),
99+ args), symtype (x))
100+ else
101+ x
102+ end
103+
104+ name = Symbol (string (op), " -" , hash (y))
89105
90106 @label lookup
91107 sym = Sym {symtype(x)} (name)
@@ -98,10 +114,8 @@ function polyize(x, pvar2sym, sym2term, vtype, pow)
98114 end
99115 end
100116
101- sym2term[sym] = x => similarterm (x,
102- op,
103- map (a-> PolyForm (a, pvar2sym, sym2term, vtype),
104- args), symtype (x))
117+ sym2term[sym] = x => y
118+
105119 return local_polyize (sym)
106120 end
107121 elseif x isa Number
@@ -120,22 +134,16 @@ function PolyForm(x::Symbolic{<:Number},
120134 pvar2sym= get_pvar2sym (),
121135 sym2term= get_sym2term (),
122136 vtype= DynamicPolynomials. PolyVar{true };
137+ Fs = Union{typeof (+ ), typeof (* ), typeof (^ )},
138+ recurse= false ,
123139 metadata= metadata (x))
124140
125141 # Polyize and return a PolyForm
126- p = polyize (x, pvar2sym, sym2term, vtype, pow)
142+ p = polyize (x, pvar2sym, sym2term, vtype, pow, Fs, recurse )
127143 MP. isconstant (p) && return convert (Number, p)
128144 PolyForm {symtype(x), typeof(metadata)} (p, pvar2sym, sym2term, metadata)
129145end
130146
131- function PolyForm (x:: MP.AbstractPolynomialLike ,
132- pvar2sym= get_pvar2sym (),
133- sym2term= get_sym2term (),
134- metadata= nothing )
135- # make number go
136- PolyForm {Number, Nothing} (x, pvar2sym, sym2term, metadata)
137- end
138-
139147PolyForm (x, args... ;kw... ) = x
140148
141149istree (x:: PolyForm ) = true
@@ -184,9 +192,7 @@ function arguments(x::PolyForm{T}) where {T}
184192 end
185193end
186194
187- function Base. show (io:: IO , x:: PolyForm )
188- Base. printstyled (io, sprint (io-> show_term (io, x)), color= :yellow )
189- end
195+ Base. show (io:: IO , x:: PolyForm ) = show_term (io, x)
190196
191197"""
192198 expand(expr)
0 commit comments