function Train() {
let vecError = new Array(Dimensions);
let embVertices = EmbTables[0].slice();
let embContexts = EmbTables[1].slice();
let lastRhoUpdate = 0;
let rho = InitRho;
for (let i = 0; i < SampleCount + 2; i++) {
if (i - lastRhoUpdate > 10000) {
rho = InitRho * (1 - (i / (SampleCount + 1)));
if (rho < InitRho * 0.0001) rho = InitRho * 0.0001;
lastRhoUpdate = i;
}
const edge = SampleEdge();
const u = Vertices.get(InputData[edge][0])[1];
const v = Vertices.get(InputData[edge][1])[1];
const lu = u * Dimensions;
vecError.fill(0);
let target = v, label = 1;
for (let j = 0; j < NegSampleCount; j++) {
if (j > 0) {
target = NegTable[Math.floor(NegTable.length * Math.random())];
label = 0;
}
const lv = target * Dimensions;
let embVector = embVertices.slice(lu, lu + Dimensions);
let embContext = embContexts.slice(lv, lv + Dimensions);
Update(embVector, embContext, label, vecError, rho);
for (let k = 0; k < Dimensions; k++) embContexts[lv + k] = embContext[k];
}
for (let j = 0; j < Dimensions; j++) embVertices[lu + j] += vecError[j];
}
return embVertices;
}