Skip to content

Commit 0e1edb9

Browse files
authored
Remove MutableArithemetics code to new package PolynomialsMutableArithmetics (#445)
* WIP * edits * move MutableArithmetics to separate package * rm tests for MA * replace tab with space
1 parent 84ec58f commit 0e1edb9

File tree

8 files changed

+35
-110
lines changed

8 files changed

+35
-110
lines changed

.github/workflows/downstream.yml

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ jobs:
1818
os: [ubuntu-latest]
1919
package:
2020
- {user: jverzani, repo: SpecialPolynomials.jl, group: All}
21+
- {user: jverzani, repo: PolynomialsMutableArithmetics.jl, group: All}
2122

2223
steps:
2324
- uses: actions/checkout@v2

Project.toml

+1-3
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@ name = "Polynomials"
22
uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45"
33
license = "MIT"
44
author = "JuliaMath"
5-
version = "3.1.8"
5+
version = "3.2.0"
66

77
[deps]
88
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
9-
MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0"
109
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
1110

1211
[compat]
13-
MutableArithmetics = "0.3,1"
1412
RecipesBase = "0.7, 0.8, 1"
1513
julia = "1.6"
1614

README.md

+31-9
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ may be noticeable in some use cases. This is amplified when the coefficients
119119
are for instance `BigInt` or `BigFloat` which are mutable themself.
120120
This can be avoided by modifying existing polynomials to contain the result
121121
of the operation using the [MutableArithmetics (MA) API](https://github.com/jump-dev/MutableArithmetics.jl).
122+
122123
Consider for instance the following arrays of polynomials
123124
```julia
124125
using Polynomials
@@ -127,34 +128,55 @@ p(d) = Polynomial(big.(1:d))
127128
A = [p(d) for i in 1:m, j in 1:n]
128129
b = [p(d) for i in 1:n]
129130
```
131+
130132
In this case, the arrays are mutable objects for which the elements are mutable
131133
polynomials which have mutable coefficients (`BigInt`s).
132134
These three nested levels of mutable objects communicate with the MA
133135
API in order to reduce allocation.
134136
Calling `A * b` requires approximately 40 MiB due to 2 M allocations
135-
as it does not exploit any mutability. Using
137+
as it does not exploit any mutability.
138+
139+
Using
140+
141+
```julia
142+
using PolynomialsMutableArithmetics
143+
```
144+
145+
to register `Polynomials` with `MutableArithmetics`, then multiplying with:
146+
136147
```julia
137148
using MutableArithmetics
138149
const MA = MutableArithmetics
139150
MA.operate(*, A, b)
140151
```
141-
exploits the mutability and hence only allocate approximately 70 KiB due to 4 k
142-
allocations. If the resulting vector is already allocated, e.g.,
152+
153+
exploits the mutability and hence only allocates approximately 70 KiB due to 4 k
154+
allocations.
155+
156+
If the resulting vector is already allocated, e.g.,
157+
143158
```julia
144159
z(d) = Polynomial([zero(BigInt) for i in 1:d])
145160
c = [z(2d - 1) for i in 1:m]
146161
```
162+
147163
then we can exploit its mutability with
164+
148165
```julia
149-
MA.mutable_operate!(MA.add_mul, c, A, b)
166+
MA.operate!(MA.add_mul, c, A, b)
150167
```
151-
to reduce the allocation down to 48 bytes due to 3 allocations. These remaining
152-
allocations are due to the `BigInt` buffer used to store the result of
153-
intermediate multiplications. This buffer can be preallocated with
168+
169+
to reduce the allocation down to 48 bytes due to 3 allocations.
170+
171+
These remaining allocations are due to the `BigInt` buffer used to
172+
store the result of intermediate multiplications. This buffer can be
173+
preallocated with:
174+
154175
```julia
155176
buffer = MA.buffer_for(MA.add_mul, typeof(c), typeof(A), typeof(b))
156-
MA.mutable_buffered_operate!(buffer, MA.add_mul, c, A, b)
177+
MA.buffered_operate!(buffer, MA.add_mul, c, A, b)
157178
```
179+
158180
then the second line is allocation-free.
159181

160182
The `MA.@rewrite` macro rewrite an expression into an equivalent code that
@@ -174,7 +196,7 @@ c = MA.operate(*, A1, b1)
174196
MA.mutable_operate!(MA.add_mul, c, A2, b2)
175197
```
176198

177-
*Note that currently, only the `Polynomial` implements the API and it only
199+
*Note that currently, only the `Polynomial` type implements the API and it only
178200
implements part of it.*
179201

180202
### Integrals and Derivatives

src/Polynomials.jl

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ include("common.jl")
1414

1515
# Polynomials
1616
include("polynomials/standard-basis.jl")
17-
include("polynomials/mutable-arithmetics.jl")
1817
include("polynomials/Polynomial.jl")
1918
include("polynomials/ImmutablePolynomial.jl")
2019
include("polynomials/SparsePolynomial.jl")

src/common.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -818,8 +818,8 @@ Base.:-(p::P) where {P <: AbstractPolynomial} = _convert(p, -coeffs(p))
818818

819819
Base.:*(p::AbstractPolynomial, c::Number) = scalar_mult(p, c)
820820
Base.:*(c::Number, p::AbstractPolynomial) = scalar_mult(c, p)
821-
Base.:*(c::T, p::P) where {T, P <: AbstractPolynomial{T}} = scalar_mult(c, p)
822-
Base.:*(p::P, c::T) where {T, P <: AbstractPolynomial{T}} = scalar_mult(p, c)
821+
Base.:*(c::T, p::P) where {T, X, P <: AbstractPolynomial{T,X}} = scalar_mult(c, p)
822+
Base.:*(p::P, c::T) where {T, X, P <: AbstractPolynomial{T,X}} = scalar_mult(p, c)
823823

824824
# implicitly identify c::Number with a constant polynomials
825825
Base.:+(c::Number, p::AbstractPolynomial) = +(p, c)

src/polynomials/Polynomial.jl

-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ struct Polynomial{T, X} <: StandardBasisPolynomial{T, X}
5050
end
5151

5252
@register Polynomial
53-
@register_mutable_arithmetic Polynomial
5453

5554

5655

src/polynomials/mutable-arithmetics.jl

-71
This file was deleted.

test/StandardBasis.jl

-23
Original file line numberDiff line numberDiff line change
@@ -1525,29 +1525,6 @@ end
15251525
end
15261526
end
15271527

1528-
import MutableArithmetics
1529-
const MA = MutableArithmetics
1530-
1531-
function alloc_test(f, n)
1532-
f() # compile
1533-
@test n == @allocated f()
1534-
end
1535-
1536-
@testset "Mutable arithmetics" begin
1537-
d = m = n = 4
1538-
p(d) = Polynomial(big.(1:d))
1539-
z(d) = Polynomial([zero(BigInt) for i in 1:d])
1540-
A = [p(d) for i in 1:m, j in 1:n]
1541-
b = [p(d) for i in 1:n]
1542-
c = [z(2d - 1) for i in 1:m]
1543-
buffer = MA.buffer_for(MA.add_mul, typeof(c), typeof(A), typeof(b))
1544-
@test buffer isa BigInt
1545-
c = [z(2d - 1) for i in 1:m]
1546-
MA.buffered_operate!(buffer, MA.add_mul, c, A, b)
1547-
@test c == A * b
1548-
@test c == MA.operate(*, A, b)
1549-
@test 0 == @allocated MA.buffered_operate!(buffer, MA.add_mul, c, A, b)
1550-
end
15511528

15521529
@testset "SparsePolynomial" begin
15531530
@test Polynomials.minimumexponent(SparsePolynomial) == typemin(Int)

0 commit comments

Comments
 (0)