I have an object of std::vector<std::array<double, 16>>
vector entry Data
[0] - 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
[1] - 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
[2] - 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
[...] - 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
This is intended to represent a 4x4 matrix in ravel format.
To not duplicate information I would like to create a pointer to extract a 3x3 from the above structure:
I have mathematical operations for the 3x3 structure (std::array<double, 9>
)
someStructure
: pointing to data elements [0, 1, 2, 4, 5, 6, 8, 9 10]
The end goal is do: std::array<double, 9> tst = someStructure[0] someStructure[1];
Is this doable?
Best Regards
CodePudding user response:
The 3x3 part is not contiguous, hence a pointer alone wont help here.
You can write a view_as_3x3
that allows you to access elements of the submatrix of the 4x4
as if it was contiguous:
struct view_as_3x3 {
double& operator[](size_t index) {
static size_t mapping[] = {0, 1, 2, 4, 5, 6, 8, 9, 10};
return parent[mapping[index]];
}
std::array<double, 16>& parent;
};
Such that for example
for (size_t = 0; i< 9; i) std::cout << " " << view_as_3x3{orignal_matrix}[i];
is printing the 9 elements of the 3x3 sub-matrix of the original 4x4 original_matrix
.
Then you could more easily apply your 3x3 algorithms to the 3x3 submatrix of a 4x4 matrix. You just need to replace the std::array<double, 9>
with some generic T
. For example change
double sum_of_elements(const std::array<double, 9>& arr) {
double res = 0;
for (int i=0;i <9; i) res = arr[i];
return res;
}
To:
template <typename T>
double sum_of_elements(const T& arr) {
double res = 0;
for (int i=0;i <9; i) res = arr[i];
return res;
}
The calls are then
std::array<double, 16> matrix4x4;
sum_of_elements(view_as_3x3{matrix4x4});
// or
std::array<double, 9> matrix3x3;
sum_of_elements(matrix3x3);
It would be nicer to use iterators instead of indices, however, writing the view with custom iterators requires considerable amount of boilerplate. On the other hand, I would not suggest to use naked std::array
s in the first place, but rather some my_4x4matrix
that holds the array as member and provides iterators and more convenience methods.