bigly-caret/rank.js

137 lines
No EOL
3.9 KiB
JavaScript

import { GPU, input, Input } from "gpu.js";
// derived from https://git.dervland.net/biglyderv/new-bigly-chat/src/branch/master/docs/stats.php
function rankCalc(result, iterations = 10, main = [], domain_mode = false) {
let fng = {};
let fnc = {};
let frs = {};
let msum_old = 0.001;
let pr = {};
let rl = Object.keys(result).length;
let matrixe = new Float32Array(rl ** 2);
for (let i = 0; i < rl ** 2; i += (rl + 1)) {
matrixe[i] = 1;
}
let keys = Object.keys(result);
for (let unn in result) {
let v = true;
if (domain_mode) {
v = false;
try {
let test = new URL(unn);
v = true;
} catch (err) {
v = false;
}
}
if (!v) {
continue;
}
frs[unn] = result[unn].followers || [];
fng[unn] = result[unn].following || [];
let lf = Object.keys(fng[unn]).length;
if (domain_mode) {
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;
for (let follow of fnu) {
if (follow == unn) continue;
let dst = fnc[fnu] || 0;
let n = (keys.indexOf(unn) || 0) * (rl) + (keys.indexOf(follow) || 0) * 1;
matrixe[n] = 1 + 5 / (dst + 3);
msum_old += matrixe[n];
}
}
let mm = (process.env.matrixIterations || iterations);
let gpu = new GPU();
const multiplyMatrix = gpu.createKernel(function (a, b, c) {
let sum = 0;
for (let i = 0; i < c; i++) {
sum += a[this.thread.x / c][i] * b[i][this.thread.x % c];
}
return sum;
}).setOutput([keys.length ** 2,1]);
for (let i = 0; i < mm; i++) {
let prold = pr;
pr = [];
let msum = 1;
let intv = Math.pow(0.01 / rl, Math.pow(0.09, i / mm));
console.log(`Completed ${i} iterations with ${intv} threshold`)
matrixe = multiplyMatrix(matrixe, matrixe, keys.length)[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 * rl + unb * 1];
}
}
let ov = Object.keys(pr);
let new_sum = ov.filter(i => !isNaN(pr[i]) && main.indexOf(i) != -1).map(n => pr[n]).reduce((a, b) => a + b, 1e-9);
let new_sum2 = ov.filter(i => !isNaN(pr[i]) && main.indexOf(i) == -1 && (domain_mode && new URL(i).host == new URL(main[0]).host)).map(n => pr[n]).reduce((a, b) => a + b, 1e-9);
let new_sum3 = ov.filter(i => !isNaN(pr[i]) && main.indexOf(i) == -1 && !(domain_mode && new URL(i).host == new URL(main[0]).host)).map(n => pr[n]).reduce((a, b) => a + b, 1e-9);
for (let unn of ov) {
if (!result[unn]) {
pr[unn] = 0;
} else if ((domain_mode && new URL(unn).host == new URL(main[0]).host) && main.indexOf(unn) == -1) {
pr[unn] /= new_sum2 * 3;
} else if (main.indexOf(unn) == -1) {
pr[unn] /= new_sum3 * (domain_mode ? 3 : 2);
} else {
pr[unn] /= new_sum * (domain_mode ? 3 : 2);
}
}
}
return pr;
}
export {
rankCalc
}