@@ -2,6 +2,8 @@ module NumericalIntegration
2
2
3
3
using LinearAlgebra
4
4
using Logging
5
+ using Base. Iterators
6
+ using Interpolations
5
7
6
8
export integrate, cumul_integrate
7
9
export Trapezoidal, TrapezoidalEven, TrapezoidalFast, TrapezoidalEvenFast
@@ -177,27 +179,75 @@ function integrate(x::AbstractVector, y::AbstractVector, m::RombergEven)
177
179
end
178
180
179
181
182
+ @inline function _midpoints (x:: AbstractVector{T} ) where T
183
+ length (x) == 1 && return x
184
+ retval = Vector {T} (undef, length (x)- 1 )
185
+ @simd for i in eachindex (retval)
186
+ retval[i] = HALF * (x[i] + x[i+ 1 ])
187
+ end
188
+ return retval
189
+ end
190
+ @inline function _midpoints (x:: AbstractRange )
191
+ length (x) == 1 && return x
192
+ Δx = HALF* step (x)
193
+ return range (first (x)+ Δx, stop= last (x)- Δx, length= length (x)- 1 )
194
+ end
180
195
181
- function integrate (X:: Tuple{AbstractVector} , Y:: AbstractVector{T} , M:: IntegrationMethod ) :: T where {T}
182
- return integrate (X[1 ], Y, M)
196
+ function integrate (X:: NTuple{N,AbstractVector} , Y:: AbstractArray{T,N} , :: Trapezoidal ) where {T,N}
197
+ @assert length .(X) == size (Y)
198
+ return integrate (X, Y, TrapezoidalFast ())
183
199
end
184
- """
185
- integrate(X::NTuple{N,AbstractVector}, Y::AbstractArray{T,N}, method, cache=nothing)
186
200
187
- Given an n-dimensional grid of values, compute the total integral along each dim
188
- """
189
- function integrate (X:: NTuple{N,AbstractVector} , Y:: AbstractArray{T,N} , M:: IntegrationMethod ) :: T where {T,N}
190
- n = last (size (Y))
191
- cache = Vector {T} (undef, n)
192
- x = X[1 : N- 1 ]
193
- @inbounds for i in 1 : n
194
- cache[i] = integrate (x, selectdim (Y,N,i), M)
195
- end
196
- return integrate (X[end ], cache, M)
201
+ function integrate (X:: NTuple{N,AbstractVector} , Y:: AbstractArray{T,N} , :: TrapezoidalFast ) where {T,N}
202
+ midpnts = map (_midpoints, X)
203
+ Δ (x:: AbstractVector ) = length (x) > 1 ? diff (x) : 1
204
+ Δxs = map (Δ, X)
205
+ interp = LinearInterpolation (X,Y)
206
+ f ((Δx,x)) = prod (Δx)* interp (x... )
207
+ return sum (f, zip (product (Δxs... ), product (midpnts... )))
208
+ end
209
+
210
+ function integrate (X:: NTuple{N,AbstractVector} , Y:: AbstractArray{T,N} , :: TrapezoidalEvenFast ) where {T,N}
211
+ midpnts = map (_midpoints, X)
212
+ Δ (x:: AbstractVector ) = length (x) > 1 ? x[2 ] - x[1 ] : 1
213
+ Δx = prod (Δ, X)
214
+ interp = LinearInterpolation (X,Y)
215
+ f (x) = interp (x... )
216
+ return Δx* sum (f, product (midpnts... ))
217
+ end
218
+
219
+ function integrate (X:: NTuple{N,AbstractRange} , Y:: AbstractArray{T,N} , :: TrapezoidalEvenFast ) where {T,N}
220
+ midpnts = map (_midpoints, X)
221
+ Δ (x:: AbstractVector ) = length (x) > 1 ? step (x) : 1
222
+ Δx = prod (Δ, X)
223
+ interp = LinearInterpolation (X,Y)
224
+ f (x) = interp (x... )
225
+ return Δx* sum (f, product (midpnts... ))
197
226
end
198
227
199
228
200
229
230
+
231
+ # function integrate(X::Tuple{AbstractVector}, Y::AbstractVector{T}, M::IntegrationMethod) :: T where {T}
232
+ # return integrate(X[1], Y, M)
233
+ # end
234
+ # """
235
+ # integrate(X::NTuple{N,AbstractVector}, Y::AbstractArray{T,N}, method, cache=nothing)
236
+ #
237
+ # Given an n-dimensional grid of values, compute the total integral along each dim
238
+ # """
239
+ # function integrate(X::NTuple{N,AbstractVector}, Y::AbstractArray{T,N}, M::IntegrationMethod) :: T where {T,N}
240
+ # n = last(size(Y))
241
+ # cache = Vector{T}(undef, n)
242
+ # x = X[1:N-1]
243
+ # @inbounds for i in 1:n
244
+ # cache[i] = integrate(x, selectdim(Y,N,i), M)
245
+ # end
246
+ # return integrate(X[end], cache, M)
247
+ # end
248
+
249
+
250
+
201
251
# cumulative integrals
202
252
203
253
"""
0 commit comments