import { GPU, input, Input } from "gpu.js"; var rls; function multiplyMatrix(a, b, c) { let outMatrix = new Float32Array(rls); for (let i in outMatrix) { let sum = 0; for (let j = 0; j < c; j++) { sum += a[(i % c) * c + j] * b[j * c + Math.floor(i / c)]; } outMatrix[i] = sum; } return [outMatrix]; } // derived from https://git.dervland.net/biglyderv/new-bigly-chat/src/branch/master/docs/stats.php function rankCalc(result, iterations = 10, main = [], domainMode = false, isGpu = false, arrayMax = 800, oldVals = false) { let fng = {}; let fnc = {}; let frs = {}; let msum_old = 0.001; let pr = {}; let keys = Object.keys(result); let leftover = []; if (oldVals) { keys = keys.sort((a, b) => oldVals[b] - oldVals[a]); } else { keys = keys.sort((a, b) => result[b].followers.length - result[a].followers.length); } let kl2 = keys.length; if (kl2 > arrayMax) { console.warn(`Array too big. Splitting into multiple arrays...`); let ll = {}; let hh = keys.slice(arrayMax); for (let g of hh) { ll[g] = result[g]; } leftover = rankCalc(ll, iterations, main, domainMode, isGpu, arrayMax); for (let i in leftover) { leftover[i] /= (kl2 / arrayMax); } } keys.length = Math.min(keys.length, 1000); let rl = keys.length; rls = rl ** 2; let matrixe = new Float32Array(rls); for (let i = 0; i < rls; i += (rl + 1)) { matrixe[i] = 1; } for (let unn in result) { let v = !domainMode; try { new URL(unn); v = true; } catch (err) { } if (!v) { continue; } frs[unn] = result[unn].followers || []; fng[unn] = result[unn].following || []; let lf = fng[unn].length; if (domainMode) { let domains = []; for (let x of fng[unn]) { try { let a = new URL(x); domains.push(a.host); } catch (err) { } } domains = [...new Set(domains)]; fnc[unn] = lf / (1 + domains.length); } else { fnc[unn] = lf; } pr[unn] = 0.1 / rl; } for (let unn in result) { let fnu = frs[unn]; if (!pr[unn]) pr[unn] = 0; let nb = keys.indexOf(unn); for (let follow of fnu) { if (follow == unn) continue; let dst = fnc[fnu] || 0; let na = keys.indexOf(follow); if (na == -1 || nb == -1) continue; let n = na * rl + (nb) * 1; matrixe[n] = 1.1 + 1 / (dst + 3); msum_old += matrixe[n]; } let fail = 1; if (domainMode) { try { let h = new URL(unn); if (!(h.pathname == '/' || h.pathname == '')) fail *= 0.5; if (!(h.search == '')) fail *= 0.4; if (main.indexOf(unn) != -1) fail = 10; } catch (err) { } } if (fail != 1) { for (let ig = nb * rl; ig < (nb + 1) * rl; ig++) { matrixe[ig] *= fail; } } } let mm = (iterations); let gpu = new GPU(); if (isGpu) { multiplyMatrix = gpu.createKernel(function (a, b, c) { let sum = 0; for (let i = 0; i < c; i++) { sum += a[(this.thread.x % c) * c + i] * b[i * c + this.thread.x / c]; } return sum; }).setOutput([rls, 1]); } else { console.warn(`GPU mode not enabled. Using CPU multiplication...`) } for (let i = 0; i < mm; i++) { let prold = pr; pr = {}; let msum = 0; console.log(`Completed ${i} iterations`) matrixe = multiplyMatrix(matrixe, matrixe, rl)[0]; for (let h in matrixe) { msum += matrixe[h]; } for (let h in matrixe) { matrixe[h] /= msum / rl; } for (let una in keys) { let una2 = keys[una]; pr[una2] = 0.1 / rl; if ((frs[una2]).length == 0) continue; for (let unb in keys) { if (isNaN(prold[una2])) continue; pr[una2] += prold[una2] * matrixe[una * 1 + unb * rl]; } } pr = Object.assign(pr, leftover); let ov = Object.keys(pr); let an = ov.filter(i => !isNaN(pr[i]) && main.indexOf(i) != -1); let new_sum = an.map(n => pr[n]).reduce((a, b) => a + b, 1e-9); let new_sum2 = ov.filter(i => !isNaN(pr[i]) && main.indexOf(i) == -1).map(n => pr[n]).reduce((a, b) => a + b, 1e-9); if (an.length == 0) { new_sum2 /= 2; } for (let unn of ov) { if (!result[unn]) { pr[unn] = 0; } else if (main.indexOf(unn) == -1) { pr[unn] /= new_sum2 * 2; } else { pr[unn] /= new_sum * 2; } } } return pr; } export { rankCalc }