### HyperDualNumbers 0.1.1------------------- --------------------------------------------------Hyper, eps1,eps1eps2 Automated 1st & 2nd order Differentiation
[if the function accepts dual numbers]
Or you can use the non-vectorized version and save the overhead of the temporary arrays being created by the addition and multiplication steps.
julia> x = linspace(0, pi, 1000000);
julia> y = sin(x);
julia> trapz1(x, y)
1.999999999998355
julia> trapz2(x, y)
1.9999999999984162
julia> @time for i in 1:100; trapz1(x, y); end
elapsed time: 4.858258575 seconds (5600105600 bytes allocated)
julia> @time for i in 1:100; trapz2(x, y); end
elapsed time: 0.41866061 seconds (1600 bytes allocated)
function trapz1{T<:Number}(x::Vector{T}, y::Vector{T})
local n = length(x)
if length(y) != n
error("Vectors 'x', 'y' must be of same length.")
end
if n == 1; return 0.0; end
sum((x[2:end]-x[1:end-1]) .* (y[2:end]+y[1:end-1])) / 2.0
end
function trapz2{T<:Number}(x::Vector{T}, y::Vector{T})
local n = length(x)
if (length(y) != n)
error("Vectors 'x', 'y' must be of same length")
end
if n == 1; return 0.0; end
r = 0.0
for i in 2:n
r += (x[i] - x[i-1]) * (y[i] + y[i-1])
end
r / 2.0
end
function trapz3{T<:Number}(x::Vector{T}, y::Vector{T})
local n = length(x)
if length(y) != n
error("Vectors 'x', 'y' must be of same length.")
end
if n == 1; return 0.0; end
int = (x[2:end]-x[1:end-1]) .* (y[2:end]+y[1:end-1])
r = 0.0
for i in 1:length(int)
r += int[i]
end
r / 2.0, BLAS.asum(int)/2.0, sum(int)/2.0
end
julia> trapz3(x, y)
(1.9999999999984162,1.9999999999983549,1.999999999998355)
The usage of construct like zero(zero(T)*zero(T)) is not really easy to understand. I assume you propose this due to the upcasting arithmetic integer behavior of non-native integer types (int16, ...), right?
WARNING: deprecated syntax "x[i:]" at /Users/ivarne/.julia/Devectorize/src/texpr.jl:493.
Use "x[i:end]" instead.
Ivar
function trapz2{T<:Number}(x::Vector{T}, y::Vector{T})
local n = length(x)
if (length(y) != n)
error("Vectors 'x', 'y' must be of same length")
end
if n == 1; return 0.0; end
r = 0.0
for i in 2:n
r += (x[i] - x[i-1]) * (y[i] + y[i-1])
end
r / 2.0
end
And as soon as you start working with complex analysis, I'm not entirely sure the trapezoidal rule is valid at all. It might just be because the article author was lazy, but the Wikipedia article only talks about integrals of real-valued functions of one (real, scalar) variable. If you need complex numbers for something more than curiosity about Julia's type system, you probably want another approach altogether...
Two additional packages are TaylorSeries (not in METADATA right now) and HyperDualNumbers, which I 'derived' from the C code by the authors (see below links).