Skip to content

Commit aa33559

Browse files
authored
Merge pull request #196 from jverzani/miles-lucas-refactor-delta
Miles lucas refactor delta
2 parents 4c99692 + 2831c82 commit aa33559

20 files changed

+474
-222
lines changed

.travis.yml

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ julia:
99
- 1.1
1010
- 1.2
1111
- 1.3
12+
- 1.4
1213
- nightly
1314

1415
matrix:

Project.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
1010
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
1111

1212
[compat]
13-
Intervals = "0.5.0"
14-
RecipesBase = "0.7, 0.8"
13+
Intervals = "0.5.0, 1.0"
14+
RecipesBase = "0.7, 0.8, 1.0"
1515
julia = "1"
1616

1717

README.md

+17-16
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ ERROR: Polynomials must have same variable.
9696
#### Integrals and Derivatives
9797

9898
Integrate the polynomial `p` term by term, optionally adding constant
99-
term `k`. The order of the resulting polynomial is one higher than the
100-
order of `p`.
99+
term `k`. The degree of the resulting polynomial is one higher than the
100+
degree of `p`.
101101

102102
```julia
103103
julia> integrate(Polynomial([1, 0, -1]))
@@ -107,8 +107,8 @@ julia> integrate(Polynomial([1, 0, -1]), 2)
107107
Polynomial(2.0 + x - 0.3333333333333333x^3)
108108
```
109109

110-
Differentiate the polynomial `p` term by term. The order of the
111-
resulting polynomial is one lower than the order of `p`.
110+
Differentiate the polynomial `p` term by term. The degree of the
111+
resulting polynomial is one lower than the degree of `p`.
112112

113113
```julia
114114
julia> derivative(Polynomial([1, 3, -1]))
@@ -119,7 +119,7 @@ Polynomial(3 - 2x)
119119

120120

121121
Return the roots (zeros) of `p`, with multiplicity. The number of
122-
roots returned is equal to the order of `p`. By design, this is not type-stable,
122+
roots returned is equal to the degree of `p`. By design, this is not type-stable,
123123
the returned roots may be real or complex.
124124

125125
```julia
@@ -130,8 +130,8 @@ julia> roots(Polynomial([1, 0, -1]))
130130

131131
julia> roots(Polynomial([1, 0, 1]))
132132
2-element Array{Complex{Float64},1}:
133-
0.0+1.0im
134-
0.0-1.0im
133+
0.0 - 1.0im
134+
0.0 + 1.0im
135135

136136
julia> roots(Polynomial([0, 0, 1]))
137137
2-element Array{Float64,1}:
@@ -141,16 +141,16 @@ julia> roots(Polynomial([0, 0, 1]))
141141

142142
#### Fitting arbitrary data
143143

144-
Fit a polynomial (of order `deg`) to `x` and `y` using a least-squares approximation.
144+
Fit a polynomial (of degree `deg`) to `x` and `y` using a least-squares approximation.
145145

146146
```julia
147147
julia> xs = 0:4; ys = @. exp(-xs) + sin(xs);
148148

149-
julia> fit(xs, ys)
150-
Polynomial(1.0000000000000016 + 0.059334723072240664*x + 0.39589720602859824*x^2 - 0.2845598112184312*x^3 + 0.03867830809692903*x^4)
149+
julia> fit(xs, ys) |> x -> round(x, digits=4)
150+
Polynomial(1.0 + 0.0593*x + 0.3959*x^2 - 0.2846*x^3 + 0.0387*x^4)
151151

152-
julia> fit(ChebyshevT, xs, ys, deg=2)
153-
ChebyshevT([0.541280671210034, -0.8990834124779993, -0.4237852336242923])
152+
julia> fit(ChebyshevT, xs, ys, deg=2) |> x -> round(x, digits=4)
153+
ChebyshevT(0.5413T_0(x) - 0.8991T_1(x) - 0.4238T_2(x))
154154
```
155155

156156
Visual example:
@@ -166,15 +166,16 @@ Polynomial objects also have other methods:
166166

167167
* `coeffs`: returns the entire coefficient vector
168168

169-
* `degree`: returns the polynomial degree, `length` is 1 plus the degree
169+
* `degree`: returns the polynomial degree, `length` is number of stored coefficients
170170

171-
* `variable`: returns the polynomial symbol as a degree 1 polynomial
171+
* `variable`: returns the polynomial symbol as polynomial in the underlying type
172172

173173
* `norm`: find the `p`-norm of a polynomial
174174

175-
* `conj`: finds the conjugate of a polynomial over a complex fiel
175+
* `conj`: finds the conjugate of a polynomial over a complex field
176+
177+
* `truncate`: set to 0 all small terms in a polynomial;
176178

177-
* `truncate`: set to 0 all small terms in a polynomial;
178179
* `chop` chops off any small leading values that may arise due to floating point operations.
179180

180181
* `gcd`: greatest common divisor of two polynomials.

docs/src/extending.md

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
# Extending Polynomials
22

3-
The [`AbstractPolynomial`](@ref) type was made to be extended via a rich interface.
3+
The [`AbstractPolynomial`](@ref) type was made to be extended via a rich interface.
44

55
```@docs
66
AbstractPolynomial
77
```
88

9-
To implement a new polynomial type, `P`, the following methods should be implemented.
9+
A polynomial's coefficients are relative to some *basis*. The `Polynomial` type relates coefficients `[a0, a1, ..., an]`, say, to the polynomial `a0 + a1*x + a2*x^ + ... + an*x^n`, through the standard basis `1, x, x^2, ..., x^n`. New polynomial types typically represent the polynomial through a different basis. For example, `CheyshevT` uses a basis `T_0=1, T_1=x, T_2=2x^2-1, ..., T_n = 2xT_{n-1} - T_{n-2}`. For this type the coefficients `[a0,a1,...,an]` are associated with the polynomial `a0*T0 + a1*T_1 + ... + an*T_n`.
10+
11+
To implement a new polynomial type, `P`, the following methods should
12+
be implemented.
1013

1114
!!! note
1215
Promotion rules will always coerce towards the [`Polynomial`](@ref) type, so not all methods have to be implemented if you provide a conversion function.
@@ -26,5 +29,6 @@ As always, if the default implementation does not work or there are more efficie
2629
| `-(::P, ::P)` | | Subtraction of polynomials |
2730
| `*(::P, ::P)` | | Multiplication of polynomials |
2831
| `divrem` | | Required for [`gcd`](@ref)|
32+
| `variable`| | Convenience to find monomial `x` in new basis|
2933

30-
Check out both the [`Polynomial`](@ref) and [`ChebyshevT`](@ref) for examples of this interface being extended!
34+
Check out both the [`Polynomial`](@ref) and [`ChebyshevT`](@ref) for examples of this interface being extended.

docs/src/index.md

+49-8
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@ ERROR: Polynomials must have same variable
104104
### Integrals and Derivatives
105105

106106
Integrate the polynomial `p` term by term, optionally adding constant
107-
term `C`. The order of the resulting polynomial is one higher than the
108-
order of `p`.
107+
term `C`. The degree of the resulting polynomial is one higher than the
108+
degree of `p`.
109109

110110
```jldoctest
111111
julia> integrate(Polynomial([1, 0, -1]))
@@ -115,8 +115,8 @@ julia> integrate(Polynomial([1, 0, -1]), 2)
115115
Polynomial(2.0 + 1.0*x - 0.3333333333333333*x^3)
116116
```
117117

118-
Differentiate the polynomial `p` term by term. The order of the
119-
resulting polynomial is one lower than the order of `p`.
118+
Differentiate the polynomial `p` term by term. The degree of the
119+
resulting polynomial is one lower than the degree of `p`.
120120

121121
```jldoctest
122122
julia> derivative(Polynomial([1, 3, -1]))
@@ -137,8 +137,8 @@ julia> roots(Polynomial([1, 0, -1]))
137137
138138
julia> roots(Polynomial([1, 0, 1]))
139139
2-element Array{Complex{Float64},1}:
140-
-0.0 + 1.0im
141140
0.0 - 1.0im
141+
0.0 + 1.0im
142142
143143
julia> roots(Polynomial([0, 0, 1]))
144144
2-element Array{Float64,1}:
@@ -148,13 +148,13 @@ julia> roots(Polynomial([0, 0, 1]))
148148

149149
### Fitting arbitrary data
150150

151-
Fit a polynomial (of order `deg`) to `x` and `y` using a least-squares approximation.
151+
Fit a polynomial (of degree `deg`) to `x` and `y` using polynomial interpolation or a (weighted) least-squares approximation.
152152

153153
```@example
154154
using Plots, Polynomials
155155
xs = range(0, 10, length=10)
156156
ys = exp.(-xs)
157-
f = fit(xs, ys)
157+
f = fit(xs, ys) # fit(xs, ys, k) for fitting a kth degreee polynomial
158158
159159
scatter(xs, ys, label="Data");
160160
plot!(f, extrema(xs)..., label="Fit");
@@ -163,14 +163,55 @@ savefig("polyfit.svg"); nothing # hide
163163

164164
![](polyfit.svg)
165165

166+
### Other bases
167+
168+
A polynomial, e.g. `a_0 + a_1 x + a_2 x^2 + ... + a_n x^n`, can be seen as a collection of coefficients, `[a_0, a_1, ..., a_n]`, relative to some polynomial basis. The most familiar basis being the standard one: `1`, `x`, `x^2`, ... Alternative bases are possible. The `ChebyshevT` polynomials are implemented, as an example. Instead of `Polynomial` or `Polynomial{T}`, `ChebyshevT` or `ChebyshevT{T}` constructors are used:
169+
170+
```jldoctest
171+
julia> p1 = ChebyshevT([1.0, 2.0, 3.0])
172+
ChebyshevT(1.0⋅T_0(x) + 2.0⋅T_1(x) + 3.0⋅T_2(x))
173+
174+
julia> p2 = ChebyshevT{Float64}([0, 1, 2])
175+
ChebyshevT(1.0⋅T_1(x) + 2.0⋅T_2(x))
176+
177+
julia> p1 + p2
178+
ChebyshevT(1.0⋅T_0(x) + 3.0⋅T_1(x) + 5.0⋅T_2(x))
179+
180+
julia> p1 * p2
181+
ChebyshevT(4.0⋅T_0(x) + 4.5⋅T_1(x) + 3.0⋅T_2(x) + 3.5⋅T_3(x) + 3.0⋅T_4(x))
182+
183+
julia> derivative(p1)
184+
ChebyshevT(2.0⋅T_0(x) + 12.0⋅T_1(x))
185+
186+
julia> integrate(p2)
187+
ChebyshevT(0.25⋅T_0(x) - 1.0⋅T_1(x) + 0.25⋅T_2(x) + 0.3333333333333333⋅T_3(x))
188+
189+
julia> convert(Polynomial, p1)
190+
Polynomial(-2.0 + 2.0*x + 6.0*x^2)
191+
192+
julia> convert(ChebyshevT, Polynomial([1.0, 2, 3]))
193+
ChebyshevT(2.5⋅T_0(x) + 2.0⋅T_1(x) + 1.5⋅T_2(x))
194+
```
195+
196+
197+
### Iteration
198+
199+
If its basis is implicit, then a polynomial may be seen as just a vector of coefficients. Vectors or 1-based, but, for convenience, polynomial types are 0-based, for purposes of indexing (e.g. `getindex`, `setindex!`, `eachindex`). Iteration over a polynomial steps through the basis vectors, e.g. `a_0`, `a_1*x`, ...
200+
201+
```jldoctest
202+
julia> as = [1,2,3,4,5]; p = Polynomial(as);
203+
204+
julia> as[3], p[2], collect(p)[3]
205+
(3, 3, Polynomial(3*x^2))
206+
```
166207

167208
## Related Packages
168209

169210
* [MultiPoly.jl](https://github.com/daviddelaat/MultiPoly.jl) for sparse multivariate polynomials
170211

171212
* [MultivariatePolynomials.jl](https://github.com/blegat/MultivariatePolynomials.jl) for multivariate polynomials and moments of commutative or non-commutative variables
172213

173-
* [Nemo.jl](https://github.com/wbhart/Nemo.jl) for generic polynomial rings, matrix spaces, fraction fields, residue rings, power series
214+
* [AbstractAlgeebra.jl](https://github.com/wbhart/AbstractAlgebra.jl) for generic polynomial rings, matrix spaces, fraction fields, residue rings, power series.
174215

175216
* [PolynomialRoots.jl](https://github.com/giordano/PolynomialRoots.jl) for a fast complex polynomial root finder
176217

docs/src/polynomials/chebyshev.md

+12-2
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,34 @@ DocTestSetup = quote
66
end
77
```
88

9+
10+
The [Chebyshev polynomials](https://en.wikipedia.org/wiki/Chebyshev_polynomials) are two sequences of polynomials, `T_n` and `U_n`. The Chebyshev polynomials of the first kind, `T_n`, can be defined by the recurrence relation `T_0(x)=1`, `T_1(x)=x`, and `T_{n+1}(x) = 2xT_n{x}-T_{n-1}(x)`. The Chebyshev polynomioals of the second kind, `U_n(x)`, can be defined by `U_0(x)=1`, `U_1(x)=2x`, and `U_{n+1}(x) = 2xU_n(x) - U_{n-1}(x)`. Both `T_n` and `U_n` have degree `n`, and any polynomial of degree `n` may be uniquely written as a linear combination of the polynomials `T_0`, `T_1`, ..., `T_n` (similarly with `U`).
11+
12+
913
## First Kind
1014

1115
```@docs
1216
ChebyshevT
1317
ChebyshevT()
1418
```
1519

20+
The `ChebyshevT` type holds coefficients representing the polynomial `a_0 T_0 + a_1 T_1 + ... + a_n T_n`.
21+
22+
For example, the basis polynomial `T_4` can be represented with `ChebyshevT([0,0,0,0,1])`.
23+
24+
1625
### Conversion
1726

1827
[`ChebyshevT`](@ref) can be converted to [`Polynomial`](@ref) and vice-versa.
1928

2029
```jldoctest
2130
julia> c = ChebyshevT([1, 0, 3, 4])
22-
ChebyshevT([1, 0, 3, 4])
31+
ChebyshevT(1⋅T_0(x) + 3⋅T_2(x) + 4⋅T_3(x))
32+
2333
2434
julia> p = convert(Polynomial, c)
2535
Polynomial(-2 - 12*x + 6*x^2 + 16*x^3)
2636
2737
julia> convert(ChebyshevT, p)
28-
ChebyshevT([1.0, 0.0, 3.0, 4.0])
38+
ChebyshevT(1.0⋅T_0(x) + 3.0⋅T_2(x) + 4.0⋅T_3(x))
2939
```

docs/src/reference.md

+8-5
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ end
1616

1717
```@docs
1818
coeffs
19-
order
2019
degree
2120
length
2221
size
2322
domain
2423
mapdomain
2524
chop
2625
chop!
26+
round
2727
truncate
2828
truncate!
2929
```
@@ -91,19 +91,22 @@ plot(::AbstractPolynomial, a, b; kwds...)
9191
will plot the polynomial within the range `[a, b]`.
9292

9393
### Example: The Polynomials.jl logo
94+
9495
```@example
9596
using Plots, Polynomials
96-
xs = range(-1, 1, length=100)
97+
# T1, T2, T3, and T4:
9798
chebs = [
9899
ChebyshevT([0, 1]),
99100
ChebyshevT([0, 0, 1]),
100101
ChebyshevT([0, 0, 0, 1]),
101102
ChebyshevT([0, 0, 0, 0, 1]),
102103
]
103104
colors = ["#4063D8", "#389826", "#CB3C33", "#9558B2"]
104-
plot() # hide
105-
for (cheb, col) in zip(chebs, colors)
106-
plot!(xs, cheb.(xs), c=col, lw=5, label="")
105+
itr = zip(chebs, colors)
106+
(cheb,col), state = iterate(itr)
107+
p = plot(cheb, c=col, lw=5, legend=false, label="")
108+
for (cheb, col) in Base.Iterators.rest(itr, state)
109+
plot!(cheb, c=col, lw=5)
107110
end
108111
savefig("chebs.svg"); nothing # hide
109112
```

src/Polynomials.jl

+6-7
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,15 @@ include("show.jl")
88
include("plots.jl")
99
include("contrib.jl")
1010

11+
# Interface for all AbstractPolynomials
12+
include("common.jl")
13+
14+
1115
# Polynomials
1216
include("polynomials/Polynomial.jl")
1317
include("polynomials/ChebyshevT.jl")
14-
include("polynomials/ChebyshevU.jl")
1518

16-
include("polynomials/Poly.jl") # Deprecated -> Will be removed
17-
include("pade.jl")
18-
include("compat.jl") # Where we keep deprecations
19-
20-
# Interface for all AbstractPolynomials
21-
include("common.jl")
19+
# to be deprecated, then removed
20+
include("compat.jl")
2221

2322
end # module

src/abstract.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ macro register(name)
3535
poly = esc(name)
3636
quote
3737
Base.convert(::Type{P}, p::P) where {P<:$poly} = p
38-
Base.convert(P::Type{<:$poly}, p::$poly) where {T} = P(p.coeffs, p.var)
38+
Base.convert(P::Type{<:$poly}, p::$poly) where {T} = P(coeffs(p), p.var)
3939
Base.promote_rule(::Type{$poly{T}}, ::Type{$poly{S}}) where {T,S} =
4040
$poly{promote_type(T, S)}
4141
Base.promote_rule(::Type{$poly{T}}, ::Type{S}) where {T,S<:Number} =

0 commit comments

Comments
 (0)