Path: news.mathworks.com!not-for-mail
From: "Steven Lord" <slord@mathworks.com>
Newsgroups: comp.soft-sys.matlab
Subject: Re: genvarname doesn't work
Date: Fri, 24 Jul 2009 11:00:32 -0400
Organization: The MathWorks, Inc.
Lines: 104
Message-ID: <h4cia8$cjb$1@fred.mathworks.com>
References: <h37t8i$6kh$1@fred.mathworks.com> <op.uwu54zbja5ziv5@uthamaa.dhcp.mathworks.com> <h389nd$omc$1@fred.mathworks.com> <h38a6i$pud$1@fred.mathworks.com> <h38c66$5f9$1@fred.mathworks.com> <h38dor$hld$1@fred.mathworks.com> <h3e536$8q4$1@fred.mathworks.com> <h4apo6$143$1@fred.mathworks.com>
Reply-To: "Steven Lord" <slord@mathworks.com>
NNTP-Posting-Host: lords.dhcp.mathworks.com
X-Trace: fred.mathworks.com 1248447624 12907 144.212.105.187 (24 Jul 2009 15:00:24 GMT)
X-Complaints-To: news@mathworks.com
NNTP-Posting-Date: Fri, 24 Jul 2009 15:00:24 +0000 (UTC)
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2900.5512
X-RFC2646: Format=Flowed; Original
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.5579
Xref: news.mathworks.com comp.soft-sys.matlab:558147



"Juliette Salexa" <juliette.physicist@gmail.com> wrote in message 
news:h4apo6$143$1@fred.mathworks.com...
> Okay Steven Lord, you have definitely convinced me that there are 
> advantages of not poofing variables into existence, but how could a loop 
> like this be done without poofing variables ??
> ---------------------------------------------------
> A='AB';
> z=1;
> for a=1:length(A) for b=1:length(A) for c=1:length(A) % for d=... for 
> e=...
>            A3(z,1)=A(a);
>            A3(z,2)=A(b);
>            A3(z,3)=A(c);
> % ................. do the same for d, e , up to , let's say n
>            z=z+1; end
>            end
>        end
> ---------------------------------------------------
>
> It would take too long to type out "for" and "end"  n times.
> The only way I see this being done is something like:
>
> indices={'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o'};
> for y=1:length(indices)
>    for indices{y}=1:length(A)

This won't work.

>            string(z,y)=A(indices(y));
> ...
>
> But at line 3 we are poofing a new variable at each iteration of the for 
> loop.  The first time we are poofing a, the second time b, etc...
>
>
> Is there a way to do this without poofing variables ??

Yes.

A = 'AB';
nvariables = 5;
clear c
[c{1:nvariables}] = ndgrid(A);
A3 = repmat(' ', numel(c{1}), nvariables);
for k = 1:nvariables
    A3(:, k) = c{k}(:);
end

Or, if you don't like comma-separated lists and don't mind the combinations 
being in a little different order:

A = 'ABC';
nvariables = 5;
len = numel(A);
numCombs = len^nvariables;
ind = dec2base(0:(numCombs-1), len);
A(ind-'0'+1)

> ------------------------------------------------------------------------------------------------------
> Also, the using eval command doesn't necessarily mean we're poofing 
> variables into existence.... Let's say we had the variables 
> AAAA,AAAB,AAAC,......DDDC,DDDD ALREADY defined and set to equal numerical 
> values.   Now I want to put only ones with two of the same letter into a 
> cell array.
>
> So I should get a cell array like:
> cell= {AABB,AACC,AADD,BBAA,BBCC....DDCC}
>
> WITH their numerical values attached to those cell array entries. 
> Defining the cell the way I did just now would take a long time especially 
> if we add E and F.  But one thing I can do is come up with an algorithm 
> that generates the names of the variables I want, and then defines those 
> variables to equal the corresponding variables that previously existed, 
> using the eval command and "poofing" variables (already they already 
> existed before).
>
> Would there be a way out of this one ?? Does it involve the symbolic 
> toolkit ??

The first alternative I can think of would involve a slight modification to 
the problem statement -- rather than creating all those variables 
individually, I would have created them as fields of a struct array.  If you 
did that, you could use the FIELDNAMES function to determine what fields the 
struct array had, figure out which fields match your condition, and use 
those with dynamic field names to extract the appropriate fields from the 
struct.

I know what I'm about to say may sound shocking, but there are some uses 
where EVAL (or more frequently its cousins EVALC and EVALIN) is useful 
and/or necessary.  In those use cases, ASSUMING you know the consequences of 
EVAL and you ACCEPT those consequences, go ahead and use EVAL/EVALC/EVALIN. 
What I want you, and others, to avoid is using EVAL _where it's not needed_ 
or _where there are more robust alternatives that don't have the same 
consequences._  EVAL is a sledgehammer -- sometimes you need a sledge to do 
your work, but you probably shouldn't use it to drive the nail from which 
you're going to hang a picture into the wall or the screw you're using to 
assemble your new desk.

-- 
Steve Lord
slord@mathworks.com