Как нормализовать вектор в MATLAB эффективно? Какая-либо связанная встроенная функция? [закрытый]

Свифт:

shareButton.titleLabel?.font = UIFont.systemFontOfSize(size)

Неважное примечание: удалено animuson ♦ 5 декабря '14 в 16:48
animuson, у меня была такая же проблема сейчас, через месяц после публикации этого ответа , Я гуглил и обнаружил этот пост, который нелегко скопировать в быстрый проект. Пока я прокручивал, увидел мой удаленный ответ и скопировал его. поэтому, пожалуйста, не удаляйте действительно полезные вещи ..

47
задан Kamran Bigdely 30 June 2009 в 00:53
поделиться

2 ответа

Исходный код, который вы предлагаете, - лучший способ.

Matlab чрезвычайно хорош в векторизованных операциях, подобных этой, по крайней мере, для больших векторов.

Встроенная функция нормы - это очень быстро. Вот некоторые результаты синхронизации:

V = rand(10000000,1);
% Run once
tic; V1=V/norm(V); toc           % result:  0.228273s
tic; V2=V/sqrt(sum(V.*V)); toc   % result:  0.325161s
tic; V1=V/norm(V); toc           % result:  0.218892s

V1 вычисляется здесь второй раз, чтобы убедиться, что при первом вызове нет серьезных штрафов за кэш.

Информация о времени здесь была получена с помощью R2008a x64 в Windows.


EDIT:

Исправленный ответ, основанный на предложениях gnovice (см. Комментарии). Матричная математика (едва) выигрывает:

clc; clear all;
V = rand(1024*1024*32,1);
N = 10;
tic; for i=1:N, V1 = V/norm(V);         end; toc % 6.3 s
tic; for i=1:N, V2 = V/sqrt(sum(V.*V)); end; toc % 9.3 s
tic; for i=1:N, V3 = V/sqrt(V'*V);      end; toc % 6.2 s ***
tic; for i=1:N, V4 = V/sqrt(sum(V.^2)); end; toc % 9.2 s
tic; for i=1:N, V1=V/norm(V);           end; toc % 6.4 s

ИМХО, разница между "norm (V)" и "sqrt (V '* V)" достаточно мала, поэтому для большинства программ лучше использовать более понятную. На мой взгляд, «norm (V)» понятнее и легче читается, но «sqrt (V '* V)» все еще идиоматичен в Matlab.

41
ответ дан 26 November 2019 в 19:47
поделиться

Единственная проблема, с которой вы столкнетесь, это если норма V равна нулю (или очень близко к ней). Это может дать вам Inf или NaN при делении, а также предупреждение о делении на ноль. Если вас не интересует получение Inf или NaN , вы можете просто включить и выключить предупреждение, используя WARNING :

oldState = warning('off','MATLAB:divideByZero');  % Return previous state then
                                                  %   turn off DBZ warning
uV = V/norm(V);
warning(oldState);  % Restore previous state

Если вы этого не сделаете » Мне нужны значения Inf или NaN , сначала нужно проверить размер нормы:

normV = norm(V);
if normV > 0,  % Or some other threshold, like EPS
  uV = V/normV;
else,
  uV = V;  % Do nothing since it's basically 0
end

Если мне это нужно в программе, я обычно помещаю приведенный выше код в свой собственная функция, обычно называемая unit (поскольку она в основном превращает вектор в единичный вектор, указывающий в том же направлении).

9
ответ дан 26 November 2019 в 19:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: