Eigen matrix data transfer between C++ and LabView
When interfacing C++ and LabView, I need to process and manipulate the data array created in LabView with Eigen. There is no need to copy the whole array and wrapping the existing array into an Eigen object is enough and efficient. Eigen::Map
should be used for this purpose.
On the other hand, before integrating C++ with LabView, I need to test algorithms implemented in C++ and Eigen’s matrix type will be used instead of raw data array from LabView. Therefore, the C++ function should accept both scenarios. Hence, Eigen::Ref
is used.
Convert a data pointer to an array to Eigen::Map
#include <Eigen/Core>
#include <Eigen/Dense>
using namespace Eigen;
// @p mat is a pointer to an array created in LabView, which is wrapped in an
// @p Eigen::Map object @p mat_out.
void
read_matrix_labview(const char *filename,
double *mat,
const unsigned int n_rows,
const unsigned int n_cols,
const char *comment_symbol)
{
Map<MatrixXd, Unaligned> mat_out(mat, n_rows, n_cols);
TSC::read_matrix(std::string(filename),
mat_out,
n_rows,
n_cols,
std::string(comment_symbol));
}
In the following function declaration, Ref<VectorXd>
can either accept a mutable VectorXd
object or a Map<VectorXd>
object. If the argument is read-only, we should use const Ref<const VectorXd>&
.
void
tsc_electronic_trap(Ref<VectorXd> trap_energies,
Ref<VectorXd> trap_densities,
const Ref<const VectorXd> &temperatures,
const Ref<const VectorXd> ¤ts,
const double temperature_ramp_rate,
const double electrode_diameter,
const double sample_thickness,
const double attemp_to_jump_frequency,
const double carrier_penetration_depth,
const double valence_band_depth,
const unsigned int energy_level_num,
const bool is_near_measurement_electrode);
The reason for the difference between mutable and const is described as follows.
- The basic situation: usually we don’t already have a
Ref<VectorXd>
object to be passed to the function, but only pass aVectorXd
orMap<VectorXd>
to the above function. Then a temporaryRef<VectorXd>
object will be created. Because it is an rvalue, it is const. - If the function argument type is
Ref<VectorXd>&
, it requires a mutable reference to the const temporary object, which is invalid. Hence, onlyRef<VectorXd>
is allowed. - If the function argument type is
const Ref<const VectorXd>
orconst Ref<const VectorXd>&
, both are grammatically correct. The former is pass-by-value with respect to the objectRef<const VectorXd>
, while the latter is pass-by-reference. Here theRef
object is created forVectorXd
, the memory of which has already been dynamically allocated. Therefore,Ref<VectorXd>
itself is a small object. ForRef<Vector3d>
, the memory forVector3d
is fixed and statically created, the entirety of which is a member ofRef<Vector3d>
. Therefore,Ref<Vector3d>
is relatively a large object and pass-by-reference is preferred. So we should useconst Ref<const Vector3d>&
. For simplicity, for any typeT
, we only useconst Ref<const T>&
.
Reference: https://stackoverflow.com/a/21138316