Skip to content

Commit e6984b1

Browse files
Alexey Stukalovalyst
authored andcommitted
get_degrees(): convert to tuple at the very end
keep vectors of degrees to optimize memory usage
1 parent 315a5c4 commit e6984b1

File tree

1 file changed

+23
-14
lines changed

1 file changed

+23
-14
lines changed

src/ordering.jl

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,43 +30,52 @@ For a sum expression, returns the `get_degrees()` result for term with the highe
3030
See also `monomial_lt` and `lexlt`.
3131
"""
3232
function get_degrees(expr)
33+
res = _get_degrees(expr)
34+
if res isa AbstractVector
35+
return Tuple(res)
36+
else
37+
return res
38+
end
39+
end
40+
41+
function _get_degrees(expr)
3342
if issym(expr)
3443
return ((Symbol(expr),) => 1,)
3544
elseif iscall(expr)
3645
# operation-specific degree handling
37-
return get_degrees(operation(expr), expr)
46+
return _get_degrees(operation(expr), expr)
3847
else
3948
return () # skip numbers and unsupported expressions
4049
end
4150
end
4251

4352
# fallback for unsupported operation
44-
get_degrees(::Any, expr) =
53+
_get_degrees(::Any, expr) =
4554
((Symbol("zzzzzzz", hash(expr)),) => 1,)
4655

4756
_getindex_symbol(arr, i) = Symbol(arr[i])
4857

49-
function get_degrees(::typeof(getindex), expr)
58+
function _get_degrees(::typeof(getindex), expr)
5059
args = arguments(expr)
5160
@inbounds return (ntuple(Base.Fix1(_getindex_symbol, args), length(args)) => 1,)
5261
end
5362

54-
function get_degrees(::typeof(*), expr)
63+
function _get_degrees(::typeof(*), expr)
5564
args = arguments(expr)
5665
ds = sizehint!(Vector{Any}(), length(args))
5766
for arg in args
58-
degs = get_degrees(arg)
67+
degs = _get_degrees(arg)
5968
append!(ds, degs)
6069
end
6170
return sort!(ds)
6271
end
6372

64-
function get_degrees(::typeof(+), expr)
73+
function _get_degrees(::typeof(+), expr)
6574
# among the terms find the best in terms of monomial_lt
6675
sel_degs = ()
6776
sel_degsum = 0
6877
for arg in arguments(expr)
69-
degs = get_degrees(arg)
78+
degs = _get_degrees(arg)
7079
degsum = sum(last, degs, init=0)
7180
if (sel_degs == ()) || (degsum > sel_degsum) ||
7281
(degsum == sel_degsum && lexlt(degs, sel_degs))
@@ -76,10 +85,10 @@ function get_degrees(::typeof(+), expr)
7685
return sel_degs
7786
end
7887

79-
function get_degrees(::typeof(^), expr)
88+
function _get_degrees(::typeof(^), expr)
8089
base_expr, pow_expr = arguments(expr)
8190
if pow_expr isa Number
82-
@inbounds degs = map(get_degrees(base_expr)) do (base, pow)
91+
@inbounds degs = map(_get_degrees(base_expr)) do (base, pow)
8392
(base => pow * pow_expr)
8493
end
8594
if pow_expr < 0 && length(degs) > 1
@@ -90,23 +99,23 @@ function get_degrees(::typeof(^), expr)
9099
return degs
91100
else
92101
# expression in the power argument is not supported
93-
return get_degrees(nothing, expr)
102+
return _get_degrees(nothing, expr)
94103
end
95104
end
96105

97-
function get_degrees(::typeof(/), expr)
106+
function _get_degrees(::typeof(/), expr)
98107
nom_expr, denom_expr = arguments(expr)
99108
if denom_expr isa Number # constant denominator
100-
return get_degrees(nom_expr)
109+
return _get_degrees(nom_expr)
101110
elseif nom_expr isa Number # constant nominator
102-
@inbounds degs = map(get_degrees(denom_expr)) do (base, pow)
111+
@inbounds degs = map(_get_degrees(denom_expr)) do (base, pow)
103112
(base => -pow)
104113
end
105114
isa(degs, AbstractVector) || (degs = collect(degs))
106115
return sort!(degs)
107116
else
108117
# TODO expressions in both nom and denom are not yet supported
109-
return get_degrees(nothing, expr)
118+
return _get_degrees(nothing, expr)
110119
end
111120
end
112121

0 commit comments

Comments
 (0)