-
-
Notifications
You must be signed in to change notification settings - Fork 188
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
fix apply_scalar_unary and abs so that abs(complex<T>) return T #2741
Conversation
Just ran it: https://jenkins.flatironinstitute.org/blue/organizations/jenkins/Stan%2FStanc3/detail/PR-1195/11/pipeline EDIT: It passed.
unary Stan functions defined in stanc3 that have abs(int) => int
int_step(int) => int
size(int) => int
logical_negation(int) => int
minus(int) => int
plus(int) => int The latter 3 are just how For completeness, these are the unary functions that return Phi(int) => real
Phi_approx(int) => real
acos(int) => real
acosh(int) => real
asin(int) => real
asinh(int) => real
atan(int) => real
atanh(int) => real
cbrt(int) => real
ceil(int) => real
cos(int) => real
cosh(int) => real
digamma(int) => real
erf(int) => real
erfc(int) => real
exp(int) => real
exp2(int) => real
expm1(int) => real
fabs(int) => real
floor(int) => real
inv(int) => real
inv_Phi(int) => real
inv_cloglog(int) => real
inv_erfc(int) => real
inv_logit(int) => real
inv_sqrt(int) => real
inv_square(int) => real
lambert_w0(int) => real
lambert_wm1(int) => real
lgamma(int) => real
log(int) => real
log10(int) => real
log1m(int) => real
log1m_exp(int) => real
log1m_inv_logit(int) => real
log1p(int) => real
log1p_exp(int) => real
log2(int) => real
log_inv_logit(int) => real
logit(int) => real
round(int) => real
sin(int) => real
sinh(int) => real
sqrt(int) => real
square(int) => real
tan(int) => real
tanh(int) => real
tgamma(int) => real
trigamma(int) => real
trunc(int) => real |
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.
Just one minor cleanup. If Bob approves that the return types are correct, this should be good to merge.
I can confirm we want |
This is why we want to write clear issues.
and then we want to have
wherever we have |
It seems like for many of them we implicitly cast to double for int values which is fine. One thing I worry about is the compiler getting confused between whats available to cast to when it has access to the math library and the standard library. So for instance for struct exp_fun {
/**
* Return the exponential of the specified scalar argument.
*
* @tparam T type of argument
* @param[in] x argument
* @return Exponential of argument.
*/
template <typename T>
static inline auto fun(const T& x) {
using std::exp;
return exp(x);
}
}; The template <typename T, require_arithmetic_t<T>* = nullptr>
inline auto exp(T x) {
return std::exp(x);
} // Now delete the 'using std::exp' in the struct's fun caller |
I can do that in this PR or I can do it in a seperate PR. It might be good to nip that sort of issue now |
… use implicit conversion for current functions that need int input and double output
Stanc always fully qualifies function names with |
My trouble with writing clear issues is that I'm not sure I would have noticed the problem (and what I think is the solution) before I dove into the code! I think the answer to |
Yes if I remember right the compiler confusion on implicit casts for std library functions is exactly why we did that |
It was actually for overloading, previously we had a list of certain functions we would prefix with |
Wouldn't we just get rid of |
Yes so the full change would be template <typename T, require_arithmetic_t<T>* = nullptr>
inline auto exp(T x) {
return std::exp(x);
}
struct exp_fun {
/**
* Return the exponential of the specified scalar argument.
*
* @tparam T type of argument
* @param[in] x argument
* @return Exponential of argument.
*/
template <typename T>
static inline auto fun(const T& x) {
return stan::math::exp(x);
}
}; I don't think we need to call |
There is a problem with some functions also being declared in the global namespace (I think if you include <math.h> if I remember correctly). So we definitely should keep it there. |
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 @SteveBronder!
Summary
Fix for #2737 so that
abs(complex<T>)
returns the typeT
and notcomplex<T>
.@WardBrian can you try this branch out with your stanc3 branch? This should have the stuff in it to allow the full vectorization.
@bob-carpenter this does also touch
apply_scalar_unary
, do we wantabs(int)
to returnint
ordouble
? Right now it returnsdouble
but I modifiedapply_scalar_unary
to return the same type as the output of the function we pass it (sosin(int)
would still return andouble
butabs(int)
can return anint
. Is that alright?Tests
A static assert is added to the
abs()
test to make sure that if we havecomplex<T>
as the input we get backT
as the output.Side Effects
The
apply_scalar_unary
change is one we should discuss to make sure it's still doing what we would like.Release notes
Fix #2737
Checklist
Math issue allows complex abs() to be vectorized #2737
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