2025-02-01 08:40:06 -05:00
|
|
|
import { GPU, input, Input } from "gpu.js";
|
2025-01-29 19:06:26 -05:00
|
|
|
|
2025-01-29 18:54:30 -05:00
|
|
|
// derived from https://git.dervland.net/biglyderv/new-bigly-chat/src/branch/master/docs/stats.php
|
2025-02-03 06:42:01 -05:00
|
|
|
function rankCalc(result, iterations = 10, main = [], domainMode = false, isGpu = false) {
|
2025-02-01 08:40:06 -05:00
|
|
|
|
2025-01-29 18:54:30 -05:00
|
|
|
let fng = {};
|
2025-01-29 19:06:26 -05:00
|
|
|
let fnc = {};
|
2025-01-29 18:54:30 -05:00
|
|
|
let frs = {};
|
2025-01-30 08:20:17 -05:00
|
|
|
let msum_old = 0.001;
|
2025-01-29 18:54:30 -05:00
|
|
|
let pr = {};
|
2025-01-29 19:06:26 -05:00
|
|
|
|
2025-01-31 16:23:20 -05:00
|
|
|
let rl = Object.keys(result).length;
|
2025-02-01 08:40:06 -05:00
|
|
|
let matrixe = new Float32Array(rl ** 2);
|
|
|
|
|
|
|
|
for (let i = 0; i < rl ** 2; i += (rl + 1)) {
|
|
|
|
matrixe[i] = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
let keys = Object.keys(result);
|
2025-01-29 18:54:30 -05:00
|
|
|
for (let unn in result) {
|
2025-02-01 05:24:21 -05:00
|
|
|
let v = true;
|
2025-02-02 21:48:24 -05:00
|
|
|
if (domainMode) {
|
2025-02-01 02:40:16 -05:00
|
|
|
v = false;
|
|
|
|
try {
|
|
|
|
let test = new URL(unn);
|
|
|
|
v = true;
|
|
|
|
} catch (err) {
|
|
|
|
v = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!v) {
|
|
|
|
continue;
|
|
|
|
}
|
2025-01-31 23:29:01 -05:00
|
|
|
|
2025-02-01 08:40:06 -05:00
|
|
|
frs[unn] = result[unn].followers || [];
|
2025-02-01 05:34:26 -05:00
|
|
|
fng[unn] = result[unn].following || [];
|
2025-02-01 02:23:59 -05:00
|
|
|
|
2025-01-31 23:42:51 -05:00
|
|
|
let lf = Object.keys(fng[unn]).length;
|
2025-02-02 21:48:24 -05:00
|
|
|
if (domainMode) {
|
2025-01-31 23:42:51 -05:00
|
|
|
let domains = [];
|
|
|
|
for (let x of fng[unn]) {
|
|
|
|
try {
|
|
|
|
let a = new URL(x);
|
|
|
|
domains.push(a.host);
|
2025-02-01 02:23:59 -05:00
|
|
|
} catch (err) {
|
|
|
|
|
2025-01-31 23:42:51 -05:00
|
|
|
}
|
2025-01-31 23:29:01 -05:00
|
|
|
}
|
2025-01-31 23:42:51 -05:00
|
|
|
domains = [...new Set(domains)];
|
2025-02-01 02:23:59 -05:00
|
|
|
|
2025-02-01 13:52:31 -05:00
|
|
|
|
2025-02-01 02:23:59 -05:00
|
|
|
fnc[unn] = lf / (1 + domains.length);
|
2025-01-31 23:42:51 -05:00
|
|
|
} else {
|
|
|
|
fnc[unn] = lf;
|
2025-01-31 23:29:01 -05:00
|
|
|
}
|
2025-01-31 23:41:28 -05:00
|
|
|
|
2025-01-31 16:23:20 -05:00
|
|
|
pr[unn] = 0.1 / rl;
|
2025-01-29 18:54:30 -05:00
|
|
|
}
|
|
|
|
|
2025-02-01 02:40:16 -05:00
|
|
|
|
|
|
|
|
2025-01-29 19:06:26 -05:00
|
|
|
for (let unn in result) {
|
2025-01-29 18:54:30 -05:00
|
|
|
let fnu = frs[unn];
|
2025-02-01 08:40:06 -05:00
|
|
|
if (!pr[unn]) pr[unn] = 0;
|
2025-01-29 18:54:30 -05:00
|
|
|
for (let follow of fnu) {
|
|
|
|
if (follow == unn) continue;
|
|
|
|
let dst = fnc[fnu] || 0;
|
2025-02-01 08:40:06 -05:00
|
|
|
let n = (keys.indexOf(unn) || 0) * (rl) + (keys.indexOf(follow) || 0) * 1;
|
2025-02-01 09:07:57 -05:00
|
|
|
matrixe[n] = 1.1 + 1 / (dst + 3);
|
2025-02-01 08:40:06 -05:00
|
|
|
msum_old += matrixe[n];
|
2025-01-29 18:54:30 -05:00
|
|
|
}
|
2025-02-01 13:52:31 -05:00
|
|
|
|
|
|
|
let fail = 1;
|
|
|
|
try {
|
|
|
|
let h = new URL(unn);
|
|
|
|
if (!(h.pathname == '/' || h.pathname == '')) fail *= 0.5;
|
|
|
|
if (!(h.search == '')) fail *= 0.4;
|
2025-02-02 21:48:24 -05:00
|
|
|
if (main.indexOf(unn) != -1) fail = 10;
|
2025-02-01 13:52:31 -05:00
|
|
|
} catch (err) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fail != 1) {
|
|
|
|
for (let ig = (keys.indexOf(unn) || 0) * (rl); ig < ((keys.indexOf(unn) || 0) + 1) * (rl); ig++) {
|
|
|
|
matrixe[ig] *= fail;
|
2025-02-01 10:24:19 -05:00
|
|
|
}
|
2025-02-01 10:17:59 -05:00
|
|
|
}
|
2025-01-29 18:54:30 -05:00
|
|
|
}
|
|
|
|
|
2025-02-01 10:17:59 -05:00
|
|
|
let mm = (iterations);
|
2025-01-29 19:06:26 -05:00
|
|
|
|
2025-02-01 08:40:06 -05:00
|
|
|
let gpu = new GPU();
|
2025-02-02 21:48:24 -05:00
|
|
|
let multiplyMatrix;
|
|
|
|
|
|
|
|
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([keys.length ** 2, 1]);
|
|
|
|
} else {
|
|
|
|
console.warn(`GPU mode not enabled. Using CPU multiplication...`)
|
|
|
|
multiplyMatrix = function (a, b, c) {
|
|
|
|
let outMatrix = new Float32Array(keys.length ** 2);
|
|
|
|
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];
|
2025-02-01 08:40:06 -05:00
|
|
|
}
|
2025-02-02 21:48:24 -05:00
|
|
|
}
|
2025-01-30 20:17:43 -05:00
|
|
|
|
2025-01-30 09:56:42 -05:00
|
|
|
for (let i = 0; i < mm; i++) {
|
2025-01-30 07:59:30 -05:00
|
|
|
let prold = pr;
|
|
|
|
|
2025-02-01 11:43:39 -05:00
|
|
|
pr = {};
|
2025-02-01 08:40:06 -05:00
|
|
|
|
2025-02-01 08:52:47 -05:00
|
|
|
let msum = 0;
|
|
|
|
console.log(`Completed ${i} iterations`)
|
2025-02-01 08:40:06 -05:00
|
|
|
matrixe = multiplyMatrix(matrixe, matrixe, keys.length)[0];
|
2025-01-29 18:54:30 -05:00
|
|
|
|
2025-02-01 08:40:06 -05:00
|
|
|
for (let h in matrixe) {
|
|
|
|
msum += matrixe[h];
|
|
|
|
}
|
|
|
|
for (let h in matrixe) {
|
|
|
|
matrixe[h] /= msum / rl;
|
2025-01-29 18:54:30 -05:00
|
|
|
}
|
|
|
|
|
2025-02-01 08:40:06 -05:00
|
|
|
for (let una in keys) {
|
|
|
|
let una2 = keys[una];
|
|
|
|
pr[una2] = 0.1 / rl;
|
|
|
|
if ((frs[una2]).length == 0) continue;
|
2025-01-29 18:54:30 -05:00
|
|
|
|
2025-02-01 08:40:06 -05:00
|
|
|
for (let unb in keys) {
|
|
|
|
if (isNaN(prold[una2])) continue;
|
2025-02-01 09:07:57 -05:00
|
|
|
pr[una2] += prold[una2] * matrixe[una * 1 + unb * rl];
|
2025-01-29 18:54:30 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-01-31 17:54:32 -05:00
|
|
|
let ov = Object.keys(pr);
|
2025-01-31 20:55:49 -05:00
|
|
|
let new_sum = ov.filter(i => !isNaN(pr[i]) && main.indexOf(i) != -1).map(n => pr[n]).reduce((a, b) => a + b, 1e-9);
|
2025-02-01 08:52:47 -05:00
|
|
|
let new_sum2 = ov.filter(i => !isNaN(pr[i]) && main.indexOf(i) == -1).map(n => pr[n]).reduce((a, b) => a + b, 1e-9);
|
2025-02-01 13:52:31 -05:00
|
|
|
|
2025-02-01 02:40:16 -05:00
|
|
|
for (let unn of ov) {
|
|
|
|
if (!result[unn]) {
|
|
|
|
pr[unn] = 0;
|
2025-02-01 02:23:59 -05:00
|
|
|
} else if (main.indexOf(unn) == -1) {
|
2025-02-01 08:52:47 -05:00
|
|
|
pr[unn] /= new_sum2 * 2;
|
2025-01-31 17:54:32 -05:00
|
|
|
} else {
|
2025-02-01 08:52:47 -05:00
|
|
|
pr[unn] /= new_sum * 2;
|
2025-01-31 17:54:32 -05:00
|
|
|
}
|
2025-01-29 18:54:30 -05:00
|
|
|
}
|
2025-01-30 11:30:18 -05:00
|
|
|
|
2025-01-29 18:54:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return pr;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2025-01-30 07:59:30 -05:00
|
|
|
export {
|
|
|
|
rankCalc
|
|
|
|
}
|