UNPKG

clustering-tfjs

Version:

High-performance TypeScript clustering algorithms (K-Means, Spectral, Agglomerative) with TensorFlow.js acceleration and scikit-learn compatibility

66 lines (65 loc) 2.65 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.detectConnectedComponents = detectConnectedComponents; exports.checkGraphConnectivity = checkGraphConnectivity; /** * Detects the number of connected components in a graph based on its affinity matrix. * * A graph is considered fully connected if there's only 1 component. * Multiple components are detected by counting near-zero eigenvalues of the Laplacian. * * @param affinity - Affinity/adjacency matrix (n x n) * @param tolerance - Tolerance for detecting zero eigenvalues (default: 1e-2) * @returns Object containing: * - numComponents: Number of connected components * - isFullyConnected: Whether the graph has only 1 component * - componentLabels: Array indicating which component each node belongs to */ function detectConnectedComponents(affinity, tolerance = 1e-2) { const n = affinity.shape[0]; const componentLabels = new Int32Array(n).fill(-1); // Get affinity data for graph traversal const affinityData = affinity.arraySync(); // BFS to find connected components let currentComponent = 0; for (let startNode = 0; startNode < n; startNode++) { if (componentLabels[startNode] !== -1) continue; // Already assigned // BFS from this node const queue = [startNode]; componentLabels[startNode] = currentComponent; while (queue.length > 0) { const node = queue.shift(); // Check all neighbors for (let neighbor = 0; neighbor < n; neighbor++) { if (neighbor !== node && componentLabels[neighbor] === -1 && affinityData[node][neighbor] > tolerance) { componentLabels[neighbor] = currentComponent; queue.push(neighbor); } } } currentComponent++; } const numComponents = currentComponent; return { numComponents, isFullyConnected: numComponents === 1, componentLabels, }; } /** * Issues a warning if the graph is not fully connected, similar to sklearn. * * @param affinity - Affinity matrix to check * @param tolerance - Tolerance for detecting zero eigenvalues * @returns true if graph is fully connected, false otherwise */ function checkGraphConnectivity(affinity, tolerance = 1e-2) { const { isFullyConnected } = detectConnectedComponents(affinity, tolerance); if (!isFullyConnected) { console.warn('Graph is not fully connected, spectral embedding may not work as expected.'); } return isFullyConnected; }