DAS_2024_1/bondarenko_max_lab_6/matrix.operations.js

61 lines
2.0 KiB
JavaScript

const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');
function getMinor(matrix, row, col) {
return matrix
.filter((_, i) => i !== row)
.map(row => row.filter((_, j) => j !== col));
}
function determinant(matrix) {
const n = matrix.length;
if (n === 1) return matrix[0][0];
if (n === 2) return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0];
let det = 0;
for (let j = 0; j < n; j++) {
det += matrix[0][j] * determinant(getMinor(matrix, 0, j)) * (j % 2 === 0 ? 1 : -1);
}
return det;
}
function determinantParallel(matrix, numThreads) {
return new Promise((resolve, reject) => {
const n = matrix.length;
if (n === 1) return resolve(matrix[0][0]);
if (n === 2) return resolve(matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]);
let det = 0;
let completed = 0;
const jobs = [];
for (let j = 0; j < n; j++) {
const sign = j % 2 === 0 ? 1 : -1;
const minor = getMinor(matrix, 0, j);
jobs.push({ minor, sign, value: matrix[0][j] });
}
const chunkSize = Math.ceil(jobs.length / numThreads);
const results = Array(numThreads).fill(0);
for (let i = 0; i < numThreads; i++) {
const chunk = jobs.slice(i * chunkSize, (i + 1) * chunkSize);
const worker = new Worker('./det.worker.js', { workerData: chunk });
worker.on('message', (partialDet) => {
results[i] = partialDet;
completed++;
if (completed === numThreads) {
resolve(results.reduce((acc, val) => acc + val, 0));
}
});
worker.on('error', reject);
worker.on('exit', (code) => {
if (code !== 0) reject(new Error(`Worker stopped with exit code ${code}`));
});
}
});
}
module.exports = { determinant, determinantParallel };