How can I index a MATLAB array returned by a function without first assigning it to a local variable?

前端 未结 9 1674
盖世英雄少女心
盖世英雄少女心 2020-11-21 05:02

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

相关标签:
9条回答
  • 2020-11-21 05:42

    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.
    
    0 讨论(0)
  • 2020-11-21 05:47

    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);
    
    0 讨论(0)
  • 2020-11-21 05:48

    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.

    0 讨论(0)
  • 2020-11-21 05:50

    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.

    0 讨论(0)
  • 2020-11-21 05:59

    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
    
    0 讨论(0)
  • 2020-11-21 05:59

    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.

    0 讨论(0)
提交回复
热议问题