<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress/2.3.1" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>
<channel>
	<title>Comments on: Timing Extraction of Parts of an Array</title>
	<link>http://blogs.mathworks.com/loren/2008/09/25/timing-extraction-of-parts-of-an-array/</link>
	<description>Loren Shure  works on design of the MATLAB language at &#60;a href="http://www.mathworks.com/"&#62;The MathWorks&#60;/a&#62;. She writes here about once a week on MATLAB programming and related topics. &#60;br&#62;&#60;br&#62;&#60;a href="/images/loren-full.jpg"&#62;&#60;img src="/images/loren.jpg"&#62;&#60;/a&#62;</description>
	<pubDate>Mon, 23 Nov 2009 00:53:34 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.3.1</generator>
		<item>
		<title>By: Tom</title>
		<link>http://blogs.mathworks.com/loren/2008/09/25/timing-extraction-of-parts-of-an-array/#comment-29799</link>
		<dc:creator>Tom</dc:creator>
		<pubDate>Fri, 10 Oct 2008 16:05:27 +0000</pubDate>
		<guid>http://blogs.mathworks.com/loren/2008/09/25/timing-extraction-of-parts-of-an-array/#comment-29799</guid>
		<description>For what it's worth, I agree with Dave's comments above.  While in Dave's example the find() is unnecessary, I think it might be trying to demonstrate the case in which one has the numerical index upfront.

I've posted a similar comment a while back.  If you're dealing with a large data set, it should be more efficient (both in memory and time) to use numerical indexing if the number of elements you're selecting is small.

Suppose my array has 30 billion double elements =~ 256GB memory and suppose I'm interested in a 1 million element subset of this.  A logical index will be 30GB in size, while a numerical index will be 8M.  Not to mention other programming and microarchitectural advantages:  Traversing the smaller index will not trash my CPU's TLB (if I have large page support enabled).  Also, I know the number of elements in advance, so I can preallocate the memory needed (which, unfortunately, doesn't seem to be case with MATLAB - please correct me on this!).  Of course, any operations dealing with the index itself have to only deal with a much smaller number of entries.

Logical indexing is nice in most cases but let's not make numerical indexing a second class citizen.  While uniformity may lead to greater genericity, given the increasing amounts and complexity of data people have to deal with, one-size-fits-all solutions are not the optimal way forward - a programmer needs choice in his toolbox.  Unless the Mathworks wants MATLAB to be the tool of choice for only small-to-medium size problems (and I know they don't!),  facilities such as fast numerical indexing and shared memory for distributed workers located on the same machine are a must.

Think about the target audience:  From my experience, such applications are written in compiled languages (read C++/Fortran).  Performance oriented programmers will simply balk at the idea of using a tool that makes them choose between slow indexing or allocating an additional 30GB of memory.</description>
		<content:encoded><![CDATA[<p>For what it&#8217;s worth, I agree with Dave&#8217;s comments above.  While in Dave&#8217;s example the find() is unnecessary, I think it might be trying to demonstrate the case in which one has the numerical index upfront.</p>
<p>I&#8217;ve posted a similar comment a while back.  If you&#8217;re dealing with a large data set, it should be more efficient (both in memory and time) to use numerical indexing if the number of elements you&#8217;re selecting is small.</p>
<p>Suppose my array has 30 billion double elements =~ 256GB memory and suppose I&#8217;m interested in a 1 million element subset of this.  A logical index will be 30GB in size, while a numerical index will be 8M.  Not to mention other programming and microarchitectural advantages:  Traversing the smaller index will not trash my CPU&#8217;s TLB (if I have large page support enabled).  Also, I know the number of elements in advance, so I can preallocate the memory needed (which, unfortunately, doesn&#8217;t seem to be case with MATLAB - please correct me on this!).  Of course, any operations dealing with the index itself have to only deal with a much smaller number of entries.</p>
<p>Logical indexing is nice in most cases but let&#8217;s not make numerical indexing a second class citizen.  While uniformity may lead to greater genericity, given the increasing amounts and complexity of data people have to deal with, one-size-fits-all solutions are not the optimal way forward - a programmer needs choice in his toolbox.  Unless the Mathworks wants MATLAB to be the tool of choice for only small-to-medium size problems (and I know they don&#8217;t!),  facilities such as fast numerical indexing and shared memory for distributed workers located on the same machine are a must.</p>
<p>Think about the target audience:  From my experience, such applications are written in compiled languages (read C++/Fortran).  Performance oriented programmers will simply balk at the idea of using a tool that makes them choose between slow indexing or allocating an additional 30GB of memory.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Loren</title>
		<link>http://blogs.mathworks.com/loren/2008/09/25/timing-extraction-of-parts-of-an-array/#comment-29782</link>
		<dc:creator>Loren</dc:creator>
		<pubDate>Mon, 29 Sep 2008 12:10:01 +0000</pubDate>
		<guid>http://blogs.mathworks.com/loren/2008/09/25/timing-extraction-of-parts-of-an-array/#comment-29782</guid>
		<description>Thanks Yi.

Also, for what it's worth, I have put in an enhancement request to have the deletion syntax be on parity for performance as the other ones.  I believe there are some changes we can make, but I don't know how delicate they are so I can't predict when they might occur.

--loren</description>
		<content:encoded><![CDATA[<p>Thanks Yi.</p>
<p>Also, for what it&#8217;s worth, I have put in an enhancement request to have the deletion syntax be on parity for performance as the other ones.  I believe there are some changes we can make, but I don&#8217;t know how delicate they are so I can&#8217;t predict when they might occur.</p>
<p>&#8211;loren</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Yi Cao</title>
		<link>http://blogs.mathworks.com/loren/2008/09/25/timing-extraction-of-parts-of-an-array/#comment-29781</link>
		<dc:creator>Yi Cao</dc:creator>
		<pubDate>Sat, 27 Sep 2008 16:51:13 +0000</pubDate>
		<guid>http://blogs.mathworks.com/loren/2008/09/25/timing-extraction-of-parts-of-an-array/#comment-29781</guid>
		<description>Loren,

It is an interesting experiment. I wish to point out that even in the situation where a set of unwanted indices is given, keeping wanted could still be faster than deleting unwanted. The trick is to use logical indexing.

nPts = 1e7;
A = rand(nPts,1);
B = fft(A);
unwanted = find(A&#60;0.5);
Borig = B;
Borig(1) = Borig(1) + sin(0);

t1=tic;
keep=true(nPts,1);
keep(unwanted)=false;
B=B(keep);
toc(t1)
B=Borig;
Borig(1) = Borig(1) + sin(0);
t2=tic;
B(unwanted)=[];
toc(t2)
B=Borig;
Borig(1) = Borig(1) + sin(0);
t3=tic;
keep=true(nPts,1);
keep(unwanted)=false;
C=B(keep);
toc(t3)

The results are:
Elapsed time is 0.464593 seconds.
Elapsed time is 0.549569 seconds.
Elapsed time is 0.468961 seconds.

Now with more elements to delete.

unwanted = find(A&#60;0.9);
Borig = B;
Borig(1) = Borig(1) + sin(0);

t1=tic;
keep=true(nPts,1);
keep(unwanted)=false;
B=B(keep);
toc(t1)
B=Borig;
Borig(1) = Borig(1) + sin(0);
t2=tic;
B(unwanted)=[];
toc(t2)
B=Borig;
Borig(1) = Borig(1) + sin(0);
t3=tic;
keep=true(nPts,1);
keep(unwanted)=false;
C=B(keep);
toc(t3)

Elapsed time is 0.435304 seconds.
Elapsed time is 0.488471 seconds.
Elapsed time is 0.422132 seconds.

Finally, with less elements to delete

unwanted = find(A&#60;0.1);
Borig = B;
Borig(1) = Borig(1) + sin(0);

t1=tic;
keep=true(nPts,1);
keep(unwanted)=false;
B=B(keep);
toc(t1)
B=Borig;
Borig(1) = Borig(1) + sin(0);
t2=tic;
B(unwanted)=[];
toc(t2)
B=Borig;
Borig(1) = Borig(1) + sin(0);
t3=tic;
keep=true(nPts,1);
keep(unwanted)=false;
C=B(keep);
toc(t3)

The results are

Elapsed time is 0.395496 seconds.
Elapsed time is 0.556099 seconds.
Elapsed time is 0.343438 seconds.

Three time patterns are almost the same. Deleting is still the most expensive one even when the comparison includes the time to create a logical keeping index set. If the unwanted indices are already in a logical vector, then keep=~unwanted, hence keeping is much more favorable.</description>
		<content:encoded><![CDATA[<p>Loren,</p>
<p>It is an interesting experiment. I wish to point out that even in the situation where a set of unwanted indices is given, keeping wanted could still be faster than deleting unwanted. The trick is to use logical indexing.</p>
<p>nPts = 1e7;<br />
A = rand(nPts,1);<br />
B = fft(A);<br />
unwanted = find(A&lt;0.5);<br />
Borig = B;<br />
Borig(1) = Borig(1) + sin(0);</p>
<p>t1=tic;<br />
keep=true(nPts,1);<br />
keep(unwanted)=false;<br />
B=B(keep);<br />
toc(t1)<br />
B=Borig;<br />
Borig(1) = Borig(1) + sin(0);<br />
t2=tic;<br />
B(unwanted)=[];<br />
toc(t2)<br />
B=Borig;<br />
Borig(1) = Borig(1) + sin(0);<br />
t3=tic;<br />
keep=true(nPts,1);<br />
keep(unwanted)=false;<br />
C=B(keep);<br />
toc(t3)</p>
<p>The results are:<br />
Elapsed time is 0.464593 seconds.<br />
Elapsed time is 0.549569 seconds.<br />
Elapsed time is 0.468961 seconds.</p>
<p>Now with more elements to delete.</p>
<p>unwanted = find(A&lt;0.9);<br />
Borig = B;<br />
Borig(1) = Borig(1) + sin(0);</p>
<p>t1=tic;<br />
keep=true(nPts,1);<br />
keep(unwanted)=false;<br />
B=B(keep);<br />
toc(t1)<br />
B=Borig;<br />
Borig(1) = Borig(1) + sin(0);<br />
t2=tic;<br />
B(unwanted)=[];<br />
toc(t2)<br />
B=Borig;<br />
Borig(1) = Borig(1) + sin(0);<br />
t3=tic;<br />
keep=true(nPts,1);<br />
keep(unwanted)=false;<br />
C=B(keep);<br />
toc(t3)</p>
<p>Elapsed time is 0.435304 seconds.<br />
Elapsed time is 0.488471 seconds.<br />
Elapsed time is 0.422132 seconds.</p>
<p>Finally, with less elements to delete</p>
<p>unwanted = find(A&lt;0.1);<br />
Borig = B;<br />
Borig(1) = Borig(1) + sin(0);</p>
<p>t1=tic;<br />
keep=true(nPts,1);<br />
keep(unwanted)=false;<br />
B=B(keep);<br />
toc(t1)<br />
B=Borig;<br />
Borig(1) = Borig(1) + sin(0);<br />
t2=tic;<br />
B(unwanted)=[];<br />
toc(t2)<br />
B=Borig;<br />
Borig(1) = Borig(1) + sin(0);<br />
t3=tic;<br />
keep=true(nPts,1);<br />
keep(unwanted)=false;<br />
C=B(keep);<br />
toc(t3)</p>
<p>The results are</p>
<p>Elapsed time is 0.395496 seconds.<br />
Elapsed time is 0.556099 seconds.<br />
Elapsed time is 0.343438 seconds.</p>
<p>Three time patterns are almost the same. Deleting is still the most expensive one even when the comparison includes the time to create a logical keeping index set. If the unwanted indices are already in a logical vector, then keep=~unwanted, hence keeping is much more favorable.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Loren</title>
		<link>http://blogs.mathworks.com/loren/2008/09/25/timing-extraction-of-parts-of-an-array/#comment-29779</link>
		<dc:creator>Loren</dc:creator>
		<pubDate>Fri, 26 Sep 2008 11:08:08 +0000</pubDate>
		<guid>http://blogs.mathworks.com/loren/2008/09/25/timing-extraction-of-parts-of-an-array/#comment-29779</guid>
		<description>Jebb-

Good question!  In today's MATLAB you don't need to do more than A(1) = B(1) but I was trying to write the code thinking about how MATLAB might get smarter in the future so I was trying to outwit the optimization to not copy for a longer tenure in MATLAB releases.

--Loren</description>
		<content:encoded><![CDATA[<p>Jebb-</p>
<p>Good question!  In today&#8217;s MATLAB you don&#8217;t need to do more than A(1) = B(1) but I was trying to write the code thinking about how MATLAB might get smarter in the future so I was trying to outwit the optimization to not copy for a longer tenure in MATLAB releases.</p>
<p>&#8211;Loren</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: jebb</title>
		<link>http://blogs.mathworks.com/loren/2008/09/25/timing-extraction-of-parts-of-an-array/#comment-29778</link>
		<dc:creator>jebb</dc:creator>
		<pubDate>Fri, 26 Sep 2008 09:32:02 +0000</pubDate>
		<guid>http://blogs.mathworks.com/loren/2008/09/25/timing-extraction-of-parts-of-an-array/#comment-29778</guid>
		<description>I was interested to see this method of forcing a non-lazy copy:

    A = B;
    A(1) = A(1) + sin(0);

Presumably the +sin(0) prevents the line being optimized away, though I wasn't aware that MATLAB did that kind of optimizing. In the past I've tended to use:

    A = B;
    A(1) = B(1);

Is the sin(0) method preferred? Does anybody know of a simple method that works even when the array being copied is empty? The most foolproof method is probably to write a MEX function that calls mxDuplicateArray(), however.</description>
		<content:encoded><![CDATA[<p>I was interested to see this method of forcing a non-lazy copy:</p>
<p>    A = B;<br />
    A(1) = A(1) + sin(0);</p>
<p>Presumably the +sin(0) prevents the line being optimized away, though I wasn&#8217;t aware that MATLAB did that kind of optimizing. In the past I&#8217;ve tended to use:</p>
<p>    A = B;<br />
    A(1) = B(1);</p>
<p>Is the sin(0) method preferred? Does anybody know of a simple method that works even when the array being copied is empty? The most foolproof method is probably to write a MEX function that calls mxDuplicateArray(), however.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Steve L</title>
		<link>http://blogs.mathworks.com/loren/2008/09/25/timing-extraction-of-parts-of-an-array/#comment-29776</link>
		<dc:creator>Steve L</dc:creator>
		<pubDate>Thu, 25 Sep 2008 20:37:02 +0000</pubDate>
		<guid>http://blogs.mathworks.com/loren/2008/09/25/timing-extraction-of-parts-of-an-array/#comment-29776</guid>
		<description>Dave,

Looking at your post 1 and Vincent's post 4, in addition to thinking about speed, you might want to think about memory.  If more than 1/8 of your elements in your FIND call will satisfy the condition, the double array of indices generated from your FIND call will require more memory than the logical "mask" created by your condition:
&lt;pre&gt;
&#62;&#62; x = 1:10;
&#62;&#62; ndx = find(x &#62; 8); % 2 elements &#62; (1/8) of x
&#62;&#62; mask = (x &#62; 8);
&#62;&#62; whos ndx mask
  Name      Size            Bytes  Class      Attributes

  mask      1x10               10  logical              
  ndx       1x2                16  double               
&lt;/pre&gt;
since real double values take up 8 bytes and logical values only take 1.  In addition, you can use them the same way to delete elements:
&lt;pre&gt;
&#62;&#62; x2 = x;
&#62;&#62; x3 = x;
&#62;&#62; x2(ndx) = [];
&#62;&#62; x3(mask) = [];
&#62;&#62; isequal(x2, x3)

ans =

     1
&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>Dave,</p>
<p>Looking at your post 1 and Vincent&#8217;s post 4, in addition to thinking about speed, you might want to think about memory.  If more than 1/8 of your elements in your FIND call will satisfy the condition, the double array of indices generated from your FIND call will require more memory than the logical &#8220;mask&#8221; created by your condition:</p>
<pre>
&gt;&gt; x = 1:10;
&gt;&gt; ndx = find(x &gt; 8); % 2 elements &gt; (1/8) of x
&gt;&gt; mask = (x &gt; 8);
&gt;&gt; whos ndx mask
  Name      Size            Bytes  Class      Attributes

  mask      1x10               10  logical
  ndx       1x2                16  double
</pre>
<p>since real double values take up 8 bytes and logical values only take 1.  In addition, you can use them the same way to delete elements:</p>
<pre>
&gt;&gt; x2 = x;
&gt;&gt; x3 = x;
&gt;&gt; x2(ndx) = [];
&gt;&gt; x3(mask) = [];
&gt;&gt; isequal(x2, x3)

ans =

     1
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Vincent</title>
		<link>http://blogs.mathworks.com/loren/2008/09/25/timing-extraction-of-parts-of-an-array/#comment-29773</link>
		<dc:creator>Vincent</dc:creator>
		<pubDate>Thu, 25 Sep 2008 18:52:39 +0000</pubDate>
		<guid>http://blogs.mathworks.com/loren/2008/09/25/timing-extraction-of-parts-of-an-array/#comment-29773</guid>
		<description>Dave-

On your first post, you could use logical indexing:

% keep all B different than 1234
indKeep=(B~=1234);
B=B(indKeep); 

Keeping still is faster than deleting for randomly placed elements. Like for normal indexing, deletion of a small number of elements have less penalty than deletion of a large number of elements, but deletion seems to be always slower.</description>
		<content:encoded><![CDATA[<p>Dave-</p>
<p>On your first post, you could use logical indexing:</p>
<p>% keep all B different than 1234<br />
indKeep=(B~=1234);<br />
B=B(indKeep); </p>
<p>Keeping still is faster than deleting for randomly placed elements. Like for normal indexing, deletion of a small number of elements have less penalty than deletion of a large number of elements, but deletion seems to be always slower.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Loren</title>
		<link>http://blogs.mathworks.com/loren/2008/09/25/timing-extraction-of-parts-of-an-array/#comment-29772</link>
		<dc:creator>Loren</dc:creator>
		<pubDate>Thu, 25 Sep 2008 17:44:15 +0000</pubDate>
		<guid>http://blogs.mathworks.com/loren/2008/09/25/timing-extraction-of-parts-of-an-array/#comment-29772</guid>
		<description>Dave-

It really depends on how you create the indices in the first place.  If you have the luxury of creating the keepers instead of the discards, you are probably better of skipping find and using logical indexing instead.  After all, that logical array is the input to find, so you aren't doing extra work.

I am not sure understand your 2nd question/point.  Are you trying to see what to do if you don't know the total number?  If so, there are strategies, like guessing a total amount up front, but preparing to augment in chunks as required.  Perhaps that's what you are doing???

Set the unused entries to a value that you can delete later.  If you reach the end of the chunk, add a new chunk on the same way.  Which might be what you are doing...  If so, all I can recommend is that you do some profiling with "typical" sizes and figure out a large enough chunk size without overwhelming your memory.

--Loren</description>
		<content:encoded><![CDATA[<p>Dave-</p>
<p>It really depends on how you create the indices in the first place.  If you have the luxury of creating the keepers instead of the discards, you are probably better of skipping find and using logical indexing instead.  After all, that logical array is the input to find, so you aren&#8217;t doing extra work.</p>
<p>I am not sure understand your 2nd question/point.  Are you trying to see what to do if you don&#8217;t know the total number?  If so, there are strategies, like guessing a total amount up front, but preparing to augment in chunks as required.  Perhaps that&#8217;s what you are doing???</p>
<p>Set the unused entries to a value that you can delete later.  If you reach the end of the chunk, add a new chunk on the same way.  Which might be what you are doing&#8230;  If so, all I can recommend is that you do some profiling with &#8220;typical&#8221; sizes and figure out a large enough chunk size without overwhelming your memory.</p>
<p>&#8211;Loren</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave</title>
		<link>http://blogs.mathworks.com/loren/2008/09/25/timing-extraction-of-parts-of-an-array/#comment-29771</link>
		<dc:creator>Dave</dc:creator>
		<pubDate>Thu, 25 Sep 2008 17:20:04 +0000</pubDate>
		<guid>http://blogs.mathworks.com/loren/2008/09/25/timing-extraction-of-parts-of-an-array/#comment-29771</guid>
		<description>Also, I often need to work with very large sets of data that cannot reside in memory -- let's say 1 billion elements -- and in a fashion that I cannot pre-allocate my intended output array. 

For example:
C = [];
sizeChunk = 10e6;   % 10 million element working array
Nchunks=length(BigInput)/sizeChunk; 
for n=1:Nchunks,
  B = BigInput;  % with BigInput being my 1e9 input
  Borig(1) = Borig(1) + sin(0);
  cutoff = ceil(sizeChunk * randn); % variable cutoff
  C = cat(2,C,B(1:cutoff));
end

Any thoughts? 

Thanks!</description>
		<content:encoded><![CDATA[<p>Also, I often need to work with very large sets of data that cannot reside in memory &#8212; let&#8217;s say 1 billion elements &#8212; and in a fashion that I cannot pre-allocate my intended output array. </p>
<p>For example:<br />
C = [];<br />
sizeChunk = 10e6;   % 10 million element working array<br />
Nchunks=length(BigInput)/sizeChunk;<br />
for n=1:Nchunks,<br />
  B = BigInput;  % with BigInput being my 1e9 input<br />
  Borig(1) = Borig(1) + sin(0);<br />
  cutoff = ceil(sizeChunk * randn); % variable cutoff<br />
  C = cat(2,C,B(1:cutoff));<br />
end</p>
<p>Any thoughts? </p>
<p>Thanks!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave</title>
		<link>http://blogs.mathworks.com/loren/2008/09/25/timing-extraction-of-parts-of-an-array/#comment-29770</link>
		<dc:creator>Dave</dc:creator>
		<pubDate>Thu, 25 Sep 2008 17:08:46 +0000</pubDate>
		<guid>http://blogs.mathworks.com/loren/2008/09/25/timing-extraction-of-parts-of-an-array/#comment-29770</guid>
		<description>Thanks for the article.  

I personally find myself more in the situation where I want to delete non-contiguous indicies, rather than halving an array or similar.  So, I end up using a find (similar to your previous articles) as such:
ndx=find(B==1234); 
B(ndx)=[];

Any thoughts on efficiency on this?

Thanks!</description>
		<content:encoded><![CDATA[<p>Thanks for the article.  </p>
<p>I personally find myself more in the situation where I want to delete non-contiguous indicies, rather than halving an array or similar.  So, I end up using a find (similar to your previous articles) as such:<br />
ndx=find(B==1234);<br />
B(ndx)=[];</p>
<p>Any thoughts on efficiency on this?</p>
<p>Thanks!</p>
]]></content:encoded>
	</item>
</channel>
</rss>
