Как на 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".
Возможно, кто-то подскажет что-то еще?

21 Авг 2019 в 06:15
529 +1
0
Ответы
1

Для ускорения вычислений угла между векторами в данном случае, можно попробовать использовать типизацию и типизированные массивы в 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 для ускорения обработки большого количества векторов одновременно.

Надеюсь, эти предложения помогут оптимизировать вычисления угла между векторами в вашем приложении.

20 Апр в 13:21
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Название заказа не должно быть пустым
Введите email
Бесплатные доработки
Гарантированные бесплатные доработки
Быстрое выполнение
Быстрое выполнение от 2 часов
Проверка работы
Проверка работы на плагиат
Интересные статьи из справочника
Поможем написать учебную работу
Название заказа не должно быть пустым
Введите email
Доверьте свою работу экспертам
Разместите заказ
Наша система отправит ваш заказ на оценку 83 852 авторам
Первые отклики появятся уже в течение 10 минут
Прямой эфир