Skip to content

Accuracy is a bit brittle #124

Closed
Closed
@giordano

Description

@giordano

The README of this package convinced me to use FiniteDifferences instead of Calculus in Measurements for cases where I need a numerical derivative (for functions without known derivative or automatic differentiation isn't possible, e.g. calling into C libraries). However I found that accuracy of FiniteDifferences is quite brittle (sometimes strongly depends on the number of points with big even/odd jumps, see example below) and I need to use a largish number of grid points to achieve the same accuracy I have with Calculus, which in comparison is also much faster (and makes me question the change of the backend). For example, the derivative of cosc in 0 is -(pi^2)/3, with Julia v1.5.3 I get:

julia> using Calculus, FiniteDifferences, BenchmarkTools

julia> -(pi ^ 2) / 3
-3.289868133696453

julia> (p -> FiniteDifferences.central_fdm(p, 1)(cosc, 0)).(2:10)
9-element Array{Float64,1}:
 -3.2575126788312536 # 2
  0.0                # 3
 -3.2894144933275746 # 4
 -3.9730287078618036 # 5 
 -3.289860720421136  # 6
 -3.2898376423854927 # 7
 -3.2898681297554884 # 8
 -3.289868469475128  # 9
 -3.2898681348743732 # 10

julia> Calculus.derivative(cosc, 0) 
-3.2898678494407765

To achieve an accuracy of the same order as Calculus I need 8 grid points, and this is the performance comparison:

julia> @btime FiniteDifferences.central_fdm(8, 1)($cosc, 0)
  2.340 μs (25 allocations: 992 bytes)
-3.2898681297554884

julia> @btime Calculus.derivative($cosc, 0)
  60.591 ns (0 allocations: 0 bytes)
-3.2898678494407765

Is this behaviour really expected?

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions