<?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: MATLAB Puzzler: Removing columns and rows from binary matrices</title>
	<link>http://blogs.mathworks.com/pick/2008/03/25/matlab-puzzler-removing-columns-and-rows-from-binary-matrices/</link>
	<description>&#60;a href="http://www.mathworks.com/matlabcentral/fileexchange/loadAuthor.do?objectId=969735&#38;objectType=author"&#62;Bob&#60;/a&#62;, &#60;a href="http://www.mathworks.com/matlabcentral/fileexchange/loadAuthor.do?objectId=1093599&#38;objectType=author"&#62;Brett&#60;/a&#62; &#38; &#60;a href="http://www.mathworks.com/matlabcentral/fileexchange/loadAuthor.do?objectId=1094142&#38;objectType=author"&#62;Jiro&#60;/a&#62; share favorite user-contributed submissions from the File Exchange.</description>
	<pubDate>Mon, 23 Nov 2009 00:07:17 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.3.1</generator>
		<item>
		<title>By: Bradley</title>
		<link>http://blogs.mathworks.com/pick/2008/03/25/matlab-puzzler-removing-columns-and-rows-from-binary-matrices/#comment-12555</link>
		<dc:creator>Bradley</dc:creator>
		<pubDate>Tue, 26 Aug 2008 00:46:23 +0000</pubDate>
		<guid>http://blogs.mathworks.com/pick/2008/03/25/matlab-puzzler-removing-columns-and-rows-from-binary-matrices/#comment-12555</guid>
		<description>One fast fix to this to make it faster just use logical indexing and remove the find

remember a sum is simply an or operation on the columns

A(:,sum(A)~=0)</description>
		<content:encoded><![CDATA[<p>One fast fix to this to make it faster just use logical indexing and remove the find</p>
<p>remember a sum is simply an or operation on the columns</p>
<p>A(:,sum(A)~=0)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Bradley</title>
		<link>http://blogs.mathworks.com/pick/2008/03/25/matlab-puzzler-removing-columns-and-rows-from-binary-matrices/#comment-12554</link>
		<dc:creator>Bradley</dc:creator>
		<pubDate>Tue, 26 Aug 2008 00:38:33 +0000</pubDate>
		<guid>http://blogs.mathworks.com/pick/2008/03/25/matlab-puzzler-removing-columns-and-rows-from-binary-matrices/#comment-12554</guid>
		<description>single liner for you, just in case someone looks for this and wants something simpler (just switch the sum direction and col and rows, to delete the rows)

A(:,find(sum(A)~=0))</description>
		<content:encoded><![CDATA[<p>single liner for you, just in case someone looks for this and wants something simpler (just switch the sum direction and col and rows, to delete the rows)</p>
<p>A(:,find(sum(A)~=0))</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: craig</title>
		<link>http://blogs.mathworks.com/pick/2008/03/25/matlab-puzzler-removing-columns-and-rows-from-binary-matrices/#comment-12477</link>
		<dc:creator>craig</dc:creator>
		<pubDate>Tue, 19 Aug 2008 02:54:19 +0000</pubDate>
		<guid>http://blogs.mathworks.com/pick/2008/03/25/matlab-puzzler-removing-columns-and-rows-from-binary-matrices/#comment-12477</guid>
		<description>Input: a
Output: a(:,nonzeros((1:columns(a)).*max(a!=0)))

It is completely vectorized.</description>
		<content:encoded><![CDATA[<p>Input: a<br />
Output: a(:,nonzeros((1:columns(a)).*max(a!=0)))</p>
<p>It is completely vectorized.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ned Gulley</title>
		<link>http://blogs.mathworks.com/pick/2008/03/25/matlab-puzzler-removing-columns-and-rows-from-binary-matrices/#comment-10294</link>
		<dc:creator>Ned Gulley</dc:creator>
		<pubDate>Fri, 28 Mar 2008 21:35:59 +0000</pubDate>
		<guid>http://blogs.mathworks.com/pick/2008/03/25/matlab-puzzler-removing-columns-and-rows-from-binary-matrices/#comment-10294</guid>
		<description>Yi Cao is not a MATLAB programming contest champion for nothing!

http://www.mathworks.com/contest/jumping/winners.html#winner1</description>
		<content:encoded><![CDATA[<p>Yi Cao is not a MATLAB programming contest champion for nothing!</p>
<p><a href="http://www.mathworks.com/contest/jumping/winners.html#winner1" rel="nofollow">http://www.mathworks.com/contest/jumping/winners.html#winner1</a></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Yi Cao</title>
		<link>http://blogs.mathworks.com/pick/2008/03/25/matlab-puzzler-removing-columns-and-rows-from-binary-matrices/#comment-10286</link>
		<dc:creator>Yi Cao</dc:creator>
		<pubDate>Fri, 28 Mar 2008 13:42:19 +0000</pubDate>
		<guid>http://blogs.mathworks.com/pick/2008/03/25/matlab-puzzler-removing-columns-and-rows-from-binary-matrices/#comment-10286</guid>
		<description>Doug,

Thanks for comments. I see the reason why the second does not work because it missed the cases where there are more rows than columns with all zeros. Here is the modified version.
&lt;pre&gt;
while ~isequal(any(A) &#38; any(A,2)', any(A'))
    A(~any(A),:)=0;
end
disp(['Removed columns: ',num2str(find(~any(A)))]);
disp(A(any(A),any(A)));
&lt;/pre&gt;

The first code is based on the fact that a diagonl mtrix left-multiply a matrix equivalent to multiply the matrix row by row with the corresponding elements in the diagonal vector. Hence, any(A) get a vector with 1 where the coulmn is not full zero, 0 otherwise. Using this vector to form a diagonl mtrix to left multiply A will set rows of A either all zero (multiply by 0 where corresponding column is all zero) or no change (multiply 1 where corresponding column is not full zero). This is exactly your puzzle required.

In the code, double is used to convert logical variable produced by any(A) to double so that the multiplication can be performed.

Hope this makes the code understandable.</description>
		<content:encoded><![CDATA[<p>Doug,</p>
<p>Thanks for comments. I see the reason why the second does not work because it missed the cases where there are more rows than columns with all zeros. Here is the modified version.</p>
<pre>
while ~isequal(any(A) &amp; any(A,2)', any(A'))
    A(~any(A),:)=0;
end
disp(['Removed columns: ',num2str(find(~any(A)))]);
disp(A(any(A),any(A)));
</pre>
<p>The first code is based on the fact that a diagonl mtrix left-multiply a matrix equivalent to multiply the matrix row by row with the corresponding elements in the diagonal vector. Hence, any(A) get a vector with 1 where the coulmn is not full zero, 0 otherwise. Using this vector to form a diagonl mtrix to left multiply A will set rows of A either all zero (multiply by 0 where corresponding column is all zero) or no change (multiply 1 where corresponding column is not full zero). This is exactly your puzzle required.</p>
<p>In the code, double is used to convert logical variable produced by any(A) to double so that the multiplication can be performed.</p>
<p>Hope this makes the code understandable.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Doug</title>
		<link>http://blogs.mathworks.com/pick/2008/03/25/matlab-puzzler-removing-columns-and-rows-from-binary-matrices/#comment-10285</link>
		<dc:creator>Doug</dc:creator>
		<pubDate>Fri, 28 Mar 2008 13:11:51 +0000</pubDate>
		<guid>http://blogs.mathworks.com/pick/2008/03/25/matlab-puzzler-removing-columns-and-rows-from-binary-matrices/#comment-10285</guid>
		<description>Yi,

The first algorithm seems to work.

The second fails here:

&lt;code&gt;A = [
     0     1     0     0     0
     0     0     0     0     0
     0     0     0     0     0
     1     0     0     1     0
     0     0     0     0     1]
&lt;/code&gt;

What I notice with your code is that it works, but after five minutes, I still do not really understand why.   It is very clever, more clever than me!

My goal in writing code is to make people understand it as easily as the computer does.  More often than not, the person that will need to understand it is me in a few weeks once I have forgotten all about it.  Here is my solution:

&lt;code&gt;a = full(round(sprand(5,5,0.8)))
oldEmptyCols = [];
newEmptyCols = all(~a);
%
while ~isequal(oldEmptyCols, newEmptyCols)
   a(newEmptyCols,:) = 0;
   oldEmptyCols = newEmptyCols;
   newEmptyCols = all(~a);
end
% display results
disp ('---------------')
disp(['Remove these columns: ' num2str(find(newEmptyCols))])
find(newEmptyCols)
%
a(newEmptyCols,:) = [];
a(:,newEmptyCols) = []&lt;/code&gt;

Notice that with a good variable naming scheme and use of functions that are pronounceable, this code is very readable, even without comments.  

For example, I picked: 
&lt;code&gt;~isequal(oldEmptyCols, newEmptyCols)&lt;/code&gt;
instead of 
&lt;code&gt;~(oldEmptyCols == newEmptyCols)&lt;/code&gt;

Little things like this make the code easier to understand when you need to deal with it again later.

Doug</description>
		<content:encoded><![CDATA[<p>Yi,</p>
<p>The first algorithm seems to work.</p>
<p>The second fails here:</p>
<p><code>A = [<br />
     0     1     0     0     0<br />
     0     0     0     0     0<br />
     0     0     0     0     0<br />
     1     0     0     1     0<br />
     0     0     0     0     1]<br />
</code></p>
<p>What I notice with your code is that it works, but after five minutes, I still do not really understand why.   It is very clever, more clever than me!</p>
<p>My goal in writing code is to make people understand it as easily as the computer does.  More often than not, the person that will need to understand it is me in a few weeks once I have forgotten all about it.  Here is my solution:</p>
<p><code>a = full(round(sprand(5,5,0.8)))<br />
oldEmptyCols = [];<br />
newEmptyCols = all(~a);<br />
%<br />
while ~isequal(oldEmptyCols, newEmptyCols)<br />
   a(newEmptyCols,:) = 0;<br />
   oldEmptyCols = newEmptyCols;<br />
   newEmptyCols = all(~a);<br />
end<br />
% display results<br />
disp (&#8217;&#8212;&#8212;&#8212;&#8212;&#8212;&#8217;)<br />
disp([&#8217;Remove these columns: &#8216; num2str(find(newEmptyCols))])<br />
find(newEmptyCols)<br />
%<br />
a(newEmptyCols,:) = [];<br />
a(:,newEmptyCols) = []</code></p>
<p>Notice that with a good variable naming scheme and use of functions that are pronounceable, this code is very readable, even without comments.  </p>
<p>For example, I picked:<br />
<code>~isequal(oldEmptyCols, newEmptyCols)</code><br />
instead of<br />
<code>~(oldEmptyCols == newEmptyCols)</code></p>
<p>Little things like this make the code easier to understand when you need to deal with it again later.</p>
<p>Doug</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Yi Cao</title>
		<link>http://blogs.mathworks.com/pick/2008/03/25/matlab-puzzler-removing-columns-and-rows-from-binary-matrices/#comment-10278</link>
		<dc:creator>Yi Cao</dc:creator>
		<pubDate>Fri, 28 Mar 2008 08:46:41 +0000</pubDate>
		<guid>http://blogs.mathworks.com/pick/2008/03/25/matlab-puzzler-removing-columns-and-rows-from-binary-matrices/#comment-10278</guid>
		<description>Another solution may be even simpler:

&lt;pre&gt;
while ~isequal(any(A),any(A,2)')
    A(~any(A),:)=0;
end
disp(['Removed columns: ',num2str(find(~any(A)))]);
disp(A(any(A),any(A)));
</description>
		<content:encoded><![CDATA[<p>Another solution may be even simpler:</p>
<pre>
while ~isequal(any(A),any(A,2)')<br />
    A(~any(A),:)=0;<br />
end<br />
disp([&#8217;Removed columns: &#8216;,num2str(find(~any(A)))]);<br />
disp(A(any(A),any(A)));
</pre>]]></content:encoded>
	</item>
	<item>
		<title>By: Yi Cao</title>
		<link>http://blogs.mathworks.com/pick/2008/03/25/matlab-puzzler-removing-columns-and-rows-from-binary-matrices/#comment-10268</link>
		<dc:creator>Yi Cao</dc:creator>
		<pubDate>Thu, 27 Mar 2008 23:36:02 +0000</pubDate>
		<guid>http://blogs.mathworks.com/pick/2008/03/25/matlab-puzzler-removing-columns-and-rows-from-binary-matrices/#comment-10268</guid>
		<description>It is an interesting puzzle. Here is my solution. It took about 10 minutes.

while ~isequal(a,diag(double(any(a)))*a)
    a=diag(double(any(a)))*a;
end
idx=any(a);
disp(['Removed columns: ',num2str(find(~idx))])
disp(a(idx,idx))</description>
		<content:encoded><![CDATA[<p>It is an interesting puzzle. Here is my solution. It took about 10 minutes.</p>
<p>while ~isequal(a,diag(double(any(a)))*a)<br />
    a=diag(double(any(a)))*a;<br />
end<br />
idx=any(a);<br />
disp([&#8217;Removed columns: &#8216;,num2str(find(~idx))])<br />
disp(a(idx,idx))</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Francois</title>
		<link>http://blogs.mathworks.com/pick/2008/03/25/matlab-puzzler-removing-columns-and-rows-from-binary-matrices/#comment-10248</link>
		<dc:creator>Francois</dc:creator>
		<pubDate>Thu, 27 Mar 2008 01:50:16 +0000</pubDate>
		<guid>http://blogs.mathworks.com/pick/2008/03/25/matlab-puzzler-removing-columns-and-rows-from-binary-matrices/#comment-10248</guid>
		<description>Hello,

Here is another solution based on MATLAB's powerful indexing capabilities:

&lt;pre&gt;
function res = puzzler(a)
sub = 1:size(a, 1); 
rem = zeros(1, 0);
zer = 0;
while ~isempty(zer)
    zer=find(sum(a(sub, sub), 1)==0);
    rem = [rem sub(zer)];
    sub(zer)=[];
end
disp(sprintf('Removed: %s', mat2str(rem)));
res = a(sub,sub);
&lt;/pre&gt;    

(this works "in place" without disturbing the contents of a)</description>
		<content:encoded><![CDATA[<p>Hello,</p>
<p>Here is another solution based on MATLAB&#8217;s powerful indexing capabilities:</p>
<pre>
function res = puzzler(a)
sub = 1:size(a, 1);
rem = zeros(1, 0);
zer = 0;
while ~isempty(zer)
    zer=find(sum(a(sub, sub), 1)==0);
    rem = [rem sub(zer)];
    sub(zer)=[];
end
disp(sprintf('Removed: %s', mat2str(rem)));
res = a(sub,sub);
</pre>
<p>(this works &#8220;in place&#8221; without disturbing the contents of a)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Tim Davis</title>
		<link>http://blogs.mathworks.com/pick/2008/03/25/matlab-puzzler-removing-columns-and-rows-from-binary-matrices/#comment-10247</link>
		<dc:creator>Tim Davis</dc:creator>
		<pubDate>Thu, 27 Mar 2008 00:40:34 +0000</pubDate>
		<guid>http://blogs.mathworks.com/pick/2008/03/25/matlab-puzzler-removing-columns-and-rows-from-binary-matrices/#comment-10247</guid>
		<description>You can read the code that does this inside x=A\b at

http://www.cise.ufl.edu/research/sparse/umfpack/UMFPACK/Source/umf_singletons.c

which includes a picture of the result.  Nice puzzler - very realistic and important problem.</description>
		<content:encoded><![CDATA[<p>You can read the code that does this inside x=A\b at</p>
<p><a href="http://www.cise.ufl.edu/research/sparse/umfpack/UMFPACK/Source/umf_singletons.c" rel="nofollow">http://www.cise.ufl.edu/research/sparse/umfpack/UMFPACK/Source/umf_singletons.c</a></p>
<p>which includes a picture of the result.  Nice puzzler - very realistic and important problem.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
