Re: [eigen] writing a function that takes Eigen::MatrixBase or Eigen::Block |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [eigen] writing a function that takes Eigen::MatrixBase or Eigen::Block
- From: Christoph Hertzberg <chtz@xxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Fri, 4 Oct 2019 13:19:20 +0200
- Dkim-signature: v=1; a=rsa-sha256; c=simple/simple; d=uni-bremen.de; s=2019; t=1570187960; i=@uni-bremen.de; bh=m1bD6pOD0i7p7zdSxjtUVju5V8BbA/sPqgeJJMKh7mA=; h=To:References:From:Date:In-Reply-To; b=RUJ/v6IiCbNS9y7xzId5gvBR8JrYM+9O6IIU3Xikbg9Pt8+k2kB1zlIi7UtTqD7ql hi//KSNt8zRj81+HEULOqML43x6ZIEj08vTQhQu/j11TBMWXwGoxMarUPgQM+bQUei DmGpreyYZN0qVVHl+EvOjkT/83Bp6VJ4UcrtRu6nUJ6mHiTETNwEeBBCfDqkBZWv7Z q9Zk8b6Lc4kOhTJujkCiXNMV9/kn676l4omEYxnvP3XqR2Z4nfSPJVx2wjGrO5+zFs 3iRZKrMB/h145f3M3HG04OJ2CE6hNcp/U9xafs9iLGtKvMbQsjeP8Rt94NjyFpTwBp adHYy3B0WnlcA==
Hi!
On 03/10/2019 06.45, Dale Lukas Peterson wrote:
Following the guidance here [0], I have:
template <typename Derived>
void test(const Eigen::MatrixBase<Derived>& a)
{
// Use case 1:
Derived aa;
// do stuff with aa
// Use case 2:
Derived bb = a;
// do stuff with bb
}
If I create an Eigen::Matrix and call test like so, it works fine:
Eigen::Matrix<double, 2, 4> A;
A << 1, 2, 3, 4,
5, 6, 7, 8;
// Works
test(A);
This works, because `Derived = Matrix<double, 2, 4>` in this case, which
is a valid standalone object.
However, the following doesn't work:
test(A.block<2, 1>(0, 1));
In this case `Derived` is something like `Block<Matrix<double,2,4>,2,1>`
which is not usable as a stand-alone object. It can only be constructed
from an existing Matrix object where it points to.
However, the following does work:
test(A.block<2, 1>(0, 1).eval());
The result of `.eval()` is again a `Matrix` object (should be
`Matrix<double,2,1>`).
Is .eval() the right approach here? Should I being doing something else at
the call site, or in my function definition to better handle this? Does the
return value of `.block<2, 1>(0, 1)` constitute a "plain matrix or vector
(not an expression)" [1] or not, so that I can be certain this isn't
creating a useless copy?
`.block<..>(..)` will always return a "free" view into an existing
object (or actually a block of another expression), `anything.eval()`
will always return a `Matrix<...>` (or `Array<...>` object) which will
be a copy, unless `anything` already was a plain Matrix or Array (in
that case it will return a const reference).
If you want to have a modifiable plain matrix object inside `void
test(...)` with the same size as `MatrixBase<Derived>`, you can write
typedef typename Derived::PlainObject Mat;
Mat aa;
Usage demo: https://godbolt.org/z/hgaEra
Cheers,
Christoph
Sincerely,
Luke
[0] https://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html
[1] https://eigen.tuxfamily.org/dox/classEigen_1_1DenseBase.html#title39
--
Dr.-Ing. Christoph Hertzberg
Besuchsadresse der Nebengeschäftsstelle:
DFKI GmbH
Robotics Innovation Center
Robert-Hooke-Straße 5
28359 Bremen, Germany
Postadresse der Hauptgeschäftsstelle Standort Bremen:
DFKI GmbH
Robotics Innovation Center
Robert-Hooke-Straße 1
28359 Bremen, Germany
Tel.: +49 421 178 45-4021
Zentrale: +49 421 178 45-0
E-Mail: christoph.hertzberg@xxxxxxx
Weitere Informationen: http://www.dfki.de/robotik
-------------------------------------------------------------
Deutsches Forschungszentrum für Künstliche Intelligenz GmbH
Trippstadter Strasse 122, D-67663 Kaiserslautern, Germany
Geschäftsführung:
Prof. Dr. Jana Koehler (Vorsitzende)
Dr. Walter Olthoff
Vorsitzender des Aufsichtsrats:
Prof. Dr. h.c. Hans A. Aukes
Amtsgericht Kaiserslautern, HRB 2313
-------------------------------------------------------------