如何在MATLAB中有效地标准化vector? 任何相关的内置函数?

我在MATLAB中对vectorV进行归一化,如下所示:

normalized_V = V/norm(V); 

然而,在MATLAB中规范化vector是否是最优雅(有效)的方法呢?

您build议的原始代码是最好的方法。

Matlab非常擅长vector化操作,至less对于大型vector来说。

内置的规范function非常快。 以下是一些计时结果:

 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在这里被第二次计算,以确保在第一次调用时没有重要的caching损失。

这里的时序信息是在Windows上用R2008a x64制作的。


编辑:

根据gnovice的build议修改答案(见注释)。 matrixmath(几乎)赢:

 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 

恕我直言,“规范(V)”和“sqrt(V'* V)”之间的区别足够小,对于大多数程序来说,最好使用更清晰的程序。 对我来说,“规范(V)”更清晰易读,但“sqrt(V'* V)”在Matlab中仍然是惯用的。

我不知道任何MATLAB,我从来没有使用它,但在我看来,你正在分裂。 为什么? 这样的事情会更快:

 d = 1/norm(V) V1 = V * d 

你遇到的唯一问题是如果V的范数是零(或者非常接近它)。 这可能会给你InfNaN ,除以零分的警告。 如果您不关心获取InfNaN ,可以使用警告开启和closures警告 :

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

如果您不需要任何InfNaN值,则必须先检查规范的大小:

 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 

如果我在程序中需要它,我通常会把上面的代码放在我自己的函数中,通常称为单位 (因为它基本上把一个vector变成指向相同方向的单位vector)。

我拿了Fooz先生的代码,也加了Arlen的解决scheme,下面是我为Octave获得的时间:

 clc; clear all; V = rand(1024*1024*32,1); N = 10; tic; for i=1:N, V1 = V/norm(V); end; toc % 7.0 s tic; for i=1:N, V2 = V/sqrt(sum(V.*V)); end; toc % 6.4 s tic; for i=1:N, V3 = V/sqrt(V'*V); end; toc % 5.5 s tic; for i=1:N, V4 = V/sqrt(sum(V.^2)); end; toc % 6.6 s tic; for i=1:N, V1 = V/norm(V); end; toc % 7.1 s tic; for i=1:N, d = 1/norm(V); V1 = V*d;end; toc % 4.7 s 

然后,由于我目前正在看的东西,我testing了这个代码,以确保每行的总和为1:

 clc; clear all; m = 2048; V = rand(m); N = 100; tic; for i=1:N, V1 = V ./ (sum(V,2)*ones(1,m)); end; toc % 8.2 s tic; for i=1:N, V2 = bsxfun(@rdivide, V, sum(V,2)); end; toc % 5.8 s tic; for i=1:N, V3 = bsxfun(@rdivide, V, V*ones(m,1)); end; toc % 5.7 s tic; for i=1:N, V4 = V ./ (V*ones(m,m)); end; toc % 77.5 s tic; for i=1:N, d = 1./sum(V,2);V5 = bsxfun(@times, V, d); end; toc % 2.83 s tic; for i=1:N, d = 1./(V*ones(m,1));V6 = bsxfun(@times, V, d);end; toc % 2.75 s tic; for i=1:N, V1 = V ./ (sum(V,2)*ones(1,m)); end; toc % 8.2 s 

通过增加一切的合理性,我在列表的最后添加条目

  clc; clear all; V = rand(1024*1024*32,1); N = 10; tic; for i=1:N, V1 = V/norm(V); end; toc % 4.5 s tic; for i=1:N, V2 = V/sqrt(sum(V.*V)); end; toc % 7.5 s tic; for i=1:N, V3 = V/sqrt(V'*V); end; toc % 4.9 s tic; for i=1:N, V4 = V/sqrt(sum(V.^2)); end; toc % 6.8 s tic; for i=1:N, V1 = V/norm(V); end; toc % 4.7 s tic; for i=1:N, d = 1/norm(V); V1 = V*d;end; toc % 4.9 s tic; for i=1:N, d = norm(V)^-1; V1 = V*d;end;toc % 4.4 s 

到目前为止最快(时间与雅各比相比):

 clc; clear all; V = rand(1024*1024*32,1); N = 10; tic; for i=1:N, d = 1/sqrt(V(1)*V(1)+V(2)*V(2)+V(3)*V(3)); V1 = V*d; end; toc % 1.5s