项目引入
VS2019环境下
- 点击<项目>
- 管理NuGet程序包
- 搜索Eigen3,安装即可
在项目源代码添加头文件
#include <unsupported/Eigen/CXX11/Tensor>
类型转换
C++ 数组转Eigen::Tensor(包含reshape操作)
例如从float数组转到储存类型为float的Tensor
- float数组转Eigen::TensorMap
- Eigen::TensorMap类型转换回Eigen::Tensor
#include <iostream>
#include <unsupported/Eigen/CXX11/Tensor>
int main()
{
float arr[] = { 0.1, 0.2, 0.3, 0.4 };
auto mapped_t = Eigen::TensorMap<Eigen::Tensor<float, 2>>(arr, 2, 2);
std::cout << typeid(mapped_t).name() << std::endl;
auto result = Eigen::Tensor<float, 2>(mapped_t);
std::cout << typeid(result).name() << std::endl;
std::cout << result << std::endl;
}
输出
class Eigen::TensorMap<class Eigen::Tensor<float,2,0,__int64>,0,struct Eigen::MakePointer>
class Eigen::Tensor<float,2,0,__int64>
0.1 0.3
0.2 0.4
上面的操作与python numpy的narray.reshape()是一致的。下面代码是对narray.reshape()的实现。已验证与上面结果一致。
Eigen::Tensor<float, 3> reshape(float* oneDimArray, int channel,int height, int width)
{
const int frameSize = height * width;
const auto length = channel * height * width;
int index = 0;
Eigen::Tensor<float, 3> result(channel, height, width);
for (int c = 0; c < channel; c++)
{
for (int w = 0; w < width; w++)
{
for (int h = 0; h < height; h++)
{
index = c * frameSize + w * height + h;
float value = oneDimArray[index];
result(c, h, w) = value;
}
}
}
return result;
}
Tensor操作
concatenate
#include <iostream>
#include <unsupported/Eigen/CXX11/Tensor>
int main()
{
Eigen::Tensor<float, 2, 1> a(2, 2);
Eigen::Tensor<float, 2, 1> b(2, 2);
a.setConstant(1.0);
b.setConstant(2.0);
auto res = a.concatenate(b, 0);
std::cout << res << std::endl;
}
输出结果:
1 1
1 1
2 2
2 2
transpose
#include <iostream>
#include <unsupported/Eigen/CXX11/Tensor>
using namespace std;
int main()
{
Eigen::Tensor<int, 3> m(2, 3, 3);
m.setValues(
{
{{1, 2, 3},
{4, 5, 6},
{7, 8, 9}},
{{10, 11, 12},
{13, 14, 15},
{16, 17, 18}}
});
Eigen::array<int, 3> shuffling({ 2, 1, 0});
Eigen::Tensor<int, 3> transposed = m.shuffle(shuffling);
cout << transposed(0, 0, 0) << ',' << transposed(0, 0, 1) << endl;
cout << transposed(0, 1, 0) << ',' << transposed(0, 1, 1) << endl;
cout << transposed(0, 2, 0) << ',' << transposed(0, 2, 1) << endl;
cout << transposed(1, 0, 0) << ',' << transposed(1, 0, 1) << endl;
cout << transposed(1, 1, 0) << ',' << transposed(1, 1, 1) << endl;
cout << transposed(1, 2, 0) << ',' << transposed(1, 2, 1) << endl;
cout << transposed(2, 0, 0) << ',' << transposed(2, 0, 1) << endl;
cout << transposed(2, 1, 0) << ',' << transposed(2, 1, 1) << endl;
cout << transposed(2, 2, 0) << ',' << transposed(2, 2, 1) << endl;
}
输出
1,10
4,13
7,16
2,11
5,14
8,17
3,12
6,15
9,18
该操作与python的numpy库的ndarray.transpose一致
import numpy as np
mat = [
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]],
[[10, 11, 12],
[13, 14, 15],
[16, 17, 18]]
]
mat = np.array(mat)
mat = mat.transpose(2, 1, 0)
print(mat[0][0][0], mat[0][0][1])
print(mat[0][1][0], mat[0][1][1])
print(mat[0][2][0], mat[0][2][1])
print(mat[1][0][0], mat[1][0][1])
print(mat[1][1][0], mat[1][1][1])
print(mat[1][2][0], mat[1][2][1])
print(mat[2][0][0], mat[2][0][1])
print(mat[2][1][0], mat[2][1][1])
print(mat[2][2][0], mat[2][2][1])
输出
1 10
4 13
7 16
2 11
5 14
8 17
3 12
6 15
9 18
reshape
|