代码之家  ›  专栏  ›  技术社区  ›  graille

在函数输出处直接分解单元格

  •  0
  • graille  · 技术社区  · 6 年前

    例如,如果我想从 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 3 .

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

    0 回复  |  直到 13 年前
        1
  •  373
  •   gnovice    7 年前

    事实上 可以做你想做的事情,但是你必须使用索引操作符的函数形式。当使用索引操作时 () 你实际上是在打电话给 subsref 功能。所以,即使你 不能 这样做:

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

    可以 这样做:

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

    丑陋,但有可能。;)

    通常,您只需将索引步骤更改为函数调用,这样您就不会立即有两组括号。另一种方法是定义自己的 anonymous function 进行下标索引。例如:

    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
    

    然而,当一切都说了做了,临时局部变量解是 许多的 更可读,而且绝对是我的建议。

        2
  •  128
  •   nekomatic    8 年前

    只是 good blog post Loren on the Art of Matlab 几天前用了一些可能有用的宝石。特别是,使用助手函数,如:

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

    哪里 paren() 可以像

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

    会回来的

    ans = 16
    

    我也会猜测这将比gnovice的答案快,但我没有检查(使用profiler!!!!)。也就是说,还必须在某个地方包含这些函数定义。我个人已经使它们在我的道路上独立的功能,因为它们是超级有用的。

    这些功能和其他功能现在可以在 函数程序设计构造 可通过Matlab加载项资源管理器或 File Exchange .

        3
  •  75
  •   Amro    9 年前

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

    >> 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会话。

        4
  •  53
  •   Cris Luengo    7 年前

    至少在Matlab2013A中你可以使用 getfield 像:

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

    在(1,2)处获取元素

        5
  •  15
  •   second    14 年前

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

    tmp = magic(3);
    myVar = tmp(3,3);
    clear tmp
    
        6
  •  12
  •   user davidism    7 年前

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

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

        7
  •  6
  •   Shai    12 年前

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

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

    然后使用它:

    value = getElem(magic(5), 3, 3);
    
        8
  •  4
  •   Andreas GS    13 年前

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

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

    如果您在循环中这样做,您可以每次重新分配M,同时也忽略明文语句。

        9
  •  1
  •   nirvana-msu    9 年前

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

    Bug(…)与FEVAL(…)相同,只是它将调用 原始内置版本的函数,即使重载一个 存在(为了让它工作,你不能超载 建筑)

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

    有趣的是 费韦尔 似乎只是比 小精灵 (大约3.5%),至少在matlab 2013b中是这样,这很奇怪 小精灵 需要检查函数是否重载,与 内建 :

    >> 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.