Eigen::DenseBase has no data member - eigen

Why does Eigen::DenseBase<Derived> has no data() method?
I thought a dense array would be contiguous in the memory.
Are blocks also DenseBase?
template <typename Derived>
void f(Eigen::DenseBase<Derived>& x) {
std::sort(x.data(), x.data() + x.size());
}
ArrayBase also has no data method.
Work around:
template <typename Derived>
void f(Eigen::DenseBase<Derived>& x) {
std::sort(&x[0], &x[0] + x.size()); // sort the whole vector
}

DenseBase is the base class for any dense expressions, including A+B, A*B, etc. If all you want is to call std::sort, then move to Eigen's head, and write:
std::sort(x.begin(), x.end());
If the expression you passed to f has a .data() member you can still reach it as follows: x.derived().data().

Related

How to remove the nth element from a tuple?

I'm trying to write a function that creates a new std::tuple from an existing one, with skipping the element on a given index. In example:
I have a tuple t defined as below:
constexpr auto t = std::tuple(1, 2, 3, 4);
And I want to copy it to another tuple. However, I want to skip the nth element. Let's say that in this case, the nth element I want to skip is 3 (this would mean that I want to skip the element with the index 2). This would result in a new tuple defined as:
std::tuple(1, 2, 4);
This is the closest I got until now:
template<std::size_t N, typename T, std::size_t ... is>
constexpr auto fun(T&& tp, std::index_sequence<is...>&& i) noexcept {
return std::tuple((is != N ? std::get<is>(tp) : 0) ...);
}
template<std::size_t N, std::size_t... elems>
constexpr auto fun2() noexcept {
constexpr auto t = std::tuple(elems...);
return fun<N>(std::forward_as_tuple(elems...), std::make_index_sequence<sizeof...(elems)>());
}
However, instead of removing the nth element, I set it to 0.
Ideally, I would change the return argument in the function fun() to create a new tuple using multiple temporary tuples:
return std::tuple_cat((is != N ? std::tuple(std::get<is>(tp)) : std::tuple()) ...);
However, the issue with this is that the ternary operator has to have matching types on both sides.
Another approach I tried was based on recursion:
template<std::size_t N, std::size_t head, std::size_t... tail>
constexpr auto fun3() noexcept {
if constexpr(!sizeof...(tail))
return std::tuple(head);
if constexpr(sizeof...(tail) - 1 == N)
return std::tuple_cat(fun3<N, tail...>());
if constexpr(sizeof...(tail) - 1 != N)
return std::tuple_cat(std::tuple(head), fun3<N, tail...>());
}
However, that was even more unsuccessful. In this case, if N is equal to 0, the nth element (which is the first element here as well) will still be used in the new tuple. Also, this won't even compile, because there's an issue with the second statement:
if constexpr(sizeof...(tail) - 1 == N)
What am I missing here? How can I copy a tuple and skip one of its elements during the copy?
I'm using C++17, and I need the function to be evaluated during compile-time.
What about
return std::tuple_cat( foo<is, N>::func(std::get<is>(tp)) ...);
where foo is a struct with specialization as follows?
template <std::size_t, std::size_t>
struct foo
{
template <typename T>
static auto func (T const & t)
{ return std::make_tuple(t); }
}
template <std::size_t N>
struct foo<N, N>
{
template <typename T>
static std::tuple<> func (T const &)
{ return {}; }
}
(caution: code not tested).
This is almost your ternary operator idea but without the problem of matching the types in both sides: only the right type is instantiated.
Another solution would be to create two index sequences that refer to the before and after parts of the tuple.
template<std::size_t nth, std::size_t... Head, std::size_t... Tail, typename... Types>
constexpr auto remove_nth_element_impl(std::index_sequence<Head...>, std::index_sequence<Tail...>, std::tuple<Types...> const& tup) {
return std::tuple{
std::get<Head>(tup)...,
// We +1 to refer one element after the one removed
std::get<Tail + nth + 1>(tup)...
};
}
template<std::size_t nth, typename... Types>
constexpr auto remove_nth_element(std::tuple<Types...> const& tup) {
return remove_nth_element_impl<nth>(
std::make_index_sequence<nth>(), // We -1 to drop one element
std::make_index_sequence<sizeof...(Types) - nth - 1>(),
tup
);
}
Here's a test for this function:
int main() {
constexpr auto tup = std::tuple{1, 1.2, 'c'};
constexpr auto tup2 = remove_nth_element<0>(tup);
constexpr auto tup3 = remove_nth_element<2>(tup);
static_assert(std::is_same_v<decltype(tup2), const std::tuple<double, char>>);
static_assert(std::is_same_v<decltype(tup3), const std::tuple<int, double>>);
return 0;
}
Live example
This solution has the advantages of not constructing intermediary tuples and not using std::tuple_cat, which both can be hard on compile times.
Just a few minutes after posting the question, I found a workaround. It's not ideal, but hey:
template<std::size_t N, typename T, std::size_t ... is>
constexpr auto fun(T&& tp, std::index_sequence<is...>&& i) noexcept {
return std::tuple((is < N ? std::get<is>(tp) : std::get<is+1>(tp)) ...);
}
template<std::size_t N, std::size_t... elems>
constexpr auto fun2() noexcept {
constexpr auto t = std::tuple(elems...);
return fun<N>(std::forward_as_tuple(elems...), std::make_index_sequence<sizeof... (elems) - 1>());
}
This way, we copy all of the elements prior to the nth element, and when we reach the nth element, we increase every next index for 1. We won't go out of range, since we pass the index_sequence that has 1 element less than the tuple that is passed.
I hope that this answer helps someone.

ScaleAndAddTo in Eige GMEV

In order to provide matrix by vector multiplication, Eigen implements scaleAndAddTo operation which can be specialized for the users matrix type.
According to https://eigen.tuxfamily.org/dox/group__MatrixfreeSolverExample.html
the user have to provide an specialization for scaleAndAddTo, which computes dst += alpha * lhs * rhs.
I have been following the call stack of until this is called and Eigen is doing the following:
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
{ dst.setZero(); scaleAndAddTo(dst, lhs, rhs, Scalar(1)); }
Since dst is set to zero, I can't understand why we need to provide a scaleAndAddTo instead of something like scale directly.
Why is the add part required?

Why does this partial specialization of a template friend function work?

I am writing simple classes that implement vectors and matrices as part of trying to learn OpenGL. I have matrix and vector classes that look like this :
// Forward declarations
template <typename T, size_t N/*len*/> struct vec;
template<typename T, size_t N /*rows*/, size_t M /*cols*/> struct mat;
// Forward declare *operator for matrix
// (NxM) matrix multiplied by (MxP) matrix yields (NxP) matrix
mat<T, N, P> operator* (const mat<T, N, M>& A, const mat<T, M, P>& B);
template <typename T, size_t N>
struct vec {
public:
vec() {}
virtual ~vec() {}
private:
T[N] m_data;
};
template <typename T, size_t N, size_t M>
struct mat {
public:
mat() {}
virtual ~mat() {}
// This is where it gets interesting. By my reading of the rules
// of C++11, this counts as a partial specialization of the
// operator template, and should not work.
// However, it compiles just fine!
template <size_t n, size_t m, size_t p>
friend mat<T, n, p> operator* (const mat<T, n, m>& A,
const mat<T, m, p> &B);
// Implementation appears later in the same header file.
private:
T[N*M] m_data;
};
I declare the * operator as a friend because I want it to have access to the internal m_data member, but I don't want the users of 'mat' and 'vec' to know the internals.
This compiles and runs just fine. I have a unit test for that matrix multiplication, and it works just fine. However, I don't know why it even compiles, let alone runs. By my reading of the rules of C++ templates, the declaration of the * operator counts as a partial specialization of function template, and is illegal.
What am I missing here?
Turns out this does *NOT* compile. I thought it was compiling because I wasn't invoking the template stream operator in my unit test when I thought I was.
Sorry for the stupid question!

storing map<string, struct> into vector to sort

I have the following code that I am trying. I am trying to sort it by ascending or descending size, and from z-a (three different sorts). I can't figure out how to even store it in the vector let alone sort it. Thanks for the help!
struct countSize {
int count;
uintmax_t size;
void sortMap(map<string, countSize> &extCount)
{
// Copy
vector<string, countSize> v(extCount.begin(), extCount.end());
// Sort the vector according to either file size or desc alphabetically
//print
}
int main()
{
map<string, countSize> mp;
mp["hello"] = { 1, 200 };
mp["Ace"] = { 5, 600 };
mp["hi"] = { 3, 300 };
mp["br"] = { 2, 100 };
sortMap(mp);
}
If you iterate over a map, you get a stream of std::pair<const X, Y>. That's a bit awkward for storing in a vector, because of the const. One solution is to just drop the const:
using my_map = std::map<std::string, countSize>;
// Mutable element type.
using my_map_element = std::pair<typename my_map::key_type,
typename my_map::mapped_type>;
using my_element_list = std::vector<my_map_element>;
Then it's very straight-forward to build a vector and sort it. Here, we use a template for the comparison function which makes it a lot easier to use a lambda for the comparator:
template<typename Functor>
my_element_list sortMap(const my_map& the_map, Functor compare) {
my_element_list v(the_map.begin(), the_map.end());
std::sort(v.begin(), v.end(), compare);
return v;
}
Unlike your code, this returns the sorted list. The caller can print the list if desired. See, for example, the example live on Coliru.
That's not really ideal, though. If the individual elements of the map are at all complicated, it may well be more efficient to make a vector of pointers to the elements, rather than copies of the elements. Amongst other things, this does not require readjusting the element type, and that makes it possible to be agnostic about the base container type as well. However, you need to remember that the comparison functor will now receive pointers to the elements to be compared. See the modified example.

c++ 11. Matrices multiplication

Hello. I write matrix class but i have some problem with matrices multiplication which have different dimensions.
template< typename T, size_t Row, size_t Col >
class Matrix
{
public:
.....................................
template< typename MulT >
auto operator * (const MulT& other) -> Matrix<T, Row, other.getColNum()>
{
if (other.getRowNum() != getColNum())
throw std::logic_error("Multiplication are not possible");
Matrix<T, Row, other.getColNum()> temp;
// Some operations.
return temp; // Must return matrix with this type Matrix<T, Row, other.getColNum()>
// but it dont work.
}
.....................................
}; // class Matrix
This code don't work. It is possible to resolve this problem?
other.getColNum() is probably not a constexpr function and can therefore not be used as a template non-type argument.
Read up on constexpr here: http://en.cppreference.com/w/cpp/language/constexpr
You don't want to check the if if (other.getRowNum() != getColNum()) at runtime, this should be done at compile time. One way to do this is to define the operator only for when the multiplication is valid. In this case:
template< typename T, size_t Row, size_t Col >
class Matrix
{
public:
.....................................
template<size_t _RHSWIDTH>
Matrix<_T, _RHSWIDTH, Row> operator * (const Matrix<T, _RHSWIDTH, Col> &rhs) const
{
Matrix<_T, _RHSWIDTH, Row> temp;
// Some operations.
return temp;
}
.....................................
}; // class Matrix
As a result, any attempt to multiply matrices which cannot be multiplied will fail at compile time. For a complete example, I wrote a complete matrix template a long time ago which uses very similar syntax: https://github.com/Enseed/GenericGeometry/blob/master/Matrix.h

Resources