NumericalIntegration.jl icon indicating copy to clipboard operation
NumericalIntegration.jl copied to clipboard

InexactError caused by milliseconds in DateTime

Open wjholden opened this issue 4 years ago • 0 comments

I am trying to compute the numerical integral from a time series. This fails due to a type conversion error that I do not really understand.

julia> using Dates, NumericalIntegration

julia> t = now() .- Millisecond.(90:-10:0)
10-element Vector{DateTime}:
 2021-05-29T16:28:27.071
 2021-05-29T16:28:27.081
 2021-05-29T16:28:27.091
 2021-05-29T16:28:27.101
 2021-05-29T16:28:27.111
 2021-05-29T16:28:27.121
 2021-05-29T16:28:27.131
 2021-05-29T16:28:27.141
 2021-05-29T16:28:27.151
 2021-05-29T16:28:27.161

julia> y = rand(10)
10-element Vector{Float64}:
 0.9599798922023242
 0.6541501943939838
 0.37632284117351933
 0.7371585093938842
 0.3863796441086791
 0.033734632856622815
 0.7643338520694836
 0.15143170117912086
 0.9771867088054458
 0.1608486283477646

julia> integrate(t, y)
ERROR: InexactError: Int64(16.14130086596308)
Stacktrace:
 [1] Int64
   @ ./float.jl:723 [inlined]
 [2] convert
   @ ./number.jl:7 [inlined]
 [3] Millisecond
   @ /buildworker/worker/package_linuxarmv7l/build/usr/share/julia/stdlib/v1.6/Dates/src/type                                                                                                 s.jl:34 [inlined]
 [4] *
   @ /buildworker/worker/package_linuxarmv7l/build/usr/share/julia/stdlib/v1.6/Dates/src/peri                                                                                                 ods.jl:94 [inlined]
 [5] integrate(x::Vector{DateTime}, y::Vector{Float64}, #unused#::TrapezoidalFast)
   @ NumericalIntegration ~/.julia/packages/NumericalIntegration/p29gp/src/NumericalIntegrati                                                                                                 on.jl:83
 [6] integrate
   @ ~/.julia/packages/NumericalIntegration/p29gp/src/NumericalIntegration.jl:58 [inlined]
 [7] #integrate#13
   @ ~/.julia/packages/NumericalIntegration/p29gp/src/NumericalIntegration.jl:333 [inlined]
 [8] integrate(x::Vector{DateTime}, y::Vector{Float64})
   @ NumericalIntegration ~/.julia/packages/NumericalIntegration/p29gp/src/NumericalIntegrati                                                                                                 on.jl:333
 [9] top-level scope
   @ REPL[5]:1

I don't think this is really a bug in NumericalIntegration.jl, since you can easily produce the same fault directly without the package.

julia> [t[i] - t[i-1] for i in 2:length(t)] .* [(y[i] + y[i-1])/2 for i in 2:length(y)]
ERROR: InexactError: Int64(8.07065043298154)
Stacktrace:
  [1] Int64
    @ ./float.jl:723 [inlined]
  [2] convert
    @ ./number.jl:7 [inlined]
  [3] Millisecond
    @ /buildworker/worker/package_linuxarmv7l/build/usr/share/julia/stdlib/v1.6/Dates/src/types.jl:34 [inlined]
  [4] *
    @ /buildworker/worker/package_linuxarmv7l/build/usr/share/julia/stdlib/v1.6/Dates/src/periods.jl:94 [inlined]
  [5] _broadcast_getindex_evalf
    @ ./broadcast.jl:648 [inlined]
  [6] _broadcast_getindex
    @ ./broadcast.jl:621 [inlined]
  [7] getindex
    @ ./broadcast.jl:575 [inlined]
  [8] macro expansion
    @ ./broadcast.jl:984 [inlined]
  [9] macro expansion
    @ ./simdloop.jl:77 [inlined]
 [10] copyto!
    @ ./broadcast.jl:983 [inlined]
 [11] copyto!
    @ ./broadcast.jl:936 [inlined]
 [12] copy
    @ ./broadcast.jl:908 [inlined]
 [13] materialize(bc::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(*), Tuple{Vector{Millisecond}, Vector{Float64}}})
    @ Base.Broadcast ./broadcast.jl:883
 [14] top-level scope
    @ REPL[6]:1

As a workaround, you can use Dates.value to coerce a usable differential.

julia> Dates.value.([t[i] - t[i-1] for i in 2:length(t)]) .* [(y[i] + y[i-1])/2 for i in 2:length(y)]
9-element Vector{Float64}:
 8.07065043298154
 5.152365177837516
 5.567406752837018
 5.6176907675128165
 2.1005713848265097
 3.9903424246305317
 4.578827766243022
 5.643092049922833
 5.690176685766052

julia> sum(Dates.value.([t[i] - t[i-1] for i in 2:length(t)]) .* [(y[i] + y[i-1])/2 for i in 2:length(y)])
46.41112344255784

julia> integrate(Dates.value.(t), y)
46.41112344255784

wjholden avatar May 29 '21 14:05 wjholden