Shift slicing to the workspace
LTLA opened this issue · 2 comments
This makes it possible to compute slice information once and then re-use it across multiple row
or column
calls.
Slicing can also be performed with arbitrary indices rather than requiring a [start, end)
range.
Probably will need to ask Matrix
subclass implementers to provide some more methods. For dense rows:
virtual const T* row(size_t r, T* buffer, SimpleWorkspace* work) const;
virtual const T* row(size_t r, T* buffer, BlockWorkspace* work) const;
virtual const T* row(size_t r, T* buffer, SliceWorkspace* work) const;
And same for sparse rows or sparse/dense columns. This obviously requires the definition of the newBlockWorkspace
and SliceWorkspace
classes, which are not subclasses of SimpleWorkspace
(so as to avoid mixing them up). Similarly, we need new overloads to create them:
std::shared_ptr<SimpleWorkspace> new_workspace(bool row) const;
std::shared_ptr<BlockWorkspace> new_workspace(bool row, size_t first, size_t last) const;
std::shared_ptr<SliceWorkspace> new_workspace(bool row, const IDX* slice_begin, const IDX* slice_end) const;
Developers may assume that indices in [slice_begin, slice_end)
are ordered, unique and in range.
All existing non-workspace functions also have their own virtual overloads in Matrix
. These are optional and Matrix
will provide a base definition that creates a workspace and calls the relevant required method. Developers can override the base method if workspace construction is expensive and a more efficient (non-workspace) algorithm is available. The cost of an extra virtual look-up is considered to be acceptable
virtual const T* row(size_t r, T* buffer) const;
virtual const T* row(size_t r, T* buffer, size_t first, size_t last) const;
virtual const T* row(size_t r, T* buffer, const IDX* slice_begin, const IDX* slice_end) const;
Then we just have the remaining non-virtual overloads and methods; these are extended as necessary for the new workspace types and slicing paradigms.