在 GNU Octave 版本 3.4.3 中,我无法应用自定义函数对矩阵中的每个项目/元素进行操作。
我有一个 (2,3) 矩阵,如下所示:
mymatrix = [1,2,3;4,5,6];
mymatrix
1 2 3
4 5 6
我想将矩阵的每个元素用作输入,并对其运行自定义函数,并让函数的输出逐项替换 mymatrix 的内容。
arrayfun很适合这个:
arrayfun(@(x) 1/(1+e^(-x)), [0, 1; 2, 3])
输出:
ans =
0.50000 0.73106
0.88080 0.95257
这基本上1/(1+e^(-x))
在矩阵/向量的每个元素上运行函数。
或者,您可以使用以下元素运算符(注意点前缀):
例如
mymatrix = 1 ./ (1 .+ e.^(-mymatrix));
function [ out ] = myfun(num)
out = num + 5;
end
将此代码放在名为“main.m”的文件名中
arrayfun(@myfun, [1, 0, -1; 3, 4, 5] )
输出:
ans =
6 5 4
8 9 10
请注意该过程(加 5)如何应用于矩阵中的每个项目。
下面arrayfun
从 Vectorization 的角度分析下到 lowlevel C 的能力。下到裸机上的多核多线程优化:
这段arrayfun
代码是“矢量化的”,GNU Octave 将这段代码打包后交给预先优化的 C 代码,而不是让 GNU Octave 管理自己的冰河迭代。像上面这样以矢量化方式执行的操作比将其放在 for 循环中快 2 到 5 个数量级。像这样的矢量化代码通常对于典型任务来说已经足够了,但是如果从 Alienware 的 QUAD-CHIP 32 核超线程 CPU 中提取每一转马力是关键任务,请继续阅读。
不要错误地说这段代码是“多线程”或“多核”,因为它不是。C 代码仍在以类似队列的迭代先进先出方式处理此代码。第 4 次添加必须等待第 3 次,第 3 次必须等待第 2 次。当这个迭代发生时,你的 CPU 正在转动它的拇指。如果您希望您的办公桌下的 16 核 CPU 在执行此操作时将其 CPU 使用率最大化到 100%,那么就没有逃脱的余地:您必须在面向多线程和多核的情况下停止并重新定义此问题方式。多线程和多核超出了这个答案的范围,最简单的方法是定义你的八度代码以产生8个单独的并行job1.m
通过job8.m
同时运行的所有文件,让它们都处理手头任务的 1/8,最后等待所有文件完成然后重新加入答案。此处的 GNU Octave Vectorization 不等于金属上的多线程。
正如 Nasser 指出的那样,更简单的方法是以下八度音程代码:
f=@(x) x+5;
A = [1, 0, -1; 3, 4, 5];
result = f(A)
result
将 (x+5) 应用于传入的每个元素,它会打印:
result =
6 5 4
8 9 10