61 lines
2.0 KiB
JavaScript
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 };
|