@@ -9,7 +9,7 @@ with a symbol, store the symbol => term mapping in `dict`.
99function labels! end
1010
1111# Turn a Term into a multivariate polynomial
12- function labels! (dicts, t:: Sym )
12+ function labels! (dicts, t:: Sym , variable_type :: Type )
1313 sym2term, term2sym = dicts
1414 if ! haskey (term2sym, t)
1515 sym2term[t] = t
@@ -18,14 +18,14 @@ function labels!(dicts, t::Sym)
1818 return t
1919end
2020
21- function labels! (dicts, t)
22- if t isa Integer
21+ function labels! (dicts, t, variable_type :: Type )
22+ if t isa Number
2323 return t
2424 elseif istree (t) && (operation (t) == (* ) || operation (t) == (+ ) || operation (t) == (- ))
2525 tt = arguments (t)
26- return similarterm (t, operation (t), map (x-> labels! (dicts, x), tt), symtype (t))
26+ return similarterm (t, operation (t), map (x-> labels! (dicts, x, variable_type ), tt), symtype (t))
2727 elseif istree (t) && operation (t) == (^ ) && length (arguments (t)) > 1 && isnonnegint (arguments (t)[2 ])
28- return similarterm (t, operation (t), map (x-> labels! (dicts, x), arguments (t)), symtype (t))
28+ return similarterm (t, operation (t), map (x-> labels! (dicts, x, variable_type ), arguments (t)), symtype (t))
2929 else
3030 sym2term, term2sym = dicts
3131 if haskey (term2sym, t)
@@ -36,7 +36,7 @@ function labels!(dicts, t)
3636 sym = Sym {symtype(t)} (gensym (nameof (operation (t))))
3737 dicts2 = _dicts (dicts[2 ])
3838 sym2term[sym] = similarterm (t, operation (t),
39- map (x-> to_mpoly (x, dicts)[1 ], arguments (t)),
39+ map (x-> to_mpoly (x, variable_type, dicts)[1 ], arguments (t)),
4040 symtype (t))
4141 else
4242 sym = Sym {symtype(t)} (gensym (" literal" ))
@@ -49,7 +49,7 @@ function labels!(dicts, t)
4949 end
5050end
5151
52- ismpoly (x) = x isa MPoly || x isa Integer
52+ ismpoly (x) = x isa MP . AbstractPolynomialLike || x isa Number
5353isnonnegint (x) = x isa Integer && x >= 0
5454
5555_dicts (t2s= OrderedDict {Any, Sym} ()) = (OrderedDict {Sym, Any} (), t2s)
7171 MPOLY_MAKER = Fixpoint (Postwalk (PassThrough (RestartedChain (mpoly_rules)), similarterm= simterm))
7272
7373 global to_mpoly
74- function to_mpoly (t, dicts= _dicts ())
74+ function to_mpoly (t, variable_type :: Type = DynamicPolynomials . PolyVar{ true }, dicts= _dicts ())
7575 # term2sym is only used to assign the same
7676 # symbol for the same term -- in other words,
7777 # it does common subexpression elimination
7878 t = MPOLY_CLEANUP (t)
7979 sym2term, term2sym = dicts
80- labeled = labels! ((sym2term, term2sym), t)
80+ labeled = labels! ((sym2term, term2sym), t, variable_type )
8181
8282 if isempty (sym2term)
8383 return MPOLY_MAKER (labeled), Dict {Sym,Any} ()
8484 end
8585
8686 ks = sort (collect (keys (sym2term)), lt= < ₑ)
87- R, vars = PolynomialRing (ZZ, String .( nameof .(ks) ))
87+ vars = MP . similarvariable .(variable_type, nameof .(ks))
8888
89- replace_with_poly = Dict {Sym,MPoly } (zip (ks, vars))
89+ replace_with_poly = Dict {Sym,eltype(vars) } (zip (ks, vars))
9090 t_poly = substitute (labeled, replace_with_poly, fold= false )
9191 MPOLY_MAKER (t_poly), sym2term
9292 end
9393end
9494
9595function to_term (reference, x, dict)
96- syms = Dict (zip (nameof .(keys (dict)), keys (dict)))
96+ syms = Dict (zip (string .( nameof .(keys (dict) )), keys (dict)))
9797 dict = copy (dict)
9898 for (k, v) in dict
9999 dict[k] = _to_term (reference, v, dict, syms)
100100 end
101- _to_term (reference, x, dict, syms)
101+ return _to_term (reference, x, dict, syms)
102+ # return substitute(t, dict, fold=false)
102103end
103104
104- function _to_term (reference, x:: MPoly , dict, syms)
105-
106- function mul_coeffs (exps, ring)
107- l = length (syms)
108- ss = symbols (ring)
109- monics = [e == 1 ? syms[ss[i]] : syms[ss[i]]^ e for (i, e) in enumerate (exps) if ! iszero (e)]
110- if length (monics) == 1
111- return monics[1 ]
112- elseif length (monics) == 0
113- return 1
114- else
115- return similarterm (reference, * , monics, symtype (reference))
105+ _to_term (reference, x:: Number , dict, syms) = x
106+ _to_term (reference, var:: MP.AbstractVariable , dict, syms) = substitute (syms[MP. name (var)], dict, fold= false )
107+ function _to_term (reference, mono:: MP.AbstractMonomialLike , dict, syms)
108+ monics = [
109+ begin
110+ t = _to_term (reference, var, dict, syms)
111+ exp == 1 ? t : t^ exp
116112 end
113+ for (var, exp) in MP. powers (mono) if ! iszero (exp)
114+ ]
115+ if length (monics) == 1
116+ return monics[1 ]
117+ elseif isempty (monics)
118+ return 1
119+ else
120+ return similarterm (reference, * , monics, symtype (reference))
117121 end
122+ end
118123
119- monoms = [ mul_coeffs ( exponent_vector (x, i), x . parent) for i in 1 : x . length]
120- if length (monoms) == 0
121- return 0
122- elseif length (monoms) == 1
123- t = ! isone (x . coeffs[ 1 ]) ? monoms[ 1 ] * Int (x . coeffs[ 1 ]) : monoms[ 1 ]
124+ function _to_term (reference, term :: MP.AbstractTermLike , dict, syms)
125+ coef = MP . coefficient (term)
126+ mono = _to_term (reference, MP . monomial (term), dict, syms)
127+ if isone (coef)
128+ return mono
124129 else
125- t = similarterm (reference,
126- + ,
127- map ((x,y)-> isone (y) ? x : Int (y)* x,
128- monoms, x. coeffs[1 : length (monoms)]),
129- symtype (reference))
130+ return MP. coefficient (term) * mono
130131 end
132+ end
131133
132- substitute (t, dict, fold= false )
134+ function _to_term (reference, x:: MP.AbstractPolynomialLike , dict, syms)
135+ if MP. nterms (x) == 0
136+ return 0
137+ elseif MP. nterms (x) == 1
138+ return _to_term (reference, first (MP. terms (x)), dict, syms)
139+ else
140+ terms = map (MP. terms (x)) do term
141+ _to_term (reference, term, dict, syms)
142+ end
143+ return similarterm (reference, + , terms, symtype (reference))
144+ end
133145end
134146
135147function _to_term (reference, x, dict, vars)
136148 if istree (x)
137- t= similarterm (x, operation (x), _to_term .((reference,), arguments (x), (dict,), (vars,)), symtype (x))
149+ t = similarterm (x, operation (x), _to_term .((reference,), arguments (x), (dict,), (vars,)), symtype (x))
138150 else
139151 if haskey (dict, x)
140152 return dict[x]
@@ -144,18 +156,21 @@ function _to_term(reference, x, dict, vars)
144156 end
145157end
146158
147- < ₑ (a:: MPoly , b:: MPoly ) = false
159+ < ₑ (a:: MP.AbstractPolynomialLike , b:: MP.AbstractPolynomialLike ) = false
148160
149161"""
150- expand(expr)
162+ expand(expr, variable_type::Type=DynamicPolynomials.PolyVar{true} )
151163
152- Expand expressions by distributing multiplication over addition.
164+ Expand expressions by distributing multiplication over addition, e.g.,
165+ `a*(b+c)` becomes `ab+ac`.
153166
154- `a*(b+c)` becomes `ab+ac`. `expand` uses [AbstractAlgebra.jl](https://nemocas.github.io/AbstractAlgebra.jl/latest/) to construct
155- dense Multi-variate polynomial to do this very fast.
167+ `expand` uses replace symbols and non-algebraic expressions by variables of type
168+ `variable_type` to compute the distribution using a specialized sparse
169+ multivariate polynomials implementation.
170+ `variable_type` can be any subtype of `MultivariatePolynomials.AbstractVariable`.
156171"""
157- function expand (x )
158- to_term (x , to_mpoly (x )... )
172+ function expand (expr, variable_type :: Type = DynamicPolynomials . PolyVar{ true } )
173+ to_term (expr , to_mpoly (expr, variable_type )... )
159174end
160175
161176Base. @deprecate polynormalize (x) expand (x)
0 commit comments