Path: news.mathworks.com!not-for-mail
From: "Sven " <sven.holcombe@gmail.deleteme.com>
Newsgroups: comp.soft-sys.matlab
Subject: Re: eval, feval, global
Date: Thu, 27 Mar 2008 04:22:02 +0000 (UTC)
Organization: The MathWorks, Inc.
Lines: 116
Message-ID: <fsf7da$g1$1@fred.mathworks.com>
References: <fsebf0$43u$1@fred.mathworks.com> <fsf3ss$e2e$1@fred.mathworks.com>
Reply-To: "Sven " <sven.holcombe@gmail.deleteme.com>
NNTP-Posting-Host: webapp-05-blr.mathworks.com
Content-Type: text/plain; charset="ISO-8859-1"
Content-Transfer-Encoding: 8bit
X-Trace: fred.mathworks.com 1206591722 513 172.30.248.35 (27 Mar 2008 04:22:02 GMT)
X-Complaints-To: news@mathworks.com
NNTP-Posting-Date: Thu, 27 Mar 2008 04:22:02 +0000 (UTC)
X-Newsreader: MATLAB Central Newsreader 1326470
Xref: news.mathworks.com comp.soft-sys.matlab:459397


"Yuri Geshelin" <geshelin@hotmail.com> wrote in message
<fsf3ss$e2e$1@fred.mathworks.com>...
> Thanks to everyone who replied. I agree with John about 
> GLOBAL.
> 
> As for EVAL, as Peter suggested, let me show you my code, 
> which I found useful. 
> 
> (Actually, there are two situations, in which I use EVAL, 
> but I will start with presenting the 1st one, as it is 
> perhaps the more controversial.)
> 
> Suppose we have 2 arrays of equal length:
> 
> a = [15 23 35 43];
> b = [ 2 11  8  3];
> 
> and we need an algorithm, which constructs output array c 
> as follows:
> 
> c = [15 15 <23 repeated 11 times> <35 repeated 8 times> 43 
> 43 43]
> 
> Here is a simple function construct_array1, which 
> accomplishes this task.
> 
> % *************************** top of construct_array1
> function c = construct_array1(a,b)
> 
> c = [];
> for i = 1 : length(a)
>     c = [c ones(1,b(i))*a(i)];
> end
> 
> % *************************** end of construct_array1
> 
> And here is another function construct_array, which 
> accomplishes the same task.
> 
> % *************************** top of construct_array
> function c = construct_array(a,b)
> 
> if length(a) ~= length(b)
>     error('arrays a and b should be of equal lengths!')
> end
> 
> k = floor(log10(max(a)))+1;
> i = floor(log10(max(b)))+1;
> n = length(a);
> m = ones(n,1);
> c = eval(['[' ...
>     reshape([char([m*'o' m*'n' m*'e' m*'s' m*'(' m*'1' 
> m*',']) ...
>     reshape(sprintf(['%' num2str(i) 'd'],b),i,n)' ...
>     char([m*')' m*'*']) ...
>     reshape(sprintf(['%' num2str(k) 'd'],a),k,n)' ...
>     char(m*' ')]',1,n*(k+i+10)) ']']);
> % *************************** end of construct_array
> 
> Think this is crazy? However, let us test both functions:
> 
> >> t = cputime; construct_array1(1:10,1000001:1000010); 
> cputime-t
> 
> ans =
> 
>      1.1875
> 
> >> t = cputime; construct_array(1:10,1000001:1000010); 
> cputime-t
> 
> ans =
> 
>      0.4531
> 
> (I was afraid that matlab would crash, but it did not.)
> 
> This was experimented on
> 
> MATLAB Version 7.0.4.365 (R14) Service Pack 2
> Operating System: Microsoft Windows XP Version 5.1 (Build 
> 2600: Service Pack 2)
> Pentuim(R) 4 CPU 3.20 GHz, 1.00 GB of RAM.
> 
> My implementation is thus 2.6 times faster than the use of 
> a loop. 
> I admit that this can be costly in terms of RAM, because 
> the text string supplied to eval can 
> be huge. But in my practice, the arrays are not too long 
> (way shorter than in the test case). 
> The cpu time is saved because I call my function many times 
> in a loop.
> 
> Yuri
> 


Hi Yuri,

I haven't tested exactly how much, but I'm sure
preallocating your result array will significantly speed up
the non-eval version of the function.

Eg:

startIdx = 1;
c = zeros(1,sum(b));
for i = 1:length(b)
    c((0:b(i)-1) + startIdx) = ones(1,b(i))*a(i);
    startIdx = startIdx + b(i);
end

And I'm sure this can be improved further still.

Cheers,
Sven.