Я запрограммировал кусок кода, где у меня есть огромная трехмерная матрица на C ++, используя boost :: multi_array.
Для каждого элемента матрицы я хочу суммировать окрестности на определенном расстоянии dist.Каждый элемент взвешивается в соответствии с его расстоянием до центра.Центральный элемент не должен быть включен в сумму.
Расстояние dist задается пользователем и может варьироваться.Моя программа делает правильные вычисления, но медленная, когда матрица становится большой.Иногда у меня есть матрицы с более чем 100000 элементов ...
Так что мой вопрос: есть ли способ сделать это вычисление быстрее?Может также использовать другую библиотеку?
Часть состоит в основном из двух функций.В первой функции я получаю доступ к каждому элементу матрицы и вычисляю сумму окрестности.InputMatrix - это трехмерный бустерный мультимассив:
boost::multi_array<float, 3> inputMatrix = imageMatrix;
T actualElement;
int posActualElement;
for (int depth = 0; depth<inputMatrix.shape()[2]; depth++) {
for (int row = 0; row<inputMatrix.shape()[0]; row++) {
for (int col = 0; col<inputMatrix.shape()[1]; col++) {
indexOfElement[0] = row;
indexOfElement[1] = col;
indexOfElement[2] = depth;
//get actual Element if it is the centre of a whole neighborhood
actualElement = inputMatrix[row][col][depth];
if (!std::isnan(actualElement)) {
//get the sum of the actual neighborhood
sumOfActualNeighborhood = getNeighborhood3D(inputMatrix, indexOfElement);
}
}
}
}
Функция окрестность3D выглядит следующим образом:
template <class T, size_t R>
T NGTDMFeatures3D<T, R>::getNeighborhood3D(boost::multi_array<T, R> inputMatrix, int *indexOfElement) {
std::vector<T> neighborhood;
T actElement;
float weight;
for (int k = -dist; k<dist + 1; k++) {
for (int i = -dist; i<dist + 1; i++) {
for (int j = -dist; j<dist + 1; j++) {
if (i != 0 || j != 0 || k != 0) {
if (indexOfElement[0] + i>-1 && indexOfElement[0] + i<inputMatrix.shape()[0] && indexOfElement[1] + j>-1 && indexOfElement[1] + j<inputMatrix.shape()[1] && indexOfElement[2] + k>-1 && indexOfElement[2] + k<inputMatrix.shape()[2]) {
actElement = inputMatrix[indexOfElement[0] + i][indexOfElement[1] + j][indexOfElement[2] + k];
if (!std::isnan(actElement)) {
weight = calculateWeight3D(i, j, k, normNGTDM, actualSpacing);
neighborhood.push_back(weight*actElement);
}
}
}
}
}
}
T sum = accumulate(neighborhood.begin(), neighborhood.end(), 0);
sum = sum / neighborhood.size();
return sum;
}