Skip to content

Commit 84b5f87

Browse files
authored
Unitful support (#25)
* Added Unitful into test dependencies * Handling types with x*y multiplication. * Avoid redundant typeof * Added test for cumulative integration * Precompute values outside of loop for RombergEven
1 parent 5cc3fde commit 84b5f87

File tree

3 files changed

+26
-7
lines changed

3 files changed

+26
-7
lines changed

Project.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ HCubature = "19dc6840-f33b-545b-b366-655c7e3ffd49"
1616
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
1717
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
1818
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
19+
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
1920

2021
[targets]
21-
test = ["Test", "InteractiveUtils", "StaticArrays", "HCubature"]
22+
test = ["Test", "InteractiveUtils", "StaticArrays", "HCubature", "Unitful"]

src/NumericalIntegration.jl

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ RombergEven() = RombergEven(1e-12)
2626

2727
const HALF = 1//2
2828

29-
3029
#documentation
3130

3231
"""
@@ -147,12 +146,16 @@ end
147146
function integrate(x::AbstractVector, y::AbstractVector, m::RombergEven)
148147
@assert length(x) == length(y) "x and y vectors must be of the same length!"
149148
@assert ((length(x) - 1) & (length(x) - 2)) == 0 "Need length of vector to be 2^n + 1"
150-
maxsteps = Int(log2(length(x)-1))
151-
rombaux = zeros(eltype(y), maxsteps, 2)
149+
maxsteps::Integer = Int(log2(length(x)-1))
150+
@inbounds h = x[end] - x[1]
151+
@inbounds v = (y[1] + y[end]) * h * HALF
152+
rombaux = Matrix{typeof(v)}(undef, maxsteps, 2)
153+
rombaux[1,1] = v
152154
prevcol = 1
153155
currcol = 2
154-
@inbounds h = x[end] - x[1]
155-
@inbounds rombaux[1, 1] = (y[1] + y[end])*h*HALF
156+
# Precomputed values for norm check
157+
acc_compare = m.acc * oneunit(norm(v,Inf))
158+
minsteps = maxsteps ÷ 3
156159
@inbounds for i in 1 : (maxsteps-1)
157160
h *= HALF
158161
npoints = 1 << (i-1)
@@ -167,7 +170,9 @@ function integrate(x::AbstractVector, y::AbstractVector, m::RombergEven)
167170
rombaux[j, currcol] = (n_k*rombaux[j-1, currcol] - rombaux[j-1, prevcol])/(n_k - 1)
168171
end
169172

170-
if i > maxsteps//3 && norm(rombaux[i, prevcol] - rombaux[i+1, currcol], Inf) < m.acc
173+
# Clunky way to address Unitful compatibility, while also allowing for vectors
174+
normval = norm(rombaux[i, prevcol] - rombaux[i+1, currcol], Inf)
175+
if i > minsteps && normval < acc_compare
171176
return rombaux[i+1, currcol]
172177
end
173178

test/runtests.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,16 @@ end
7777
expwarn = "RombergEven :: final step reached, but accuracy not: 1.3333333333333335 > 1.0e-12"
7878
@test_logs (:warn, expwarn) integrate(xs, ys, m)
7979
end
80+
81+
using Unitful
82+
83+
@testset "Unitful compatibility" begin
84+
x = LinRange(1u"s", 10u"s", 9)
85+
y = rand(9)*u"m/s"
86+
for M in subtypes(IntegrationMethod)
87+
@test typeof(integrate(x,y,M())) == typeof(1.0u"m")
88+
if hasmethod(cumul_integrate, Tuple{AbstractVector, AbstractVector, M})
89+
@test typeof(cumul_integrate(x,y,M())) == Vector{typeof(1.0u"m")}
90+
end
91+
end
92+
end

0 commit comments

Comments
 (0)