using TaylorSeries
# Parámetros para el integrador de Taylor
const ordenTaylor = 28
const epsAbs = 1.0e-20
println(" Taylor order = $ordenTaylor\n Eps = $epsAbs\n")
Taylor order = 28 Eps = 1.0e-20
function taylorStepper{T<:Real}( jetEqs::Function, vec0::Array{T,1}, order::Int64, epsilon::T)
n = length( vec0 )
vec0T = [ Taylor([vec0[i]], order) for i=1:n ]
vec1T = jetEqs( vec0T )
# Step-size
hh = Inf
for i=1:n
h1 = stepsize( vec1T[i], epsilon )
hh = min( hh, h1 )
end
#hh = hh*0.125
# Values at t0+h
for i=1:n
vec0[i] = evalTaylor( vec1T[i], hh )
end
return hh, vec0
end
taylorStepper (generic function with 1 method)
function stepsize{T<:Real}(x::Taylor{T}, epsilon::Float64)
ord = x.order
h = Inf
for k in [ord-1, ord]
kinv = 1.0/k
aux = abs( x.coeffs[k+1] )
h = min(h, (epsilon/aux)^kinv)
end
return h
end
stepsize (generic function with 1 method)
energy{T<:Real}( x::T, vx::T ) = 0.5*vx^2 - cos(x)
energy (generic function with 1 method)
function jetPendulum{T<:Real}( vec::Array{Taylor{T},1} )
xT = vec[1]
vxT = vec[2]
ord = xT.order
# Now the implementation
for k = 0:ord-1
knext = k+1
# Taylor expansions up to order k <--- This part makes it somewhat slower
xTt = Taylor( xT.coeffs[1:k+1], k)
vxTt = Taylor( vxT.coeffs[1:k+1], k)
# Eqs of motion <--- This is quite straight :-)
xDot = vxTt
vxDot = -sin(xTt)
# The equations of motion define the recurrencies
xT.coeffs[knext+1] = xDot.coeffs[knext] / knext
vxT.coeffs[knext+1] = vxDot.coeffs[knext] / knext
end
return [ Taylor(xT, ord), Taylor(vxT, ord) ]
end
jetPendulum (generic function with 1 method)
x0 = pi-0.001
vx0 = 0.0
energy(x0,vx0)
0.9999995000000417
taylorStepper( jetPendulum, [x0, vx0], ordenTaylor, epsAbs )
(1.6634940262677569,[3.13886,-0.00254412])
function pendulumIntegration( x0::Float64, vx0::Float64, time_max::Float64, jetEqs::Function,
orden::Int64=ordenTaylor, epsilon::Float64=epsAbs )
# Initial conditions and energy
t0 = 0.0
ene0 = energy(x0, vx0)
# Change, measured in the local `eps` of the change of energy
eps_ene = eps(ene0); dEne = zero(Int64)
# Vectors to plot the orbit with PyPlot
tV, xV, vxV = Float64[], Float64[], Float64[]
DeneV = Int64[]
push!(tV, t0)
push!(xV, x0)
push!(vxV, vx0)
push!(DeneV, zero(Int64))
# This is the main loop; we include a minimum step size for security
dt = 1.0
while t0 < time_max && dt>1.0e-8
# Here we integrate
dt, (x1, vx1) = taylorStepper( jetEqs, [x0, vx0], orden, epsilon );
t0 += dt
push!(tV,t0)
push!(xV,x1)
push!(vxV, vx1)
eneEnd = energy(x1, vx1)
dEne = itrunc( (eneEnd-ene0)/eps_ene )
push!(DeneV, dEne)
x0, vx0 = x1, vx1
end
return tV, xV, vxV, DeneV
end
pendulumIntegration (generic function with 3 methods)
tV, xV, vxV, DeneV = pendulumIntegration( x0, vx0, 2pi, jetPendulum);
@time tV, xV, vxV, DeneV = pendulumIntegration( x0, vx0, 73.0, jetPendulum);
elapsed time: 0.008199471 seconds (8622688 bytes allocated)
minimum([tV[i+1]-tV[i] for i=1:length(tV)-1])
0.27844305590169327
using PyPlot
INFO: Loading help data...
plot(tV, xV, "-", tV, vxV, "-")
2-element Array{Any,1}: PyObject <matplotlib.lines.Line2D object at 0x11c0a5f10> PyObject <matplotlib.lines.Line2D object at 0x11c0a91d0>
plot(tV, DeneV, "-")
1-element Array{Any,1}: PyObject <matplotlib.lines.Line2D object at 0x117508b10>