Skip to content

Commit 684f09e

Browse files
committed
minor changes to major change
1 parent 4627e9b commit 684f09e

18 files changed

+390
-161
lines changed

README.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ julia> using Polynomials
2222

2323
* `Polynomial` - Standard polynomials
2424
* `ChebyshevT` - Chebyshev polynomials of the first kind
25+
* `Bersntein` - Bernstein polynomials of degree n
2526

2627
#### Construction and Evaluation
2728

@@ -130,8 +131,8 @@ julia> roots(Polynomial([1, 0, -1]))
130131

131132
julia> roots(Polynomial([1, 0, 1]))
132133
2-element Array{Complex{Float64},1}:
133-
0.0+1.0im
134-
0.0-1.0im
134+
0.0 - 1.0im
135+
0.0 + 1.0im
135136

136137
julia> roots(Polynomial([0, 0, 1]))
137138
2-element Array{Float64,1}:
@@ -146,11 +147,11 @@ Fit a polynomial (of degree `deg`) to `x` and `y` using a least-squares approxim
146147
```julia
147148
julia> xs = 0:4; ys = @. exp(-xs) + sin(xs);
148149

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

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

156157
Visual example:
@@ -166,15 +167,16 @@ Polynomial objects also have other methods:
166167

167168
* `coeffs`: returns the entire coefficient vector
168169

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

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

173174
* `norm`: find the `p`-norm of a polynomial
174175

175-
* `conj`: finds the conjugate of a polynomial over a complex fiel
176+
* `conj`: finds the conjugate of a polynomial over a complex field
176177

177178
* `truncate`: set to 0 all small terms in a polynomial;
179+
178180
* `chop` chops off any small leading values that may arise due to floating point operations.
179181

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

docs/src/extending.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ The [`AbstractPolynomial`](@ref) type was made to be extended via a rich interfa
66
AbstractPolynomial
77
```
88

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 natural basis `1, x, x^2, ..., x^n`. New p olynomial 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`.
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`.
1010

1111
To implement a new polynomial type, `P`, the following methods should
1212
be implemented.

docs/src/index.md

Lines changed: 46 additions & 8 deletions
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,9 +163,47 @@ 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+
166197
### Iteration
167198

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]`, reelative to some polynomial basis. The most familiar basis being `1`, `x`, `x^2`, ... If the basis is implicit, then a polynomial is just a vector. Vectors or 1-based, but 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`, ...
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+
```
169207

170208
## Related Packages
171209

docs/src/polynomials/bernstein.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ end
77
```
88

99

10-
The [Bernstein polynomials](https://en.wikipedia.org/wiki/Bernstein_polynomial) are a family of polynomials defined on the interval `[0,1]`. For each `n` there are `n+1` polynomials, given by: `b(n,nu) = choose(n,nu) x^nu * (1-x)^(n-nu)` for `nu` in `0:n`. Together, these form a basis that can represent any polynomial of degree `n` or less through a linear combination.
10+
The [Bernstein polynomials](https://en.wikipedia.org/wiki/Bernstein_polynomial) are a family of polynomials defined on the interval `[0,1]`. For each `n` there are `n+1` polynomials, given by: `b(n,nu) = choose(n,nu) x^nu * (1-x)^(n-nu)` for `nu` in `0:n`. Together, these form a basis that can represent any polynomial of degree `n` or less through a unique linear combination.
1111

1212

1313
## Bernstein(N,T)

docs/src/polynomials/chebyshev.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ end
77
```
88

99

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 written as a linear combination of the polynomials `T_0`, `T_1`, ..., `T_n` (similarly with `U`).
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`).
1111

1212

1313
## First Kind

docs/src/reference.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ 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
9697
# T1, T2, T3, and T4:

src/Polynomials.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ include("contrib.jl")
1111
# Polynomials
1212
include("polynomials/Polynomial.jl")
1313
include("polynomials/ChebyshevT.jl")
14-
include("polynomials/ChebyshevU.jl")
14+
#include("polynomials/ChebyshevU.jl")
1515
include("polynomials/Bernstein.jl")
1616

17-
include("polynomials/Poly.jl") # Deprecated -> Will be removed
17+
include("polynomials/Poly.jl") # to be deprecated, then removed
1818
include("pade.jl")
1919
include("compat.jl") # Where we keep deprecations
2020

src/common.jl

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -60,39 +60,40 @@ fromroots(A::AbstractMatrix{T}; var::SymbolLike = :x) where {T <: Number} =
6060
fromroots(Polynomial, eigvals(A), var = var)
6161

6262
"""
63-
fit(x, y; [weights], deg=length(x) - 1, var=:x)
64-
fit(::Type{<:AbstractPolynomial}, x, y; [weights], deg=length(x)-1, var=:x)
63+
fit(x, y, deg=length(x) - 1; [weights], var=:x)
64+
fit(::Type{<:AbstractPolynomial}, x, y, deg=length(x)-1; [weights], var=:x)
6565
66-
Fit the given data as a polynomial type with the given degree. Uses linear least squares. When weights are given, as either a `Number`, `Vector` or `Matrix`, will use weighted linear least squares. The default polynomial type is [`Polynomial`](@ref). This will automatically scale your data to the [`domain`](@ref) of the polynomial type using [`mapdomain`](@ref)
66+
Fit the given data as a polynomial type with the given degree. Uses linear least squares. When weights are given, as either a `Number`, `Vector` or `Matrix`, will use weighted linear least squares. The default polynomial type is [`Polynomial`](@ref). This will automatically scale your data to the [`domain`](@ref) of the polynomial type using [`mapdomain`](@ref). To specify a different range to scale to, specify `domain=(a,b)` where `a <= minimum(xs) && maximum(xs) <= b`.
6767
"""
6868
function fit(P::Type{<:AbstractPolynomial},
69-
x::AbstractVector{T},
70-
y::AbstractVector{T};
71-
weights = nothing,
72-
deg::Integer = length(x) - 1,
73-
var = :x,) where {T}
74-
x = mapdomain(P, x)
69+
x::AbstractVector{T},
70+
y::AbstractVector{T},
71+
deg::Integer=length(x) - 1;
72+
domain=(minimum(x), maximum(x)),
73+
weights = nothing,
74+
var = :x,) where {T}
75+
x = mapdomain(P, first(domain),last(domain)).(x)
7576
vand = vander(P, x, deg)
7677
if weights !== nothing
7778
coeffs = _wlstsq(vand, y, weights)
7879
else
79-
coeffs = pinv(vand) * y
80+
coeffs = vand \ y #pinv(vand) * y
8081
end
8182
return P(T.(coeffs), var)
8283
end
8384

8485
fit(P::Type{<:AbstractPolynomial},
8586
x,
86-
y;
87+
y,
88+
deg::Integer = length(x) - 1;
8789
weights = nothing,
88-
deg::Integer = length(x) - 1,
89-
var = :x,) = fit(P, promote(collect(x), collect(y))...; weights = weights, deg = deg, var = var)
90+
var = :x,) = fit(P, promote(collect(x), collect(y))..., deg; weights = weights, var = var)
9091

9192
fit(x::AbstractVector,
92-
y::AbstractVector;
93+
y::AbstractVector,
94+
deg::Integer = length(x) - 1;
9395
weights = nothing,
94-
deg::Integer = length(x) - 1,
95-
var = :x,) = fit(Polynomial, x, y; weights = weights, deg = deg, var = var)
96+
var = :x,) = fit(Polynomial, x, y, deg; weights = weights, var = var)
9697

9798
# Weighted linear least squares
9899
_wlstsq(vand, y, W::Number) = _wlstsq(vand, y, fill!(similar(y), W))
@@ -353,6 +354,11 @@ function mapdomain(P::Type{<:AbstractPolynomial}, x::AbstractArray)
353354
end
354355
mapdomain(::P, x::AbstractArray) where {P <: AbstractPolynomial} = mapdomain(P, x)
355356

357+
function mapdomain(P::Type{<:AbstractPolynomial}, a::Number, b::Number)
358+
a, b = a < b ? (a,b) : (b,a)
359+
x -> mapdomain(P, [a,x,b])[2]
360+
end
361+
356362
#=
357363
indexing =#
358364
Base.firstindex(p::AbstractPolynomial) = 0
@@ -362,10 +368,14 @@ Base.broadcastable(p::AbstractPolynomial) = Ref(p)
362368

363369
# basis
364370
# return the kth basis polynomial for the given polynomial type, e.g. x^k for Polynomial{T}
365-
function basis(p::P, k::Int) where {P <: AbstractPolynomial}
366-
zs = zeros(eltype(p), k+1)
367-
zs[k+1] = 1
368-
P(zs, p.var)
371+
function basis(p::P, k::Int) where {P<:AbstractPolynomial}
372+
basis(P, k)
373+
end
374+
375+
function basis(::Type{P}, k::Int; var=:x) where {P <: AbstractPolynomial}
376+
zs = zeros(Int, k+1)
377+
zs[end] = 1
378+
P(zs, var)
369379
end
370380

371381
# iteration

src/compat.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ end
1919
polyint(p::AbstractPolynomial, C = 0) = integrate(p, C)
2020
polyint(p::AbstractPolynomial, a, b) = integrate(p, a, b)
2121
polyder(p::AbstractPolynomial, ord = 1) = derivative(p, ord)
22-
polyfit(x, y, n = length(x) - 1) = fit(Polynomial, x, y; deg = n)
23-
polyfit(x, y, sym::Symbol) = fit(Polynomial, x, y; var = sym)
22+
polyfit(x, y, n = length(x) - 1, sym=:x) = fit(Polynomial, x, y, n; var = sym)
23+
polyfit(x, y, sym::Symbol) = fit(Polynomial, x, y, var = sym)
2424

2525
padeval(PQ::Pade, x::Number) = PQ(x)
2626
padeval(PQ::Pade, x) = PQ.(x)

0 commit comments

Comments
 (0)