将二进制文件加载到eigen矩阵中时,请删除潜在的冗余模板参数
Removing potentially redundant template parameters when loading a binary file into Eigen matrix
我想读一个普通的二进制文件,其中包含许多未签名的16位整数到特征矩阵中,我写了一个模板的实用程序来做到这一点。这就是呼叫者的样子:
Matrix<uint16_t, Dynamic, Dynamic> data;
int retval = read_data<Matrix<uint16_t, Dynamic, Dynamic>, uint16_t>(
argv[1], data);
这就是read_data
的样子:
template <typename Derived, typename Scalar> // Per @Jarod42, get rid of Scalar here (*)
int read_data(const char* const fname, MatrixBase<Derived>& data) {
// (*) If we don't have Scalar as a template, just uncomment this:
// typedef typename Derived::Scalar Scalar;
ifstream fin(fname, ios::binary);
if (!fin) {
return 2;
}
fin.seekg(0, fin.end);
long long bytes = fin.tellg();
if (bytes % sizeof(Scalar) != 0) {
// The available number of bytes won't fill an even number of Scalar
// values
return 3;
}
long long nscalars = bytes / sizeof(Scalar);
// See http://forum.kde.org/viewtopic.php?f=74&t=107551
MatrixBase<Derived>& data_edit = const_cast<MatrixBase<Derived>&>(data);
data_edit.derived().resize(nscalars, 1);
Scalar* buffer = new Scalar[nscalars]; // Switched to vector per @Casey
fin.seekg(0, fin.beg);
fin.read(reinterpret_cast<char*>(buffer), bytes);
if (!fin) {
// All data not read. fin.gcount() will indicate bytes read.
return 4;
}
for (long long idx = 0; idx < nscalars; ++idx) {
data_edit(idx) = buffer[idx];
}
return 0;
}
简要
- 打开文件,
- 获得其大小,
- 动态分配一个数组以存储所有数据,
- 将文件读取到数组中,
- 阵列的内容被复制到矩阵中。
这是合理的,它有效(尽管我对改进的建议很开放),但是我认为该功能具有一个太多的模板参数, ,呼叫者中的函数调用也是冗长。我认为应该有一种消除第二个模板参数的方法,该参数仅用于告诉 read_data
每个标量的字节数(在uint16_t
的情况下为2),我相信应该使用第一个模板参数来下降。p> 问题有没有办法消除看似冗余的第二个模板参数到read_data
?
另外,我的方法是传递矩阵参考仅在read_data
函数中调整它的大小(使用详细和令人困惑的习语来创建对矩阵的可修改引用,以通过derived()
进行调整大小)。?我意识到这动态分配了记忆,这很好,但是我认为这没有做任何浪费的事情---正确?
(讨论此代码是否还有其他改进?我是C或Python数字编码器;在C中,我只是处理void*
阵列并传递额外函数参数告诉每个标量的函数;使用Python,我会做numpy.fromfile('path/to/file.bin', dtype=numpy.uint16)
并使用它。但是我想通过EIGEN和C 做正确的操作。)
nb。我使用矩阵而不是向量,因为稍后我将它们调整到矩形矩阵中。
nb2。在固定尺寸的特征类型中,作为参数,促进使用标量类型模板函数的概念。我并不反对这种方法,我选择通过read_data
矩阵参考,而不是使其返回矩阵对象,因为我想要整数返回值指示错误 - - 现在我意识到我应该做出这些例外。
nb3。在C 检查模板参数的嵌套类型中,以获取其标量基本类型,我认为,精心设计的辅助类别集用于对模板类的类似效果。我很好奇是否可以在此处使用更简单的方法,用于模板函数。
nb4。我知道的一个简单的改进是键入Matrix<uint16_t, Dynamic, Dynamic>
来减少冗长的速度。
我认为Matrix<uint16_t, Dynamic, Dynamic>
应该具有typedef
的uint16_t
。如果是这样,您可以作为第一行写(假设是type
):
typedef typename Derived::type Scalar;
如果没有typedef
,则可以为此写一个特征:
template <typename> struct matrix_type;
template <typename T, typename U1, typename U2>
struct matrix_type<Matrix<T, U1, U2> >
{
typedef T type;
typedef U1 type1;
typedef U2 type2;
};
然后写
typedef typename matrix_type<Derived>::type Scalar;
注意:如果您已按其他顺序编写了参数
template <typename Derived, typename Scalar>
int read_data(const char* const fname, MatrixBase<Derived>& data);
您可以写(因为可以推论最后一个参数):
Matrix<uint16_t, Dynamic, Dynamic> data;
int retval = read_data<uint16_t>(argv[1], data);
现在,参数已过时,您可以直接写入:
Matrix<uint16_t, Dynamic, Dynamic> data;
int retval = read_data(argv[1], data);
您可能想查看eigen中的地图。它直接将记忆带入了一个。
tutorialmapclass.html"> http://eigen.tuxfamily.org/dox/group_tutorialmapclass.html
要构建一个MAP变量,您还需要其他两个信息:定义系数数组的内存区域的指针,以及矩阵或向量的所需形状。例如,要定义一个在编译时确定尺寸的浮子矩阵,您可以执行以下操作:
MAP MF(PF,行,列);
- 如何擦除冗余输入?
- 使用提升几何缓冲区缩放多边形时的冗余折点
- 我应该担心冗余声明吗?
- Qt的slot(?)将冗余命名空间插入连接
- 方法冗余移动调用的移动语义
- 使用 llvm 和本地值编号算法擦除冗余表达式
- 优化堆上创建的冗余变量
- 如何消除访客模式冗余?
- 表达式模板需要冗余重载
- C++,处理多个构造函数重载和冗余代码
- 使用模板基类消除工厂类派生类冗余的干净方法
- 连接两个文件时如何避免冗余尾随换行符?
- CMake:修改共享库时的冗余链接
- 提升精神 X3:"属性没有预期的大小"冗余
- 如何删除 QStringList 中的冗余元素
- 将二进制文件加载到eigen矩阵中时,请删除潜在的冗余模板参数
- 如何删除格式化的流中的冗余
- 删除不使用的或冗余的代码
- 在MFC项目中有删除冗余资源的工具吗?
- BOOST共享指针导致冗余引用删除