-
Notifications
You must be signed in to change notification settings - Fork 2
Description
One of the biggest outstanding problems with libalgebra vectors at the moment is the lack of flexible constructors. This is especially evident in esig, where we have to work very hard to construct vectors from the Lie increments taken from a Numpy array. To remedy this problem we need to introduce some new constructors for the vector classes which allow us to construct the vector directly from either the raw pointers to the data from the Numpy arrays, or using some kind of iterator wrapper.
I propose we add two constructors to the vector interface (vectors/vector.h). The first will take a templated input iterator type containing key-value pairs to be added to the newly constructed vector. The second will take a pointer to the scalar type and a size argument, and construct a vector containing the raw data enumerated by the first size members of the basis. (This requires the basis to be ordered, which we'll have to check.) The templated constructor might look like this:
template <typename InputIt>
vector(InputIt first, InputIt last) : UndelyingVectorType(first, last) {}We have several options about how this actually works. The first is as shown above, where we delegate construction to the underlying vector type. Alternatively, we can construct a blank vector and use the insert method, which I believe already supports this templated iterator inputs. We could also use element access methods to insert each pair individually.
The pointer constructor is a bit more simple. We should definitely delegate to the underlying vector type because different vectors will need to handle this differently. Dense and hybrid vectors can insert directly into the storage std::vector. The sparse vector will have to do something a bit more basic.
vector(SCALAR const* begin, DIMN size) : UnderlyingVectorType(begin, size) {}The implementation for the sparse vector will be something like this
sparse_vector(SCALAR const* begin, DIMN size) : MAP() {
KEY key(basis.begin());
SCALAR const* value(begin);
for (DIMN i=0; i < size && key != basis.end(); ++i, key = basis.nextkey(key), ++value) {
if (*value != zero) (*this)[key] = *value;
}
}We have a choice as to whether we provide begin and size or begin and end. Both are roughly equivalent.