实现一个任意1-4维的矩阵类 Tensor
完成这个实验课题目能让我们懂得高维到1维展开的一般方法,和帮助我们更好地理解和完成本周的理论课作业。
请先阅读主程序,然后实现函数:
double & Tensor_get(int dimensions, const int sizes[], const double data[], int x0, int x1, int x2, int x3)
注意
这个类的对象的构造函数指定了tensor的维数和每维的大小
成员函数get的前4行保证给定的每维的维度和大小都不越界
EXAMPLE INPUT
0 0
2 1
0 2
2 3 4
2 3 0
1 1 2
1 1 3 1
1 3 3 0
1 3 4 40
EXAMPLE OUTPUT
0
21
2
234
230
112
1131
1330
1344
主程序 (不能修改)
#include "source.cpp"
#include <iostream>
using namespace std;
void _assert(bool valid, const char err_msg[]) {
if (valid) return;
cout << err_msg << endl;
exit(1);
}
class Tensor
{
private:
double * data;
int sizes[4];
int dimensions;
public:
Tensor(int size0, int size1=-1, int size2=-1, int size3=-1) {
_assert(size0 > 0, "第0维大小必须大于0");
if (size1 != -1) _assert(size1 > 0, "第1维大小必须大于0");
if (size2 != -1) _assert(size2 > 0, "第2维大小必须大于0");
if (size3 != -1) _assert(size3 > 0, "第3维大小必须大于0");
this->dimensions = 1;
this->sizes[0] = size0;
this->sizes[1] = this->sizes[2] = this->sizes[3] = 1;
if (size1 != -1) {
this->dimensions = 2;
this->sizes[1] = size1;
}
if (size2 != -1) {
this->dimensions = 3;
this->sizes[2] = size2;
}
if (size3 != -1) {
this->dimensions = 4;
this->sizes[3] = size3;
}
int totel_size = this->numel();
this->data = new double[totel_size];
for (int i = 0; i < totel_size; ++ i)
this->data[i] = 0;
}
int numel() { // number of elements
return this->sizes[0] * this->sizes[1] * this->sizes[2] * this->sizes[3];
}
void fill(double value) {
for (int i = 0; i < this->numel(); ++ i)
this->data[i] = value;
}
~Tensor() {
delete [] this->data;
}
double & get(int x0, int x1=-1, int x2=-1, int x3=-1) {
// 检查有否越界
_assert(x0 >= 0 && x0 < this->sizes[0], "第0维越界");
_assert((this->dimensions < 2 && x1 == -1) || (x1 >= 0 && x1 < this->sizes[1]), "第1维越界");
_assert((this->dimensions < 3 && x2 == -1) || (x2 >= 0 && x2 < this->sizes[2]), "第2维越界");
_assert((this->dimensions < 4 && x3 == -1) || (x3 >= 0 && x3 < this->sizes[3]), "第3维越界");
return Tensor_get(this->dimensions, this->sizes, this->data, x0, x1, x2, x3);
}
};
int main() {
// 测试1
Tensor t1(3, 4);
for (int i = 0; i < 3; ++ i) {
for (int j = 0; j < 4; ++ j) {
t1.get(i, j) = i * 10 + j;
}
}
for (int i = 0; i < 3; ++ i) {
int x0, x1;
cin >> x0 >> x1;
cout << t1.get(x0, x1) << endl;
}
cout << endl;
// 测试2
Tensor t2(3, 4, 5);
for (int i = 0; i < 3; ++ i) {
for (int j = 0; j < 4; ++ j) {
for (int k = 0; k < 5; ++ k) {
t2.get(i, j, k) = i * 100 + j * 10 + k;
}
}
}
for (int i = 0; i < 3; ++ i) {
int x0, x1, x2;
cin >> x0 >> x1 >> x2;
cout << t2.get(x0, x1, x2) << endl;
}
cout << endl;
// 测试3
Tensor t3(3, 4, 5, 6);
for (int i = 0; i < 3; ++ i) {
for (int j = 0; j < 4; ++ j) {
for (int k = 0; k < 5; ++ k) {
for (int l = 0; l < 6; ++ l) {
t3.get(i, j, k, l) = i * 1000 + j * 100 + k * 10 + l;
}
}
}
}
for (int i = 0; i < 3; ++ i) {
int x0, x1, x2, x3;
cin >> x0 >> x1 >> x2 >> x3;
cout << t3.get(x0, x1, x2, x3) << endl;
}
}
参考答案
double & Tensor_get(int dimensions, const int sizes[], double data[], int x0, int x1, int x2, int x3){
int index=0;
if(dimensions==1) index=x0;
else if(dimensions==2) index=x0*sizes[1]+x1;
else if(dimensions==3) index=x0*sizes[2]*sizes[1]+x1*sizes[2]+x2;
else if(dimensions==4) index=x0*sizes[3]*sizes[2]*sizes[1]+x1*sizes[3]*sizes[2]+x2*sizes[3]+x3;
return data[index];
}