magic(5)
读取中间值,可以像这样做:M = magic(5);
value = M(3,3);
我希望得到value == 13
的值。我想做类似以下其中一种方式的操作:
value = magic(5)(3,3);
value = (magic(5))(3,3);
如何在不使用中间变量的情况下从数组/矩阵中读取值?但是,MATLAB在第一个括号之前出现 Unbalanced or unexpected parenthesis or bracket
的错误提示。
magic(5)
读取中间值,可以像这样做:M = magic(5);
value = M(3,3);
我希望得到value == 13
的值。我想做类似以下其中一种方式的操作:
value = magic(5)(3,3);
value = (magic(5))(3,3);
如何在不使用中间变量的情况下从数组/矩阵中读取值?但是,MATLAB在第一个括号之前出现 Unbalanced or unexpected parenthesis or bracket
的错误提示。
()
进行索引操作时,实际上是在调用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
clear
的麻烦(实际上没有人这样做)-- 临时变量往往会停留更长时间。 - Rody Oldenhuis几天前,Matlab之美的这篇好博客文章提供了一些技巧,可能会有所帮助。特别是,使用类似于以下的辅助函数:
paren = @(x, varargin) x(varargin{:});
curly = @(x, varargin) x{varargin{:}};
可以像这样使用paren()
paren(magic(5), 3, 3);
将返回
ans = 16
我认为这比gnovice的答案更快,但我还没有检查(使用分析器!)。话虽如此,你也必须在某个地方包含这些函数定义。我个人已经将它们作为独立函数放在我的路径中,因为它们非常有用。myfunc().attr
是什么情况? - gerritmyfunc()
返回一个包含属性attr
的结构体,那么要访问attr
目前需要这样做:S = myfunc(); S.attr
。问题是我们是否可以有一个辅助函数,类似于paren
和curly
辅助函数,如getattr(myfunc(),'attr')
。我不明白这与数据库工具箱有什么关系。 - gerrit你对使用未记录的功能有何感想:
>> 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 会话。
':'
一起使用,以避免出现错误Undefined function or variable "builtin"
。 - Dominikbuiltin('_paren', magic(5), ':', 2)
(在某些情况下,直接使用冒号而不是引号,例如在命令提示符中直接运行而不是从函数内部运行时,它可以正常工作。我猜这是解析器中的一个错误!) - Amroend
啊? - knedlseppa(1, :)
。我尝试过 getfield(rand(5), {1, 1:5})
和 getfield(rand(5), {1:5, 1})
,它们可以正常工作,但不够优雅。 - ZR Hangetfield(rand(5), {1, ':'})
。 - John很遗憾,Matlab不支持像magic(5)(3,3)
这样的语法。您需要使用临时中间变量。例如,您可以在使用后释放内存。
tmp = magic(3);
myVar = tmp(3,3);
clear tmp
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没有指针,你必须接受这一点。
function [ element ] = getElem( matrix, index1, index2 )
element = matrix(index1, index2);
end
然后使用它:
value = getElem(magic(5), 3, 3);
subref
所做的...但以更一般的方式。 - Shai您最初的表示法是实现这个的最简洁方式:
M = magic(5); %create
value = M(3,3); % extract useful data
clear M; %free memory
clear
语句会显著地减缓您的代码运行速度,除非M非常大且您在某些地方内存不足,否则最好将其省略。 - Cris Luengo补充Amro的回答,你可以使用feval
代替builtin
。实际上并没有什么区别,除非你尝试重载操作符函数:
BUILTIN(...)
与FEVAL(...)
相同,只是它会调用原始的内置函数版本,即使已经存在重载的版本(为了使其工作,您必须永远不要重载BUILTIN
)。
>> 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%),这很奇怪,因为与builtin
不同,feval
需要检查函数是否被重载:>> 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.
feval
执行“正常”的操作,因此可以充分利用该列表。builtin
必须在其他地方搜索,因此只能找到内置函数。很可能这种情况没有像“正常”情况那样进行优化,因为为什么要把钱投入到不经常使用的东西上呢? - Cris Luengo
testmatrix('magi', 5)(3, 3)
和Octave上的magic(5)(3, 3)
都能够完美运行! - Foad S. Farimani