UNPKG

arela

Version:

AI-powered CTO with multi-agent orchestration, code summarization, visual testing (web + mobile) for blazing fast development.

116 lines 3.55 kB
/** * Modularity calculations for slice cohesion */ /** * Calculate cohesion score for a community (0-100) * Cohesion = internal edges / (internal edges + external edges) * 100 */ export function calculateCohesion(community, graph) { const internal = countInternalEdges(community, graph); const external = countExternalEdges(community, graph); const total = internal + external; if (total === 0) { return 100; // Isolated community } return (internal / total) * 100; } /** * Calculate overall modularity of the clustering */ export function calculateModularityScore(communities, graph) { const m = graph.edges.length; if (m === 0) return 0; let Q = 0; for (const community of communities) { if (community.nodes.length === 0) continue; const eIn = countInternalEdges(community, graph); const degree = getTotalDegree(community, graph); Q += eIn / m - Math.pow(degree / (2 * m), 2); } return Q; } /** * Count edges within a community */ function countInternalEdges(community, graph) { const nodeSet = new Set(community.nodes); let count = 0; for (const edge of graph.edges) { if (nodeSet.has(edge.from) && nodeSet.has(edge.to)) { count += edge.weight; } } return count; } /** * Count edges going out of a community */ function countExternalEdges(community, graph) { const nodeSet = new Set(community.nodes); let count = 0; for (const edge of graph.edges) { const fromIn = nodeSet.has(edge.from); const toIn = nodeSet.has(edge.to); if ((fromIn && !toIn) || (!fromIn && toIn)) { count += edge.weight; } } return count; } /** * Get total degree of nodes in a community */ function getTotalDegree(community, graph) { let totalDegree = 0; for (const nodeId of community.nodes) { const node = graph.nodes.find((n) => n.id === nodeId); if (node) { totalDegree += node.degree; } } return totalDegree; } /** * Calculate coupling between two communities */ export function calculateCoupling(comm1, comm2, graph) { const set1 = new Set(comm1.nodes); const set2 = new Set(comm2.nodes); let edges = 0; for (const edge of graph.edges) { if ((set1.has(edge.from) && set2.has(edge.to)) || (set1.has(edge.to) && set2.has(edge.from))) { edges += edge.weight; } } return edges; } /** * Calculate average cohesion across all communities */ export function calculateAverageCohesion(communities, graph) { if (communities.length === 0) return 0; const totalCohesion = communities.reduce((sum, comm) => sum + calculateCohesion(comm, graph), 0); return totalCohesion / communities.length; } /** * Get statistics about communities */ export function getCommunitiesStats(communities, graph) { const sizes = communities.map((c) => c.nodes.length); const cohesions = communities.map((c) => calculateCohesion(c, graph)); return { count: communities.length, avgSize: sizes.reduce((a, b) => a + b, 0) / communities.length, minSize: Math.min(...sizes), maxSize: Math.max(...sizes), avgCohesion: cohesions.reduce((a, b) => a + b, 0) / communities.length, minCohesion: Math.min(...cohesions), maxCohesion: Math.max(...cohesions), modularity: calculateModularityScore(communities, graph), }; } //# sourceMappingURL=modularity.js.map