如何索引函数返回的 MATLAB 数组而不先将其分配给局部变量?

发布于 2024-09-16 20:55:05 字数 350 浏览 6 评论 0原文

例如,如果我想从 magic(5) 读取中间值,我可以这样做:

M = magic(5);
value = M(3,3);

获取 value == 13。我希望能够执行以下操作之一:

value = magic(5)(3,3);
value = (magic(5))(3,3);

无需中间变量。但是,MATLAB 会抱怨 3 之前的第一个括号上存在 不平衡或意外的括号或方括号

是否可以从数组/矩阵中读取值而不先将其分配给变量?

For example, if I want to read the middle value from magic(5), I can do so like this:

M = magic(5);
value = M(3,3);

to get value == 13. I'd like to be able to do something like one of these:

value = magic(5)(3,3);
value = (magic(5))(3,3);

to dispense with the intermediate variable. However, MATLAB complains about Unbalanced or unexpected parenthesis or bracket on the first parenthesis before the 3.

Is it possible to read values from an array/matrix without first assigning it to a variable?

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

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

发布评论

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

评论(9

最初的梦 2024-09-23 20:55:05

实际上可以做你想做的事,但是你必须使用索引运算符的函数形式。当您使用 () 执行索引操作时,您实际上是在调用 subsref 函数。因此,即使您不能这样做:

value = magic(5)(3, 3);

可以这样做:

value = subsref(magic(5), struct('type', '()', 'subs', {{3, 3}}));

丑陋,但可能。 ;)

一般来说,您只需将索引步骤更改为函数调用,这样就不会出现紧随其后的两组括号。另一种方法是定义您自己的匿名函数进行下标索引。例如:

subindex = @(A, r, c) A(r, c);     % An anonymous function for 2-D indexing
value = subindex(magic(5), 3, 3);  % Use the function to index the matrix

然而,总而言之,临时局部变量解决方案的可读性要高得多,这绝对是我所建议的。

It actually is possible to do what you want, but you have to use the functional form of the indexing operator. When you perform an indexing operation using (), you are actually making a call to the subsref function. So, even though you can't do this:

value = magic(5)(3, 3);

You can do this:

value = subsref(magic(5), struct('type', '()', 'subs', {{3, 3}}));

Ugly, but possible. ;)

In general, you just have to change the indexing step to a function call so you don't have two sets of parentheses immediately following one another. Another way to do this would be to define your own anonymous function to do the subscripted indexing. For example:

subindex = @(A, r, c) A(r, c);     % An anonymous function for 2-D indexing
value = subindex(magic(5), 3, 3);  % Use the function to index the matrix

However, when all is said and done the temporary local variable solution is much more readable, and definitely what I would suggest.

孤者何惧 2024-09-23 20:55:05

只有 好博文,关于 Loren 谈 Matlab 艺术 几天之前有一些可能有帮助的宝石。特别是,使用像这样的辅助函数:

paren = @(x, varargin) x(varargin{:});
curly = @(x, varargin) x{varargin{:}};

where paren() can be use like

paren(magic(5), 3, 3);

will return

ans = 16

我也猜测这会比 gnovice 的答案更快,但我还没有检查过(使用探查器! !)。话虽如此,您还必须在某处包含这些函数定义。我个人在我的道路上使它们成为独立的功能,因为它们非常有用。

这些函数和其他函数现在可在函数式编程构造附加组件中使用,该附加组件可通过 MATLAB 附加组件资源管理器或在 文件交换

There was just good blog post on Loren on the Art of Matlab a couple days ago with a couple gems that might help. In particular, using helper functions like:

paren = @(x, varargin) x(varargin{:});
curly = @(x, varargin) x{varargin{:}};

where paren() can be used like

paren(magic(5), 3, 3);

would return

ans = 16

I would also surmise that this will be faster than gnovice's answer, but I haven't checked (Use the profiler!!!). That being said, you also have to include these function definitions somewhere. I personally have made them independent functions in my path, because they are super useful.

These functions and others are now available in the Functional Programming Constructs add-on which is available through the MATLAB Add-On Explorer or on the File Exchange.

悲凉≈ 2024-09-23 20:55:05

您对使用未记录的功能有何感受:

>> builtin('_paren', magic(5), 3, 3)               %# M(3,3)
ans =
    13

或对于单元阵列:

>> builtin('_brace', num2cell(magic(5)), 3, 3)     %# C{3,3}
ans =
    13

就像魔术一样:)


更新:

坏消息,上述黑客在R2015b中不再起作用!没关系,它是未记录的功能,我们不能依赖它作为受支持的功能:)

对于那些想知道在哪里可以找到此类内容的人,请查看文件夹 fullfile(matlabroot,'bin','registry')< /代码>。那里有一堆 XML 文件,列出了各种好东西。请注意,直接调用其中一些函数很容易使您的 MATLAB 会话崩溃。

How do you feel about using undocumented features:

>> builtin('_paren', magic(5), 3, 3)               %# M(3,3)
ans =
    13

or for cell arrays:

>> builtin('_brace', num2cell(magic(5)), 3, 3)     %# C{3,3}
ans =
    13

Just like magic :)


UPDATE:

Bad news, the above hack doesn't work anymore in R2015b! That's fine, it was undocumented functionality and we cannot rely on it as a supported feature :)

For those wondering where to find this type of thing, look in the folder fullfile(matlabroot,'bin','registry'). There's a bunch of XML files there that list all kinds of goodies. Be warned that calling some of these functions directly can easily crash your MATLAB session.

尛丟丟 2024-09-23 20:55:05

至少在 MATLAB 2013a 中,您可以使用 getfield 就像:

a=rand(5);
getfield(a,{1,2}) % etc

获取 (1,2) 处的元素

At least in MATLAB 2013a you can use getfield like:

a=rand(5);
getfield(a,{1,2}) % etc

to get the element at (1,2)

梦冥 2024-09-23 20:55:05

不幸的是,matlab 不支持像 magic(5)(3,3) 这样的语法。您需要使用临时中间变量。您可以在使用后释放内存,例如

tmp = magic(3);
myVar = tmp(3,3);
clear tmp

unfortunately syntax like magic(5)(3,3) is not supported by matlab. you need to use temporary intermediate variables. you can free up the memory after use, e.g.

tmp = magic(3);
myVar = tmp(3,3);
clear tmp
失退 2024-09-23 20:55:05

请注意,如果将运行时间与标准方式(分配结果然后访问条目)进行比较,它们是完全相同的。

subs=@(M,i,j) M(i,j);
>> for nit=1:10;tic;subs(magic(100),1:10,1:10);tlap(nit)=toc;end;mean(tlap)

ans =

0.0103

>> for nit=1:10,tic;M=magic(100); M(1:10,1:10);tlap(nit)=toc;end;mean(tlap)

ans =

0.0101

在我看来,底线是:MATLAB 没有指针,你必须忍受它。

Note that if you compare running times with the standard way (asign the result and then access entries), they are exactly the same.

subs=@(M,i,j) M(i,j);
>> for nit=1:10;tic;subs(magic(100),1:10,1:10);tlap(nit)=toc;end;mean(tlap)

ans =

0.0103

>> for nit=1:10,tic;M=magic(100); M(1:10,1:10);tlap(nit)=toc;end;mean(tlap)

ans =

0.0101

To my opinion, the bottom line is : MATLAB does not have pointers, you have to live with it.

属性 2024-09-23 20:55:05

可能会更简单:

function [ element ] = getElem( matrix, index1, index2 )
    element = matrix(index1, index2);
end

如果你创建一个新函数,然后使用它,

value = getElem(magic(5), 3, 3);

It could be more simple if you make a new function:

function [ element ] = getElem( matrix, index1, index2 )
    element = matrix(index1, index2);
end

and then use it:

value = getElem(magic(5), 3, 3);
‖放下 2024-09-23 20:55:05

您的初始符号是执行此操作的最简洁方法:

M = magic(5);  %create
value = M(3,3);  % extract useful data
clear M;  %free memory

如果您在循环中执行此操作,则每次都可以重新分配 M 并忽略clear语句。

Your initial notation is the most concise way to do this:

M = magic(5);  %create
value = M(3,3);  % extract useful data
clear M;  %free memory

If you are doing this in a loop you can just reassign M every time and ignore the clear statement as well.

还不是爱你 2024-09-23 20:55:05

为了补充 Amro 的答案,您可以使用 feval 而不是 builtin。实际上,没有什么区别,除非您尝试重载运算符函数:

BUILTIN(...) 与 FEVAL(...) 相同,只是它会调用
函数的原始内置版本,即使是重载的版本
存在(要使其工作,您绝不能超载
内置)。

>> feval('_paren', magic(5), 3, 3)               % M(3,3)
ans =
    13

>> feval('_brace', num2cell(magic(5)), 3, 3)     % C{3,3}
ans =
    13

有趣的是,feval 似乎比 builtin 快一点点(约 3.5%),至少在 Matlab 2013b 中是这样,考虑到 feval 需要检查函数是否重载,与 builtin 不同:

>> tic; for i=1:1e6, feval('_paren', magic(5), 3, 3); end; toc;
Elapsed time is 49.904117 seconds.
>> tic; for i=1:1e6, builtin('_paren', magic(5), 3, 3); end; toc;
Elapsed time is 51.485339 seconds.

To complement Amro's answer, you can use feval instead of builtin. There is no difference, really, unless you try to overload the operator function:

BUILTIN(...) is the same as FEVAL(...) except that it will call the
original built-in version of the function even if an overloaded one
exists (for this to work, you must never overload
BUILTIN).

>> feval('_paren', magic(5), 3, 3)               % M(3,3)
ans =
    13

>> feval('_brace', num2cell(magic(5)), 3, 3)     % C{3,3}
ans =
    13

What's interesting is that feval seems to be just a tiny bit quicker than builtin (by ~3.5%), at least in Matlab 2013b, which is weird given that feval needs to check if the function is overloaded, unlike builtin:

>> tic; for i=1:1e6, feval('_paren', magic(5), 3, 3); end; toc;
Elapsed time is 49.904117 seconds.
>> tic; for i=1:1e6, builtin('_paren', magic(5), 3, 3); end; toc;
Elapsed time is 51.485339 seconds.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文