Skip to content
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

Supporting a static Taylor1 or TaylorN type? #240

Open
mewilhel opened this issue Apr 3, 2020 · 4 comments
Open

Supporting a static Taylor1 or TaylorN type? #240

mewilhel opened this issue Apr 3, 2020 · 4 comments

Comments

@mewilhel
Copy link

mewilhel commented Apr 3, 2020

I was just wondering if anyone has thoughts around possibly supporting statically typed versions of Taylor series in this package. I've thrown together a sample implementation and it seems like there is a reasonable speed up to be had.

addition speedup: 63.0x
subtraction speedup: 63.0x
scalar multiplication speedup: 14.0x
multiplication speed up: 10.0x

Sample Snippet:

import Base: +, -, *

struct STaylor1{N,T}
    coeffs::SVector{N,T}
end

+(x::STaylor1{N,T}, y::STaylor1{N,T}) where {T<:Number,N} = STaylor1{N,T}(x.coeffs + y.coeffs)
-(x::STaylor1{N,T}, y::STaylor1{N,T}) where {T<:Number,N} = STaylor1{N,T}(x.coeffs - y.coeffs)
*(x::STaylor1{N,T}, y::T) where {T<:Number,N} = STaylor1{N,T}(y*x.coeffs)
*(y::T, x::STaylor1{N,T}) where {T<:Number,N} = STaylor1{N,T}(y*x.coeffs)

 @generated function *(x::STaylor1{N,T}, y::STaylor1{N,T}) where {T<:Number,N}
    ex_calc = quote end
    for j = 1:N
        ex_line = :(x.coeffs[1]*y.coeffs[$j])
        for k = 2:j
            ex_line = :($ex_line + x.coeffs[$k]*y.coeffs[$(j-k+1)])
        end
        sym = Symbol("c$j")
        ex_line = :($sym = $ex_line)
        push!(ex_calc.args, ex_line)
    end
    exout = :((c1,))
    for i = 2:N
        sym = Symbol("c$i")
        push!(exout.args, sym)
    end
    return quote
            $ex_calc
            tup = $exout
            svec = SVector{N,T}(tup)
            return STaylor1{N,T}(svec)
         end
end

Benchmarking script:

using StaticArrays, BenchmarkTools, TaylorSeries

order = 5
a = 1.1

s1 = @SVector rand(order)
s2 = @SVector rand(order)

st1 = STaylor1{order,Float64}(s1)
st2 = STaylor1{order,Float64}(s2)

out1 = Taylor1(Float64[s1[i] for i in 1:length(s1)])
t1 = Taylor1(Float64[s1[i] for i in 1:length(s1)])
t2 = Taylor1(Float64[s2[i] for i in 1:length(s2)])

function f(g, x, y, n)
    t = x
    for i=1:n
        t = g(t,x)
        t = g(t,y)
    end
    t
end

n = 500

@btime f($+, $st1, $st2, $n)
@btime f($+, $t1, $t2, $n)
static_time = @belapsed f($+, $st1, $st2, $n)
var_time = @belapsed f($+, $t1, $t2, $n)
println("addition speedup: $(floor(var_time/static_time))x")

@btime f($-, $st1, $st2, $n)
@btime f($-, $t1, $t2, $n)
static_time = @belapsed f($-, $st1, $st2, $n)
var_time = @belapsed f($-, $t1, $t2, $n)
println("subtraction speedup: $(floor(var_time/static_time))x")

@btime f($*, $a, $st2, $n)
@btime f($*, $a, $t2, $n)
static_time = @belapsed f($*, $a, $st2, $n)
var_time = @belapsed f($*, $a, $t2, $n)
println("scalar multiplication speedup: $(floor(var_time/static_time))x")

@btime f($*, $st1, $st2, $n)
@btime f($*, $t1, $t2, $n)
static_time = @belapsed f($*, $st1, $st2, $n)
var_time = @belapsed f($*, $t1, $t2, $n)
println("multiplication speed up: $(floor(var_time/static_time))x")
@lbenet
Copy link
Member

lbenet commented Apr 3, 2020

That would be truly fantastic! I have been thinking about this lately, since I learned recently about Setfield.jl, which may be handy. Would you like to open a PR so we can check what would be running and what not? I guess the speed up would also go to TaylorIntegration.jl and TaylorModels.jl, so I am really interested on this.

@dpsanders
Copy link
Contributor

I have some (unreleased) work along these lines that basically does exactly what you're doing:
https://github.com/dpsanders/StaticTaylorSeries.jl

We should definitely put together something there.

@mewilhel
Copy link
Author

mewilhel commented Apr 3, 2020

Excellent! I'm definitely interested in pursuing this. Would you all prefer the work to be done on a fork of TaylorSeries.jl or shall I start playing with the StaticTaylorSeries.jl repository?

@lbenet
Copy link
Member

lbenet commented Apr 3, 2020

For me it's ok if you would like to have it here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants