如何设置匿名函数以将矢量输入在八度中获取?

发布于 2025-02-07 14:34:20 字数 677 浏览 0 评论 0原文

我想定义一个匿名函数,但除非指定向量中的每个元素:

Data = 
[ X11 X12;
  X21 X22];

迭代#1:v - > [x11 x12](每次迭代时要传递到“ some_func”的值行)。 迭代#2:v - > [x21 x22]

这项工作:

good_func_handle = @(a1,a2)  some_func([a1,a2],bla,bla)
output = arrayfun(good_func_handle,Data(:,1),Data(:,2)) -> to avoid having to write a for loop

这是不起作用的:

bad_func_handle = @(vec)  some_func(vec,bla,bla)
output = arrayfun(bad_func_handle,Data)

当这被称为第一个元素x11时,将传递给some_func,但> x11x12

有没有办法设置该函数以将向量变量作为输入,而不必指定向量中的所有元素?

I would like to define an anonymous function that takes a vector, but I am unable to achieve that unless every element in the vector is specified:

Data = 
[ X11 X12;
  X21 X22];

Iteration #1: V -> [X11 X12] (desired row of values to be passed into 'some_func' at each iteration).
Iteration #2: V -> [X21 X22]

This works:

good_func_handle = @(a1,a2)  some_func([a1,a2],bla,bla)
output = arrayfun(good_func_handle,Data(:,1),Data(:,2)) -> to avoid having to write a for loop

This doesn't work:

bad_func_handle = @(vec)  some_func(vec,bla,bla)
output = arrayfun(bad_func_handle,Data)

When this is called only the first element X11 is passed in to some_func but not X11 and X12.

Is there a way to set up the function to take a vector variable as input instead of having to specify all elements in the vector?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

2025-02-14 14:34:20

问题在于arrayfun,而不是在被调用的函数中。 arrayfun循环输入数组的每个元素,而不是每一行。在第一个解决方案中,您创建了输入数组,以使每个元素上的循环是正确的事情。

由于arrayfun只是一个循环,因此除了程序员时间之外,使用它没有时间。它应该只是简化在数组上编写循环。 [资格:在matlab中,arrayfun添加开销,因为需要调用每个迭代的函数;如下所示,这可能很重要。在八度,arrayfun似乎比平原循环效率更高,请参见 smcmi的评论下面的评论


a = zeros(1, 1e6);

b = method1(a);
c = method2(a);
assert(isequal(b,c))

timeit(@()method1(a))
timeit(@()method2(a))

function out = method1(in)
    out = zeros(size(in));
    for ii=1:numel(in)
        out(ii) = in(ii) * 2;
    end
end

function out = method2(in)
    out = arrayfun(@(x) x * 2, in);
end

使用MATLAB在线运行此操作(通常非常慢)我会看到此输出:

ans =
    0.0036

ans =
    2.5299

即,平原循环为0.0036 s,而arrayfun以2.5 s为单位。这是三个数量级差异。

arrayfun中最大的成本是调用每个数组元素的功能。在MATLAB中,调用功能仍然具有一定的开销,而循环被JIT完全优化,并以类似于任何编译语言的速度运行。

在八度中,时间差异很大,因为它根本没有JIT。请参阅下面的评论以获取八度性能。

The problem is in arrayfun, not in the function being called. arrayfun loops over each element of the input array, not each row. In your first solution, you created input arrays such that looping over each element was the right thing to do.

Since arrayfun is just a loop, there is no advantage in time for using it, other than programmer time. It is just supposed to simplify writing a loop over an array. [Qualifications: In MATLAB, arrayfun adds overhead because a function needs to be called for each iteration; this can be significant as shown below. In Octave, arrayfun seems to be a bit more efficient than a plain loop, see smcmi's comments below.]


In response to the comment below by @smcmi, I re-created their experiment as follows:

a = zeros(1, 1e6);

b = method1(a);
c = method2(a);
assert(isequal(b,c))

timeit(@()method1(a))
timeit(@()method2(a))

function out = method1(in)
    out = zeros(size(in));
    for ii=1:numel(in)
        out(ii) = in(ii) * 2;
    end
end

function out = method2(in)
    out = arrayfun(@(x) x * 2, in);
end

Running this using MATLAB Online (which is pretty slow usually) I see this output:

ans =
    0.0036

ans =
    2.5299

That is, the plain loop takes 0.0036 s, whereas arrayfun takes 2.5 s. This is three orders of magnitude difference.

The largest cost in arrayfun is calling a function for every array element. In MATLAB, calling a function still carries a bit of overhead, whereas the loop is completely optimized by the JIT and runs at speeds similar to those seen in any compiled language.

In Octave the timings are quite different, as it has no JIT at all. See comments below this answer for Octave performance.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文