C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Interest in Linear Algebra functionality

From: Richard W Hornbuckle <longhornbuckle_at_[hidden]>
Date: Wed, 19 Apr 2023 15:53:47 -0500
Firstly, I appreciate the feedback.



Your first bullet is a good point. I'm somewhat inclined to agree; however,
often times (math) vectors and matrices can be small. There is non-trivial
memory savings in being able to convey size via type rather than via
containing a size attribute. I imagine that could significantly bloat the
memory footprint of a number of applications and thus be undesirable. I
don't think such use cases are all that uncommon.

- I could see separating the fixed size tensor into a separate proposal to
warrant further discussion.

- I could also see it as motivation for embracing the slightly more
cumbersome extents type rather than using a variadic size type parameter.
If the extents type

is entirely static, then it could be optimized out with
[[no_unique_address]]. I am inclined to explore this.



- Along the same vain, I think I could and should collapse the matrix and
vector classes into the tensor classes. I had thought I would have more
special accessors and mutators for one and two dimensional tensors, but
really only ended up with a few row / column functions for matrix and a
subvector overload for vector (which arguably isn't needed). As such,
vector and matrix could just be aliases for one and two dimensional tensors.



I'm trying to appreciate your other bullets and final point. Some of the
wording I got a little confused by. Are you in favor of ...

- A) a matrix container which has an allocator and a multidimensional index
operator (and does not necessarily conform to the existing named
requirements for an STL container)?

- B) a matrix container which has an allocator and conforms to existing STL
Container requirements?

- C) a matrix container adapter which adapts existing containers with a
multi-dimensional accessor (which is pretty much mdarray)?

In either case, do you truly mean matrix in the two dimensional context or
really referring to a tensor (which would be the more generic N dimensional
case)?



- If A) I think that starts to look a lot like the dr_tensor.

- I think that could involve defining a set of named requirements for
an STL MD Container and MD SequenceContainer analagous to the existing
Container and SequenceContainer. I'm a bit hesitant to dive into that. I
think the group behind mdspan, mdsubspan, and mdarray is considering what
an MD iterator could look like (or was at one point) and am interested in
the direction they would take. Furthermore, one would need to consider what
operations like insert and erase could look like.



- If B) it sound like you're suggesting somehow a container which acts
like a one dimensional container and thus can fit into an mdspan or
mdarray, but actually somehow knows it is a multidimensional container and
thus structure its memory appropriately for efficient resizing. That seems
awkward and difficult to make work.



- If C) I'm not sure I want to step on what the mdarray proposal is
trying to do, but am interested in how or if they would introduce resizing
into their proposal.



I'm also trying to understand what you mean by the best features of
std::valarry? If you're pointing out we should be optimize successive
operations on a matrix, I agree and want to tackle that via expression
types. I just didn't want to tackle that right out of gate so to speak. Add
/ subtract isn't hard, but multiplication and in general thinking through
how to make expression types expandable to additional operations (like
inverse) will take some work. My hope is with maybe a little work,
construction from expression types could fit into the construct from
lambda expression and thus wouldn't require modifying the existing
interface.



Just some points on the extendibility...

- One goal was to not need to create new matrix classes when adding new
matrix types like triangular, banded, symmetric, skew symmetric, etc. -
just add new layout types. I think some work still needed to make it
extendible in that way. Though I think something like block matrices would
be a bridge too far (and getting too far ahead of myself). Also, given the
current mdspan interface, I think one would need to have a custom accessor
and layout class for something like a triangular matrix (where the layout
would return an invalid index as a cue to the accessor when the client
wanted a value from the zero part of the triangular matrix).

- The intent was to scope the requirements on the structs defining
operations on tensor such that new types like a triangular matrix would
conform to stricter requirements and thus appropriate overloads could be
added without modifying the existing code.

On Wed, Apr 19, 2023 at 8:44 AM LoS via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> Finally I managed to read your code, so I can give you the full feedback.
> I have an overall idea of how your proposal can be changed, but I want to
> respond to your comments individually first.
> - it is true that several functions that one might expect to be in the
> interface of a math object only conditionally make sense if the underlying
> container supports dynamic memory allocation, but this can be applied to
> any object, such as an STL container. There are circumstances that lead a
> user to use a static std::list or std::vector, but this does not justify
> the creation of two identical containers that differ only in static or
> dynamic memory management. If this were done, the STL library would be much
> bloated, making the existence of the allocators partly useless: since the
> allocator is used to abstract the memory management (or rather, it is a
> handle to the memory), you can implement an allocator that is essentially a
> handle to a static array. In this way, although it is not very elegant, it
> is possible to create a custom fixed_vector or a fixed_list by passing,
> respectively, a static allocator to a std::vector or a std::list. It is up
> to the user to avoid calling member functions that can lead to memory
> resizing, such as reserve(), otherwise a std::bad_alloc is thrown, as if a
> simple dynamic allocation failed.
> - if you want to adopt a container adapter interface, as already present
> in all container adapters, you create two overloads for the constructors,
> one without an allocator and the other with an allocator (if the
> std::uses_allocator type trait is true).
> - although already-existing containers do not support efficient
> multidimensional resizing, it is still possible for the user to implement a
> custom container. It depends on what the user thinks.
> But your comment "existing containers don't support efficient
> multidimensional resizing" is precisely the key point: over the guarantee
> of a complete interface for performing linear algebra operations, does the
> matrix container offer advantages in terms of flexibility and performance?
> In my opinion, creating a matrix container, whose implementation takes the
> best features between std::valarray and mdarray would be the best. Without
> introducing new containers or container adapters, the matrix container
> could fill some of std::valarray's shortcomings by providing an interface
> that allows the user to perform easily simple and complex linear algebra
> operations on N-dimensional arrays.
> If that is okay, you can present a draft of the matrix container,
> especially highlighting the benefits of linear algebra operations and
> memory management.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2023-04-19 20:54:01