Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我如何索引函数返回的MATLAB数组而不首先将其分配给局部变量?_Matlab_Indexing_Matrix_Return Value_Variable Assignment - Fatal编程技术网

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

我如何索引函数返回的MATLAB数组而不首先将其分配给局部变量?,matlab,indexing,matrix,return-value,variable-assignment,Matlab,Indexing,Matrix,Return Value,Variable Assignment,例如,如果我想从magic5读取中间值,我可以这样做: M = magic(5); value = M(3,3); 获取值==13。我希望能够做到以下几点: value = magic(5)(3,3); value = (magic(5))(3,3); 省去中间变量。但是,MATLAB抱怨3之前的第一个括号或括号不平衡或意外 是否可以从数组/矩阵中读取值而不首先将其分配给变量?不幸的是,matlab不支持magic53,3这样的语法。您需要使用临时中间变量。你可以在使用后释放内存,例如 tm

例如,如果我想从magic5读取中间值,我可以这样做:

M = magic(5);
value = M(3,3);
获取值==13。我希望能够做到以下几点:

value = magic(5)(3,3);
value = (magic(5))(3,3);
省去中间变量。但是,MATLAB抱怨3之前的第一个括号或括号不平衡或意外

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

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

tmp = magic(3);
myVar = tmp(3,3);
clear tmp
实际上,可以做您想要做的事情,但是您必须使用索引操作符的函数形式。使用执行索引操作时,实际上是在调用该函数。所以,即使你不能这样做:

您可以这样做:

难看,但有可能

通常,您只需将索引步骤更改为函数调用,这样就不会有两组括号紧跟其后。另一种方法是定义自己的方法来执行订阅索引。例如:

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

然而,当所有的事情都说了又做了之后,临时局部变量解决方案更具可读性,这也是我的建议。

请注意,如果您将运行时间与标准方法进行比较,即先指定结果,然后访问条目,则它们是完全相同的

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没有指针,你必须接受它。

你的初始符号是最简洁的方法:

M = magic(5);  %create
value = M(3,3);  % extract useful data
clear M;  %free memory
如果在循环中执行此操作,则每次只需重新分配M,同时忽略clear语句

就在几天前,有几件珠宝可能会有所帮助。特别是,使用辅助函数,如:

paren = @(x, varargin) x(varargin{:});
curly = @(x, varargin) x{varargin{:}};
在哪里可以像这样使用paren

paren(magic(5), 3, 3);
会回来吗

ans = 16
我还推测这将比gnovice的答案更快,但我还没有检查使用分析器!!!。也就是说,您还必须在某个地方包含这些函数定义。我个人在我的道路上使它们成为独立的功能,因为它们非常有用


这些函数和其他函数现在可以在Functional Programming Constructions加载项中找到,该加载项可通过MATLAB加载项资源管理器或上获得。

您对使用未记录的功能有何看法:

>> builtin('_paren', magic(5), 3, 3)               %# M(3,3)
ans =
    13
或对于单元阵列:

>> builtin('_brace', num2cell(magic(5)), 3, 3)     %# C{3,3}
ans =
    13
就像魔术一样:

更新: 坏消息是,上述破解在R2015b中不再有效!这很好,它是未记录的功能,我们不能依赖它作为受支持的功能:


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

如果创建一个新函数,可能会更简单:

function [ element ] = getElem( matrix, index1, index2 )
    element = matrix(index1, index2);
end
然后使用它:

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

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


要获得1,2处的元素以补充Amro的答案,可以使用feval而不是内置元素。实际上没有区别,除非您尝试重载运算符函数:

内置的。。。和FEVAL一样。。。除了它会调用 函数的原始内置版本,即使是重载版本 为使其工作,您决不能超载 内置的

有趣的是,至少在Matlab 2013b中,feval似乎比builtin快了约3.5%,这很奇怪,因为feval需要检查函数是否过载,而builtin不同:


好吧,你知道什么!虽然我同意这很难看,而且可能不如临时变量解决方案可读+1对于令人印象深刻的晦涩的matlab知识!这很恶心,但答案很清楚。干得好!我应该猜到会有一条回头路。我想我会继续使用temp变量。请记住,中间变量仍然是完全创建的。因此,如果目的是通过不必创建临时局部变量来节省内存,那就不走运了。@SamRoberts:用像Matlab这样的严格计算语言,你真的无法绕过这个问题。人们希望这样做的主要原因是简洁性/可读性,而不是节省内存。@SamRoberts:没错,但它确实可以让你从要求明确临时性的负担中解脱出来,这是从来没有人做过的——临时性倾向于停留在longerI周围。我还发现了以下关于这个主题的文章:任何人都有关于这个主题的新信息,它会被实现吗?这个语法在八度音阶中实际上很好用。我只是在使用MATLAB的同事在运行我的代码时遇到问题时才发现这个问题。简而言之,MATLAB。自版本6以来,递归提取也在Scilab中工作。Scilab上的testmatrix'magi',53,3和Octave上的magic53,3都工作得很好!我同意
这更简洁,正如您所说,清除是循环中的一个好主意,但问题是是否可以避免中间赋值。清除语句将显著降低代码的速度,最好不要使用它,除非M非常大,并且你在某处内存不足;也很好。myfunc.attr呢?@gerrit,at如何提供帮助?除非您有数据库工具箱,否则x.attr字段不可用。@t.Furfaro,嗯?如果myfunc返回一个包含属性attr的结构,那么要当前访问attr,我需要执行S=myfunc;S.attr。问题是我们是否可以有一个类似于paren和curly助手的助手函数getattrmyfunc、“attr”。我不明白这与数据库工具箱有什么关系。@gerrit抱歉,完全混淆我不知道您的attr是任意的-在db tb中定义了这样一个字段明确性。我相信你正在寻找的是,但这正是subref所做的。。。但是用更一般的方式。是的,更一般的方式,但不友好。。。在我看来,这太难看了。@RodyOldenhuis:我现在不记得了,我想我一定是读过一些隐藏的代码;冒号:运算符必须与撇号“:”一起使用,以避免出现未定义函数或变量内置的错误。@Dominik:好的,假设您要对第二列进行切片,即:内置“\u paren”,magic5“:”,2在某些地方,它不直接使用引号,与“:”相反,类似于直接在命令提示符下运行,而不是从函数内部运行。我猜这是解析器中的一个bug!我不认为有什么方法可以使用end来处理这个问题?@knedlsepp:不,不幸的是,整个语法都不适用,您必须在索引中明确表示。。同样的限制也适用于大多数其他列出的答案。这实际上是一个很好的方法。有什么缺点吗?@mmumboss:这是未记录的行为,在未来的版本中,此功能可能会在不通知的情况下消失。除此之外,并没有任何缺点。从MATLAB2017b开始,此功能已被记录在案。如何获得一列或一行输出?如a1,:。我尝试过getfieldrand5,{1,1:5}和getfieldrand5,{1:5,1}这两个函数工作得很好,但并不优雅。这其实并不奇怪:MATLAB保留了一个定义函数的列表,没有那么多搜索要做。feval做“正常”的事情,因此可以充分利用这个列表。内置函数必须在别处搜索,以便只查找内置函数。很可能这个案例没有像“正常”案例那样优化,因为你为什么要把钱花在优化一些不经常使用的东西上?
function [ element ] = getElem( matrix, index1, index2 )
    element = matrix(index1, index2);
end
value = getElem(magic(5), 3, 3);
a=rand(5);
getfield(a,{1,2}) % etc
>> feval('_paren', magic(5), 3, 3)               % M(3,3)
ans =
    13

>> feval('_brace', num2cell(magic(5)), 3, 3)     % C{3,3}
ans =
    13
>> 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.