/**
 * CPM (Constant Potts Model) quality functions.
 * Vendored from ngraph.leiden (MIT) — no external dependencies.
 */
// Typed array safe-access helper (see adapter.ts for rationale)
function fget(a, i) {
    return a[i];
}
function iget(a, i) {
    return a[i];
}
export function diffCPM(part, g, v, c, gamma = 1.0) {
    const oldC = iget(part.nodeCommunity, v);
    if (c === oldC)
        return 0;
    let w_old;
    let w_new;
    let selfCorrection = 0;
    if (g.directed) {
        w_old =
            (part.getOutEdgeWeightToCommunity(oldC) || 0) +
                (part.getInEdgeWeightFromCommunity(oldC) || 0);
        w_new =
            c < g.n
                ? (part.getOutEdgeWeightToCommunity(c) || 0) + (part.getInEdgeWeightFromCommunity(c) || 0)
                : 0;
        // Self-loop weight appears in both out and in arrays for oldC,
        // making w_old include 2x selfLoop. Correct to match moveNodeToCommunity.
        selfCorrection = 2 * (fget(g.selfLoop, v) || 0);
    }
    else {
        w_old = part.getNeighborEdgeWeightToCommunity(oldC) || 0;
        w_new = c < g.n ? part.getNeighborEdgeWeightToCommunity(c) || 0 : 0;
    }
    const s_v = fget(g.size, v) || 1;
    const S_old = fget(part.communityTotalSize, oldC) || 0;
    const S_new = c < part.communityTotalSize.length ? fget(part.communityTotalSize, c) : 0;
    return w_new - w_old + selfCorrection - gamma * s_v * (S_new - S_old + s_v);
}
export function qualityCPM(part, _g, gamma = 1.0) {
    let sum = 0;
    for (let c = 0; c < part.communityCount; c++) {
        const S = fget(part.communityTotalSize, c) || 0;
        sum += fget(part.communityInternalEdgeWeight, c) - (gamma * (S * (S - 1))) / 2;
    }
    return sum;
}
//# sourceMappingURL=cpm.js.map