<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	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/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>GBuffer.net &#187; maths</title>
	<atom:link href="http://www.gbuffer.net/archives/tag/maths/feed" rel="self" type="application/rss+xml" />
	<link>http://www.gbuffer.net</link>
	<description>&#62; Sid’s data dump</description>
	<lastBuildDate>Thu, 06 Oct 2011 16:09:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.1</generator>
		<item>
		<title>A different way to find a point on a hyperplane closest to a given point</title>
		<link>http://www.gbuffer.net/archives/193</link>
		<comments>http://www.gbuffer.net/archives/193#comments</comments>
		<pubDate>Sat, 12 Jun 2010 21:59:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[maths]]></category>

		<guid isPermaLink="false">http://www.gbuffer.net/?p=193</guid>
		<description><![CDATA[As a graphics programmer, I often need to find a point on a hyperplane (line or plane) closest to a given point. So far my understanding of the problem has been based on trigonometric concepts that is probably the simplest way of approaching the problem. I&#8217;m not going to explain the boring trigonometric approach to [...]]]></description>
			<content:encoded><![CDATA[<p>As a graphics programmer, I often need to find a point on a hyperplane (line or plane) closest to a given point. So far my understanding of the problem has been based on trigonometric concepts that is probably the simplest way of approaching the problem. I&#8217;m not going to explain the boring trigonometric approach to the problem here. You can find that on some other website using <a href="http://www.google.co.uk/search?q=point%20on%20a%20line%20closest%20to%20a%20given%20point">Google</a>.</p>
<p>A few weeks back I came across a new concept in maths called Lagrange multipliers. In addition to the problem that I was addressing at the time, I was interested in seeing if it could be applied to find a point on a hyperplane closest to a given point.</p>
<p>If you are not familiar with Lagrange multipliers then just go to the <a href="http://en.wikipedia.org/wiki/Lagrange_multipliers">Wikipedia</a> page that explains it all. I think they give a better explanation of the problem than I ever will. Ok, so if you haven&#8217;t already figured out how we are going to approach this problem, read on.</p>
<p>Lets work in 2 dimensions with  a line of the form<br />
<img src='http://s.wordpress.com/latex.php?latex=%5Calpha%20x%2B%5Cbeta%20y%2B%5Cgamma%20%3D%200&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\alpha x+\beta y+\gamma = 0' title='\alpha x+\beta y+\gamma = 0' class='latex' /><br />
Lets try and visualize this&#8230;<br />
The vector <img src='http://s.wordpress.com/latex.php?latex=%28%5Calpha%2C%5Cbeta%29%5ET&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='(\alpha,\beta)^T' title='(\alpha,\beta)^T' class='latex' /> represents the normal to the line<br />
The constant <img src='http://s.wordpress.com/latex.php?latex=%5Cgamma&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\gamma' title='\gamma' class='latex' /> is the distance to closest point on the line to the origin.<br />
If you are used to only seeing the line in the slope intercept form as <img src='http://s.wordpress.com/latex.php?latex=y%3Dmx%20%2B%20b&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='y=mx + b' title='y=mx + b' class='latex' /><br />
then we can simply assume that<br />
<img src='http://s.wordpress.com/latex.php?latex=%5Calpha%20%3D%20m&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\alpha = m' title='\alpha = m' class='latex' />, <img src='http://s.wordpress.com/latex.php?latex=%5Cbeta%20%3D%20-1&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\beta = -1' title='\beta = -1' class='latex' /> and <img src='http://s.wordpress.com/latex.php?latex=%5Cgamma%20%3D%20b&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\gamma = b' title='\gamma = b' class='latex' />.</p>
<p>Now lets take our point <img src='http://s.wordpress.com/latex.php?latex=P%3D%28x_p%2C%20y_p%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='P=(x_p, y_p)' title='P=(x_p, y_p)' class='latex' /> in space. Now we would like to do is minimise the Euclidean distance to this point.  The Euclidean distance is calculated using the equation<br />
<img src='http://s.wordpress.com/latex.php?latex=f%28x%2C%20y%29%20%3D%20%5Csqrt%7B%28x-x_%7Bp%7D%29%5E2%2B%28y-y_%7Bp%7D%29%5E2%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='f(x, y) = \sqrt{(x-x_{p})^2+(y-y_{p})^2}' title='f(x, y) = \sqrt{(x-x_{p})^2+(y-y_{p})^2}' class='latex' /><br />
Minimizing this problem is dead simple. The closest point to a point is the point it self. But now we would like to add a constraint such that the closest point must lie of the line, whose equation is<br />
<img src='http://s.wordpress.com/latex.php?latex=g%28x%2Cy%29%20%3D%20%5Calpha%20x%20%2B%20%5Cbeta%20y%20%2B%20%5Cgamma%20%3D%200&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='g(x,y) = \alpha x + \beta y + \gamma = 0' title='g(x,y) = \alpha x + \beta y + \gamma = 0' class='latex' /><br />
We approach this problem using a simple form of the Lagrange multiplier where we minimize the function <img src='http://s.wordpress.com/latex.php?latex=f%28x%2Cy%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='f(x,y)' title='f(x,y)' class='latex' /> subject to the constraint <img src='http://s.wordpress.com/latex.php?latex=g%28x%2Cy%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='g(x,y)' title='g(x,y)' class='latex' />. The best way to show that this works is with an example so&#8230;</p>
<h3>Lets try this with an example</h3>
<p>Lets assume we have a line of the form<br />
<img src='http://s.wordpress.com/latex.php?latex=y%3D0.5%20x%20%2B%201&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='y=0.5 x + 1' title='y=0.5 x + 1' class='latex' /> and we would like to find a point on this line that is closest to a given point <img src='http://s.wordpress.com/latex.php?latex=P%20%3D%20%283%2C2%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='P = (3,2)' title='P = (3,2)' class='latex' /></p>
<p>We know the general form of the Lagrange multiplier which states that<br />
<img src='http://s.wordpress.com/latex.php?latex=f%28x%2Cy%29%20%3D%20-%5Clambda%5C%3A%20g%28x%2Cy%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='f(x,y) = -\lambda\: g(x,y)' title='f(x,y) = -\lambda\: g(x,y)' class='latex' /><br />
In English this simply means the that we need to find a point <img src='http://s.wordpress.com/latex.php?latex=X%20%3D%20%28x%2C%20y%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='X = (x, y)' title='X = (x, y)' class='latex' /> where the functions <img src='http://s.wordpress.com/latex.php?latex=f%28x%2Cy%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='f(x,y)' title='f(x,y)' class='latex' /> and <img src='http://s.wordpress.com/latex.php?latex=g%28x%2Cy%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='g(x,y)' title='g(x,y)' class='latex' /> give us vectors that point in the same direction. By multiplying one of the vectors with a constant <img src='http://s.wordpress.com/latex.php?latex=-%5Clambda&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='-\lambda' title='-\lambda' class='latex' /> we make both  vectors equal in length and direction. We could also write the equation above as<br />
<img src='http://s.wordpress.com/latex.php?latex=%5CLambda%28x%2Cy%2C%5Clambda%29%20%3D%20f%28x%2Cy%29%2B%5Clambda%5C%3A%20g%28x%2Cy%29%20%3D%200&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\Lambda(x,y,\lambda) = f(x,y)+\lambda\: g(x,y) = 0' title='\Lambda(x,y,\lambda) = f(x,y)+\lambda\: g(x,y) = 0' class='latex' /></p>
<p>Before we start we change our distance function to a squared distance function. So in this case <img src='http://s.wordpress.com/latex.php?latex=f%28x%2Cy%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='f(x,y)' title='f(x,y)' class='latex' /> would become<br />
<img src='http://s.wordpress.com/latex.php?latex=f%28x%2Cy%29%20%3D%20%28x-3%29%5E2%2B%28y-2%29%5E2&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='f(x,y) = (x-3)^2+(y-2)^2' title='f(x,y) = (x-3)^2+(y-2)^2' class='latex' /><br />
We can do this because <img src='http://s.wordpress.com/latex.php?latex=f%28x%2Cy%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='f(x,y)' title='f(x,y)' class='latex' /> is just a function that needs to be minimised and for us it does not make a difference if we minimise the distance or the squared distance. We make this change as differentiating the squared distance function is much simpler and results in a system of linear equations. The function <img src='http://s.wordpress.com/latex.php?latex=g%28x%2Cy%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='g(x,y)' title='g(x,y)' class='latex' /> remains the same.</p>
<p>So now we need to find<br />
<img src='http://s.wordpress.com/latex.php?latex=%5Cnabla_%7Bx%2Cy%2C%5Clambda%7D%5CLambda%28x%2Cy%2C%5Clambda%29%20%3D%200&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\nabla_{x,y,\lambda}\Lambda(x,y,\lambda) = 0' title='\nabla_{x,y,\lambda}\Lambda(x,y,\lambda) = 0' class='latex' /><br />
In this case<br />
<img src='http://s.wordpress.com/latex.php?latex=%5CLambda%28x%2Cy%2C%5Clambda%29%20%3D%20%28x-3%29%5E2%20%2B%20%28y-2%29%5E2%20%2B%20%5Clambda%5C%3A%280.5x-y%2B1%29%3D0&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\Lambda(x,y,\lambda) = (x-3)^2 + (y-2)^2 + \lambda\:(0.5x-y+1)=0' title='\Lambda(x,y,\lambda) = (x-3)^2 + (y-2)^2 + \lambda\:(0.5x-y+1)=0' class='latex' /><br />
We now need to find<br />
<img src='http://s.wordpress.com/latex.php?latex=%5Cfrac%7B%5Cdisplaystyle%5Cpartial%7D%7B%5Cdisplaystyle%5Cpartial%20x%7D%5CLambda%28x%2Cy%2C%5Clambda%29%20%3D%200&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\frac{\displaystyle\partial}{\displaystyle\partial x}\Lambda(x,y,\lambda) = 0' title='\frac{\displaystyle\partial}{\displaystyle\partial x}\Lambda(x,y,\lambda) = 0' class='latex' /><br />
<img src='http://s.wordpress.com/latex.php?latex=%5Cfrac%7B%5Cdisplaystyle%5Cpartial%7D%7B%5Cdisplaystyle%5Cpartial%20y%7D%5CLambda%28x%2Cy%2C%5Clambda%29%20%3D%200&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\frac{\displaystyle\partial}{\displaystyle\partial y}\Lambda(x,y,\lambda) = 0' title='\frac{\displaystyle\partial}{\displaystyle\partial y}\Lambda(x,y,\lambda) = 0' class='latex' /><br />
<img src='http://s.wordpress.com/latex.php?latex=%5Cfrac%7B%5Cdisplaystyle%5Cpartial%7D%7B%5Cdisplaystyle%20%5Cpartial%20%5Clambda%7D%5CLambda%28x%2Cy%5Clambda%29%20%3D%200&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\frac{\displaystyle\partial}{\displaystyle \partial \lambda}\Lambda(x,y\lambda) = 0' title='\frac{\displaystyle\partial}{\displaystyle \partial \lambda}\Lambda(x,y\lambda) = 0' class='latex' /><br />
After doing all the hairy math, we get<br />
<img src='http://s.wordpress.com/latex.php?latex=%5Cfrac%7B%5Cdisplaystyle%20%5Cpartial%7D%7B%5Cdisplaystyle%20%5Cpartial%20x%7D%5CLambda%28x%2Cy%2C%5Clambda%29%20%3D%200.5%5Clambda%2B2x-6%3D0&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\frac{\displaystyle \partial}{\displaystyle \partial x}\Lambda(x,y,\lambda) = 0.5\lambda+2x-6=0' title='\frac{\displaystyle \partial}{\displaystyle \partial x}\Lambda(x,y,\lambda) = 0.5\lambda+2x-6=0' class='latex' /><br />
<img src='http://s.wordpress.com/latex.php?latex=%5Cfrac%7B%5Cdisplaystyle%5Cpartial%7D%7B%5Cdisplaystyle%5Cpartial%20y%7D%5CLambda%28x%2Cy%2C%5Clambda%29%20%3D%20-%5Clambda%20%2B%202y%20-4%3D0&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\frac{\displaystyle\partial}{\displaystyle\partial y}\Lambda(x,y,\lambda) = -\lambda + 2y -4=0' title='\frac{\displaystyle\partial}{\displaystyle\partial y}\Lambda(x,y,\lambda) = -\lambda + 2y -4=0' class='latex' /><br />
<img src='http://s.wordpress.com/latex.php?latex=%5Cfrac%7B%5Cdisplaystyle%5Cpartial%7D%7B%5Cdisplaystyle%5Cpartial%20%5Clambda%20%7D%20%5CLambda%28x%2Cy%2C%5Clambda%29%20%3D0.5x-y%2B1%3D%200&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\frac{\displaystyle\partial}{\displaystyle\partial \lambda } \Lambda(x,y,\lambda) =0.5x-y+1= 0' title='\frac{\displaystyle\partial}{\displaystyle\partial \lambda } \Lambda(x,y,\lambda) =0.5x-y+1= 0' class='latex' /><br />
We now have a system of three linear equations with three unknowns. This should be fairly easy to solve using a number of methods. If we had used the distance function instead of the squared distance, we would have ended up with a system of non-linear equations which would not been so easy to solve.</p>
<p>Ok so after solving for <img src='http://s.wordpress.com/latex.php?latex=x%2Cy%2C%5Clambda&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='x,y,\lambda' title='x,y,\lambda' class='latex' /> we get<br />
<img src='http://s.wordpress.com/latex.php?latex=x%3D%5Cfrac%7B14%7D%7B5%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='x=\frac{14}{5}' title='x=\frac{14}{5}' class='latex' /><br />
<img src='http://s.wordpress.com/latex.php?latex=y%3D%5Cfrac%7B12%7D%7B5%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='y=\frac{12}{5}' title='y=\frac{12}{5}' class='latex' /><br />
We are not really interested in <img src='http://s.wordpress.com/latex.php?latex=%5Clambda&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\lambda' title='\lambda' class='latex' /> anymore, so we shall leave that out. So the point on the line is<br />
<img src='http://s.wordpress.com/latex.php?latex=X%3D%5Cleft%20%28%5Cfrac%7B14%7D%7B5%7D%2C%20%5Cfrac%7B12%7D%7B5%7D%20%5Cright%20%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='X=\left (\frac{14}{5}, \frac{12}{5} \right )' title='X=\left (\frac{14}{5}, \frac{12}{5} \right )' class='latex' /></p>
<p>We can use several different methods to verify if this answer is correct. We can solve for the same point using the trigonometric method or we can check if the vectors <img src='http://s.wordpress.com/latex.php?latex=%5Coverrightarrow%7BPX%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\overrightarrow{PX}' title='\overrightarrow{PX}' class='latex' /> and <img src='http://s.wordpress.com/latex.php?latex=%5Coverrightarrow%7BAX%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\overrightarrow{AX}' title='\overrightarrow{AX}' class='latex' /> are orthonormal to each other. Here <img src='http://s.wordpress.com/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' /> is just another point on our line. We shall use the latter method to verify our results. We already have<br />
<img src='http://s.wordpress.com/latex.php?latex=P%3D%283%2C%202%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='P=(3, 2)' title='P=(3, 2)' class='latex' />, <img src='http://s.wordpress.com/latex.php?latex=X%3D%5Cleft%28%5Cfrac%7B14%7D%7B5%7D%2C%20%5Cfrac%7B12%7D%7B5%7D%5Cright%20%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='X=\left(\frac{14}{5}, \frac{12}{5}\right )' title='X=\left(\frac{14}{5}, \frac{12}{5}\right )' class='latex' />. We can find <img src='http://s.wordpress.com/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' /> by just setting <img src='http://s.wordpress.com/latex.php?latex=x%3D0&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='x=0' title='x=0' class='latex' /> in line equation. So we get<br />
<img src='http://s.wordpress.com/latex.php?latex=A%3D%280%2C%201%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A=(0, 1)' title='A=(0, 1)' class='latex' /><br />
So we get<br />
<img src='http://s.wordpress.com/latex.php?latex=%5Coverrightarrow%7BAX%7D%20%3D%20%5Cleft%20%28%20-%5Cfrac%7B14%7D%7B5%7D%2C%20-%5Cfrac%7B7%7D%7B5%7D%20%5Cright%20%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\overrightarrow{AX} = \left ( -\frac{14}{5}, -\frac{7}{5} \right )' title='\overrightarrow{AX} = \left ( -\frac{14}{5}, -\frac{7}{5} \right )' class='latex' /><br />
<img src='http://s.wordpress.com/latex.php?latex=%5Coverrightarrow%7BPX%7D%20%3D%20%5Cleft%20%28%20%5Cfrac%7B1%7D%7B5%7D%2C%20-%5Cfrac%7B2%7D%7B5%7D%20%5Cright%20%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\overrightarrow{PX} = \left ( \frac{1}{5}, -\frac{2}{5} \right )' title='\overrightarrow{PX} = \left ( \frac{1}{5}, -\frac{2}{5} \right )' class='latex' /><br />
and&#8230;<br />
<img src='http://s.wordpress.com/latex.php?latex=%5Clangle%5Coverrightarrow%7BAX%7D%2C%5Coverrightarrow%7BPX%7D%5Crangle%3D%200&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\langle\overrightarrow{AX},\overrightarrow{PX}\rangle= 0' title='\langle\overrightarrow{AX},\overrightarrow{PX}\rangle= 0' class='latex' /><br />
<strong><br />
&#8230;or in plain English: IT WORKS!!</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.gbuffer.net/archives/193/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Square root without sqrt</title>
		<link>http://www.gbuffer.net/archives/30</link>
		<comments>http://www.gbuffer.net/archives/30#comments</comments>
		<pubDate>Mon, 17 Mar 2008 16:12:24 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[maths]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://pacman/testrun/?p=30</guid>
		<description><![CDATA[A few months back, I was given an interesting project to work on in an interview test. The test required me to build a small particle system for the Nintendo DS, using the homebrew tool chain. Well I don&#8217;t know if I was stupid or just plain blind, but I was unable to find a [...]]]></description>
			<content:encoded><![CDATA[<p>A few months back, I was given an interesting project to work on in an interview test. The test required me to build a small particle system for the Nintendo DS, using the homebrew tool chain. Well I don&#8217;t know if I was stupid or just plain blind, but I was unable to find a sqrt in their standard math.h include file. Posting questions on a forum resulted in no replies and time was running short. I had only about a week to make my submission. So I decided to write my own implementation. After all I remember doing this in high scool.</p>
<p><strong>The old school method&#8230;</strong></p>
<p>As usual I headed over to google and after a little searching I found it on <a title="Square root algorithm" href="http://www.geocities.com/cnowlen/Cathy/Emat4680/Squareroot.htm">this website</a>. Well this was exactly what I was looking for, but unfortunately it required too much guessing at every step. Now as we all know computers are not good at guessing. All hopes of implementing a square root function quickly evaporated.</p>
<p>Next day in office, with some help from my coleague Ashwini Kumar, we came up with a very promising solution.</p>
<p>We found something interesting about the patterns a square root takes</p>
<p>sqrt(1.0) = 1.0<br />
sqrt(10.0) = 3.1622<br />
sqrt(100.0) = 10.0<br />
sqrt(1000.0) = 31.622</p>
<p>Now for those of you who have not realized yet, sqrt(1000.0) = sqrt(10.0) * 10.0</p>
<p>Well this could work pretty well and all we needed to do then is just generate a look up table of the first 100 numbers and then just do a multiplication based on it&#8217;s 10th power. So I came up with this code&#8230;</p>
<pre class="brush: c++">
// LUT for square roots below 100. Takes 396 bytes

const static float SQRT_LUT[] =
{
       1.000000f,      1.414214f,      1.732051f,      2.000000f,
       2.236068f,      2.449490f,      2.645751f,      2.828427f,
       3.000000f,      3.162278f,      3.316625f,      3.464102f,
       3.605551f,      3.741657f,      3.872983f,      4.000000f,
       4.123106f,      4.242640f,      4.358899f,      4.472136f,
       4.582576f,      4.690416f,      4.795832f,      4.898980f,
       5.000000f,      5.099020f,      5.196152f,      5.291502f,
       5.385165f,      5.477226f,      5.567764f,      5.656854f,
       5.744563f,      5.830952f,      5.916080f,      6.000000f,
       6.082763f,      6.164414f,      6.244998f,      6.324555f,
       6.403124f,      6.480741f,      6.557438f,      6.633250f,
       6.708204f,      6.782330f,      6.855655f,      6.928203f,
       7.000000f,      7.071068f,      7.141428f,      7.211102f,
       7.280110f,      7.348469f,      7.416198f,      7.483315f,
       7.549834f,      7.615773f,      7.681146f,      7.745967f,
       7.810250f,      7.874008f,      7.937254f,      8.000000f,
       8.062258f,      8.124039f,      8.185352f,      8.246211f,
       8.306623f,      8.366600f,      8.426149f,      8.485281f,
       8.544003f,      8.602325f,      8.660254f,      8.717798f,
       8.774964f,      8.831760f,      8.888194f,      8.944272f,
       9.000000f,      9.055386f,      9.110434f,      9.165152f,
       9.219544f,      9.273619f,      9.327379f,      9.380832f,
       9.433981f,      9.486833f,      9.539392f,      9.591663f,
       9.643651f,      9.695360f,      9.746795f,      9.797959f,
       9.848858f,      9.899495f,      9.949874f,
} ;

float SqrtLUT(const float fNum)
{
     int      nIdx ;
     int      nApproxLog = 0 ;
     float    fCopy = fNum ;
     float    fMultiplier = 1.0f, fDivider = 0.1f ;

     if (fNum &lt; 100.0f &amp;&amp; fNum &gt;= 1.0f) // Use LUT

     {
         nIdx = static_cast&lt;int&gt;(fNum) ;
         if (nIdx)
         {
             --nIdx ;
             return SQRT_LUT[nIdx] ;
         }
     }

     // Number is above 100, bring it down and just multiply the answer

     if (fNum &gt;= 100.0f)
     {
         while (fCopy &gt; 1.0f)
         {
             fCopy *= 0.1f ;

             if ((nApproxLog &amp; ~3) &amp;&amp; (nApproxLog &amp; 1))
             {
                 fMultiplier *= 10.0f ;
                 fDivider *= fDivider ;
             }

             ++nApproxLog ;
         }
     }
     // Number is below 1. Bring it with in the 1-100 range

     else
     {
         // ...
         // Something very similar to the if block above
         // ...
     }

     return GuessSqrt(fNum * fDivider) * fMultiplier ;
}
</pre>
<p>This worked really well for numbers under 10^3, but as the numbers grew larger the errors started growing larger and larger. Even a LUT of doubles instead of floats just offset the errors to a slightly larger numbers.</p>
<p>Time to look for a new solution&#8230;</p>
<p><strong>The Babylonian Method</strong></p>
<p>A quick recap of old college textbooks revealed a suprising simple method. This method only produces an estimate, but the accuracy of the estimate grows rapidly on every iteration. For those of you who need a quick recap of the algorithm, here is a recap from <a href="http://pballew.net/oldsqrt.htm">http://pballew.net/oldsqrt.htm</a></p>
<p>1) Guess a number for the square root<br />
2) Divide the number by the guess<br />
3) Average the original guess and the new guess<br />
4) make this average value your new guess and<br />
5) Go back to step 2 if the accuracy of the result is not satifactory&#8230;</p>
<p>The problem with this method is that it still requires a guess like the old scool method, but this requires a guess only once and the rest of the guesses are relatively small calculations which don&#8217;t need any sort of loop. Besides with our LUT method we can now provde a fairly accurate guess relatively fast. So the initial implementation looked something like this&#8230;</p>
<pre class="brush: c++">
const static int gIterations 20 ;

float mSqrt(const float fNum)
{
 float x1 ;

 x1 = GuessSqrt(fNum) ; // Just uses the LUT function mentioned above

 for (int i=0; i&lt;gIterations; ++i)
 {
 x1 = ( ( fNum / x1 ) + x1 ) * 0.5f ;
 }
}
</pre>
<p>After a little trial and error I decided the the number of iterations are best kept at 12.</p>
<p><strong>The end result</strong></p>
<p>Turns out it aint that bad. On my old 1.6Ghz system this implementation is only 0.002 seconds (approximately) slower than sqrt() when calculating 10000 square roots.</p>
<p>My implementation (available in the attachment below) has a much more complicated implentation that does a loop unwind using C++ templates. How else can I justify spending large amounts of time spent trying to understand <a href="http://erdani.org/">Andrei&#8217;s</a> book, <a title="Modern C++ design" href="http://erdani.org/book/main.html">Modern C++ design</a> . As of now that book has become my latest programming fad. <img src='http://www.gbuffer.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>You can download the VS.Net 2005 project of my implementation (Attached at the end of this blog entry). The .cpp file has code to check the speed and accuaracy of the results against the standard CRT sqrt function. Most of the code that you should be interested in, is in main.cpp. If you want to use the function in your own project, just copy everything except the main function in main.cpp</p>
<p>Until next time</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gbuffer.net/archives/30/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

