C++/CLI 将托管 MathNet 矩阵转换为 Eigen MatrixXi 以在本机中使用 class
C++/CLI converting managed MathNet Matrix to Eigen MatrixXi for use in native class
我正在尝试为包含 Eigen::MatrixXi
的本机 C++ class 构建托管包装器。假设本机 class 有一个成员 matrix
存储并通过其构造函数获取,以及稍后使用该成员的方法:
#include <Eigen/Dense>
#include <Eigen/Core>
#include <iostream>
using Eigen::MatrixXi;
class Foo
{
public:
const MatrixXi matrix;
Foo(const MatrixXi &matrix);
void Bar();
};
Foo::Foo(const MatrixXi &matrix)
: matrix(matrix) {}
void Foo::Bar()
{
for (int y = 0; y < matrix.rows(); y++)
{
for (int x = 0; x < matrix.cols(); x++)
{
std::cout << matrix(y, x);
}
std::cout << std::endl;
}
}
我做了以下包装:
using namespace MathNet::Numerics::LinearAlgebra;
using namespace MathNet::Numerics::LinearAlgebra::Single;
template<class T>
public ref class ManagedObject
{
protected:
T* m_Instance;
public:
ManagedObject(T* instance)
: m_Instance(instance)
{
}
virtual ~ManagedObject()
{
if (m_Instance != nullptr)
{
delete m_Instance;
}
}
!ManagedObject()
{
if (m_Instance != nullptr)
{
delete m_Instance;
}
}
T* GetInstance()
{
return m_Instance;
}
};
public ref class ManagedFoo : public ManagedObject<Foo>
{
public:
ManagedFoo(MathNet::Numerics::LinearAlgebra::Matrix<float>^ matrix);
void Bar();
};
ManagedFoo::ManagedFoo(MathNet::Numerics::LinearAlgebra::Matrix<float>^ matrix)
: ManagedObject(new Foo(mathnet_to_eigen(matrix))) {}
void ManagedFoo::Bar()
{
m_Instance->Bar();
}
mathnet_to_eigen
方法会是什么样子?我尝试了以下方法:
#include <vector>
#include <Eigen/Dense>
#include <Eigen/Core>
using Eigen::MatrixXi;
static Eigen::MatrixXi mathnet_to_eigen(MathNet::Numerics::LinearAlgebra::Matrix<float>^ data)
{
int length = data->RowCount * data->ColumnCount;
std::vector<int> data_converted(length);
for (size_t i = 0; i < data->RowCount; i++)
{
for (size_t j = 0; j < data->ColumnCount; j++)
{
data_converted[i * data->ColumnCount + j] = data[i, j];
}
}
Eigen::MatrixXi mat = Eigen::Map<Eigen::Matrix<int, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>(&data_converted[0], data->RowCount, data->ColumnCount);
return mat;
}
这似乎可行,但我不确定内存管理和效率。我应该使用固定吗?那会是什么样子?我感觉我做的不正确,可能使用了指向被垃圾收集的内存的指针。
在这种情况下,我不关心如何完成 float 到 int 的转换(rounding/taking 整数部分)。
我发现这是最简洁的方法:
static Eigen::MatrixXf MathNetToEigen(MathNet::Numerics::LinearAlgebra::Matrix<float>^ data)
{
auto mat = Eigen::MatrixXf(data->RowCount, data->ColumnCount);
for (size_t i = 0; i < data->RowCount; i++)
for (size_t j = 0; j < data->ColumnCount; j++)
mat(i, j) = data[i, j];
return mat;
}
并转换回来:
static MathNet::Numerics::LinearAlgebra::Matrix<float>^ EigenToMathNet(Eigen::MatrixXf& data)
{
auto mat = MathNet::Numerics::LinearAlgebra::Matrix<float>::Build->Dense(data.rows(), data.cols());
for (size_t i = 0; i < data.rows(); i++)
for (size_t j = 0; j < data.cols(); j++)
mat[i, j] = data(i, j);
return mat;
}
我正在尝试为包含 Eigen::MatrixXi
的本机 C++ class 构建托管包装器。假设本机 class 有一个成员 matrix
存储并通过其构造函数获取,以及稍后使用该成员的方法:
#include <Eigen/Dense>
#include <Eigen/Core>
#include <iostream>
using Eigen::MatrixXi;
class Foo
{
public:
const MatrixXi matrix;
Foo(const MatrixXi &matrix);
void Bar();
};
Foo::Foo(const MatrixXi &matrix)
: matrix(matrix) {}
void Foo::Bar()
{
for (int y = 0; y < matrix.rows(); y++)
{
for (int x = 0; x < matrix.cols(); x++)
{
std::cout << matrix(y, x);
}
std::cout << std::endl;
}
}
我做了以下包装:
using namespace MathNet::Numerics::LinearAlgebra;
using namespace MathNet::Numerics::LinearAlgebra::Single;
template<class T>
public ref class ManagedObject
{
protected:
T* m_Instance;
public:
ManagedObject(T* instance)
: m_Instance(instance)
{
}
virtual ~ManagedObject()
{
if (m_Instance != nullptr)
{
delete m_Instance;
}
}
!ManagedObject()
{
if (m_Instance != nullptr)
{
delete m_Instance;
}
}
T* GetInstance()
{
return m_Instance;
}
};
public ref class ManagedFoo : public ManagedObject<Foo>
{
public:
ManagedFoo(MathNet::Numerics::LinearAlgebra::Matrix<float>^ matrix);
void Bar();
};
ManagedFoo::ManagedFoo(MathNet::Numerics::LinearAlgebra::Matrix<float>^ matrix)
: ManagedObject(new Foo(mathnet_to_eigen(matrix))) {}
void ManagedFoo::Bar()
{
m_Instance->Bar();
}
mathnet_to_eigen
方法会是什么样子?我尝试了以下方法:
#include <vector>
#include <Eigen/Dense>
#include <Eigen/Core>
using Eigen::MatrixXi;
static Eigen::MatrixXi mathnet_to_eigen(MathNet::Numerics::LinearAlgebra::Matrix<float>^ data)
{
int length = data->RowCount * data->ColumnCount;
std::vector<int> data_converted(length);
for (size_t i = 0; i < data->RowCount; i++)
{
for (size_t j = 0; j < data->ColumnCount; j++)
{
data_converted[i * data->ColumnCount + j] = data[i, j];
}
}
Eigen::MatrixXi mat = Eigen::Map<Eigen::Matrix<int, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>(&data_converted[0], data->RowCount, data->ColumnCount);
return mat;
}
这似乎可行,但我不确定内存管理和效率。我应该使用固定吗?那会是什么样子?我感觉我做的不正确,可能使用了指向被垃圾收集的内存的指针。
在这种情况下,我不关心如何完成 float 到 int 的转换(rounding/taking 整数部分)。
我发现这是最简洁的方法:
static Eigen::MatrixXf MathNetToEigen(MathNet::Numerics::LinearAlgebra::Matrix<float>^ data)
{
auto mat = Eigen::MatrixXf(data->RowCount, data->ColumnCount);
for (size_t i = 0; i < data->RowCount; i++)
for (size_t j = 0; j < data->ColumnCount; j++)
mat(i, j) = data[i, j];
return mat;
}
并转换回来:
static MathNet::Numerics::LinearAlgebra::Matrix<float>^ EigenToMathNet(Eigen::MatrixXf& data)
{
auto mat = MathNet::Numerics::LinearAlgebra::Matrix<float>::Build->Dense(data.rows(), data.cols());
for (size_t i = 0; i < data.rows(); i++)
for (size_t j = 0; j < data.cols(); j++)
mat[i, j] = data(i, j);
return mat;
}