-
-
Notifications
You must be signed in to change notification settings - Fork 187
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
Adds support for var<matrix> in scalar_seq_view<> distributions #2214
Conversation
…e it can support var matrices
…4.1 (tags/RELEASE_600/final)
…4.1 (tags/RELEASE_600/final)
…4.1 (tags/RELEASE_600/final)
…' into feature/scalar-sequence-val-probs2
…4.1 (tags/RELEASE_600/final)
inline T&& as_column_vector_or_scalar(T&& a) { | ||
inline auto as_column_vector_or_scalar(T&& a) { | ||
return std::forward<T>(a); | ||
} |
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.
@t4c1 I changed this because of what we talked about in the past where passing in an rvalue and returning an rvalue can cause the destructor to go off. Should we just have specializations for doubles where it passes back the correct reference type?
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.
We don't need references for doubles. Although this will always return value (even when it should return a lvalue reference). What you wanted here is decltype(auto)
. What I would prefer here is T
- it will behave exactly the same.
} // namespace math | ||
} // namespace stan | ||
|
||
#endif |
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.
TODO: Need to write tests for all these new functions (I think we can delete some of them)
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.
Also update docs
…m/stan-dev/math into feature/scalar-sequence-val-probs
…4.1 (tags/RELEASE_600/final)
@SteveBronder got the basic normal lpdf/cdf/lcdf/lccdf tests working. I'm running all the tests now to find out if there are broken distributions. |
…4.1 (tags/RELEASE_600/final)
…4.1 (tags/RELEASE_600/final)
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 PR is getting quite large. Can you split it up? Maybe keep just one distribution in the first one and leave the reminder for another one.
* @param i index | ||
* @return the element at the specified position in the container | ||
*/ | ||
auto operator[](int i) const { return c_.coeffRef(i); } |
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.
auto operator[](int i) const { return c_.coeffRef(i); } | |
auto operator[](int i) const { return c_.coeff(i); } |
Same change for other functions returning a value.
template <typename T, require_eigen_t<T>* = nullptr, | ||
require_not_plain_type_t<T>* = nullptr> | ||
inline auto to_value_array_or_scalar(T&& v) { | ||
return value_of(v.eval()).array(); |
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.
Why eval? Also this should use a holder for rvalues (as should other non-scalar overloads of this and other new helper functions).
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.
Actually I think none of these overloads should use eval. If you need eval you should add a separate helper that also evals the result. Or if you dont need non-evaling ones you can skip them, but if some helper also evals it should have eval in its name.
@@ -159,7 +158,8 @@ return_type_t<T_size1, T_size2> beta_binomial_lpmf(const T_n& n, const T_N& N, | |||
+= digamma_n_plus_alpha[i] + digamma_diff[i] - digamma_alpha[i]; | |||
if (!is_constant_all<T_size2>::value) | |||
ops_partials.edge2_.partials_[i] | |||
+= digamma(value_of(N_vec[i] - n_vec[i] + beta_vec[i])) | |||
// is this a typo?? | |||
+= digamma(value_of(N_vec[i] - n_vec[i] + beta_vec[i])) // ?? |
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.
Obviously invoking value_of on each term separately makes more sense.
+ !is_constant_all<T_scale>::value | ||
+ !is_constant_all<T_y>::value | ||
>= 2>( | ||
inv_beta * std::move(exp_y_m_mu_over_beta) - inv_beta); |
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.
That move does not do anything.
= -std::move(y_minus_mu_over_beta) * std::move(scaled_diff) | ||
- std::move(inv_beta); |
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.
Nor do these.
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.
Yeah my b I think I was doing something silly here when testing this out
auto&& sigma_val_vec | ||
= to_ref(as_column_vector_or_scalar(value_of_rec(sigma_ref))); |
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 as_column_vector_or_scalar
is called woth a lvalue it does not need to construct a holder, so previous version is better.
auto&& x_val = to_ref_if<!is_constant<T_beta>::value>(value_of_rec(x_ref)); | ||
auto&& y_val_vec = as_column_vector_or_scalar(value_of_rec(y_ref)); | ||
auto&& alpha_val_vec = as_column_vector_or_scalar(value_of_rec(alpha_ref)); | ||
auto&& beta_val_vec = to_ref_if<!is_constant<T_x>::value>( | ||
as_column_vector_or_scalar(value_of_rec(beta_ref))); |
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.
Do you need these to be non-const for some reason?
const T_partials_return alpha_dbl = value_of(alpha_vec[n]); | ||
const T_partials_return log_dbl = log(y_min_vec.val(n) / y_vec.val(n)); | ||
const T_partials_return y_min_inv_dbl = 1.0 / y_vec.val(n); | ||
const T_partials_return alpha_dbl = y_vec.val(n); |
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.
const T_partials_return alpha_dbl = y_vec.val(n); | |
const T_partials_return alpha_dbl = alpha_vec.val(n); |
I haven't looked through this yet. Let me know if I'm holding anything up by not doing that. |
No idt so, I just have a lot of other stuff on my plate and haven't had time to come back to this |
@t4c1 I think your right this should be broken up. But the one issue here is that I'd really like to not mess with the distributions test code too much as there's not meta level tests to test it and it's pretty dense/old. I think what would be good here is to break this up into three PRs.
Doing all the distributions at once is brutal but without it we have to tweak the distribution tests to only run for |
I like this. Happy to do the big boring review ("A PR that then uses all that stuff in the distributions.") I'm working on the ldlt/multivariate stuff now.
Yeah, good point, we're writing new test files and we write them for all or none (this file) |
There's only one big PR left for this right? It should just be the testing framework stuff? |
Summary
Adds a
.val(i)
method toscalar_seq_view<T>
and a specialization ofscalar_seq_view<>
forvar<matrix>
types. WhenT
has a autodiff value type.val(i)
get's back the value from the autodiff type. Else ifT
is an arithmetic type it just returns that valueTests
I actually don't know how to test this yet, is there a way to conditionally test this for some of the distributions in the distributions tests? Otherwise I have a separate branch for distributions are vectorized and I need to sort out the last bits of
vector_seq_view
. Should we wait to turn onvar<matrix>
tests until all of those are tested?Side Effects
idt so
Release notes
Adds methods to helpers in probability distributions to support
var<matrix>
Checklist
Math issue How to add static matrix? #1805
Copyright holder: Steve Bronder
The copyright holder is typically you or your assignee, such as a university or company. By submitting this pull request, the copyright holder is agreeing to the license the submitted work under the following licenses:
- Code: BSD 3-clause (https://opensource.org/licenses/BSD-3-Clause)
- Documentation: CC-BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
the basic tests are passing
./runTests.py test/unit
)make test-headers
)make test-math-dependencies
)make doxygen
)make cpplint
)the code is written in idiomatic C++ and changes are documented in the doxygen
the new changes are tested