Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interpolation API: switch interpolations to BSplineKit #85

Merged
merged 8 commits into from
Feb 6, 2022

Conversation

alecloudenback
Copy link
Member

@alecloudenback alecloudenback commented Feb 6, 2022

Closes #76, Ref #75

To-dos

  • Migrate from Interpolations.jl to BSplineKit
  • Add cubic spline interpolation
  • Expose bootstrapping choice to user
  • Update documentation
  • bump package version for breaking changes (API + default of cubic spline)

API Changes

For relevant boostrapped class of curves, there is a new kwarg interpolation which has two options currently: CubicSpline() and LinearSpline(). This should facilitate more advanced choices in the future such as #70. Example of change:

curve = Yields.CMT(cmt, mats) # now uses cubic spline by default, no change to signature
curve = Yields.CMT(cmt, mats; interpolation=LinearSpline()) # linear interp
curve = Yields.CMT(cmt, mats; interpolation=CubicSpline())  # cubic spline interp

Speed

This PR is almost as fast when discount, but about twice as slow to actually bootstrap.

The discount is probably used much more frequently so the comporable speed is good.

The bootstrapping shoud be able to be sped up using interpolate! from BSplineKit, and in general the implementation is a bit ad-hoc to add extrapolations to BSplineKit. The author of BSK thinks that it could be made more efficient.

Benchmark script:

using BenchmarkTools
cmt = [5.25, 5.5, 5.75, 6.0, 6.25, 6.5, 6.75, 6.8, 7.0, 7.1, 7.15, 7.2, 7.3, 7.35, 7.4, 7.5, 7.6, 7.6, 7.7, 7.8] ./ 100
mats = collect(0.5:0.5:10.0)
curve = Yields.CMT(cmt, mats)
@benchmark Yields.CMT(cmt, mats)

@benchmark discount(curve, 10)

master:

julia> @benchmark Yields.CMT(cmt, mats)
BenchmarkTools.Trial: 5985 samples with 1 evaluation.
 Range (min … max):  697.583 μs …   3.701 ms  ┊ GC (min … max):  0.00% … 76.07%
 Time  (median):     723.958 μs               ┊ GC (median):     0.00%
 Time  (mean ± σ):   833.731 μs ± 465.795 μs  ┊ GC (mean ± σ):  12.20% ± 15.63%

  █▆▃▂▁                                                    ▁▁▁  ▁
  █████▆▄▃▃▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▆███▇ █
  698 μs        Histogram: log(frequency) by time       2.94 ms <

 Memory estimate: 2.10 MiB, allocs estimate: 23748.

julia> @benchmark discount(curve, 10)
BenchmarkTools.Trial: 10000 samples with 996 evaluations.
 Range (min … max):  25.142 ns …  1.038 μs  ┊ GC (min … max): 0.00% … 96.22%
 Time  (median):     25.393 ns              ┊ GC (median):    0.00%
 Time  (mean ± σ):   26.168 ns ± 17.602 ns  ┊ GC (mean ± σ):  1.14% ±  1.67%

  █▆▃▆▅▂▁▁▂▁                                                  ▂
  ███████████▇██▇▇▇▅▆▆▅▄▅▅▄▄▃▁▄▅▃▁▁▁▄▄▁▃▁▃▃▃▄▁▃▄▁▄▄▃▄▁▄▄▄▃▁▅▅ █
  25.1 ns      Histogram: log(frequency) by time      38.9 ns <

 Memory estimate: 16 bytes, allocs estimate: 1.

This PR (linear interpolation):

BenchmarkTools.Trial: 3029 samples with 1 evaluation.
 Range (min … max):  1.514 ms …   4.089 ms  ┊ GC (min … max): 0.00% … 55.51%
 Time  (median):     1.558 ms               ┊ GC (median):    0.00%
 Time  (mean ± σ):   1.649 ms ± 385.351 μs  ┊ GC (mean ± σ):  5.13% ± 11.17%

  ▇█▆▃                                                    ▁▁  ▁
  █████▇▅▅▅▅▄▁▁▁▃▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▅▅████ █
  1.51 ms      Histogram: log(frequency) by time      3.37 ms <

 Memory estimate: 2.14 MiB, allocs estimate: 21831.

julia> @benchmark discount(curve, 10)
BenchmarkTools.Trial: 10000 samples with 994 evaluations.
 Range (min … max):  31.187 ns …  1.080 μs  ┊ GC (min … max): 0.00% … 95.39%
 Time  (median):     32.067 ns              ┊ GC (median):    0.00%
 Time  (mean ± σ):   32.865 ns ± 17.929 ns  ┊ GC (mean ± σ):  0.93% ±  1.65%

  ▄▆▁██▂▄▆▄▅▄▂▂▁▁▁▁▂▁                                         ▂
  ███████████████████▇▇█▇▅▇▆▅▆▄▄▅▄▄▃▃▁▄▃▄▄▃▃▃▁▃▄▁▃▄▃▃▄▄▅▅▅▅▅▆ █
  31.2 ns      Histogram: log(frequency) by time      43.6 ns <

 Memory estimate: 16 bytes, allocs estimate: 1.

And this PR, with cubic spline interpolation (not possible with non-evenly spaced points on Interpolations.jl):

julia> @benchmark Yields.CMT(cmt, mats)
BenchmarkTools.Trial: 2998 samples with 1 evaluation.
 Range (min … max):  1.506 ms …   6.555 ms  ┊ GC (min … max): 0.00% …  0.00%
 Time  (median):     1.561 ms               ┊ GC (median):    0.00%
 Time  (mean ± σ):   1.666 ms ± 417.329 μs  ┊ GC (mean ± σ):  5.26% ± 11.28%

  ▇█▆▅▃▁                                                ▁     ▁
  ████████▇▇▅▅▃▃▃▃▁▃▁▃▁▁▁▁▁▁▁▃▁▁▁▃▁▁▁▁▁▃▁▁▁▁▁▁▁▁▁▁▁▁▁▁▇███▇▇▇ █
  1.51 ms      Histogram: log(frequency) by time      3.48 ms <

 Memory estimate: 2.14 MiB, allocs estimate: 21831.

julia> @benchmark discount(curve, 10)
BenchmarkTools.Trial: 10000 samples with 994 evaluations.
 Range (min … max):  31.313 ns …  1.162 μs  ┊ GC (min … max): 0.00% … 95.63%
 Time  (median):     32.655 ns              ┊ GC (median):    0.00%
 Time  (mean ± σ):   33.689 ns ± 19.736 ns  ┊ GC (mean ± σ):  0.96% ±  1.66%

  ▃▄ █▄▆▆▄▄▄▅▃▂▁▂▂▁                                           ▂
  ███████████████████▇█▇▆▇▆▇▆▆▆▆▆▆▅▆▇▆▅▅▅▅▄▅▆▅▅▄▅▅▅▅▅▄▅▅▄▄▅▃▅ █
  31.3 ns      Histogram: log(frequency) by time      45.6 ns <

 Memory estimate: 16 bytes, allocs estimate: 1.

@codecov
Copy link

codecov bot commented Feb 6, 2022

Codecov Report

Merging #85 (e368150) into master (ddcb778) will increase coverage by 0.38%.
The diff coverage is 96.49%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #85      +/-   ##
==========================================
+ Coverage   96.80%   97.19%   +0.38%     
==========================================
  Files           8        7       -1     
  Lines         282      321      +39     
==========================================
+ Hits          273      312      +39     
  Misses          9        9              
Impacted Files Coverage Δ
src/bootstrap.jl 93.10% <90.90%> (ø)
src/utils.jl 100.00% <100.00%> (ø)
src/Yields.jl

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ddcb778...e368150. Read the comment docs.

@alecloudenback alecloudenback marked this pull request as ready for review February 6, 2022 05:47
@alecloudenback
Copy link
Member Author

Tests pass locally, needs in-progress compat release of ActuaryUtilities.jl

@alecloudenback alecloudenback merged commit 3a95c9d into master Feb 6, 2022
@alecloudenback alecloudenback deleted the boostrap_choice branch February 6, 2022 18:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

bootstrapping interpolation algorithm
1 participant