【问题标题】:Is there something like arrayfun, but for multiple dimensions?有没有像arrayfun这样的东西,但是对于多个维度?
【发布时间】:2015-11-18 18:22:37
【问题描述】:

给定

X = [x0,x1,...,xN];
Y = [y0,y1,...,yM];
function result = f(x, y)
    ... % Cannot use broadcasting. Must take values. Returns a value.
end

我想得到一个矩阵

f(x0,y0) f(x0,y1) ... f(x0,yM)
f(x1,y0) f(x1,y1) ... f(x1,yM)
...      ...      ... ...
f(xN,y0) f(xN,y1) ... f(xN,yN)

我知道我可以只使用两个嵌套的for 循环,但是有什么东西可以并行化吗?界面类似于arrayfun的东西?


对于那些对f 功能感到好奇的人:

X = [some vector]
W = [some vector]
p(w) % returns a real number; for given vector, returns a vector
g(x, w) % returns value from X; can use broadcasting just like (x .* w).

function result = f(x, y)                  % takes 2 values from X
    result = sum( p( W( g(x,W) == y ) ) );
    %                   |         |        - boolean vector
    %                |              |      - vector of some values from W
    %             |                   |    - vector of some real values
    %        |                          |  - a single value
end

【问题讨论】:

  • This 可能值得一看。能分享一下f函数的实现吗?
  • arrayfun 不并行化,它只是编写迭代的另一种方式。至少在最近的 matlab 版本中,我希望嵌套循环至少与任何其他解决方案一样快。除非你使用广播来完成它。
  • 仅供参考 arrayfun 可以接受多个参数:arrayfun(@(x,y) f(x,y), X,Y)
  • @Geoff 是的,但输入必须是相同大小的向量,它会产生一个f(x0,y0) f(x1,y1) ... f(xN,yN) 的向量。完全不同的东西。
  • 那么,g(x,w)(x .* w)g 是一个函数,对吧?

标签: octave cartesian-product


【解决方案1】:

@Matt 的答案看起来比这更好,但它绝对可以使用 arrayfun 使用 meshgrid' 来格式化输入和输出:

X       = rand(10,1); 
Y       = rand(5,1); 
f       = @(a,b) a+b;
[xx,yy] = meshgrid(X,Y);
out     = arrayfun(@(a,b) f(a,b),xx,yy)';

【讨论】:

  • 在发布我的解决方案之前,我没有意识到 MATLAB 标记已被删除 - 如果此解决方案对 OCTAVE 无效,我将删除它。
  • 不要删除它!效果很好!谢谢 :) (小调整:ndgrid 不需要转置)
  • 虽然它仍然是顺序的并且与嵌套循环具有相同的速度,但至少我的代码变得更清晰了。
【解决方案2】:

这样的事情应该可以工作。

   f = @(a,b) a + b;
   x = (0:10)';
   y = -5:1;
   res = bsxfun(f, x, y);

res =

-5    -4    -3    -2    -1     0     1
-4    -3    -2    -1     0     1     2
-3    -2    -1     0     1     2     3
-2    -1     0     1     2     3     4
-1     0     1     2     3     4     5
 0     1     2     3     4     5     6
 1     2     3     4     5     6     7
 2     3     4     5     6     7     8
 3     4     5     6     7     8     9
 4     5     6     7     8     9    10
 5     6     7     8     9    10    11

使bsxfun 工作的关键是安排您的输入,以便它们能够正确扩展。使用doc bsxfun 查看您在非单一维度方面需要什么以获得所需的输出。

当然,我的输出是从原始请求转置的,但这很容易用res = res'; 解决。

【讨论】:

  • Octave 文档说“函数 F 必须能够接受两个长度相等的列向量参数,或者一个列向量参数和一个标量。”。正如我所写,我的函数必须采用两个值。
  • @etam1024 那么你需要从你的问题中删除matlab 标签。因为它在 Matlab 中运行良好。显然,我的示例显示了 2 个不同长度的向量。
  • 但是 bsxfun 上的 Matlab 文档也说该函数必须接受向量作为参数(我不会在这里粘贴它,因为它很长)。修改你的f 函数,让它显示传递的参数并告诉你得到了什么。
  • @etam1024 mathworks.com/help/matlab/ref/bsxfun.html 我不知道您在阅读什么文档,但它不是来自 MathWorks。
  • “形式为 C = fun(A,B) 的二进制逐元素函数接受任意但大小相等的数组 A 和 B,并返回相同大小的输出。[...] fun 还必须支持标量扩展,这样如果 A 或 B 是标量,则 C 是将标量应用于另一个输入数组中的每个元素的结果"
猜你喜欢
  • 1970-01-01
  • 2013-07-30
  • 2014-09-29
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多