【问题标题】:Defining a multivariable function for vector inputs为向量输入定义多变量函数
【发布时间】:2017-07-21 20:44:24
【问题描述】:

我在使用Matlab方面有点新,我有一个关于为向量输入定义多变量函数的问题。

如果函数是单个函数,比如f(t),我知道如何将其用于向量输入。一般的方法是在定义一个f(t)之后使用arrayfun。多变量函数怎么样,比如f(x,y)?我想要做的是获得两个输入,比如x[1 2 3]y[4 5 6 7] (维度可能不同,但它们都是列向量或行向量)以便我可以计算给予

[f(1,4),f(1,5),f(1,6),f(1,7);
 f(2,4),f(2,5),f(2,6),f(2,7);
 f(3,4),f(3,5),f(3,6),f(3,7)]

困难在于xy的向量输入可能不在同一个维度。

我知道如果我没有f(x,y) 的示例,可能很难说明。对于我使用f(x,y)来说,显示f(x,y)可能会很复杂。为简单起见,将f(x,y) 视为x^2+y,一旦定义,就不能将其更改为x.^2+y 用于向量输入。

【问题讨论】:

  • 很容易将x^2+y 用于向量。但是,您不可能以一种可以用两个向量而不是两个变量提供函数的方式更改函数,这是否正确?制作一个包含两个不同大小向量的所有组合的矩阵并不难。
  • 另外,一般的方法是使用arrayfun,而是使用良好的老式循环。我还没有看到arrayfun 比循环更快的情况。当然,arrayfun 可能看起来更干净,而且更短。
  • 你的意思是 for 循环比使用 arrayfun 更快?对于我使用循环编写它,我使用双循环。如果维度很高,那么它可能会很慢。
  • 另外,will_check,你应该开始upvote and/or accept在这个网站上回答你的问题(到目前为止你甚至没有接受一个答案),所以未来的读者会知道什么对你有用。
  • @StewieGriffin 你赢了!我对其进行了更彻底的测试,似乎只要将单个循环与arrayfun 进行比较(否则不公平......),for 循环更快。

标签: matlab vectorization


【解决方案1】:

这里有一组使用ndgrid的建议:

testfun = @(x,y) x^2+y; % non-vectorized form
x = 1:3;
y = 4:7;
[X,Y] = ndgrid(x,y);

% if the function can be vectorized (fastest!):
testfun_vec = @(x,y) x.^2+y; % vectorized form
A = testfun_vec(X,Y);

% or without ndgrid (also super fast):
B = bsxfun(testfun_vec,x.',y); % use the transpose to take all combinations

% if not, or if it's not bivariate operation (slowest):
C = arrayfun(testfun,X(:),Y(:));
C = reshape(C,length(x),length(y));

% and if you want a loop:
D = zeros(length(x),length(y));
for k = 1:length(X(:))
    D(k) = testfun(X(k),Y(k));
end

将输出所有情况(ABCD):

     5     6     7     8
     8     9    10    11
    13    14    15    16

如前所述,如果您可以矢量化您的函数 - 这是最好的解决方案,如果它只有两个输入 bsxfun 也是一个很好的解决方案。否则,如果您有少量数据并希望保持代码紧凑,请使用 arrayfun,如果您正在处理大型数组,请使用 un-nested for 循环。

【讨论】:

    【解决方案2】:

    这是使用 for 循环和内联函数的代码:

    x = [1 2 3];
    y = [4 5 6 7];
    f = @(x,y) x^2 +y;
    A = zeros(length(x), length(y));
    for m = 1:length(x)
        for n = 1:length(y)
            A(m, n) = f(x(m), y(n));
        end
    end
    disp(A);
    

    结果:

    A =
    
         5     6     7     8
         8     9    10    11
        13    14    15    16
    

    【讨论】:

      【解决方案3】:
      >> x = [1 2 3];
      >> y = [4 5 6 7];
      >> outValue = foo(x, y);
      
      >> outValue
      
      outValue =
      
       5     6     7     8
       8     9    10    11
      13    14    15    16
      

      制作这个函数:

      function out = foo(x, y)
      
      for i = 1 : length(x)
          for j = 1 : length(y)
             out(i, j) = x(i)^2 + y(j);
          end
      end
      

      【讨论】:

      • 函数 foo: out(i, j) = x(i)^2 + y(j); 中的小错字。你不妨矢量化内循环:out(i, :) = x(i)^2 + y(:);
      猜你喜欢
      • 1970-01-01
      • 2013-12-02
      • 1970-01-01
      • 1970-01-01
      • 2021-06-11
      • 1970-01-01
      • 1970-01-01
      • 2023-02-03
      • 2023-03-24
      相关资源
      最近更新 更多