У меня есть следующая функция, которая должна вычислять ковариационную матрицу нескольких векторов. Ковариация функции зависит от двух других функций transpose
и mean
. Все три функции являются чистыми функциями, что означает, что ни одна из них не изменяет свои параметры. Однако значение элемента матрицы изменилось после выполнения функции mean
без предупреждения.
std::vector<std::vector<double>> covariance(const std::vector<std::vector<double>> &matrix) {
std::vector<std::vector<double>> ret;
const std::vector<std::vector<double>> transposed = transpose(matrix);
const std::vector<double> meanVector = mean(matrix);
...
}
Так выглядит функция транспонирования (как вы можете видеть, в этой функции нет ничего особенного, просто для l oop):
std::vector<std::vector<double>> transpose(const std::vector<std::vector<double>> matrix) {
std::vector<std::vector<double>> ret(matrix[0].size(), std::vector<double>(matrix.size(), 0));
for (auto y = 0; y < matrix.size(); y++) {
for (auto x = 0; x < matrix[y].size(); x++) {
ret[x][y] = matrix[y][x];
}
}
return ret;
}
И среднее значение функции выглядит так (также только некоторые if / else и циклы):
std::vector<double> mean(const std::vector<std::vector<double>> &matrix) {
if (!matrix.empty()) {
std::vector<double> cols(matrix[0].size(), 0);
for (auto y = 0; y < matrix.size(); y++) {
for (auto x = 0; x < matrix.size(); x++) {
cols[x] += matrix[y][x];
}
}
for (double &col : cols) {
col /= matrix.size();
}
return cols;
} else {
return std::vector<double>();
}
}
Как вы можете видеть, ни одна функция не изменяет свои параметры. Я хочу проверить ковариацию функции с помощью следующего модульного теста:
TEST_CASE("Test covariance") {
auto ret = linalg::covariance(
{{64, 580, 29},{66, 570, 33}, {68, 590, 37}, {69, 660, 46}, {73, 600, 55}});
}
Теперь наступает действительно забавная часть этой программы. После того, как я транспонирую матрицу, вот так выглядит результат. Обратите внимание на строку 2 и столбец 1, у меня 580. Вот так выглядит мой отладчик, извините за темные цвета.
Но после выполняя следующий шаг, вычисляя средний вектор матрицы, значение столбца 1 строки 2 изменилось на 788:
Я пометил все как константу и ни одна функция не мутировала свой параметр. Почему изменяется значение моей транспонированной матрицы?