Неверный подсчет определителя произвольной матрицы
Функция det2by2(m) вычисляет определитель матрицы 2x2, функция detNbyN(m) вычисляет определитель матрицы любого размера. Функция minor(m, num) вычисляет минор матрицы, здесь num - индекс числа первой строки матрицы. Определитель матрицы в конце кода должен быть равен 62, но в консоль выводится 48, предположительное проблемное место помечено *. Как нужно изменить код, чтобы он правильно считал определитель?
function determinant(m) {
function det2by2(m) {
return m[0][0] * m[1][1] - m[0][1] * m[1][0];
}
function detNbyN(m) {
const firstRow = m[0];
if (firstRow.length === 2) return det2by2(m);
let sum = 0;
for (let i = 0; i < m.length; i++) {
sum += firstRow[i] * (-1) ** 2 + i * detNbyN(minor(m, i)); // *
}
return sum;
}
function minor(m, num) {
const m1 = JSON.parse(JSON.stringify(m));
m1.splice(0, 1);
for (let elem of m1) {
elem.forEach((el, i) => {
if (i === num) elem.splice(i, 1);
});
}
return m1;
}
if (m.length === 1) return m[0][0];
if (m.length === 2) return det2by2(m);
if (m.length >= 3) return detNbyN(m);
};
console.log(determinant(
[
[2, 4, 2, 2],
[3, 1, 1, 2],
[1, 2, 0, 2],
[3, 4, 5, 6]
]
)); // **
Ответы (2 шт):
- Не уверен, что в JavaScript оператор
**выполняет возведение в степень. Воспользуемся функциейMath.pow. - Формула расчёта элемента суммы у вас записана неправильно. При разложении матрицы по строке знаки должны чередоваться, начиная с плюса. То есть множитель перед элементом строки и минором должен быть равен
(-1)^(i), гдеi=0, 1, 2....
function detNbyN(m) {
const firstRow = m[0];
if (firstRow.length === 2) return det2by2(m);
let sum = 0;
for (let i = 0; i < m.length; i++) {
sum += firstRow[i] * Math.pow(-1, i) * detNbyN(minor(m, i)); // *
}
return sum;
}
Если ещё есть какие-то проблемы, связанные с языком, то тут я уже не помощник. Функцию minor проверить не могу, в ней используются особые функции JS.
Может вы хотели написать
sum += firstRow[i] * ((-1) ** (2 + i)) * detNbyN(minor(m, i));
хотя вообще лучше написать как в учебнике:
sum += Math.pow(-1, i) * firstRow[i] * detNbyN(minor(m, i));
— однозначно, понятно и не нужно мучаться расстановкой скобочек.