特征矩阵的原位元素类型转换

时间:2017-08-10 20:04:17

标签: c++ eigen

我想将整数矩阵转换为浮点矩阵,例如:

  1. 不会复制数据。
  2. 没有分配新内存
  3. 数据的新浮点视图是可变的。
  4. 最新尝试:

    #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";
    }
    

    运行时错误:

    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)
    

    以下内容无法编译:

    #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";
    }
    

    我猜CastXpr<NewType>::Type可能有效(documentation)。但我无法弄清楚如何使用它。

    CastXpr似乎是unaryExprHow do I in-place modify each element of a 1D Array?

2 个答案:

答案 0 :(得分:1)

首先,你不能将它转换为double(不分配更多空格)矩阵,因为double是8个字节的内存,而int是4个字节。

我认为您可以简单地将浮点指针强制转换为原始Matrix。以下代码为我工作。

#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;
}

输出:

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 . . .

所以...只要你使用这个指针,分配的对象就会充当一个浮点矩阵,但请记住,你不能使用&#39; x&#39;好像它是一个浮点矩阵,因为任何函数调用使用&#39; x&#39;将导致分配的内存被解释为整数矩阵

例如:因为我们已将原始(2,2)从int更改为float,如果您尝试使用&#39; x&#39;你会看到这样的东西。

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

输出:

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

答案 1 :(得分:0)

修复类型后,最终会有效。

程序:

#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";
}

结果:

0.5   1 1.5
  2 2.5   3
3.5   4 4.5