Skip to content

Commit 18090b9

Browse files
authored
Define more mapcoefficient functions (#183)
* Define more mapcoefficient functions * Clean up * Fix * Fix doc * Fix * Fix
1 parent 7c5153d commit 18090b9

File tree

6 files changed

+77
-14
lines changed

6 files changed

+77
-14
lines changed

Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0"
1111

1212
[compat]
1313
DataStructures = "0.17.7, 0.18"
14-
DynamicPolynomials = "0.3.16"
14+
DynamicPolynomials = "0.4"
1515
MutableArithmetics = "0.3"
16-
TypedPolynomials = "0.2.9"
16+
TypedPolynomials = "0.3"
1717
julia = "1"
1818

1919
[extras]

docs/src/types.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ leadingmonomial
6868
removeleadingterm
6969
removemonomials
7070
monic
71-
mapcoefficientsnz
71+
mapcoefficients
72+
mapcoefficients!
73+
mapcoefficients_to!
7274
```
7375

7476
## Rational Polynomial Function

src/operators.jl

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,15 @@ Base.:/(A::AbstractArray, p::APL) = map(f -> f / p, A)
6565

6666
constant_function(::typeof(+)) = plusconstant
6767
constant_function(::typeof(-)) = minusconstant
68-
MA.operate!(op::Union{typeof(+), typeof(-)}, p::APL, α) = MA.operate!(constant_function(op), p, α)
68+
constant_function(::typeof(*)) = multconstant
69+
MA.operate!(op::Union{typeof(+), typeof(-), typeof(*)}, p::APL, α) = MA.operate!(constant_function(op), p, α)
70+
71+
MA.operate!(op::typeof(*), α, p::APL) = MA.operate!(multconstant, α, p)
72+
MA.operate!(op::typeof(*), p::APL, α) = MA.operate!(multconstant, p, α)
73+
MA.operate!(op::typeof(/), p::APL, α) = mapcoefficients!(Base.Fix2(op, α), p)
6974
MA.operate_to!(output::AbstractPolynomial, op::typeof(*), α, p::APL) = MA.operate_to!(output, multconstant, α, p)
7075
MA.operate_to!(output::AbstractPolynomial, op::typeof(*), p::APL, α) = MA.operate_to!(output, multconstant, p, α)
76+
MA.operate_to!(output::APL, op::typeof(/), p::APL, α) = mapcoefficients_to!(output, Base.Fix2(op, α), p)
7177

7278
function polynomial_merge!(
7379
n1::Int, n2::Int, get1::Function, get2::Function,
@@ -250,8 +256,7 @@ _multconstant(α, f, p::AbstractPolynomialLike) = _multconstant(α, f, polynomia
250256
multconstant(α, p::AbstractPolynomialLike) = _multconstant(α, β -> α*β, p)
251257
multconstant(p::AbstractPolynomialLike, α) = _multconstant(α, β -> β*α, p)
252258

253-
function mapcoefficientsnz_to! end
254-
259+
# TODO delete once DynamicPolynomials stops using it
255260
function _multconstant_to!(output, α, f, p)
256261
if iszero(α)
257262
MA.operate!(zero, output)
@@ -260,10 +265,16 @@ function _multconstant_to!(output, α, f, p)
260265
end
261266
end
262267
function MA.operate_to!(output, ::typeof(multconstant), p::APL, α)
263-
_multconstant_to!(output, α, β -> β*α, p)
268+
return _multconstant_to!(output, α, β -> β*α, p)
264269
end
265270
function MA.operate_to!(output, ::typeof(multconstant), α, p::APL)
266-
_multconstant_to!(output, α, β -> α*β, p)
271+
return _multconstant_to!(output, α, β -> α*β, p)
272+
end
273+
function MA.operate!(::typeof(multconstant), p::APL, α)
274+
return mapcoefficients!(Base.Fix2(*, α), p)
275+
end
276+
function MA.operate!(::typeof(multconstant), α, p::APL)
277+
return mapcoefficients!(Base.Fix1(*, α), p)
267278
end
268279

269280
MA.operate_to!(output::AbstractMonomial, ::typeof(*), m1::AbstractMonomialLike, m2::AbstractMonomialLike) = mapexponents_to!(output, +, m1, m2)

src/polynomial.jl

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export coefficienttype, monomialtype
33
export mindegree, maxdegree, extdegree, effective_variables
44
export leadingterm, leadingcoefficient, leadingmonomial
55
export removeleadingterm, removemonomials, monic
6+
export mapcoefficients, mapcoefficients!, mapcoefficients_to!
67

78
LinearAlgebra.norm(p::AbstractPolynomialLike, r::Int=2) = LinearAlgebra.norm(coefficients(p), r)
89

@@ -389,22 +390,65 @@ function _divtoone(t::AbstractTermLike{T}, α::S) where {T, S}
389390
end
390391
end
391392

393+
# TODO deprecate
394+
mapcoefficientsnz(f::Function, p::APL) = mapcoefficients(f, p, nonzero = true)
395+
mapcoefficientsnz_to!(output::APL, f::Function, p::APL) = mapcoefficients_to!(output, f, p, nonzero = true)
396+
392397
"""
393-
mapcoefficientsnz(f::Function, p::AbstractPolynomialLike)
398+
mapcoefficients(f::Function, p::AbstractPolynomialLike, nonzero = false)
399+
400+
Returns a polynomial with the same monomials as `p` but each coefficient `α` is replaced by `f(α)`.
401+
The function may return zero in which case the term is dropped.
402+
If the function is known to never returns zero for a nonzero input, `nonzero`
403+
can be set to `true` to get a small speedup.
394404
395-
Returns the polynomial obtained by applying `f` to each coefficients where `f` is a function such that `f(x)` is nonzero if `x` is nonzero.
405+
See also [`mapcoefficients!`](@ref) and [`mapcoefficients_to!`](@ref).
396406
397407
### Examples
398408
399-
Calling `mapcoefficientsnz(α -> α^2, 2x*y + 3x + 1)` should return `4x*y + 9x + 1`.
409+
Calling `mapcoefficients(α -> mod(3α, 6), 2x*y + 3x + 1)` should return `3x + 3`.
400410
"""
401-
function mapcoefficientsnz(f::Function, p::AbstractPolynomialLike)
411+
function mapcoefficients end
412+
function mapcoefficients(f::Function, p::AbstractPolynomialLike; nonzero = false) # TODO remove
402413
# Invariant: p has only nonzero coefficient
403414
# therefore f(α) will be nonzero for every coefficient α of p
404415
# hence we can use Uniq
405-
polynomial!(mapcoefficientsnz.(f, terms(p)), SortedUniqState())
416+
polynomial!(mapcoefficients.(f, terms(p)), nonzero ? SortedUniqState() : SortedState())
406417
end
407-
mapcoefficientsnz(f::Function, t::AbstractTermLike) = term(f(coefficient(t)), monomial(t))
418+
function mapcoefficients(f::Function, t::AbstractTermLike; nonzero = false)
419+
return term(f(coefficient(t)), monomial(t))
420+
end
421+
422+
"""
423+
mapcoefficients!(f::Function, p::AbstractPolynomialLike, nonzero = false)
424+
425+
Mutate `p` by replacing each coefficient `α` by `f(α)`.
426+
The function may return zero in which case the term is dropped.
427+
If the function is known to never returns zero for a nonzero input, `nonzero`
428+
can be set to `true` to get a small speedup.
429+
The function returns `p`, which is identically equal to the second argument.
430+
431+
See also [`mapcoefficients`](@ref) and [`mapcoefficients_to!`](@ref).
432+
433+
### Examples
434+
435+
Let `p = 2x*y + 3x + 1`, after `mapcoefficients!(α -> mod(3α, 6), p)`, `p` is
436+
equal to `3x + 3`.
437+
"""
438+
function mapcoefficients! end
439+
440+
"""
441+
mapcoefficients_to!(output::AbstractPolynomialLike, f::Function, p::AbstractPolynomialLike, nonzero = false)
442+
443+
Mutate `output` by replacing each coefficient `α` of `p` by `f(α)`.
444+
The function may return zero in which case the term is dropped.
445+
If the function is known to never returns zero for a nonzero input, `nonzero`
446+
can be set to `true` to get a small speedup.
447+
The function returns `output`, which is identically equal to the first argument.
448+
449+
See also [`mapcoefficients!`](@ref) and [`mapcoefficients`](@ref).
450+
"""
451+
function mapcoefficients_to! end
408452

409453
"""
410454
deg_num_leading_terms(p::AbstractPolynomialLike, var)

test/polynomial.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
using Test
2+
using LinearAlgebra
13
import MutableArithmetics
24
const MA = MutableArithmetics
5+
using MultivariatePolynomials
36
const MP = MultivariatePolynomials
47
@testset "Polynomial" begin
58
Mod.@polyvar x

test/utils.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
using Test
2+
using MultivariatePolynomials
3+
14
# Allocating size for allocating a `BigInt`.
25
# Half size on 32-bit.
36
const BIGINT_ALLOC = Sys.WORD_SIZE == 64 ? 48 : 24

0 commit comments

Comments
 (0)