Как на JS быстро найти угол между векторами? (22-мерные вектора, поиск по условию минимального/максимального угла из 5 000 записей)? Собственно, в заголовке весь вопрос. Есть клиентское приложение на JS, внутри него необходимо (в рамках рекомендательного алгоритма) из приблизительно 5к записей выбрать определенные, наиболее подходящие по критерию. Оптимизации выборки уже есть, хотелось бы оптимизировать. Сейчас расчитываю по стандартной формуле cos α = a·b / |a|·|b|. Код выглядит примерно так:function getScaledAngleForVectors(vec1, vec2) { //cos α = a·b / |a|·|b| var length = Math.max(vec1.length, vec2.length); var scalarMulti = 0; for (var i = 0; i < length; i++) scalarMulti += vec1[i] * vec2[i] || 0; var cosAlpha = scalarMulti / (getLength(vec1) * getLength(vec2)); var alpha = Math.acos(cosAlpha); return 1 - cosAlpha; } function getLength(vec) { var n = vec.length; var length = 0; for (var i = 0; i < n; i++) length += Math.pow(vec[i] || 0, 2); return Math.pow(length, .5); } Перспективные направления - использование целочисленных значений и работа с Uint16Array, либо приведение векторов к единичным - в таком случае шаг "cos α = a·b / |a|·|b|" можно свести до "cos α = a·b". Возможно, кто-то подскажет что-то еще?
Для ускорения вычислений угла между векторами в данном случае, можно попробовать использовать типизацию и типизированные массивы в JavaScript. Например, можно использовать TypedArray для хранения значений векторов и выполнения операций над ними.
Вот пример оптимизированной версии функции для вычисления угла между векторами с использованием Uint16Array:
function getScaledAngleForVectors(vec1, vec2) { var length = Math.min(vec1.length, vec2.length); var scalarMulti = 0; var vec1Typed = new Uint16Array(vec1); var vec2Typed = new Uint16Array(vec2); for (var i = 0; i < length; i++) { scalarMulti += vec1Typed[i] * vec2Typed[i]; } var cosAlpha = scalarMulti / (getLength(vec1Typed) * getLength(vec2Typed)); var alpha = Math.acos(cosAlpha); return 1 - cosAlpha; } function getLength(vec) { var n = vec.length; var length = 0; for (var i = 0; i < n; i++) { length += vec[i] ** 2; } return Math.sqrt(length); }
Также можно попробовать параллельные вычисления с помощью Web Workers для ускорения обработки большого количества векторов одновременно.
Надеюсь, эти предложения помогут оптимизировать вычисления угла между векторами в вашем приложении.
Для ускорения вычислений угла между векторами в данном случае, можно попробовать использовать типизацию и типизированные массивы в JavaScript. Например, можно использовать TypedArray для хранения значений векторов и выполнения операций над ними.
Вот пример оптимизированной версии функции для вычисления угла между векторами с использованием Uint16Array:
function getScaledAngleForVectors(vec1, vec2) {var length = Math.min(vec1.length, vec2.length);
var scalarMulti = 0;
var vec1Typed = new Uint16Array(vec1);
var vec2Typed = new Uint16Array(vec2);
for (var i = 0; i < length; i++) {
scalarMulti += vec1Typed[i] * vec2Typed[i];
}
var cosAlpha = scalarMulti / (getLength(vec1Typed) * getLength(vec2Typed));
var alpha = Math.acos(cosAlpha);
return 1 - cosAlpha;
}
function getLength(vec) {
var n = vec.length;
var length = 0;
for (var i = 0; i < n; i++) {
length += vec[i] ** 2;
}
return Math.sqrt(length);
}
Также можно попробовать параллельные вычисления с помощью Web Workers для ускорения обработки большого количества векторов одновременно.
Надеюсь, эти предложения помогут оптимизировать вычисления угла между векторами в вашем приложении.