StatProfilerHTML.jl report
Generated on Thu, 26 Mar 2020 19:09:01
File source code
Line Exclusive Inclusive Code
1 struct Variable{Name} <: AbstractVariable
2 end
3
4 MP.name(::Type{Variable{N}}) where {N} = N
5 MP.name(v::Variable) = name(typeof(v))
6 MP.name_base_indices(v::Variable) = name_base_indices(typeof(v))
7 function MP.name_base_indices(v::Type{Variable{N}}) where N
8 name = string(N)
9 splits = split(string(N), r"[\[,\]]\s*", keepempty=false)
10 if length(splits) == 1
11 return name, Int[]
12 else
13 return splits[1], parse.(Int, splits[2:end])
14 end
15 end
16
17
18 MP.variables(v::Variable) = (v,)
19 MP.variables(::Type{V}) where {V <: Variable} = (V(),)
20 Base.hash(v::Variable, u::UInt) = hash(name(v), u)
21
22 checksorted(x::Tuple{Any}, cmp) = true
23 checksorted(x::Tuple{}, cmp) = true
24 checksorted(x::Tuple, cmp) = cmp(x[1], x[2]) && checksorted(Base.tail(x), cmp)
25
26
27
28 struct Monomial{V, N} <: AbstractMonomial
29 exponents::NTuple{N, Int}
30
31 function Monomial{V, N}(exponents::NTuple{N, Int}=ntuple(_ -> 0, Val{N}())) where {V, N}
32 @assert checksorted(V, >)
33 new{V, N}(exponents)
34 end
35 Monomial{V}(exponents::NTuple{N, Integer}=()) where {V, N} = Monomial{V, N}(exponents)
36 Monomial{V}(exponents::AbstractVector{<:Integer}) where {V} = Monomial{V}(NTuple{length(V), Int}(exponents))
37 end
38
39 Monomial(v::Variable) = monomialtype(v)((1,))
40 MP.monomial(v::Variable) = Monomial(v)
41
42 MP.variables(::Type{<:Monomial{V}}) where {V} = V
43 MP.variables(m::Monomial) = variables(typeof(m))
44 MP.nvariables(::Type{<:Monomial{V}}) where {V} = length(V)
45 MP.nvariables(m::Monomial) = nvariables(typeof(m))
46 MP.monomialtype(::Type{V}) where V<:Variable = monomialtype(V())
47 MP.monomialtype(v::Variable) = Monomial{(v,), 1}
48
49 MP.exponents(m::Monomial) = m.exponents
50 MP.exponent(m::Monomial, i::Integer) = m.exponents[i]
51 _exponent(v::V, p1::Tuple{V, Integer}, p2...) where {V <: Variable} = p1[2]
52 _exponent(v::Variable, p1::Tuple{Variable, Integer}, p2...) = _exponent(v, p2...)
53 _exponent(v::Variable) = 0
54 MP.exponent(m::Monomial, v::Variable) = _exponent(v, powers(m)...)
55
56
57
58 struct Term{CoeffType, M <: Monomial} <: AbstractTerm{CoeffType}
59 coefficient::CoeffType
60 monomial::M
61 end
62 Term(v::Variable) = Term(Monomial(v))
63 Term(x, v::Variable) = Term(x, Monomial(v))
64 Term(m::Monomial) = Term(1, m)
65
66 MP.coefficient(t::Term) = t.coefficient
67 MP.monomial(t::Term) = t.monomial
68 coefftype(::Type{<:Term{C}}) where {C} = C
69 MP.termtype(::Union{Term{C, M}, Type{<:Term{C, M}}}, ::Type{T}) where {C, M, T} = Term{T, M}
70 MP.termtype(::Union{M, Type{M}}, ::Type{T}) where {M<:Monomial, T} = Term{T, M}
71 MP.monomialtype(::Type{<:Term{C, M}}) where {C, M} = M
72 MP.monomialtype(t::Term) = monomialtype(typeof(t))
73 MP.variables(t::Union{Term, Type{<:Term}}) = variables(monomialtype(t))
74 MP.nvariables(t::Union{Term, Type{<:Term}}) = nvariables(monomialtype(t))
75
76 struct Polynomial{CoeffType, T <: Term{CoeffType}, V <: AbstractVector{T}} <: AbstractPolynomial{CoeffType}
77 terms::V
78
79 79 (9 %) 79 (9 %)
79 (9 %) samples spent in Polynomial
79 (100 %) (ex.), 79 (100 %) (incl.) when called from Polynomial line 82
Polynomial{C, T, V}(terms::AbstractVector{T}) where {C, T, V} = new{C, T, V}(terms)
80 Polynomial{C, T, V}(p::Polynomial{C, T, V}) where {C, T, V} = p
81 end
82 79 (9 %)
79 (9 %) samples spent in Polynomial
79 (100 %) (incl.) when called from polynomial! line 46
79 (100 %) samples spent calling Polynomial
Polynomial(terms::AbstractVector{T}) where {C, T <: Term{C}} = Polynomial{C, T, typeof(terms)}(terms)
83 Polynomial(t::AbstractVector) = Polynomial(Term.(t))
84 Polynomial(x) = Polynomial(Term(x))
85 MP.termtype(::Type{<:Polynomial{C, T}}) where {C, T} = T
86 changeeltype(::Type{<:Vector}, ::Type{T}) where T = Vector{T}
87 function MP.polynomialtype(::Type{<:Polynomial{C, T, V}}, ::Type{NewC}) where {C, T, V, NewC}
88 NewT = termtype(T, NewC)
89 Polynomial{NewC, NewT, changeeltype(V, NewT)}
90 end
91 MP.polynomialtype(::Type{Term{C, M}}) where {C, M} = Polynomial{C, Term{C, M}, Vector{Term{C, M}}}
92 Polynomial(term::TT) where TT<:Term = Polynomial(iszero(term) ? TT[] : [term])
93
94 MP.terms(p::Polynomial) = p.terms
95 MP.variables(::Union{Polynomial{C, T}, AbstractArray{<:Polynomial{C, T}}, Type{<:Polynomial{C, T}}}) where {C, T} = variables(T)
96 MP.nvariables(::Union{Polynomial{C, T}, AbstractArray{<:Polynomial{C, T}}, Type{<:Polynomial{C, T}}}) where {V, N, C, M<:Monomial{V, N}, T<:Term{C, M}} = N
97 const MonomialLike = Union{Variable, Monomial}
98 const TermLike = Union{MonomialLike, Term}
99 const PolynomialLike = Union{TermLike, Polynomial}
100
101 MP.variables(::Union{AbstractVector{T}, Type{<:AbstractVector{T}}}) where {T <: PolynomialLike} = variables(T)
102 MP.nvariables(::Union{AbstractVector{T}, Type{<:AbstractVector{T}}}) where {T <: PolynomialLike} = nvariables(T)
103 MP.variable_union_type(::Union{PolynomialLike, Type{<:PolynomialLike}}) = Variable
104 MP.constantmonomial(p::PolynomialLike) = Monomial{variables(p), nvariables(p)}()
105 MP.constantmonomial(::Type{TT}) where {TT<:PolynomialLike} = Monomial{variables(TT), nvariables(TT)}()
106
107
108 # Based on fillZfordeg!() from MultivariatePolynomials.jl by Benoit Legat
109 # https://github.com/blegat/MultivariatePolynomials.jl/blob/d85ad85de413afa20fc8f5354c980387218ced2c/src/mono.jl#L186-L259
110 function monomial_powers(::Val{N}, degree) where N
111 result = Vector{NTuple{N, Int}}()
112 powers = zeros(Int, N)
113 powers[1] = degree
114 while true
115 push!(result, NTuple{N, Int}(powers))
116 if powers[end] == degree
117 break
118 end
119 total = 1
120 for j in (N - 1):-1:1
121 if powers[j] != 0
122 powers[j] -= 1
123 powers[j+1] += total
124 break
125 else
126 total += powers[j+1]
127 powers[j+1] = 0
128 end
129 end
130 end
131 result
132 end
133
134 function MP.monomials(vars::Tuple{Vararg{<:Variable}}, degree::Integer, filter::Function=m->true)
135 checksorted(vars, >) || throw(ArgumentError("Variables must be in order"))
136 Monomial{vars, length(vars)}[Monomial{vars}(p) for p in monomial_powers(Val{length(vars)}(), degree) if filter(Monomial{vars}(p))]
137 end
138
139 function MP.monomials(vars::Tuple{Vararg{<:Variable}}, degrees::AbstractArray, filter::Function=m->true)
140 checksorted(vars, >) || throw(ArgumentError("Variables must be in order"))
141 if isempty(degrees)
142 # Otherwise, the following error is thrown: "ArgumentError: argument to Flatten must contain at least one iterator"
143 Monomial{vars, length(vars)}[]
144 else
145 Monomial{vars, length(vars)}[Monomial{vars}(p) for d in sort(degrees, rev=true)
146 for p in monomial_powers(Val{length(vars)}(), d) if filter(Monomial{vars}(p))]
147 end
148 end
149
150 MP.similarvariable(::Union{PolynomialLike, Type{<:PolynomialLike}}, ::Type{Val{N}}) where N = Variable{N}()