Octave自带的帮助文件中有这样一条目录:
19.1 基本向量化
在向量化方面,一个很好的近似目标是编写避免循环并使用整个数组操作的代码。举个简单的例子,考虑以下代码:
for i = 1:n
for j = 1:m
c(i,j) = a(i,j) + b(i,j);
endfor
endfor
与简单得多的相比,
c = a + b;
这不仅更易于撰写;也更容易进行内部优化。Octave将此操作委托给底层实现,其中包括使用特殊的向量硬件指令或甚至可能并行执行加法等优化。通常情况下,如果代码被向量化,底层实现在为了实现更快的执行而做出更多假设。
这对于具有“廉价”主体的循环特别重要。通常,仅向量化最内部的循环就足以获得可接受的性能。一个经验法则是,向量化主体的“顺序”应大于或等于封闭循环的“顺序”。
作为一个不太平凡的例子,可以用以下方式改写:
for i = 1:n-1
a(i) = b(i+1) - b(i);
endfor
写作
a = b(2:n) - b(1:n-1)
这展示了使用数组进行索引而不是循环索引变量的重要概念。同时,要大量使用布尔索引。如果需要测试条件,该条件也可以编写为布尔索引。例如,可以使用布尔索引代替
for i = 1:n
if (a(i) > 5)
a(i) -= 20
endif
endfor
写
a(a>5) -= 20;
利用“a>5”产生布尔索引的事实,尽可能使用逐元素向量运算符以避免循环(例如“.*”和“.^”)。
算术运算。对于简单的内联函数,“vectorize”函数可以自动完成此操作。
-- 内置函数:vectorize(FUN)
通过将所有出现的“”、“/”等替换为“.”、“./”等,创建内联函数FUN的矢量化版本。
This may be useful, for example, when using inline functions with
numerical integration or optimization where a vector-valued
function is expected.
fcn = vectorize (inline ("x^2 - 1"))
=> fcn = f(x) = x.^2 - 1
quadv (fcn, 0, 3)
=> 6
See also:  inline,  formula,
 argnames.
同时在这些逐元素运算中利用广播来避免循环和不必要的中间内存分配。
尽可能使用内置和库函数。内置和编译函数非常快。即使是m-file库函数,很可能已经优化过,或者将在以后的版本中进一步优化。
例如,甚至比
a = b(2:n) - b(1:n-1)
is
a = diff (b);
大多数 Octave 函数都是针对向量和数组参数编写的。如果你发现自己在编写一个非常简单操作的循环,那么很有可能已经存在这样一个函数。以下函数在向量化代码中经常出现:
Index manipulation
* find
* sub2ind
* ind2sub
* sort
* unique
* lookup
* ifelse / merge
Repetition
* repmat
* repelems
Vectorized arithmetic
* sum
* prod
* cumsum
* cumprod
* sumsq
* diff
* dot
* cummax
* cummin
Shape of higher dimensional arrays
* reshape
* resize
* permute
* squeeze
* deal
请查看以下这些来自斯坦福机器学习维基的页面,以获取更多的指导和示例。
http://ufldl.stanford.edu/wiki/index.php/Vectorization
http://ufldl.stanford.edu/wiki/index.php/Logistic_Regression_Vectorization_Example
http://ufldl.stanford.edu/wiki/index.php/Neural_Network_Vectorization