Reputation: 775
Do you know if Eigen has its own arange
function, and if not, why?
For now, I have written my own arange function using Eigen::VectorXd::LinSpaced()
/*
* Return evenly spaced values within a given interval.
* Values are generated within the half-open interval [start, stop)
* (in other words, the interval including start but excluding stop).
*/
template <typename Scalar>
Eigen::VectorXd arange(const Scalar start, const Scalar stop, const Scalar step) {
if(step == 0)
throw std::domain_error("Arange's step cannot be 0");
Scalar delta = stop - start;
size_t size = ceil(delta / step);
return Eigen::VectorXd::LinSpaced(size, start, start+(size-1)*step);
}
Upvotes: 0
Views: 1121
Reputation: 1422
Easier implementation from previous answers: calculate N
and then use Eigen::LinSpaced
:
typedef Eigen::VectorXd vec;
vec arange(double low, double high, double step, bool with_last = false)
{
high -= (with_last) ? 0 : step;
int N = static_cast<int>(std::floor((high - low) / step) + 1);
return vec::LinSpaced(N, low, high);
}
You can then enhance with some validity check over the parameters passed
Upvotes: 0
Reputation: 543
A dummy implementation:
Eigen::VectorXd arange(double low, double high, double step, bool with_last=false)
{
int N = static_cast<int>(std::floor((high - low) / step) + 1);
Eigen::VectorXi V(N);
std::iota(V.data(), V.data() + N, 0);
Eigen::VectorXd ret = V.cast<double>();
ret.array() *= step;
ret.array() += low;
if (with_last && ret[N - 1] != high) {
ret.conservativeResize(N + 1);
ret[N] = high;
}
return ret;
}
test:
ASSERT_EQ(arange(0, 1, 0.25), (Eigen::VectorXd(4) << 0, 0.25, 0.5, 0.75, 1.0).finished());
ASSERT_EQ(arange(0, 1, 0.25 - 1e-3).size(), 5);
ASSERT_EQ(arange(0, 1, 0.25 - 1e-3, true).size(), 6);
ASSERT_EQ(arange(1, 0, -0.25), (Eigen::VectorXd(4) << 1, 0.75, 0.5, 0.25, 0.0).finished());
Upvotes: 0
Reputation: 50826
There is indeed LinSpaced
currently available for such an operation, but apparently no direct equivalent of arange
in Eigen. There are working notes related to this (eg. range and iota) but so far nothing appear to be included in the code for that. In the new Eigen 3.4 with a recent C++ version, you can use std::iota
since Eigen now support STL iterators. Thus, there is no real need for a feature like arange
to be added in Eigen (in fact LinSpaced
is often good enough for most users).
Upvotes: 1