Line | Exclusive | Inclusive | Code |
---|---|---|---|
1 | export variables, nvariables, exponents, degree, isconstant, powers, constantmonomial, mapexponents | ||
2 | |||
3 | """ | ||
4 | monomialtype(p::AbstractPolynomialLike) | ||
5 | |||
6 | Return the type of the monomials of `p`. | ||
7 | |||
8 | termtype(::Type{PT}) where PT<:AbstractPolynomialLike | ||
9 | |||
10 | Returns the type of the monomials of a polynomial of type `PT`. | ||
11 | """ | ||
12 | monomialtype(::Union{M, Type{M}}) where M<:AbstractMonomial = M | ||
13 | monomialtype(::Union{PT, Type{PT}}) where PT <: APL = monomialtype(termtype(PT)) | ||
14 | monomialtype(::Union{AbstractVector{PT}, Type{<:AbstractVector{PT}}}) where PT <: APL = monomialtype(PT) | ||
15 | |||
16 | """ | ||
17 | variables(p::AbstractPolynomialLike) | ||
18 | |||
19 | Returns the tuple of the variables of `p` in decreasing order. It could contain variables of zero degree, see the example section. | ||
20 | |||
21 | ### Examples | ||
22 | |||
23 | Calling `variables(x^2*y)` should return `(x, y)` and calling `variables(x)` should return `(x,)`. | ||
24 | Note that the variables of `m` does not necessarily have nonzero degree. | ||
25 | For instance, `variables([x^2*y, y*z][1])` is usually `(x, y, z)` since the two monomials have been promoted to a common type. | ||
26 | """ | ||
27 | function variables end | ||
28 | |||
29 | """ | ||
30 | nvariables(p::AbstractPolynomialLike) | ||
31 | |||
32 | Returns the number of variables in `p`, i.e. `length(variables(p))`. It could be more than the number of variables with nonzero degree (see the Examples section of [`variables`](@ref)). | ||
33 | |||
34 | ### Examples | ||
35 | |||
36 | Calling `nvariables(x^2*y)` should return at least 2 and calling `nvariables(x)` should return at least 1. | ||
37 | """ | ||
38 | nvariables(::Union{AbstractVariable, Type{<:AbstractVariable}}) = 1 | ||
39 | |||
40 | """ | ||
41 | exponents(t::AbstractTermLike) | ||
42 | |||
43 | Returns the exponent of the variables in the monomial of the term `t`. | ||
44 | |||
45 | ### Examples | ||
46 | |||
47 | Calling `exponents(x^2*y)` should return `(2, 1)`. | ||
48 | """ | ||
49 | exponents(t::AbstractTerm) = exponents(monomial(t)) | ||
50 | exponents(v::AbstractVariable) = (1,) | ||
51 | |||
52 | """ | ||
53 | degree(t::AbstractTermLike) | ||
54 | |||
55 | Returns the *total degree* of the monomial of the term `t`, i.e. `sum(exponents(t))`. | ||
56 | |||
57 | degree(t::AbstractTermLike, v::AbstractVariable) | ||
58 | |||
59 | Returns the exponent of the variable `v` in the monomial of the term `t`. | ||
60 | |||
61 | ### Examples | ||
62 | |||
63 | Calling `degree(x^2*y)` should return 3 which is ``2 + 1``. | ||
64 | Calling `degree(x^2*y, x)` should return 2 and calling `degree(x^2*y, y)` should return 1. | ||
65 | |||
66 | """ | ||
67 | 137 (16 %) |
137 (16 %)
samples spent in degree
123 (90 %) (incl.) when called from isless line 15 14 (10 %) (incl.) when called from isless line 14
137 (100 %)
samples spent calling
sum
degree(t::AbstractTermLike) = sum(exponents(t))
|
|
68 | |||
69 | degree(t::AbstractTermLike, var::AbstractVariable) = degree(monomial(t), var) | ||
70 | degree(v::AbstractVariable, var::AbstractVariable) = (v == var ? 1 : 0) | ||
71 | #_deg(v::AbstractVariable) = 0 | ||
72 | #_deg(v::AbstractVariable, power, powers...) = v == power[1] ? power[2] : _deg(v, powers...) | ||
73 | #degree(m::AbstractMonomial, v::AbstractVariable) = _deg(v, powers(t)...) | ||
74 | |||
75 | function degree(m::AbstractMonomial, v::AbstractVariable) | ||
76 | i = findfirst(isequal(v), variables(m)) | ||
77 | if i === nothing || iszero(i) | ||
78 | 0 | ||
79 | else | ||
80 | exponents(m)[i] | ||
81 | end | ||
82 | end | ||
83 | |||
84 | """ | ||
85 | isconstant(t::AbstractTermLike) | ||
86 | |||
87 | Returns whether the monomial of `t` is constant. | ||
88 | """ | ||
89 | isconstant(t::AbstractTermLike) = all(iszero.(exponents(t))) | ||
90 | isconstant(v::AbstractVariable) = false | ||
91 | |||
92 | """ | ||
93 | powers(t::AbstractTermLike) | ||
94 | |||
95 | Returns an tuple of the powers of the monomial of `t`. | ||
96 | |||
97 | ### Examples | ||
98 | |||
99 | Calling `powers(3x^4*y) should return `((x, 4), (y, 1))`. | ||
100 | """ | ||
101 | powers(t::AbstractTermLike) = tuplezip(variables(t), exponents(t)) | ||
102 | |||
103 | """ | ||
104 | constantmonomial(p::AbstractPolynomialLike) | ||
105 | |||
106 | Returns a constant monomial of the monomial type of `p` with the same variables as `p`. | ||
107 | |||
108 | constantmonomial(::Type{PT}) where {PT<:AbstractPolynomialLike} | ||
109 | |||
110 | Returns a constant monomial of the monomial type of a polynomial of type `PT`. | ||
111 | """ | ||
112 | function constantmonomial end | ||
113 | |||
114 | """ | ||
115 | mapexponents(f, m1::AbstractMonomialLike, m2::AbstractMonomialLike) | ||
116 | |||
117 | If ``m_1 = \\prod x^{\\alpha_i}`` and ``m_2 = \\prod x^{\\beta_i}`` then it returns the monomial ``m = \\prod x^{f(\\alpha_i, \\beta_i)}``. | ||
118 | |||
119 | ### Examples | ||
120 | |||
121 | The multiplication `m1 * m2` is equivalent to `mapexponents(+, m1, m2)`, the unsafe division `_div(m1, m2)` is equivalent to `mapexponents(-, m1, m2)`, `gcd(m1, m2)` is equivalent to `mapexponents(min, m1, m2)`, `lcm(m1, m2)` is equivalent to `mapexponents(max, m1, m2)`. | ||
122 | """ | ||
123 | mapexponents(f, m1::AbstractMonomialLike, m2::AbstractMonomialLike) = mapexponents(f, monomial(m1), monomial(m2)) | ||
124 | |||
125 | function mapexponents_to! end | ||
126 | function mapexponents! end | ||
127 | |||
128 | Base.one(::Type{TT}) where {TT<:AbstractMonomialLike} = constantmonomial(TT) | ||
129 | Base.one(t::AbstractMonomialLike) = constantmonomial(t) | ||
130 | MA.promote_operation(::typeof(one), MT::Type{<:AbstractMonomialLike}) = monomialtype(MT) | ||
131 | # See https://github.com/JuliaAlgebra/MultivariatePolynomials.jl/issues/82 | ||
132 | # By default, Base do oneunit(v::VT) = VT(one(v)). | ||
133 | # This tries to convert a monomial to a variable which does not work. | ||
134 | # The issue here is there is no way to represent the multiplicative identity | ||
135 | # using the variable type. The best we can do is return a monomial even | ||
136 | # if it does not exactly match the definition of oneunit. | ||
137 | Base.oneunit(v::AbstractVariable) = one(v) | ||
138 | Base.oneunit(VT::Type{<: AbstractVariable}) = one(VT) |