C ++ - Значение в константном векторе изменяется после выполнения чистой функции (странное поведение) - PullRequest
1 голос
/ 26 апреля 2020

У меня есть следующая функция, которая должна вычислять ковариационную матрицу нескольких векторов. Ковариация функции зависит от двух других функций 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. Вот так выглядит мой отладчик, извините за темные цвета.

enter image description here

Но после выполняя следующий шаг, вычисляя средний вектор матрицы, значение столбца 1 строки 2 изменилось на 788:

enter image description here

Я пометил все как константу и ни одна функция не мутировала свой параметр. Почему изменяется значение моей транспонированной матрицы?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...