/** * mathWorker.js * Optimized background math worker for processing high-dimensional activation matrices using 1D Float32Arrays. */ self.onmessage = function (event) { const { task, payload, transactionId } = event.data; try { switch (task) { case 'resampleMatrixZ': { const { sourceData, sourceZ, sourceX, targetZ, targetX } = payload; const resultBuffer = executeResampleZ(sourceData, sourceZ, sourceX, targetZ, targetX); self.postMessage( { transactionId, status: 'success', data: resultBuffer }, [resultBuffer.buffer] ); break; } case 'computeDeltaAndSimilarity': { const { matrixA, matrixB, length } = payload; const result = executeDeltaAndSimilarity(matrixA, matrixB, length); self.postMessage( { transactionId, status: 'success', data: result.delta, similarity: result.similarity }, [result.delta.buffer] ); break; } case 'sortDimensionsByVariance': { const { data, rows, cols } = payload; const result = executeVarianceSort(data, rows, cols); self.postMessage( { transactionId, status: 'success', sortedIndices: result.indices, variances: result.variances }, [result.indices.buffer, result.variances.buffer] ); break; } default: throw new Error(`Unsupported task type: ${task}`); } } catch (error) { self.postMessage({ transactionId, status: 'error', error: error.message }); } }; function sinc(x) { if (x === 0) return 1.0; const piX = Math.PI * x; return Math.sin(piX) / piX; } function executeResampleZ(sourceData, sourceZ, sourceX, targetZ, targetX) { const output = new Float32Array(targetZ * targetX); const ratioZ = sourceZ / targetZ; const ratioX = sourceX / targetX; for (let tz = 0; tz < targetZ; tz++) { const srcFloatZ = tz * ratioZ; const minZ = Math.max(0, Math.floor(srcFloatZ) - 3); const maxZ = Math.min(sourceZ - 1, Math.floor(srcFloatZ) + 3); for (let tx = 0; tx < targetX; tx++) { const srcFloatX = tx * ratioX; const minX = Math.max(0, Math.floor(srcFloatX) - 3); const maxX = Math.min(sourceX - 1, Math.floor(srcFloatX) + 3); let accumulator = 0.0; let normalization = 0.0; for (let sz = minZ; sz <= maxZ; sz++) { const weightZ = sinc(srcFloatZ - sz); for (let sx = minX; sx <= maxX; sx++) { const weightX = sinc(srcFloatX - sx); const weight = weightZ * weightX; accumulator += sourceData[sz * sourceX + sx] * weight; normalization += weight; } } output[tz * targetX + tx] = normalization === 0 ? 0.0 : accumulator / normalization; } } return output; } function executeDeltaAndSimilarity(matrixA, matrixB, length) { const delta = new Float32Array(length); let dotProduct = 0.0; let normA = 0.0; let normB = 0.0; for (let i = 0; i < length; i++) { const valA = matrixA[i]; const valB = matrixB[i]; delta[i] = valA - valB; dotProduct += valA * valB; normA += valA * valA; normB += valB * valB; } const similarity = normA === 0 || normB === 0 ? 0.0 : dotProduct / (Math.sqrt(normA) * Math.sqrt(normB)); return { delta, similarity }; } function executeVarianceSort(data, rows, cols) { const variances = new Float32Array(cols); const indices = new Int32Array(cols); for (let c = 0; c < cols; c++) { indices[c] = c; let sum = 0.0; let sumSq = 0.0; for (let r = 0; r < rows; r++) { const val = data[r * cols + c]; sum += val; sumSq += val * val; } const mean = sum / rows; variances[c] = (sumSq / rows) - (mean * mean); } const indexArray = Array.from(indices); indexArray.sort((a, b) => variances[b] - variances[a]); const sortedIndices = new Int32Array(indexArray); return { indices: sortedIndices, variances }; }