简体   繁体   English

本征矩阵的就地元素类型转换

[英]In-place element type conversion for an Eigen matrix

I want to cast an integer matrix to a floating point matrix, such that: 我想将整数矩阵转换为浮点矩阵,例如:

  1. data is not copied. 数据未复制。
  2. no new memory is allocated 没有分配新的内存
  3. the new floating point view of the data is mutable. 数据的新浮点视图是可变的。

newest try: 最新尝试:

#include "Eigen/Eigen"
#include <iostream>
int main(){
    using namespace Eigen;
    MatrixXi x(3,3);
    x.fill(0);
    double* ptr_x = (double*)(x.data());
    Map<MatrixXd> y(ptr_x, x.rows(), x.cols());
    x(0,0) = 100;
    y = x.cast<double>();
    y(1,1) = 0.5f;
    std::cout << y << "\n";
}

Run time error: 运行时错误:

a.out: malloc.c:2405: 

    sysmalloc: 
        Assertion `(old_top == initial_top (av) && old_size == 0) 
        || ((unsigned long) (old_size) >= MINSIZE 
        && prev_inuse (old_top) 
        && ((unsigned long) old_end & (pagesize - 1)) == 0)' 
    failed.

Aborted (core dumped)

The following does not compile: 以下内容无法编译:

#include "Eigen/Eigen"
#include <stdint.h>

#include <iostream>
int main(){
    using namespace Eigen;
    MatrixXi x(3,3);
    x.fill(0);
    float* ptr_x = (float*)(x.data());

    Map<MatrixXd> y(ptr_x, x.rows(), x.cols());
    x(0,0) = 100;
    y(1,1) = 0.5f;
    y = x.cast<float>();
    std::cout << y << "\n";
}

I guess the CastXpr<NewType>::Type might work ( documentation ). 我想CastXpr<NewType>::Type可能有效( 文档 )。 But I cant figure out how to use that. 但我不知道如何使用它。

The CastXpr seems to be an unaryExpr : How do I in-place modify each element of a 1D Array? CastXpr似乎是unaryExpr如何就地修改一维数组的每个元素?

First of all, you cannot cast it into a double (without allocating more space) matrix since a double is 8 bytes in memory while an int is 4 bytes. 首先,由于double在内存中为8字节,而int为4字节,因此无法将其转换为double(不分配更多空间)矩阵。

I think you can simply cast a float pointer to the original Matrix. 我认为您可以简单地将float指针转换为原始Matrix。 Following code worked for me. 以下代码为我工作。

#include "Eigen/Eigen"
#include <iostream>
int main()
{
    using namespace Eigen;
    MatrixXi x(3, 3);
    x.fill(2);
    MatrixXf* float_ptr = (MatrixXf*) &x;
    float_ptr->operator()(2,2) = 42.1f;

    std::cout << "float cast(2,2): " << 
        float_ptr->operator()(2, 2) << std::endl;
    std::cout << "float cast(1,1): " <<
        float_ptr->operator()(1, 1) << std::endl;
    std::cout << "x(1,1): " << x(1, 1) << std::endl;
}

output: 输出:

float cast(2,2): 42.1
float cast(1,1): 2.8026e-45 (which is ~2)
x(1,1): 2
Press any key to continue . . .

So... As long as you use this pointer, the allocated object will act as a floating point matrix but please keep that in mind that you cannot use 'x' as if it's a floating point matrix since any function call using 'x' will cause the allocated memory to be interpreted as an integer matrix 因此...只要使用此指针,分配的对象将充当浮点矩阵,但请记住,由于任何使用'x'的函数调用,您都无法像使用浮点矩阵那样使用'x'将导致分配的内存被解释为整数矩阵

For example: since we have changed the original (2,2) from int to a float, if you try to retrieve it with 'x' you will see something like this. 例如:由于我们已将原始(2,2)从int更改为float,如果尝试使用'x'进行检索,则会看到类似以下内容。

    .
    .
    .
    std::cout << "float cast(2,2): " << 
        float_ptr->operator()(2, 2) << std::endl;
    std::cout << "x(2,2): " << x(2, 2) << std::endl;

the output: 输出:

float cast(2,2): 42.1
x(2,2): 1109943910

After fixing the types, the following finally works. 固定类型后,以下内容终于可以使用了。

Program: 程序:

#include "Eigen/Eigen"
#include <iostream>
int main(){
    using namespace Eigen;
    MatrixXi x(3,3);
    x.fill(0);
    float* ptr_x = (float*)(x.data());

    Map<MatrixXf> y(ptr_x, x.rows(), x.cols());

    x << 1,2,3,4,5,6,7,8,9;
    y = x.cast<float>();
    y /= 2;
    std::cout << y << "\n";
}

Result: 结果:

0.5   1 1.5
  2 2.5   3
3.5   4 4.5

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM