- edited description
Introduce shape() function
Issue #201
wontfix
Sometimes it is necessary to check/compare the dimensions of a given matrix or a vector in a uniform fashion. For this purpose,
- We can define shape of a matrix as a pair of numbers (M, N) where M is the number of rows and N is the number of columns.
- For a vector, the shape can be defined as a pair of a number and a bool (N, TF), where N is the size of a vector and TF is the transpose flag.
- Alternatively, the shape of a vector can be defined as a pair of numbers, too, such that
for a column vector
cv
the the shape is(size(cv), 1)
, and for a row vectorrv
the shape is(1, size(rv))
. In this case shape of a vector can be compared to a shape of a matrix. I am not sure which of the two options is better.
Possible implementation:
namespace blaze {
template <typename M, bool SO>
inline auto shape(Matrix<M, SO>& m)
{
return std::pair<size_t, size_t>(rows(m), columns(m));
}
template <typename V, bool TF>
inline auto shape(Vector<V, rowVector>& v)
{
return std::pair<size_t, bool>(size(v), TF);
}
}
Then, the following generic code can be written (which is a simplified example of what I needed to implement):
template <
typename Value, // A type that can be either a vector of a matrix
typename ExpectedShape // A functor that returns the correct shape of a matrix or a vector for a given key
>
class PropertyMap
{
public:
PropertyMap(Value& val, ExpectedShape expected_shape)
: val_(val)
, expectedShape_(expected_shape)
{
}
template <typename V>
friend void put(PropertyMap const& pm, int key, V const& val)
{
if (shape(val) != pm.expectedShape_(key))
throw std::invalid_argument("Invalid argument shape");
pm.val_ = val;
}
private:
Value& val_;
ExpectedShapeFunc expectedShape_;
};
class Foo
{
public:
using Matrix = blaze::DynamicMatrix<double>;
using Vector = blaze::DynamicVector<double>;
// Define many like those:
auto propertyMap1()
{
return PropertyMap(m1, [] (int key) { return std::pair<size_t, size_t>(abs(key) + 42, 42); } );
}
auto propertyMap1()
{
return PropertyMap(m2, [] (int key) { return std::pair<size_t, size_t>(abs(key) + 43, 43); } );
}
auto propertyMap3()
{
return PropertyMap(v_, [] (int key) { return std::pair<size_t, bool>(abs(key + 11), true); } );
}
private:
Matrix m1_;
Matrix m2_;
Vector v_;
}
Comments (3)
-
reporter -
reporter - edited description
-
- changed status to wontfix
Hi Mikhail!
Thanks a lot for the proposal. We have given this idea some thought, but currently we feel that it would not fit well as a general feature. Since we plan to introduce n-dimensional data structures (see issue #53), we simply don't have a firm understanding of what the
shape()
function should return in general. Still, thanks for sharing the idea,Best regards,
Klaus!
- Log in to comment