xtensor-stack / xtensor-r

R bindings for xtensor
BSD 3-Clause "New" or "Revised" License
87 stars 15 forks source link

Behavior of computations with length 0 input #97

Closed DavisVaughan closed 5 years ago

DavisVaughan commented 5 years ago

I'm wondering about the behavior of xtensor functions like sum() when the input is of length 0. What should the result be? Currently, it crashes.

// [[Rcpp::depends(xtensorrr)]]
// [[Rcpp::plugins(cpp14)]]

#include <xtensor-r/rarray.hpp>
#include <xtensor/xio.hpp>
#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
SEXP print_zero_length(SEXP x) {
  xt::rarray<int> x_rarray = xt::rarray<int>(x);

  std::cout << x_rarray << std::endl;

  return SEXP(IntegerVector::create(1));
}

// [[Rcpp::export]]
SEXP sum_zero_length(SEXP x) {
  xt::rarray<int> x_rarray = xt::rarray<int>(x);
  xt::rarray<int> res = xt::sum(x_rarray);
  return res;
}
Rcpp::sourceCpp("~/Desktop/test.cpp")

sum_zero_length(c(1L, 2L))
#> [1] 3

sum_zero_length(as.array(1L))
#> [1] 1

# 0 length int / int array
x <- integer()
x_array <- as.array(x)

x
#> integer(0)
length(x)
#> [1] 0
class(x)
#> [1] "integer"
attributes(x)
#> NULL

x_array
#> integer(0)
length(x_array)
#> [1] 0
class(x_array)
#> [1] "array"
attributes(x_array)
#> $dim
#> [1] 0

# crashes
# sum_zero_length(x)
# sum_zero_length(x_array)

# print these out
trash <- print_zero_length(x)
# {}

trash <- print_zero_length(x_array)
# {}

trash <- print_zero_length(1L)
# 1

trash <- print_zero_length(as.array(1L))
# {1}

R has standard results for these situations:

sum(integer())
#> [1] 0

sum(integer(), 1, 2)
#> [1] 3

prod(integer())
#> [1] 1

Is crashing the right behavior? Can you reproduce this with pure xtensor? I would imagine so.

DavisVaughan commented 5 years ago

numpy sum() and prod() both do the same as R (see the Notes section of both): https://docs.scipy.org/doc/numpy/reference/generated/numpy.sum.html https://docs.scipy.org/doc/numpy/reference/generated/numpy.prod.html

DavisVaughan commented 5 years ago

This seems to be fixed in xtensor 0.20.7, but I'm not quite sure which of the 0-length array issues fixed it