Skip to content

Initial work on Static Taylor Series #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: arithmetic
Choose a base branch
from
1 change: 1 addition & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
comment: false
29 changes: 29 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
language: julia
#codecov: true
coveralls: true

os:
- linux
- osx
- windows

julia:
- 1.2
- 1.3
- 1.4
- 1.5
- nightly

jobs:
allow_failures:
- julia: nightly

after_success:
- julia -e 'import Pkg; Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder()); Codecov.submit(process_folder())'

notifications:
email: false

addons:
apt_packages:
- gfortran
7 changes: 6 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@ uuid = "91725f60-9ab6-11e9-00d0-87fe6d51fd3a"
authors = ["David Sanders <[email protected]>"]
version = "0.1.0"

[deps]
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
TaylorSeries = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea"

[compat]
julia = "1"
Requires = "~1"
TaylorSeries = "~0.10"

[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Expand Down
34 changes: 33 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,33 @@
# StaticTaylorSeries
# StaticTaylorSeries.jl
A [Julia](http://julialang.org) package used to compute static 1D Taylor
polynomial expansions

[![Build Status](https://api.travis-ci.org/dpsanders/TaylorSeries.jl.svg?branch=master)](https://travis-ci.org/JuliaDiff/TaylorSeries.jl)
[![Coverage Status](https://coveralls.io/repos/dpsanders/TaylorSeries.jl/badge.svg?branch=master)](https://coveralls.io/github/JuliaDiff/TaylorSeries.jl?branch=master)

[![](https://img.shields.io/badge/docs-stable-blue.svg)](https://github.com/dpsanders/TaylorSeries.jl/stable)
[![](https://img.shields.io/badge/docs-latest-blue.svg)](https://github.com/dpsanders/TaylorSeries.jl/latest)

This package contains a static implementation of the Taylor1 structure in TaylorSeries.jl.

## Key Differences

This package introduces the `STaylor1{N,T}` structure which can be used as a
replacement for the `Taylor1{T}` structure of TaylorSeries.jl. Arithmetic operators are defined via generated functions and do not allocate.

Key differences are:
- Arithmetic with `STaylor1{N,T}` structures use entirely immutable storage types
for calculations whereas `Taylor1{T}` calculations make use of a number of
arrays for intermediate storage. As a consequence, the `STaylor1{N,T}` implementation
will be significant faster for calculations involving low-order Taylor series.
- The `STaylor1{N,T}` structure stores coefficients as an `NTuple` rather than
an array.
- Constructors: Most constructors are similar to those used for Taylor1. The
constructor `STaylor1(x::T, v::Val{N})` is used in place of `Taylor1(x::T, order::Int)`.
- In place functions (e.g. `tan!(a,c,k)`) are not supported.
- Currently, **tan**, **tanh**, **asin**, **acos**, **atan** are
unsupported.

#### License

`StaticTaylorSeries` is licensed under the [MIT "Expat" license](./LICENSE.md).
226 changes: 39 additions & 187 deletions src/StaticTaylorSeries.jl
Original file line number Diff line number Diff line change
@@ -1,192 +1,44 @@
module StaticTaylorSeries

export StaticTaylor

"""
Static Taylor series with variable V, length N (i.e. order N-1) and element type T.
"""
struct StaticTaylor{N,T}
coeffs::NTuple{N,T}
end


function coeffstring(t::StaticTaylor, i, variable=:x)

if i == 1 # order 0
return string(t.coeffs[i])

elseif i == 2 # order 1
return string(t.coeffs[i], variable)

else
return string(t.coeffs[i], variable, "^", i-1)
end
end


function print_taylor(io::IO, t::StaticTaylor, variable=:x)

print(io, "(" * join([coeffstring(t, i, variable) for i in 1:length(t.coeffs)], " + ") * ")")

end

function Base.show(io::IO, t::StaticTaylor)
print_taylor(io, t)
end

function Base.show(io::IO, t::StaticTaylor{N,T}) where {N, T<:StaticTaylor}
print_taylor(io, t, :y)
end

#StaticTaylor(iterable...) = StaticTaylor(SVector(iterable...))

StaticTaylor{N}(v::NTuple{N,T}) where {N,T} = StaticTaylor(v)



#StaticTaylor{N}(iterable) where {N} = StaticTaylor{N}(iterable)

StaticTaylor{N}(iterable...) where {N} = StaticTaylor{N}(iterable)

# StaticTaylor(v) = StaticTaylor(v)

StaticTaylor(iterable...) = StaticTaylor{length(iterable)}(iterable)

import Base:getindex, length, eltype

getindex(s::StaticTaylor, i::Integer) = s.coeffs[i+1]

length(s::StaticTaylor{N,T}) where {N,T} = N

eltype(s::StaticTaylor{N,T}) where {N,T} = T


import Base: +, -, * ,^

function +(s::StaticTaylor{N,T}, t::StaticTaylor{N,T}) where {N,T}
return StaticTaylor(s.coeffs .+ t.coeffs)
using Requires
using TaylorSeries: AbstractSeries, NumberNotSeries

import Base: ==, +, -, *, /, ^

import Base: iterate, size, eachindex, firstindex, lastindex,
eltype, length, getindex, setindex!, axes, copyto!

import Base: zero, one, zeros, ones, isinf, isnan, iszero,
convert, promote_rule, promote, show,
real, imag, conj, adjoint,
rem, mod, mod2pi, abs, abs2,
sqrt, exp, log, sin, cos, tan,
asin, acos, atan, sinh, cosh, tanh,
power_by_squaring,
rtoldefault, isfinite, isapprox, rad2deg, deg2rad

export STaylor1

export getcoeff, derivative, integrate, differentiate,
evaluate, evaluate!, inverse, set_taylor1_varname,
show_params_TaylorN, show_monomials, displayBigO, use_show_default,
get_order, get_numvars, set_variables, get_variables,
get_variable_names, get_variable_symbols,
taylor_expand, update!, constant_term, linear_polynomial,
normalize_taylor, evaluate

include("constructors.jl")
include("conversion.jl")
include("auxiliary.jl")
include("arithmetic.jl")
include("power.jl")
include("functions.jl")
include("other_functions.jl")
include("evaluate.jl")
include("printing.jl")

function __init__()
@require IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" include("intervals.jl")
end

function +(s::StaticTaylor{N,T}, α::Real) where {N,T}
return StaticTaylor{N,T}(ntuple(i -> i == 1 ? s.coeffs[1] + α : s.coeffs[i], N))
end

+(α::Real, s::StaticTaylor) = s + α

-(s::StaticTaylor) = StaticTaylor(.-(s.coeffs))

function -(s::StaticTaylor{N,T}, t::StaticTaylor{N,T}) where {N,T}
return StaticTaylor(s.coeffs .- t.coeffs)
end

-(s::StaticTaylor, α::Real) = s + (-α)

-(α::Real, s::StaticTaylor) = -(s - a)





Base.literal_pow(::typeof(^), x::StaticTaylor, ::Val{p}) where {p} = x^p

^(x::StaticTaylor, n::Integer) = Base.power_by_squaring(x, n)



# function *(s::StaticTaylor{N,T}, t::StaticTaylor{N,T}) where {N,T}
# v = SVector(ntuple(k->sum(s[i]*t[k-1-i] for i in 0:k-1), Val(N)))
# return StaticTaylor(v)
# end

# The following is modified from StaticUnivariatePolynomials.jl
@generated function Base.:*(p1::StaticTaylor{N,T}, p2::StaticTaylor{N,T}, max_degree=N) where {N, T}
exprs = Any[nothing for i in 1:N]
for i in 0 : N-1 # order is N-1
for j in 0 : N-1
k = i + j + 1 # setindex does not have offset

if k > max_degree
continue
end

if exprs[k] === nothing
exprs[k] = :(p1[$i] * p2[$j])
else
exprs[k] = :(muladd(p1[$i], p2[$j], $(exprs[k])))
end
end
end

# Core.println("Generated code with N=$N:")
# Core.println(exprs)
# Core.println()

return quote
Base.@_inline_meta
StaticTaylor{N,T}(tuple($(exprs...)))
end
end

@generated function mult(p1::StaticTaylor{N,T}, p2::StaticTaylor{N,T}, ::Val{max_degree}) where {N, T, max_degree}
exprs = Any[nothing for i in 1:max_degree]
for i in 0 : N-1 # order is N-1
for j in 0 : N-1
k = i + j + 1 # setindex does not have offset

if k > max_degree
continue
end

if exprs[k] === nothing
exprs[k] = :(p1[$i] * p2[$j])
else
exprs[k] = :(muladd(p1[$i], p2[$j], $(exprs[k])))
end
end
end

# Core.println("Generated code with N=$N:")
# Core.println(exprs)
# Core.println()

return quote
Base.@_inline_meta
StaticTaylor{max_degree,T}(tuple($(exprs...)))
end
end
#
# @generated function *(p1::StaticTaylor{N,T}, p2::StaticTaylor{N,T}) where {N, T}
# exprs = Any[nothing for i in 1:N]
# for i in 0 : N-1 # order is N-1
# for j in 0 : N-1
# k = i + j + 1 # setindex does not have offset
#
# if k > N
# continue
# end
#
# if exprs[k] === nothing
# exprs[k] = :(p1[$i] * p2[$j])
# else
# exprs[k] = :(muladd(p1[$i], p2[$j], $(exprs[k])))
# end
# end
# end
#
# # Core.println("Generated code with N=$N:")
# # Core.println(exprs)
# # Core.println()
#
# return quote
# Base.@_inline_meta
# StaticTaylor{N,T}(tuple($(exprs...)))
# end
# end


*(s::StaticTaylor, α::Real) = StaticTaylor(α .* s.coeffs)
*(α::Real, s::StaticTaylor) = s * α

/(s::StaticTaylor, α::Real) = StaticTaylor(s.coeffs ./ α)

end # module
Loading