2025-12-28 14:33:45 +08:00
|
|
|
|
/*
|
|
|
|
|
|
Description: 多维度嵌套的数组
|
|
|
|
|
|
|
|
|
|
|
|
Copyright : All right reserved by ICT
|
|
|
|
|
|
|
|
|
|
|
|
Author : Zhang Zhonghai
|
|
|
|
|
|
Date : 2025/12/24
|
|
|
|
|
|
*/
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
#include "spdlog/spdlog.h"
|
|
|
|
|
|
|
|
|
|
|
|
using std::vector;
|
|
|
|
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
|
|
struct Array2D {
|
2025-12-30 01:21:13 +08:00
|
|
|
|
vector<T> data;
|
|
|
|
|
|
int d1 = 0, d2 = 0;
|
|
|
|
|
|
int s1 = 0, cap = 0; // strides for each dimension
|
|
|
|
|
|
Array2D() {}
|
2025-12-28 14:33:45 +08:00
|
|
|
|
Array2D(int dim1, int dim2) { init(dim1, dim2); }
|
2025-12-30 01:21:13 +08:00
|
|
|
|
void init(int dim1, int dim2) { d1 = dim1; d2 = dim2; s1 = dim2; cap = d1 * d2; data.resize(cap); }
|
|
|
|
|
|
inline T& operator()(int k1, int k2) { return data[k1 * s1 + k2]; }
|
2025-12-28 14:33:45 +08:00
|
|
|
|
#define _Foreach2D(array, valName, codes) \
|
2025-12-30 01:21:13 +08:00
|
|
|
|
for (auto& valName : array.data) { \
|
|
|
|
|
|
codes; \
|
2025-12-28 14:33:45 +08:00
|
|
|
|
}
|
2025-12-30 01:21:13 +08:00
|
|
|
|
|
2025-12-28 14:33:45 +08:00
|
|
|
|
#define _Foreach2DK(array, valName, codes) \
|
|
|
|
|
|
do { \
|
2025-12-30 01:21:13 +08:00
|
|
|
|
int k1 = 0, k2 = 0, kg = 0; \
|
|
|
|
|
|
for (auto& valName : array.data) { \
|
|
|
|
|
|
codes; \
|
|
|
|
|
|
++kg; \
|
|
|
|
|
|
k1 = kg / (array.s1); \
|
|
|
|
|
|
k2 = kg % (array.s1); \
|
2025-12-28 14:33:45 +08:00
|
|
|
|
} \
|
|
|
|
|
|
} while (0)
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-12-30 01:21:13 +08:00
|
|
|
|
// 不能是bool
|
2025-12-28 14:33:45 +08:00
|
|
|
|
template <class T>
|
|
|
|
|
|
struct Array3D {
|
2025-12-30 01:21:13 +08:00
|
|
|
|
vector<T> data;
|
|
|
|
|
|
int d1 = 0, d2 = 0, d3 = 0;
|
|
|
|
|
|
int s1 = 0, s2 = 0, cap = 0; // strides for each dimension
|
2025-12-28 14:33:45 +08:00
|
|
|
|
Array3D() {}
|
|
|
|
|
|
Array3D(int dim1, int dim2, int dim3) { init(dim1, dim2, dim3); }
|
|
|
|
|
|
void init(int dim1, int dim2, int dim3) {
|
2025-12-30 01:21:13 +08:00
|
|
|
|
d1 = dim1; d2 = dim2; d3 = dim3;
|
|
|
|
|
|
s1 = dim2 * dim3; s2 = dim3; cap = d1 * d2 * d3;
|
|
|
|
|
|
data.resize(cap);
|
|
|
|
|
|
}
|
|
|
|
|
|
inline T& operator()(int k1, int k2, int k3) {
|
|
|
|
|
|
return data[k1 * s1 + k2 * s2 + k3];
|
2025-12-28 14:33:45 +08:00
|
|
|
|
}
|
2025-12-30 01:21:13 +08:00
|
|
|
|
|
2025-12-28 14:33:45 +08:00
|
|
|
|
#define _Foreach3D(array, valName, codes) \
|
2025-12-30 01:21:13 +08:00
|
|
|
|
for (auto& valName : array.data) { \
|
|
|
|
|
|
codes; \
|
2025-12-28 14:33:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-30 01:21:13 +08:00
|
|
|
|
#define _Foreach3DK(array, valName, codes) \
|
|
|
|
|
|
do { \
|
|
|
|
|
|
int k1 = 0, k2 = 0, k3 = 0, kg = 0; \
|
|
|
|
|
|
for (auto& valName : array.data) { \
|
|
|
|
|
|
codes; \
|
|
|
|
|
|
++kg; \
|
|
|
|
|
|
const int mod1 = kg % (array.s1); \
|
|
|
|
|
|
k1 = kg / (array.s1); \
|
|
|
|
|
|
k2 = mod1 / (array.s2); \
|
|
|
|
|
|
k3 = mod1 % (array.s2); \
|
|
|
|
|
|
} \
|
2025-12-28 14:33:45 +08:00
|
|
|
|
} while (0)
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
|
|
struct Array4D {
|
2025-12-30 01:21:13 +08:00
|
|
|
|
vector<T> data;
|
|
|
|
|
|
int d1 = 0, d2 = 0, d3 = 0, d4;
|
|
|
|
|
|
int s1 = 0, s2 = 0, s3 = 0, cap = 0; // strides for each dimension
|
2025-12-28 14:33:45 +08:00
|
|
|
|
Array4D() {}
|
|
|
|
|
|
Array4D(int dim1, int dim2, int dim3, int dim4) { init(dim1, dim2, dim3, dim4); }
|
|
|
|
|
|
void init(int dim1, int dim2, int dim3, int dim4) {
|
2025-12-30 01:21:13 +08:00
|
|
|
|
d1 = dim1; d2 = dim2; d3 = dim3; d4 = dim4;
|
|
|
|
|
|
s1 = d2 * d3 * d4; s2 = d3 * d4; s3 = d4; cap = d1 * d2 * d3 * d4;
|
|
|
|
|
|
data.resize(cap);
|
2025-12-28 14:33:45 +08:00
|
|
|
|
}
|
2025-12-30 01:21:13 +08:00
|
|
|
|
inline T& operator()(int k1, int k2, int k3, int k4) { return data[k1 * s1 + k2 * s2 + k3 * s3 + k4]; }
|
|
|
|
|
|
|
|
|
|
|
|
#define _Foreach4D(array, valName, codes) \
|
|
|
|
|
|
for (auto& valName : array.data) { \
|
|
|
|
|
|
codes; \
|
2025-12-28 14:33:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-30 01:21:13 +08:00
|
|
|
|
#define _Foreach4DK(array, valName, codes) \
|
|
|
|
|
|
do { \
|
|
|
|
|
|
int k1 = 0, k2 = 0, k3 = 0, k4 = 0, kg = 0; \
|
|
|
|
|
|
for (auto& valName : array.data) { \
|
|
|
|
|
|
codes; \
|
|
|
|
|
|
++kg; \
|
|
|
|
|
|
const int mod1 = kg % (array.s1); \
|
|
|
|
|
|
const int mod2 = mod1 % (array.s2); \
|
|
|
|
|
|
k1 = kg / (array.s1); \
|
|
|
|
|
|
k2 = mod1 / (array.s2); \
|
|
|
|
|
|
k3 = mod2 / (array.s3); \
|
|
|
|
|
|
k4 = mod2 % (array.s3); \
|
|
|
|
|
|
} \
|
2025-12-28 14:33:45 +08:00
|
|
|
|
} while (0)
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-12-30 01:21:13 +08:00
|
|
|
|
// 类似一个tensor,性能太低,不用了
|
2025-12-28 14:33:45 +08:00
|
|
|
|
template <class T>
|
|
|
|
|
|
struct NestedArray {
|
|
|
|
|
|
vector<T> data;
|
|
|
|
|
|
vector<int> dimensions;
|
|
|
|
|
|
vector<int> dim_offset;
|
|
|
|
|
|
|
|
|
|
|
|
NestedArray() { }
|
|
|
|
|
|
|
|
|
|
|
|
template <typename... Args>
|
|
|
|
|
|
NestedArray(Args... dims) {
|
|
|
|
|
|
init(dims...);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template <typename... Args>
|
|
|
|
|
|
void init(Args... dims) {
|
|
|
|
|
|
(dimensions.emplace_back(std::forward<Args>(dims)), ...);
|
|
|
|
|
|
// spdlog::info("dimensions: {}", dimensions.size());
|
|
|
|
|
|
// for (auto& val : dimensions) spdlog::info("dim: {}", val);
|
|
|
|
|
|
dim_offset.resize(dimensions.size(), 1);
|
|
|
|
|
|
for (int i = dimensions.size() - 2; i >= 0; --i) {
|
|
|
|
|
|
dim_offset[i] = dim_offset[i + 1] * dimensions[i + 1];
|
|
|
|
|
|
}
|
|
|
|
|
|
data.resize(dimensions[0] * dim_offset[0]);
|
|
|
|
|
|
// for (int i = 0; i < data.size(); ++i) data[i] = i;
|
|
|
|
|
|
// for (auto& val : dim_offset) spdlog::info("dim offset: {}", val);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 根据索引位置获取数据
|
|
|
|
|
|
template <typename... Args>
|
|
|
|
|
|
T& get(Args... keys) {
|
|
|
|
|
|
vector<int> keyArr;
|
|
|
|
|
|
(keyArr.emplace_back(std::forward<Args>(keys)), ...);
|
|
|
|
|
|
assert(keyArr.size() == dimensions.size());
|
|
|
|
|
|
int idx = 0;
|
|
|
|
|
|
for (int i = 0; i < keyArr.size(); ++i) {
|
|
|
|
|
|
idx += keyArr[i] * dim_offset[i];
|
|
|
|
|
|
}
|
|
|
|
|
|
return data[idx];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 根据关键字,在对应位置插入数据
|
|
|
|
|
|
template <typename... Args>
|
|
|
|
|
|
void put(T value, Args... keys) {
|
|
|
|
|
|
vector<int> keyArr;
|
|
|
|
|
|
(keyArr.emplace_back(std::forward<Args>(keys)), ...);
|
|
|
|
|
|
assert(keyArr.size() == dimensions.size());
|
|
|
|
|
|
int idx = 0;
|
|
|
|
|
|
for (int i = 0; i < keyArr.size(); ++i) {
|
|
|
|
|
|
idx += keyArr[i] * dim_offset[i];
|
|
|
|
|
|
}
|
|
|
|
|
|
data[idx] = value;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|