## Draft: Generic matrix-vector product for DenseMatrix and transposed/hermitian matrix views

### Summary

This is an attempt to fill-in missing method (`A.mhv()`

) in the `DenseMatrix`

implementation and unify the code for matrix-vector products using just one generic method.

### Details

All matrix-vector like methods look very similar and share a lot of code, like bounds checking and the loops. Only minor differences occur, like the assignment to the resulting vector. Thus, a way of abstracting this is to implement just one generic method that gets an additional parameter for the assignment. This help to have `.mv()`

and `.umv()`

consistent.

Wrapping the matrix itself into a transposed and hermitian view allows the code to be implemented even more generic. Then all matrix-vector products can be encoded into a single function. All individual functions call this one with proper arguments. It is nearly as short as the general `usm[t|h]v()`

function but covers all cases.

In a similar fashion also matrix-matrix products can be implemented very generically.

### Example

```
FieldMatrix<double,3,4> A{...};
FieldVector<double,4> x{...};
FieldVector<double,3> y;
A.mtv(x,y); // y = A^T*x
// this is equivalent to
transposedView(A).mv(x,y);
A.mhv(x,y); // y = A^H*x
// this is equivalent to
hermitianView(A).mv(x,y);
auto At = transposedView(A);
assert(A[2][1] == At[1][2]); // interchanged indices
auto Ah = hermitianView(A);
assert(conjugateComplex(A[2][1]) == Ah[1][2]);
```

### Possible regression?

The approach shown here does not change anything in the generated code for `A.mv()`

or `A.umv()`

, see the assembly output in https://godbolt.org/z/hPzaE4vGM (can be tested by setting the variable `IMPLEMENTATION`

to either `1`

or `2`

)

### Relations

The MR is related to an issue about deficiencies in the general matrix interface as indicated in MR !953 and discussed in #253