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

Add row vector, array and int_array construction utilities #1636

Merged

Conversation

mcol
Copy link
Contributor

@mcol mcol commented Jan 21, 2020

Summary

This adds the code to implement the following function signatures:

  • row_vector one_hot_row_vector(int K, int k)
  • row_vector ones_row_vector(int K)
  • row_vector spaced_row_vector(int K, real low, real high)
  • row_vector zeros_row_vector(int K)
  • real[] one_hot_array(int K, int k)
  • real[] ones_array(int K)
  • real[] spaced_array(int K, real low, real high)
  • real[] zeros_array(int K)
  • int[] one_hot_int_array(int K, int k)
  • int[] ones_int_array(int K)
  • int[] zeros_int_array(int K)

Fixes #692.

Tests

Added unit tests for each function.

Side Effects

None.

Checklist

  • Math issue Container construction utilities #692

  • Copyright holder: Marco Colombo

    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

    • unit tests pass (to run, use: ./runTests.py test/unit)
    • header checks pass, (make test-headers)
    • docs build, (make doxygen)
    • code passes the built in C++ standards checks (make cpplint)
  • the code is written in idiomatic C++ and changes are documented in the doxygen

  • the new changes are tested

@bob-carpenter
Copy link
Contributor

bob-carpenter commented Jan 21, 2020

Before reviewing, I have some comments on scope.

All of the constant_XXX functions are duplicates of existing rep_XXX functions. For instance, constant_int_array and const(_real)_array are currently overloaded as rep_array(double, int) and rep_array(int, int). const_vector and const_row_vector are rep_vector and rep_row_vector.

The naming rep_ is similar to that used in R.

The matrix versions are missing from this list. We currently have rep_matrix and 2D and 3D arrays as overloads of rep_array. There are also a bunch of other fixed matrix and vector constructs that'd be useful like unit matrix and uniform-simplex (or symmetric simplex), though they don't need to all be added as part of this PR.

set_XXX functions should not have set_ as a prefix as nothing is getting set.

constant_XXX functions should not have constant_ as a prefix because the result isn't constant in any sense. I mean constant_XXX(...) is not an lvalue, but as soon as you assign it, which you have to do to use it, it's not constant any more. This is why Eigen just uses Zero and One. Note that they do not use Zeros and Ones, but I'm OK with its usage in the functions here, though I'm also OK with one_array and zero_array.

@mcol
Copy link
Contributor Author

mcol commented Jan 21, 2020

I don't have any particular attachment to these functions or names, so I'm happy to remove those that duplicate existing functionality. I followed the indications in #692, and when reviewing #1620 none of this came up. So whatever you settle on here will potentially affect the other functions (I'm totally fine with it).

@bob-carpenter
Copy link
Contributor

bob-carpenter commented Jan 21, 2020 via email

@mcol
Copy link
Contributor Author

mcol commented Jan 21, 2020

No problem at all, it's better to get these right while they are not exposed yet.

@bob-carpenter
Copy link
Contributor

bob-carpenter commented Jan 21, 2020 via email

Copy link
Contributor

@bob-carpenter bob-carpenter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some necessary changes and some optional ones. I laid out a few test patterns that should be applied throughout (specifically to include the size 0 tests in the general loop).

It'd be fantastic if you could write an expect-std-vector-eq function like the matrix ones. We really need that badly either in this PR or in another one.

stan/math/prim/fun/one_hot_row_vector.hpp Show resolved Hide resolved
* @throw std::domain_error if K is not positive, or if k is less than 1 or
* greater than K.
*/
inline std::vector<int> one_hot_int_array(int K, int k) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[optional]
Probably not worth refactoring, but a single implementation would work here. I realize there'd need to be two fronting functions to work easily with the Stan language, but the core implementation is shared. They'd probably need an enable-if to ensure the type is arithmetic.

That's true of most of these functions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll pass on this for now.

*/
inline std::vector<double> ones_array(int K) {
check_nonnegative("ones_array", "size", K);
return std::vector<double>(K, 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can just be return {K, 1}; You can always return curly braces around constructor args for the return type.

And same for next definition.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't work:

./stan/math/prim/fun/ones_array.hpp:19:11: error: non-constant-expression cannot be
      narrowed from type 'int' to 'double' in initializer list [-Wc++11-narrowing]
  return {K, 1};
          ^
./stan/math/prim/fun/ones_array.hpp:19:11: note: insert an explicit cast to silence
      this issue
  return {K, 1};
          ^
          static_cast<double>( )

If I use the static cast around K, it builds a vector of two elements.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for trying. I've never seen that error and it's suprrising in that I thought you could always replace return-type constructor calls with braces. It clearly requires a stricter match.

Copy link
Contributor

@bob-carpenter bob-carpenter Jan 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does look like declaring const int K might also work, but I'd rather not sprinkle consts around.

stan/math/prim/fun/spaced_array.hpp Show resolved Hide resolved
*/
inline std::vector<double> zeros_array(int K) {
check_nonnegative("zeros_array", "size", K);
return std::vector<double>(K, 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should use braces constructor return.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as in the ones case.

test/unit/math/prim/fun/zeros_row_vector_test.cpp Outdated Show resolved Hide resolved
test/unit/math/prim/fun/zeros_int_array_test.cpp Outdated Show resolved Hide resolved
test/unit/math/prim/fun/zeros_array_test.cpp Outdated Show resolved Hide resolved
test/unit/math/prim/fun/spaced_array_test.cpp Outdated Show resolved Hide resolved
@mcol
Copy link
Contributor Author

mcol commented Jan 29, 2020

I've addressed your request, apart from those that I couldn't get to compile. To be honest those don't seem a big deal, as my code was not much longer anyway. The suggestion to merge the array/int array implementations is good, but there are a number of moving pieces that I'm not familiar with just yet, so I may revisit it in the future.

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.

Container construction utilities
2 participants