<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Collinearity</title>
	<atom:link href="http://blogs.mathworks.com/loren/2008/06/06/collinearity/feed/" rel="self" type="application/rss+xml" />
	<link>http://blogs.mathworks.com/loren/2008/06/06/collinearity/</link>
	<description>Loren Shure works on design of the MATLAB language at MathWorks. She writes here about once a week on MATLAB programming and related topics.</description>
	<lastBuildDate>Thu, 09 Feb 2012 04:19:21 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
	<item>
		<title>By: Loren</title>
		<link>http://blogs.mathworks.com/loren/2008/06/06/collinearity/#comment-29784</link>
		<dc:creator>Loren</dc:creator>
		<pubDate>Wed, 01 Oct 2008 11:09:01 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/loren/2008/06/06/collinearity/#comment-29784</guid>
		<description>Michel-

I am not sure you can extend it.  What you can do is run it twice, first with 3 points, and then, if they are collinear, run it again, substituting the 4th point for any of the other points.

However, I think you will see at least one solution (svd/rank) in the comments that extends fully to multiple points.

--Loren</description>
		<content:encoded><![CDATA[<p>Michel-</p>
<p>I am not sure you can extend it.  What you can do is run it twice, first with 3 points, and then, if they are collinear, run it again, substituting the 4th point for any of the other points.</p>
<p>However, I think you will see at least one solution (svd/rank) in the comments that extends fully to multiple points.</p>
<p>&#8211;Loren</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Michel Charette</title>
		<link>http://blogs.mathworks.com/loren/2008/06/06/collinearity/#comment-29783</link>
		<dc:creator>Michel Charette</dc:creator>
		<pubDate>Tue, 30 Sep 2008 21:26:20 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/loren/2008/06/06/collinearity/#comment-29783</guid>
		<description>My head&#039;s still spinning trying to figure out how the solution got from ultra-fragile floating point solution to a ultra-elegant integer solution...

My question is: how would this be generalized to N points?  In particular I&#039;m interested in detecting collinearity of 4 points, I fail to see how the matrix in Method 7 can be generalized.</description>
		<content:encoded><![CDATA[<p>My head&#8217;s still spinning trying to figure out how the solution got from ultra-fragile floating point solution to a ultra-elegant integer solution&#8230;</p>
<p>My question is: how would this be generalized to N points?  In particular I&#8217;m interested in detecting collinearity of 4 points, I fail to see how the matrix in Method 7 can be generalized.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: J.B. Brown</title>
		<link>http://blogs.mathworks.com/loren/2008/06/06/collinearity/#comment-29664</link>
		<dc:creator>J.B. Brown</dc:creator>
		<pubDate>Thu, 07 Aug 2008 12:10:06 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/loren/2008/06/06/collinearity/#comment-29664</guid>
		<description>Ah, and I am at fault for simply testing collinearity with the origin in the example above.</description>
		<content:encoded><![CDATA[<p>Ah, and I am at fault for simply testing collinearity with the origin in the example above.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: J.B. Brown</title>
		<link>http://blogs.mathworks.com/loren/2008/06/06/collinearity/#comment-29663</link>
		<dc:creator>J.B. Brown</dc:creator>
		<pubDate>Thu, 07 Aug 2008 02:01:11 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/loren/2008/06/06/collinearity/#comment-29663</guid>
		<description>Indeed,
&gt; collinear( [0 3],[0 8],[0 -1e21+2e-15] )
ans =  1
&gt; collinear( [0 3],[0 8],[0 -1e22+2e-15] )
ans = 0
&gt; rank( [ [0 3]&#039; [0 8]&#039; [0 -1e22+2e-15]&#039; ] )
ans =  1

Of course, the point of this article is to convey the point &quot;there is more than one way to skin a cat,&quot; which Loren and others have sufficiently exemplified. :)</description>
		<content:encoded><![CDATA[<p>Indeed,<br />
&gt; collinear( [0 3],[0 8],[0 -1e21+2e-15] )<br />
ans =  1<br />
&gt; collinear( [0 3],[0 8],[0 -1e22+2e-15] )<br />
ans = 0<br />
&gt; rank( [ [0 3]&#8216; [0 8]&#8216; [0 -1e22+2e-15]&#8216; ] )<br />
ans =  1</p>
<p>Of course, the point of this article is to convey the point &#8220;there is more than one way to skin a cat,&#8221; which Loren and others have sufficiently exemplified. :)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Loren</title>
		<link>http://blogs.mathworks.com/loren/2008/06/06/collinearity/#comment-29661</link>
		<dc:creator>Loren</dc:creator>
		<pubDate>Wed, 06 Aug 2008 11:33:59 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/loren/2008/06/06/collinearity/#comment-29661</guid>
		<description>JB-

It looks to me like Ilya&#039;s solution and therefore yours are equivalent to the determinant.  As Tim and others have pointed out, svd/rank solutions are more robust.

--Loren</description>
		<content:encoded><![CDATA[<p>JB-</p>
<p>It looks to me like Ilya&#8217;s solution and therefore yours are equivalent to the determinant.  As Tim and others have pointed out, svd/rank solutions are more robust.</p>
<p>&#8211;Loren</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: J.B. Brown</title>
		<link>http://blogs.mathworks.com/loren/2008/06/06/collinearity/#comment-29658</link>
		<dc:creator>J.B. Brown</dc:creator>
		<pubDate>Wed, 06 Aug 2008 02:27:15 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/loren/2008/06/06/collinearity/#comment-29658</guid>
		<description>It would appear to me that Ilya Rozenfeld&#039;s solution would be the cleanest.  Just to help those who might have no background in linear algebra,

using
cos(theta) = [dot(v1,v2) / (&#124;&#124;v1&#124;&#124;*&#124;&#124;v2&#124;&#124;) ], and getting one on the right side would mean theta = 0, and the points are collinear.  However, since &#124;&#124;v1&#124;&#124; = sqrt(dot(v1,v1)), and sqrt(.) can lead to roundoff error, Ilya Rozenfeld has squared both sides of the equation above, giving
cos^2(theta) = dot(v1,v2)^2 / (sqrt(dot(v1,v1))^2 * sqrt(dot(v2,v2))^2 )
cos^2(theta) = dot(v1,v2)^2 / ( dot(v1,v1)*dot(v2,v2) ).
As long as they are collinear and theta = 0, cos^2(0)=1^2=1.
So, if the right side equals 1, then we have collinearity, which is why Ilya Rozenfeld has written such a solution. 

The only thing I fear is numerical precision on the dot product, but this seems to be practical enough for me:
function colOrNot = collinear(A,B,C)
% ... code to ensure all column or row vectors
v1 = A-B; v2 = B-C;
colOrNot = ( dot(v1,v2)^2/( dot(v1,v1) * dot(v2,v2) )  ) == 1;
endfunction

&gt; collinear( [0 0], [-3 -3], [6 6] )
ans =  1
&gt; collinear( [1e-8 1e-8]&#039;, [-6+10e-14 -6+10e-14]&#039;, [1e6+5e-21 1e6+5e-21]&#039; )
ans =  1
----- But I am also subject to:
&gt; eps
ans =  2.22044604925031e-16
&gt; collinear( [0 3], [0 8], [0 -1e21+2e-15] )
ans =  1
&gt; collinear( [0 3], [0 8], [0 -1e22+2e-15] )
ans = 0</description>
		<content:encoded><![CDATA[<p>It would appear to me that Ilya Rozenfeld&#8217;s solution would be the cleanest.  Just to help those who might have no background in linear algebra,</p>
<p>using<br />
cos(theta) = [dot(v1,v2) / (||v1||*||v2||) ], and getting one on the right side would mean theta = 0, and the points are collinear.  However, since ||v1|| = sqrt(dot(v1,v1)), and sqrt(.) can lead to roundoff error, Ilya Rozenfeld has squared both sides of the equation above, giving<br />
cos^2(theta) = dot(v1,v2)^2 / (sqrt(dot(v1,v1))^2 * sqrt(dot(v2,v2))^2 )<br />
cos^2(theta) = dot(v1,v2)^2 / ( dot(v1,v1)*dot(v2,v2) ).<br />
As long as they are collinear and theta = 0, cos^2(0)=1^2=1.<br />
So, if the right side equals 1, then we have collinearity, which is why Ilya Rozenfeld has written such a solution. </p>
<p>The only thing I fear is numerical precision on the dot product, but this seems to be practical enough for me:<br />
function colOrNot = collinear(A,B,C)<br />
% &#8230; code to ensure all column or row vectors<br />
v1 = A-B; v2 = B-C;<br />
colOrNot = ( dot(v1,v2)^2/( dot(v1,v1) * dot(v2,v2) )  ) == 1;<br />
endfunction</p>
<p>&gt; collinear( [0 0], [-3 -3], [6 6] )<br />
ans =  1<br />
&gt; collinear( [1e-8 1e-8]&#8216;, [-6+10e-14 -6+10e-14]&#8216;, [1e6+5e-21 1e6+5e-21]&#8216; )<br />
ans =  1<br />
&#8212;&#8211; But I am also subject to:<br />
&gt; eps<br />
ans =  2.22044604925031e-16<br />
&gt; collinear( [0 3], [0 8], [0 -1e21+2e-15] )<br />
ans =  1<br />
&gt; collinear( [0 3], [0 8], [0 -1e22+2e-15] )<br />
ans = 0</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Art</title>
		<link>http://blogs.mathworks.com/loren/2008/06/06/collinearity/#comment-29488</link>
		<dc:creator>Art</dc:creator>
		<pubDate>Wed, 11 Jun 2008 19:11:20 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/loren/2008/06/06/collinearity/#comment-29488</guid>
		<description>It should be emphasized again that the first 5 methods are highly sensitive to numerical errors. It depends on where the numbers are coming from, but if there is any chance of real data being used, it would be poor practice to even consider == or isequal for floating point numbers. It is generally much better to be thinking in terms of tolerances like eps or to use svd. I would therefore consider the point below, for Method 6, to be the FIRST and most important consideration for writing code that works (rather than merely being &quot;beautiful&quot; and not useful):

Uh-oh! What&#039;s happened? Looking back at collinear5, we see we are no longer doing just addition, subtraction, multiplication, and division. Now we&#039;re computing the norm which involves computing a sqrt. As a result, we have more opportunity for numerical roundoff issues, even if the points are confined to be rational numbers (including integers).</description>
		<content:encoded><![CDATA[<p>It should be emphasized again that the first 5 methods are highly sensitive to numerical errors. It depends on where the numbers are coming from, but if there is any chance of real data being used, it would be poor practice to even consider == or isequal for floating point numbers. It is generally much better to be thinking in terms of tolerances like eps or to use svd. I would therefore consider the point below, for Method 6, to be the FIRST and most important consideration for writing code that works (rather than merely being &#8220;beautiful&#8221; and not useful):</p>
<p>Uh-oh! What&#8217;s happened? Looking back at collinear5, we see we are no longer doing just addition, subtraction, multiplication, and division. Now we&#8217;re computing the norm which involves computing a sqrt. As a result, we have more opportunity for numerical roundoff issues, even if the points are confined to be rational numbers (including integers).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ilya Rozenfeld</title>
		<link>http://blogs.mathworks.com/loren/2008/06/06/collinearity/#comment-29481</link>
		<dc:creator>Ilya Rozenfeld</dc:creator>
		<pubDate>Mon, 09 Jun 2008 19:44:05 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/loren/2008/06/06/collinearity/#comment-29481</guid>
		<description>Following up on idea of using area of triangle even simpler solution (in Matlab at least) would be using cross product:

~any(cross([p2-p1, 0], [p3-p1, 0]))

Anohter way could be using a dot product

d1 = p2 - p1;
d2 = p3 - p1;
dot(d1,d2)^2/dot(d1,d1)/dot(d2,d2) == 1</description>
		<content:encoded><![CDATA[<p>Following up on idea of using area of triangle even simpler solution (in Matlab at least) would be using cross product:</p>
<p>~any(cross([p2-p1, 0], [p3-p1, 0]))</p>
<p>Anohter way could be using a dot product</p>
<p>d1 = p2 &#8211; p1;<br />
d2 = p3 &#8211; p1;<br />
dot(d1,d2)^2/dot(d1,d1)/dot(d2,d2) == 1</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Loren</title>
		<link>http://blogs.mathworks.com/loren/2008/06/06/collinearity/#comment-29480</link>
		<dc:creator>Loren</dc:creator>
		<pubDate>Mon, 09 Jun 2008 11:26:30 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/loren/2008/06/06/collinearity/#comment-29480</guid>
		<description>Mark and Tim-

Thanks for the comments.  Yes, I agree people should look at good references and rank is preferable to det.  

Thinking about the problem in different ways (fitting a line vs. checking area), and especially to help get algorithmic robustness was my main take-away.

--Loren</description>
		<content:encoded><![CDATA[<p>Mark and Tim-</p>
<p>Thanks for the comments.  Yes, I agree people should look at good references and rank is preferable to det.  </p>
<p>Thinking about the problem in different ways (fitting a line vs. checking area), and especially to help get algorithmic robustness was my main take-away.</p>
<p>&#8211;Loren</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Tim Davis</title>
		<link>http://blogs.mathworks.com/loren/2008/06/06/collinearity/#comment-29479</link>
		<dc:creator>Tim Davis</dc:creator>
		<pubDate>Mon, 09 Jun 2008 03:02:23 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/loren/2008/06/06/collinearity/#comment-29479</guid>
		<description>oops.  I just tested if p1, p2, and p3 were colinear with the origin as well (which these 3 points happen to be).

&lt;pre&gt;
rank ([p2-p1 ; p3-p1]) &lt; 2
&lt;/pre&gt;

is what you need.  Much more numerically reliable than your suggested

&lt;pre&gt;
det ([p2-p1 ; p3-p1]) == 0
&lt;/pre&gt;

for testing for singular matrices, which is what you&#039;re doing (See &quot;help det&quot;).</description>
		<content:encoded><![CDATA[<p>oops.  I just tested if p1, p2, and p3 were colinear with the origin as well (which these 3 points happen to be).</p>
<pre>
rank ([p2-p1 ; p3-p1]) &lt; 2
</pre>
<p>is what you need.  Much more numerically reliable than your suggested</p>
<pre>
det ([p2-p1 ; p3-p1]) == 0
</pre>
<p>for testing for singular matrices, which is what you&#8217;re doing (See &#8220;help det&#8221;).</p>
]]></content:encoded>
	</item>
</channel>
</rss>

