-
-
Notifications
You must be signed in to change notification settings - Fork 190
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 functions #1814
Interpolation functions #1814
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for submitting!
Couple quick review comments. In general I think you need to take the stuff in prim and flesh it out to work for fvar and var types for any of the parameters since you only have a rev specialization for the 5th argument to conv_gaus_line
I also think the names for these should be fleshed out. conv_gaus_line
could be something like gauss_line_convolution
double der_conv_gaus_line(double t0, double t1, double a, double b, double x0, | ||
double sig2) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally we want prim functions to be templated generically to work with any type, then the specialization in rev
will be for analytic calculations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved this function to the rev version of this file
/* | ||
evaluate the derivative of conv_gaus_line with respect to x | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need full docs for external facing functions
using stan::math::normal_cdf; | ||
double pi = stan::math::pi(); | ||
using std::exp; | ||
using std::pow; | ||
using std::sqrt; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Put using
aliases together at the top of the function
using std::exp; | ||
using std::pow; | ||
using std::sqrt; | ||
double sig = sqrt(sig2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
double sig = sqrt(sig2); | |
const double sig = sqrt(sig2); |
double sig = sqrt(sig2); | ||
double y; | ||
|
||
double alpha = sqrt(2 * pi * sig2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
double alpha = sqrt(2 * pi * sig2); | |
const double alpha = sqrt(2 * pi * sig2); |
stan/math/prim/fun/gaus_interp.hpp
Outdated
if (x <= xs[0]) | ||
return ys[0]; | ||
if (x >= xs[n - 1]) | ||
return ys[n - 1]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (x <= xs[0]) | |
return ys[0]; | |
if (x >= xs[n - 1]) | |
return ys[n - 1]; | |
if (x <= xs[0]) { | |
return ys[0]; | |
} | |
if (x >= xs[n - 1]) { | |
return ys[n - 1]; | |
} |
stan/math/prim/fun/gaus_interp.hpp
Outdated
double lin_interp_pt(int n, vector<double> xs, vector<double> ys, | ||
vector<double> as, vector<double> bs, double x) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should all be const& parameters so copies are not made
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is true for everywhere you are using std::vector, arithmetic types can be passed by value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made these changes generally and also I created a new file for lin_interp. It seemed to make sense to separate the linear interpolation from this smooth interpolation.
stan/math/prim/fun/gaus_interp.hpp
Outdated
lin_interp_coefs(n, xs, ys, as, bs); | ||
|
||
// evaluate at new points | ||
vector<double> ys_new; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reserve the vector size ahead of the loop to avoid reallocation
vector<double> ys_new; | |
vector<double> ys_new; | |
ys_new.reserve(n_new); |
stan/math/prim/fun/gaus_interp.hpp
Outdated
template <typename Tx> | ||
double min_diff(int n, std::vector<Tx> xs) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is only used in this file as an internal function then it should be in the internal namespace
stan/math/prim/fun/gaus_interp.hpp
Outdated
*/ | ||
template <typename Tx> | ||
double min_diff(int n, std::vector<Tx> xs) { | ||
double dmin = value_of(xs[1]) - value_of(xs[0]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
idt this will work for fvar<var>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is no longer relevant, because now the xs (and ys) will only be inputted as data
@SteveBronder thanks for reviewing and for these comments. There is some discussion -- stan-dev/design-docs#18 -- about how and if this should be implemented so I will wait until there is some agreement before iterating further on this. |
Just changed the title to reflect this is WIP. |
@pgree are there any blockers for this? |
@SteveBronder sorry for the delay on this, I got distracted and had some Catalina-related problems. I will get to this asap |
Cool no worries just wanted to check in! |
…o feature/58-interp
…4.1 (tags/RELEASE_600/final)
…4.1 (tags/RELEASE_600/final)
…4.1 (tags/RELEASE_600/final)
Jenkins Console Log Machine informationProductName: Mac OS X ProductVersion: 10.11.6 BuildVersion: 15G22010CPU: G++: Clang: |
Bump. What is the status of this PR? Waiting on a re-review or something else? |
@rok-cesnovar I think all the requested changes were made so just waiting for a re-review. |
Didn't we also have a design doc for this. Not sure what the status is there? |
Yes, exactly. This PR reflects what was discussed there, including your suggestions @wds15 |
@bgoodri - per our discussion today, here's the PR |
Sorry, didn't realize this existed until today. It sounds like it is already been reviewed, in which case we should merge it once the conflict with fun.hpp is fixed. But what were the pros and cons of this interpolation scheme as compared to any of the ones in Boost that we could wrap? |
This interpolation schemes has a few of advantages
At the time we decided on this interpolation scheme, Boost didn't have anything with these features |
It'd be great to add an interpolation function to Stan. Andrew and others have been asking for something like the interpolation function in BUGS for ages. Is the approach unlike any of the Boost implementations? https://www.boost.org/doc/libs/1_77_0/libs/math/doc/html/interpolation.html |
Fair enough, although since we will probably include |
From above: This interpolation scheme has a few of advantages
Also, you end up with non-oscillatory behavior between reference points. At the time we decided on this interpolation scheme, Boost didn't have anything with these features The plots for the Akima spline look nice, but I'm not sure how they would do in the environments where people will use them. I don't know if one of the Boost interpolation schemes would work well enough for users' needs. Maybe they would.
That's pretty much what we did. I discussed this with (I think) @SteveBronder a while back and we ended up settling on
which are both in this PR |
Thanks.
I probably won't be reviewing this and we don't double review, but I strongly urge you not to use |
great, will change to |
I like the more descriptive name. I'm OK with |
Since all of the interpolation schemes we might implement in Stan in the future will presumably be smooth to some extent, I don't think |
If there aren't likely to be other normal or Gaussian interpolations, I'd prefer
If there might be other Gaussian interpolations that don't involve convolution, then I'd prefer
|
…o feature/58-interp
…4.1 (tags/RELEASE_600/final)
@pgree, sorry about the delay. I'm closing the PR for the moment. Please reopen if it's still active. When that happens, I'll clear out the old review and give it a fresh one and turn that around quickly. Right now, the tests fail, so we'll need to trigger the build again anyway. |
Summary
I added a function that does interpolation of a set of function values,
(x_i, y_i)
, specified by the user. The algorithm works by first doing a linear interpolation between points and then smoothing that linear interpolation by convolution with a Gaussian.In order to enforce that the interpolated function values coincide with the user-inputted function values, the algorithm at each step convolves a Gaussian with a new piecewise linear function in which the function values are shifted by the difference between the most recent interpolation and the desired, original value.
The interpolated function can be evaluated analytically aside from an evaluation of the error function. The derivative of the interpolated function can be evaluated analytically.
This is a work-in-progress. I have discussed some of the design choices with @bbbales2 but that's it.
Tests
There are tests for the "accuracy" of the interpolation and tests for the derivative of the interpolation that compare autodiff to finite differences.
Side Effects
The variance of the Gaussian in the convolution is currently 1/10 the minimum distance between the x-values specified by the user. This has the potentially to lead to undesired behavior.
There is a tolerance hardcoded for when to stop the iterative algorithm in terms of the maximum distance between the interpolated values at the original points and the user-specified values at those points.
Checklist
Math issue Interpolation function(s) #58
Copyright holder: Columbia University
the basic tests are passing
the code is written in idiomatic C++ and changes are documented in the doxygen
the new changes are tested