@@ -2,56 +2,59 @@ __precompile__()
22
33module NumericalIntegration
44
5- using Compat
6-
75export integrate
86export Trapezoidal, TrapezoidalEven, TrapezoidalFast, TrapezoidalEvenFast
97export SimpsonEven, SimpsonEvenFast
108export IntegrationMethod
119
12- @compat abstract type IntegrationMethod end
10+ abstract type IntegrationMethod end
1311
14- immutable Trapezoidal <: IntegrationMethod end
15- immutable TrapezoidalEven <: IntegrationMethod end
16- immutable TrapezoidalFast <: IntegrationMethod end
17- immutable TrapezoidalEvenFast <: IntegrationMethod end
18- immutable SimpsonEven <: IntegrationMethod end # https://en.wikipedia.org/wiki/Simpson%27s_rule#Alternative_extended_Simpson.27s_rule
19- immutable SimpsonEvenFast <: IntegrationMethod end
12+ struct Trapezoidal <: IntegrationMethod end
13+ struct TrapezoidalEven <: IntegrationMethod end
14+ struct TrapezoidalFast <: IntegrationMethod end
15+ struct TrapezoidalEvenFast <: IntegrationMethod end
16+ struct SimpsonEven <: IntegrationMethod end # https://en.wikipedia.org/wiki/Simpson%27s_rule#Alternative_extended_Simpson.27s_rule
17+ struct SimpsonEvenFast <: IntegrationMethod end
2018
2119const HALF = 1 // 2
2220
23- function integrate {X<:Number, Y<:Number} (x:: AbstractVector{X} , y:: AbstractVector{Y} , :: Trapezoidal )
24- @assert length (x) == length (y) " x and y vectors must be of the same length!"
25- retval = zero (promote (x[1 ], y[1 ])[1 ])
21+ function _zero (x,y)
22+ ret = zero (eltype (x)) + zero (eltype (y))
23+ ret / 2
24+ end
25+
26+ function integrate (x:: AbstractVector , y:: AbstractVector , :: Trapezoidal )
27+ @assert length (x) == length (y) " x and y vectors must be of the same length!"
28+ retval = _zero (x,y)
2629 for i in 1 : length (y)- 1
27- retval += (x[i+ 1 ] - x[i]) * (y[i] + y[i+ 1 ])
30+ retval += (x[i+ 1 ] - x[i]) * (y[i] + y[i+ 1 ])
2831 end
29- return HALF * retval
32+ return HALF * retval
3033end
3134
32- function integrate {X<:Number, Y<:Number} (x:: AbstractVector{X} , y:: AbstractVector{Y} , :: TrapezoidalEven )
35+ function integrate (x:: AbstractVector , y:: AbstractVector , :: TrapezoidalEven )
3336 @assert length (x) == length (y) " x and y vectors must be of the same length!"
3437 return (x[2 ] - x[1 ]) * (HALF * (y[1 ] + y[end ]) + sum (y[2 : end - 1 ]))
3538end
3639
37- function integrate {X<:Number, Y<:Number} (x:: AbstractVector{X} , y:: AbstractVector{Y} , :: TrapezoidalFast )
38- retval = zero ( promote (x[ 1 ], y[ 1 ])[ 1 ] )
40+ function integrate (x:: AbstractVector , y:: AbstractVector , :: TrapezoidalFast )
41+ retval = _zero (x,y )
3942 @fastmath @simd for i in 1 : length (y)- 1
4043 @inbounds retval += (x[i+ 1 ] - x[i]) * (y[i] + y[i+ 1 ])
4144 end
4245 return HALF * retval
4346end
4447
45- function integrate {X<:Number, Y<:Number} (x:: AbstractVector{X} , y:: AbstractVector{Y} , :: TrapezoidalEvenFast )
46- retval = zero ( promote (x[ 1 ], y[ 1 ])[ 1 ] )
48+ function integrate (x:: AbstractVector , y:: AbstractVector , :: TrapezoidalEvenFast )
49+ retval = _zero (x,y )
4750 N = length (y) - 1
4851 @fastmath @simd for i in 2 : N
4952 @inbounds retval += y[i]
5053 end
5154 @inbounds return (x[2 ] - x[1 ]) * (retval + HALF* y[1 ] + HALF* y[end ])
5255end
5356
54- function integrate {X<:Number, Y<:Number} (x:: AbstractVector{X} , y:: AbstractVector{Y} , :: SimpsonEven )
57+ function integrate (x:: AbstractVector , y:: AbstractVector , :: SimpsonEven )
5558 @assert length (x) == length (y) " x and y vectors must be of the same length!"
5659 retval = (17 * y[1 ] + 59 * y[2 ] + 43 * y[3 ] + 49 * y[4 ] + 49 * y[end - 3 ] + 43 * y[end - 2 ] + 59 * y[end - 1 ] + 17 * y[end ]) / 48
5760 for i in 5 : length (y) - 1
@@ -60,7 +63,7 @@ function integrate{X<:Number, Y<:Number}(x::AbstractVector{X}, y::AbstractVector
6063 return (x[2 ] - x[1 ]) * retval
6164end
6265
63- function integrate {X<:Number, Y<:Number} (x:: AbstractVector{X} , y:: AbstractVector{Y} , :: SimpsonEvenFast )
66+ function integrate (x:: AbstractVector , y:: AbstractVector , :: SimpsonEvenFast )
6467 @inbounds retval = 17 * y[1 ] + 59 * y[2 ] + 43 * y[3 ] + 49 * y[4 ]
6568 @inbounds retval += 49 * y[end - 3 ] + 43 * y[end - 2 ] + 59 * y[end - 1 ] + 17 * y[end ]
6669 retval /= 48
@@ -70,6 +73,6 @@ function integrate{X<:Number, Y<:Number}(x::AbstractVector{X}, y::AbstractVector
7073 @inbounds return (x[2 ] - x[1 ]) * retval
7174end
7275
73- integrate {X<:Number, Y<:Number} (x:: AbstractVector{X} , y:: AbstractVector{Y} ) = integrate (x, y, TrapezoidalFast ())
76+ integrate (x:: AbstractVector , y:: AbstractVector ) = integrate (x, y, TrapezoidalFast ())
7477
7578end
0 commit comments