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!
2:23 pm |
Posted in New Feature, Structures |
Permalink |
You can follow any responses to this entry through the RSS 2.0 feed.
You can skip to the end and leave a response. Pinging is currently not allowed.
Leave a Reply
|
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
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
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
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
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
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.
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