Skip to content

Commit

Permalink
Merge pull request #179 from mileslucas/refactor
Browse files Browse the repository at this point in the history
Abstracting Polynomials
  • Loading branch information
jverzani authored Apr 7, 2020
2 parents 49cbdd8 + aaaa0b0 commit 4c99692
Show file tree
Hide file tree
Showing 29 changed files with 3,048 additions and 1,363 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/compat.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: CompatHelper

on:
schedule:
- cron: "0 0 * * *"

jobs:
CompatHelper:
runs-on: ${{ matrix.os }}
strategy:
matrix:
julia-version: [1.3.0]
julia-arch: [x86]
os: [ubuntu-latest]
steps:
- uses: julia-actions/setup-julia@latest
with:
version: ${{ matrix.julia-version }}
- name: Pkg.add("CompatHelper")
run: julia -e 'using Pkg; Pkg.add("CompatHelper")'
- name: CompatHelper.main()
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: julia -e 'using CompatHelper; CompatHelper.main()'
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ matrix:
notifications:
email: false

coveralls: true
codecov: true

jobs:
include:
Expand Down
7 changes: 5 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@ name = "Polynomials"
uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45"
license = "MIT"
author = "JuliaMath"
version = "0.6.1"
version = "0.7.0"

[deps]
Intervals = "d8418881-c3e1-53bb-8760-2df7ec849ed5"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"

[compat]
julia = "1.0"
Intervals = "0.5.0"
RecipesBase = "0.7, 0.8"
julia = "1"


[extras]
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Expand Down
170 changes: 80 additions & 90 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,180 +1,167 @@
# Polynomials
# Polynomials.jl

Basic arithmetic, integration, differentiation, evaluation, and root finding over dense univariate polynomials.

[![Polynomials](http://pkg.julialang.org/badges/Polynomials_0.6.svg)](http://pkg.julialang.org/?pkg=Polynomials)

Master branch:
[![](https://img.shields.io/badge/docs-stable-blue.svg)](https://JuliaMath.github.io/Polynomials.jl/stable)
[![](https://img.shields.io/badge/docs-latest-blue.svg)](https://JuliaMath.github.io/Polynomials.jl/dev)
[![Build Status](https://travis-ci.org/JuliaMath/Polynomials.jl.svg?branch=master)](https://travis-ci.org/JuliaMath/Polynomials.jl)
[![Coverage Status](https://coveralls.io/repos/github/JuliaMath/Polynomials.jl/badge.svg)](https://coveralls.io/github/JuliaMath/Polynomials.jl)
[![codecov](https://codecov.io/gh/JuliaMath/Polynomials.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/JuliaMath/Polynomials.jl)

Documentation:
[![](https://img.shields.io/badge/docs-stable-blue.svg)](https://JuliaMath.github.io/Polynomials.jl/stable)
[![](https://img.shields.io/badge/docs-latest-blue.svg)](https://JuliaMath.github.io/Polynomials.jl/latest)

#### Poly(a::Vector) where {T<:Number}
## Installation

```julia
(v1.2) pkg> add Polynomials

julia> using Polynomials
```

## Usage

#### Available Polynomials

* `Polynomial` - Standard polynomials
* `ChebyshevT` - Chebyshev polynomials of the first kind

#### Construction and Evaluation

Construct a polynomial from its coefficients, lowest order first.

```julia
julia> Poly([1,0,3,4])
Poly(1 + 3x^2 + 4x^3)
julia> Polynomial([1,0,3,4])
Polynomial(1 + 3x^2 + 4x^3)
```

An optional variable parameter can be added.

```julia
julia> Poly([1,2,3], :s)
Poly(1 + 2s + 3s^2)
julia> Polynomial([1,2,3], :s)
Polynomial(1 + 2s + 3s^2)
```

#### poly(r::AbstractVector)
Construct a polynomial from its roots.

Construct a polynomial from its roots. This is in contrast to the
`Poly` constructor, which constructs a polynomial from its
coefficients.
```julia
julia> fromroots([1,2,3]) # (x-1)*(x-2)*(x-3)
Polynomial(-6 + 11x - 6x^2 + x^3)
```

Evaluate the polynomial `p` at `x`.

```julia
// Represents (x-1)*(x-2)*(x-3)
julia> poly([1,2,3])
Poly(-6 + 11x - 6x^2 + x^3)
julia> p = Polynomial([1, 0, -1])
julia> p(0.1)
0.99
```

#### +, -, *, /, div, ==
#### Arithmetic

The usual arithmetic operators are overloaded to work on polynomials, and combinations of polynomials and scalars.

```julia
julia> p = Poly([1,2])
Poly(1 + 2x)
julia> p = Polynomial([1,2])
Polynomial(1 + 2x)

julia> q = Poly([1, 0, -1])
Poly(1 - x^2)
julia> q = Polynomial([1, 0, -1])
Polynomial(1 - x^2)

julia> 2p
Poly(2 + 4x)
Polynomial(2 + 4x)

julia> 2+p
Poly(3 + 2x)
Polynomial(3 + 2x)

julia> p - q
Poly(2x + x^2)

julia> p * q
Poly(1 + 2x - x^2 - 2x^3)
Polynomial(1 + 2x - x^2 - 2x^3)

julia> q / 2
Poly(0.5 - 0.5x^2)
Polynomial(0.5 - 0.5x^2)

julia> q ÷ p # `div`, also `rem` and `divrem`
Poly(0.25 - 0.5x)
julia> q ÷ p # `div`, also `rem` and `divrem`
Polynomial(0.25 - 0.5x)
```

Note that operations involving polynomials with different variables will error.

```julia
julia> p = Poly([1, 2, 3], :x)
julia> q = Poly([1, 2, 3], :s)
julia> p = Polynomial([1, 2, 3], :x)
julia> q = Polynomial([1, 2, 3], :s)
julia> p + q
ERROR: Polynomials must have same variable.
```

To get the degree of the polynomial use the `degree` method

```
julia> degree(p)
2
julia> degree(p^2)
4
julia> degree(p-p)
-1
```

#### polyval(p::Poly, x::Number)

Evaluate the polynomial `p` at `x`.

```julia
julia> p = Poly([1, 0, -1])
julia> polyval(p, 0.1)
0.99
```

A call method is also available:

```julia
julia> p(0.1)
0.99
```


#### polyint(p::Poly, k::Number=0)
#### Integrals and Derivatives

Integrate the polynomial `p` term by term, optionally adding constant
term `k`. The order of the resulting polynomial is one higher than the
order of `p`.

```julia
julia> polyint(Poly([1, 0, -1]))
Poly(x - 0.3333333333333333x^3)
julia> integrate(Polynomial([1, 0, -1]))
Polynomial(x - 0.3333333333333333x^3)

julia> polyint(Poly([1, 0, -1]), 2)
Poly(2.0 + x - 0.3333333333333333x^3)
julia> integrate(Polynomial([1, 0, -1]), 2)
Polynomial(2.0 + x - 0.3333333333333333x^3)
```

#### polyder(p::Poly)

Differentiate the polynomial `p` term by term. The order of the
resulting polynomial is one lower than the order of `p`.

```julia
julia> polyder(Poly([1, 3, -1]))
Poly(3 - 2x)
julia> derivative(Polynomial([1, 3, -1]))
Polynomial(3 - 2x)
```

#### roots(p::Poly)
#### Root-finding


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

```julia
julia> roots(Poly([1, 0, -1]))
julia> roots(Polynomial([1, 0, -1]))
2-element Array{Float64,1}:
-1.0
1.0

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

julia> roots(Poly([0, 0, 1]))
julia> roots(Polynomial([0, 0, 1]))
2-element Array{Float64,1}:
0.0
0.0
```

#### polyfit(x, y, n=length(x)-1)
#### Fitting arbitrary data

* `polyfit`: fits a polynomial (of order `n`) to `x` and `y` using a least-squares approximation.
Fit a polynomial (of order `deg`) to `x` and `y` using a least-squares approximation.

```julia
julia> xs = 1:4; ys = exp.(xs); polyfit(xs, ys)
Poly(-7.717211620141281 + 17.9146616149694x - 9.77757245502143x^2 + 2.298404288652356x^3)
julia> xs = 0:4; ys = @. exp(-xs) + sin(xs);

julia> fit(xs, ys)
Polynomial(1.0000000000000016 + 0.059334723072240664*x + 0.39589720602859824*x^2 - 0.2845598112184312*x^3 + 0.03867830809692903*x^4)

julia> fit(ChebyshevT, xs, ys, deg=2)
ChebyshevT([0.541280671210034, -0.8990834124779993, -0.4237852336242923])
```

Visual example:

![newplot 42](https://user-images.githubusercontent.com/3156114/41799777-9ba00582-7627-11e8-94ef-15297ec8790e.png)
![fit example](https://user-images.githubusercontent.com/14099459/70382587-9e055500-1902-11ea-8952-3f03ae08b7dc.png)

#### Other methods

Polynomial objects also have other methods:

* 0-based indexing is used to extract the coefficients of $a_0 + a_1
x + a_2 x^2 + ...$, coefficients may be changed using indexing
* 0-based indexing is used to extract the coefficients of `[a0, a1, a2, ...]`, coefficients may be changed using indexing
notation.

* `coeffs`: returns the entire coefficient vector
Expand All @@ -187,18 +174,16 @@ Polynomial objects also have other methods:

* `conj`: finds the conjugate of a polynomial over a complex fiel

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

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

* `Pade`: Return the
[Pade approximant](https://en.wikipedia.org/wiki/Pad%C3%A9_approximant)
of order `m/n` for a polynomial as a `Pade` object.
[Pade approximant](https://en.wikipedia.org/wiki/Pad%C3%A9_approximant) of order `m/n` for a polynomial as a `Pade` object.


## See also
## Related Packages

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

Expand All @@ -207,3 +192,8 @@ Polynomial objects also have other methods:
* [Nemo.jl](https://github.com/wbhart/Nemo.jl) for generic polynomial rings, matrix spaces, fraction fields, residue rings, power series

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


## Contributing

If you are interested in contributing, feel free to open an issue or pull request to get started.
4 changes: 3 additions & 1 deletion docs/Project.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
[deps]
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"

[compat]
Documenter = "0.23.3"
Documenter = "0.24"
16 changes: 12 additions & 4 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
using Documenter, Polynomials
using Documenter
using Polynomials

DocMeta.setdocmeta!(Polynomials, :DocTestSetup, :(using Polynomials); recursive=true)
DocMeta.setdocmeta!(Polynomials, :DocTestSetup, :(using Polynomials); recursive = true)

makedocs(modules = [Polynomials],
makedocs(
modules = [Polynomials],
format = Documenter.HTML(prettyurls = get(ENV, "CI", nothing) == "true"),
sitename = "Polynomials.jl",
authors = "Jameson Nash, Keno Fischer, and other contributors",
pages = [
"Manual" => "index.md",
"Home" => "index.md",
"Reference/API" => "reference.md",
"Polynomial Types" => [
"Polynomial" => "polynomials/polynomial.md",
"Chebyshev" => "polynomials/chebyshev.md",
],
"Extending" => "extending.md",
],
)

Expand Down
Loading

0 comments on commit 4c99692

Please sign in to comment.