Skip to Main Content Skip to Search
File Exchange
MATLAB Newsgroup
Link Exchange
  Blogs  
 Contest 
MathWorks.com

Loren on the Art of MATLAB

January 25th, 2006

What’s the Big deal?

So, what is the big deal? To start with, this week marks my 19th anniversary at MathWorks. Never would I have guessed back then what I am up to now, including talking about MATLAB with so many customers. I look forward to many more years working with MATLAB at MathWorks and meeting and working with so many wonderful customers.

In a recent post on the MATLAB newsgroup, Duane Hanselman mentioned that he found something interesting in the help for deal, namely the note:

In many instances, you can access the data in cell arrays and structure fields without using the deal function.
and he went on to ask when this was introduced. To find the answer, I did some archaeology in the MATLAB Release Notes and found this information in the notes for Release 14, MATLAB 7.

Why did we introduce this? Here are some of our thoughts from our design discussions:

  • Users either have to use deal or a loop to extract information from a cell array or a field of a struct array.
  • c{:} and a(:).fn both produce comma-separated lists in MATLAB. Before this change, you could enclose these expressions in square brackets ([ ]), curly braces ({ }), or parentheses for a function call (foo( )). Otherwise, they produced as many outputs as the length of the array input, each successively assigned to ans.
  • Because we were now allowing assignment with a comma separated list on the right hand side where it was not possible before, we were not going to break working code.
  • The idea seemed both natural and welcome when we spoke to some M programmers at MathWorks.

The biggest problem I see with this new construct is that it seems to have taken a while to get the exposure it deserves. While there is still clearly a role for deal, it's required less often than before MATLAB 7.

One code pattern I have seen deal used for is renaming variables. For example, you can swap the values of A and B with this:

    [B,A] = deal(A,B);

With the use of anonymous functions you can also accomplish the same outcome:

   swap=@(varargin)varargin{nargin:-1:1};

Now let's see what that does:

   a = 1;
   b = 2;
   c = 17;
   [a,b,c] = swap(a,b,c)

and the output looks like this:


a =

    17


b =

     2


c =

     1

There will be more in future articles on function handles, anonymous functions and nested functions. I have received suggestions for article topics from several of you and would love to gather even more input. Please keep the feedback coming!

6 Responses to “What’s the Big deal?”

  1. Keld replied on :

    Hello Loren,

    I’ve trying to convert my structure fields into variables, but it seems nobody is interested in this.
    My line of thought goes like this:

    s.a = 1:3
    s.b = 3×8 double
    s.c = 25×2 char array

    then struct2vars(s) produces
    a = 1:3
    b = 3×8 double
    c = 25×2 char array

    how can I achieve this?

    Keld

  2. Loren replied on :

    Hi Keld-

    You can’t do this easily in MATLAB. You could get the fieldnames of s and then use eval to create the variables, but using eval makes your program much harder to analyze and makes it less robust. Suppose later in your program, you want to call the function var. That’s all well and good, unless you now introduce a variable named var. Later, when you hit the statement where you intend the function to be called, you may or may not get a result, and it’s likely not what you wanted or were expecting.

    Far better to use the fields of the struct or put the variables into a cell array…

    –Loren

  3. Ron replied on :

    Hello, I was searching for a way to do exactly what Keld was asking.
    I was trying to do something like:

    a.b = 1; a.c = 2; a.d = 3;

    cellArray = struct2cell(a);
    names = fieldnames(a);
    eval([ ‘[’,[names{:}],’] = deal(cellArray{:})’])

    which doesn’t work because the eval string =
    [bcd] = deal(cellArray{:})

    when it needs to be:
    [b, c, d] = deal(cellArray{:})

    Is there a clever way to fix this without a for loop?

    Thanks! Ron Elmer

  4. Loren replied on :

    Ron-

    As many have noted, dynamically creating variable names in MATLAB is not a good practice. MATLAB does not always take kindly to variables being placed into the workspace, via eval and cousins, behind its back, so=to-speak.

    –Loren

  5. Oktay replied on :

    Hello,

    I don’t know if it’s really related to “deal” but I am just going to ask. Suppose that we have a function as follows:

    function [a b] = f(varargin)
    a = 1;
    b = 2;

    and somewhere we need B. So we type:

    [temp b] = f();

    which gives us a useless variable TEMP together with an M-lint warning. Moreover, if we want to call another function with input B, we need to do this in an another statement. (If it weren’t a function, we could use SUBSREF)

    So, is there a way to to achieve this in one statement?
    And is there a way not to introduce the TEMP variable?

    Thank you for your interest. And by the way keep up the great work. I gained so much from your columns.

    Oktay

  6. Loren replied on :

    Oktay-

    Depending what version of MATLAB you use, you shouldn’t see the mlint warning (the later the version, the better for that).

    There is no way to ask for just the 2nd output, so you can’t do what you want in a single statement unless you make your own function to index into outputs and grab the one you want with an extra function wrapped around the function f you are calling.

    We have it as an enhancement in our feature database to allow skipping assignment to earlier output variables.

    Today some people suggest doing something like this.

    [B,B] = f(...)
    

    so B gets overwritten. I don’t care for that as it assumes behavior of MATLAB (left-to-right) that we never wrote down and documented so could conceivably change it should that allow something new to be possible where it wouldn’t otherwise.

    –Loren

Leave a Reply


Loren Shure works on design of the MATLAB language at The MathWorks. She writes here about once a week on MATLAB programming and related topics.

  • J.B. Brown: Ah, and I am at fault for simply testing collinearity with the origin in the example above.
  • J.B. Brown: Indeed, > collinear( [0 3],[0 8],[0 -1e21+2e-15] ) ans = 1 > collinear( [0 3],[0 8],[0 -1e22+2e-15]...
  • OkinawaDolphin: Loren, thank you for telling me where to download timeit. Here are the two functions I just tested...
  • Loren: JB- It looks to me like Ilya’s solution and therefore yours are equivalent to the determinant. As Tim...
  • Loren: OkinawaDolphin, timeit can be downloaded from the File Exchange. Steve Eddins is the author. It does not ship...
  • OkinawaDolphin: It seems that neither R2007a nor R2007b have the function timeit, but I investigated computation time...
  • J.B. Brown: It would appear to me that Ilya Rozenfeld’s solution would be the cleanest. Just to help those who...
  • Loren: Markus- Congratulations on winning! And a nice illustration of how the size matters. Small enough, and the...
  • Markus: Hi Loren, which version is fastest also depends very much on the matrix dimensions. Look at my test function:...
  • Duncan: OkinawaDolphin, Regarding why your third example is slower than your second example, the result is in fact...

These postings are the author's and don't necessarily represent the opinions of The MathWorks.

Related Topics