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

New constructors for vectors #20

Open
inakleinbottle opened this issue Jul 12, 2021 · 0 comments
Open

New constructors for vectors #20

inakleinbottle opened this issue Jul 12, 2021 · 0 comments

Comments

@inakleinbottle
Copy link
Collaborator

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.

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

No branches or pull requests

1 participant