<?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>Multiplication algorithm &#8211; stoimen&#039;s web log</title>
	<atom:link href="/tag/multiplication-algorithm/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>on web development</description>
	<lastBuildDate>Tue, 13 Feb 2018 08:18:15 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.0.3</generator>
	<item>
		<title>Computer Algorithms: Strassen&#8217;s Matrix Multiplication</title>
		<link>/2012/11/26/computer-algorithms-strassens-matrix-multiplication/</link>
		<comments>/2012/11/26/computer-algorithms-strassens-matrix-multiplication/#comments</comments>
		<pubDate>Mon, 26 Nov 2012 14:16:51 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[Algebra]]></category>
		<category><![CDATA[Binary operations]]></category>
		<category><![CDATA[Coppersmith–Winograd algorithm]]></category>
		<category><![CDATA[Divide and conquer algorithm]]></category>
		<category><![CDATA[faster solution]]></category>
		<category><![CDATA[final solution]]></category>
		<category><![CDATA[given solution]]></category>
		<category><![CDATA[graph algorithms]]></category>
		<category><![CDATA[Linear algebra]]></category>
		<category><![CDATA[mathematician]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Matrix]]></category>
		<category><![CDATA[matrix multiplication algorithm]]></category>
		<category><![CDATA[Matrix theory]]></category>
		<category><![CDATA[Multiplication]]></category>
		<category><![CDATA[Multiplication algorithm]]></category>
		<category><![CDATA[n^3 algorithm]]></category>
		<category><![CDATA[n^3 matrix multiplication algorithm]]></category>
		<category><![CDATA[Numerical linear algebra]]></category>
		<category><![CDATA[NxN]]></category>
		<category><![CDATA[Operations research]]></category>
		<category><![CDATA[purpose algorithm]]></category>
		<category><![CDATA[sort algorithm]]></category>
		<category><![CDATA[sub-solutions]]></category>
		<category><![CDATA[Volker Strassen]]></category>

		<guid isPermaLink="false">/?p=3466</guid>
		<description><![CDATA[Introduction The Strassen’s method of matrix multiplication is a typical divide and conquer algorithm. We’ve seen so far some divide and conquer algorithms like merge sort and the Karatsuba’s fast multiplication of large numbers. However let’s get again on what’s behind the divide and conquer approach. Unlike the dynamic programming where we “expand” the solutions &#8230; <a href="/2012/11/26/computer-algorithms-strassens-matrix-multiplication/" class="more-link">Continue reading <span class="screen-reader-text">Computer Algorithms: Strassen&#8217;s Matrix Multiplication</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2013/01/14/computer-algorithms-multiplication/" rel="bookmark" title="Computer Algorithms: Multiplication">Computer Algorithms: Multiplication </a></li>
<li><a href="/2012/05/15/computer-algorithms-karatsuba-fast-multiplication/" rel="bookmark" title="Computer Algorithms: Karatsuba Fast Multiplication">Computer Algorithms: Karatsuba Fast Multiplication </a></li>
<li><a href="/2012/10/22/computer-algorithms-bellman-ford-shortest-path-in-a-graph/" rel="bookmark" title="Computer Algorithms: Bellman-Ford Shortest Path in a Graph">Computer Algorithms: Bellman-Ford Shortest Path in a Graph </a></li>
<li><a href="/2012/08/31/computer-algorithms-graphs-and-their-representation/" rel="bookmark" title="Computer Algorithms: Graphs and their Representation">Computer Algorithms: Graphs and their Representation </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p>The Strassen’s method of matrix multiplication is a typical divide and conquer algorithm. We’ve seen so far some divide and conquer algorithms like <a href="/2012/03/05/computer-algorithms-merge-sort/" title="Computer Algorithms: Merge Sort">merge sort</a> and the <a href="/2012/05/15/computer-algorithms-karatsuba-fast-multiplication/" title="Computer Algorithms: Karatsuba Fast Multiplication">Karatsuba’s fast multiplication</a> of large numbers. However let’s get again on what’s behind the divide and conquer approach.</p>
<p>Unlike the dynamic programming where we “expand” the solutions of sub-problems in order to get the final solution, here we are talking more on joining sub-solutions together. These solutions of some sub-problems of the general problem are equal and their merge is somehow well defined.</p>
<p>A typical example is the merge sort algorithm. In merge sort we have two sorted arrays and all we want is to get the array representing their union again sorted. Of course, the tricky part in merge sort is the merging itself. That’s because we’ve to pass through the two arrays, A and B, and we’ve to compare each “pair” of items representing an item from A and from B. A bit off topic, but this is the weak point of merge sort and although its worst-case time complexity is O(n.log(n)), quicksort is often preferred in practice because there’s no “merge”. <a href="/2012/03/13/computer-algorithms-quicksort/" title="Computer Algorithms: Quicksort">Quicksort</a> just concatenates the two sub-arrays. Note that in quicksort the sub-arrays aren’t with an equal length in general and although its worst-case time complexity is O(n^2) it often outperforms merge sort.</p>
<p>This simple example from the paragraph above shows us how sometimes merging the solutions of two sub-problems actually isn’t a trivial task to do. Thus we must be careful when applying any divide and conquer approach.</p>
<h2>History</h2>
<p><a href="http://en.wikipedia.org/wiki/Volker_Strassen" title="Volker Strassen" target="_blank">Volker Strassen</a> is a German mathematician born in 1936. He is well known for his works on probability, but in the computer science and algorithms he’s mostly recognized because of his algorithm for matrix multiplication that’s still one of the main methods that outperforms the general matrix multiplication algorithm.</p>
<p>Strassen firstly published this algorithm in 1969 and proved that the n^3 algorithm isn’t the optimal one. Actually the given solution by Strassen is slightly better, but his contribution is enormous because this resulted in many more researches about matrix multiplication that led to some faster approaches, i.e. <a href="http://en.wikipedia.org/wiki/Coppersmith%E2%80%93Winograd_algorithm" title="Coppersmith-Winograd algorithm" target="_blank">the Coppersmith-Winograd algorithm</a> with O(n^2,3737).<span id="more-3466"></span></p>
<h2>Overview</h2>
<p>The general algorithm on multiplying two matrices A[NxN] and B[NxN] is fairly simple. Although it’s more difficult than multiplying two numbers and also it is not commutative it’s still very simple – but slow.</p>
<p>Let’s first define what’s a matrix A[NxN]. As we speak about matrices NxN we usually think of a square grid with N rows and N columns. In each row and column A[i][j] we’ve a value. </p>
<figure id="attachment_3489" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/11/1.-Square-matrix.png"><img src="/wp-content/uploads/2012/11/1.-Square-matrix.png" alt="Square matrix" title="Square matrix" width="620" height="399" class="size-full wp-image-3489" srcset="/wp-content/uploads/2012/11/1.-Square-matrix.png 620w, /wp-content/uploads/2012/11/1.-Square-matrix-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>Of course, as developers, we can think of a matrix as a two-dimensional array. </p>
<pre lang="PHP">
// PHP two-dimensional array
$a = array(
    0 => array($v1, $v2, $v3, $v4),
    1 => array($v5, $v6, $v7, $v8),
    2 => array($v9, $v10, $v11, $v12),
); 
</pre>
<p>Don’t forget that a NxN matrix is just a private case for a matrix. We can equally likely have any other size of a matrix NxM (N <> M). </p>
<p>However the size of a matrix is crucial in order to multiply it with another matrix. Why is that? </p>
<p>As I said above multiplying matrices isn’t the same as multiplying numbers. First of all this operation isn’t commutative.</p>
<figure id="attachment_3488" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/11/2.-Commutative-problem.png"><img src="/wp-content/uploads/2012/11/2.-Commutative-problem.png" alt="Commutative problem" title="Commutative problem" width="620" height="399" class="size-full wp-image-3488" srcset="/wp-content/uploads/2012/11/2.-Commutative-problem.png 620w, /wp-content/uploads/2012/11/2.-Commutative-problem-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>And the second problem is the way you multiply two matrices A with B.</p>
<figure id="attachment_3487" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/11/3.-Matrix-Multiplication.png"><img src="/wp-content/uploads/2012/11/3.-Matrix-Multiplication.png" alt="Matrix Multiplication" title="Matrix Multiplication" width="620" height="399" class="size-full wp-image-3487" srcset="/wp-content/uploads/2012/11/3.-Matrix-Multiplication.png 620w, /wp-content/uploads/2012/11/3.-Matrix-Multiplication-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>Just because this works with NxN matrices we can see the problem with multiplying rectangular matrices. Indeed, this wouldn’t be possible unless the second dimension of A isn’t exactly equal to the first dimension of B. </p>
<figure id="attachment_3486" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/11/4.-Rect-Matrix-Multiplication.png"><img src="/wp-content/uploads/2012/11/4.-Rect-Matrix-Multiplication.png" alt="Rectangular Matrix Multiplication" title="Rectangular Matrix Multiplication" width="620" height="399" class="size-full wp-image-3486" srcset="/wp-content/uploads/2012/11/4.-Rect-Matrix-Multiplication.png 620w, /wp-content/uploads/2012/11/4.-Rect-Matrix-Multiplication-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>Hopefully we are now talking about square matrices with exactly the same dimensions.</p>
<p>OK, so now we know how to multiply two square matrices (with the same dimensions NxN) and now let’s evaluate the time complexity for the general purpose algorithm.</p>
<p>As we know A.B = C only when:</p>
<pre>
C[i][j] = sum(A[i][k] * B[k][j]) for k = 0 .. n
</pre>
<p>Thus we have n^3 operations. Let’s try to find out a divide and conquer approach.</p>
<p>Indeed this isn’t difficult in case of matrices because as we know we can divide in matrix in smaller sub-matrices.</p>
<figure id="attachment_3485" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/11/5.-Divide-and-Conquer.png"><img src="/wp-content/uploads/2012/11/5.-Divide-and-Conquer.png" alt="Divide and Conquer" title="Divide and Conquer" width="620" height="399" class="size-full wp-image-3485" srcset="/wp-content/uploads/2012/11/5.-Divide-and-Conquer.png 620w, /wp-content/uploads/2012/11/5.-Divide-and-Conquer-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>Now what do we have?</p>
<figure id="attachment_3484" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/11/6.-Divide-and-Conquer-Result.png"><img src="/wp-content/uploads/2012/11/6.-Divide-and-Conquer-Result.png" alt="Divide and Conquer Result" title="Divide and Conquer Result" width="620" height="399" class="size-full wp-image-3484" srcset="/wp-content/uploads/2012/11/6.-Divide-and-Conquer-Result.png 620w, /wp-content/uploads/2012/11/6.-Divide-and-Conquer-Result-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>Again &#8211; the same complexity – we have 8 products and 4 sums. Where’s the catch? </p>
<p>Of course in order to get faster solution we’ve to be looking as Strassen did in 1969. He defined P1, P2, P3, P4, P5, P6 and P7 as defined on the image below.</p>
<figure id="attachment_3483" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/11/7.-Strassens-Algorithm.png"><img src="/wp-content/uploads/2012/11/7.-Strassens-Algorithm.png" alt="Strassen&#039;s Algorithm" title="Strassen&#039;s Algorithm" width="620" height="399" class="size-full wp-image-3483" srcset="/wp-content/uploads/2012/11/7.-Strassens-Algorithm.png 620w, /wp-content/uploads/2012/11/7.-Strassens-Algorithm-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<h2>Complexity</h2>
<p>As I mentioned above the Strassen’s algorithm is slightly faster than the general matrix multiplication algorithm. The general algorithm’s time complexity is O(n^3), while the Strassen’s algorithm is O(n^2.80).</p>
<p>You can see on the chart below how slightly faster is this even for large n.</p>
<figure id="attachment_3482" style="width: 600px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/11/Strassens-Complexity.png"><img src="/wp-content/uploads/2012/11/Strassens-Complexity.png" alt="Strassen&#039;s Complexity" title="Strassen&#039;s Complexity" width="600" height="371" class="size-full wp-image-3482" srcset="/wp-content/uploads/2012/11/Strassens-Complexity.png 600w, /wp-content/uploads/2012/11/Strassens-Complexity-300x185.png 300w" sizes="(max-width: 600px) 100vw, 600px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<h2>Application</h2>
<p>Although this algorithm seems to be more close to pure mathematics than to computer practically everywhere we use NxN arrays we can benefit from matrix multiplication.</p>
<p>In the other hand the algorithm of Strassen is not much faster than the general n^3 matrix multiplication algorithm. That’s very important because for small n (usually n < 45) the general algorithm is practically a better choice. However as you can see from the chart above for n > 100 the difference can be very big.</p>
<p>In the same time typically NxN arrays are used always when we talk about adjacency matrix of graphs |V| = n and some graph algorithms practically depend on matrix multiplication. </p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2013/01/14/computer-algorithms-multiplication/" rel="bookmark" title="Computer Algorithms: Multiplication">Computer Algorithms: Multiplication </a></li>
<li><a href="/2012/05/15/computer-algorithms-karatsuba-fast-multiplication/" rel="bookmark" title="Computer Algorithms: Karatsuba Fast Multiplication">Computer Algorithms: Karatsuba Fast Multiplication </a></li>
<li><a href="/2012/10/22/computer-algorithms-bellman-ford-shortest-path-in-a-graph/" rel="bookmark" title="Computer Algorithms: Bellman-Ford Shortest Path in a Graph">Computer Algorithms: Bellman-Ford Shortest Path in a Graph </a></li>
<li><a href="/2012/08/31/computer-algorithms-graphs-and-their-representation/" rel="bookmark" title="Computer Algorithms: Graphs and their Representation">Computer Algorithms: Graphs and their Representation </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2012/11/26/computer-algorithms-strassens-matrix-multiplication/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>Computer Algorithms: Karatsuba Fast Multiplication</title>
		<link>/2012/05/15/computer-algorithms-karatsuba-fast-multiplication/</link>
		<comments>/2012/05/15/computer-algorithms-karatsuba-fast-multiplication/#comments</comments>
		<pubDate>Tue, 15 May 2012 19:52:59 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[Anatolii Alexeevitch Karatsuba]]></category>
		<category><![CDATA[Andrey Kolmogorov]]></category>
		<category><![CDATA[Cohen-Sutherland]]></category>
		<category><![CDATA[Divide and conquer algorithm]]></category>
		<category><![CDATA[Karatsuba algorithm]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Multiplication]]></category>
		<category><![CDATA[Multiplication algorithm]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[structured algorithm]]></category>

		<guid isPermaLink="false">/?p=3121</guid>
		<description><![CDATA[Introduction Typically multiplying two n-digit numbers require n2 multiplications. That is actually how we, humans, multiply numbers. Let’s take a look of an example in case we’ve to multiply two 2-digit numbers. 12 x 15 = ? OK, we know that the answer is 180 and there are lots of intuitive methods that help us &#8230; <a href="/2012/05/15/computer-algorithms-karatsuba-fast-multiplication/" class="more-link">Continue reading <span class="screen-reader-text">Computer Algorithms: Karatsuba Fast Multiplication</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2013/01/14/computer-algorithms-multiplication/" rel="bookmark" title="Computer Algorithms: Multiplication">Computer Algorithms: Multiplication </a></li>
<li><a href="/2012/11/26/computer-algorithms-strassens-matrix-multiplication/" rel="bookmark" title="Computer Algorithms: Strassen&#8217;s Matrix Multiplication">Computer Algorithms: Strassen&#8217;s Matrix Multiplication </a></li>
<li><a href="/2012/05/08/computer-algorithms-determine-if-a-number-is-prime/" rel="bookmark" title="Computer Algorithms: Determine if a Number is Prime">Computer Algorithms: Determine if a Number is Prime </a></li>
<li><a href="/2012/12/24/computer-algorithms-sorting-in-linear-time/" rel="bookmark" title="Computer Algorithms: Sorting in Linear Time">Computer Algorithms: Sorting in Linear Time </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p>Typically multiplying two n-digit numbers require n<sup>2</sup> multiplications. That is actually how we, humans, multiply numbers. Let’s take a look of an example in case we’ve to multiply two 2-digit numbers.</p>
<pre lang="php">12 x 15 = ?</pre>
<p>OK, we know that the answer is 180 and there are lots of intuitive methods that help us get the right answer. Indeed 12 x 15 it’s just a bit more difficult to calculate than 10 x 15, because multiplying by 10 it really easy &#8211; we just add one 0 at the end of the number. Thus 15 x 10 equals 150. But now again on 12 x 15 &#8211; we know that this equals 10 x 15 (which is 150) and 2 x 15, which is also very easy to calculate and it is 30. The result of 12&#215;15 will be 150 + 30, which fortunately isn’t difficult to get and equals to 180.</p>
<p>That was easy but in some cases the calculations are a bit more difficult and we need a structured algorithm to get the right answer. What about 65 x 97? That is not so easy as 12 x 15, right?</p>
<p>The algorithm we know from the primary school, described on the diagram below, is well structured and help us multiply two numbers.</p>
<div class="mceTemp">
<dl id="attachment_3139" class="wp-caption alignnone" style="width: 494px;">
<dt class="wp-caption-dt"><a href="/wp-content/uploads/2012/05/1.-Typical-Multiplication.png"><img class="size-full wp-image-3139" title="Typical Multiplication" src="/wp-content/uploads/2012/05/1.-Typical-Multiplication.png" alt="Typical Multiplication" width="484" height="518" srcset="/wp-content/uploads/2012/05/1.-Typical-Multiplication.png 484w, /wp-content/uploads/2012/05/1.-Typical-Multiplication-280x300.png 280w" sizes="(max-width: 484px) 100vw, 484px" /></a></dt>
<dd class="wp-caption-dd"></dd>
</dl>
</div>
<p>We see that even for two-digit numbers this is quite difficult &#8211; we have 4 multiplications and some additions.<span id="more-3121"></span></p>
<figure id="attachment_3143" style="width: 484px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/05/2.-Number-of-Multiplications.png"><img src="/wp-content/uploads/2012/05/2.-Number-of-Multiplications.png" alt="Number of Multiplications" title="Number of Multiplications" width="484" height="518" class="size-full wp-image-3143" srcset="/wp-content/uploads/2012/05/2.-Number-of-Multiplications.png 484w, /wp-content/uploads/2012/05/2.-Number-of-Multiplications-280x300.png 280w" sizes="(max-width: 484px) 100vw, 484px" /></a><figcaption class="wp-caption-text">We need 4 multiplications in order to calculate the product of two 2-digit numbers!</figcaption></figure>
<p>However so far we know how to multiply numbers, the only problem is that our task becomes very difficult as the numbers grow. If multiplying 65 by 97 was somehow easy, what about</p>
<pre lang="php">374773294776321
x
222384759707982</pre>
<p>It seems almost impossible.</p>
<h3>History</h3>
<p><a title="Andrey Kolmogorov" href="http://en.wikipedia.org/wiki/Andrey_Kolmogorov" target="_blank">Andrey Kolmogorov</a> is one of the brightest russian mathematicians of the 20th century. In 1960, during a seminar, Kolmogorov stated that two n-digit numbers can’t be multiplied with less than n<sup>2</sup> multiplications!<br />
Only a week later a 23-year young student called <a title="Anatolii Alexeevitch Karatsuba" href="http://en.wikipedia.org/wiki/Anatolii_Alexeevitch_Karatsuba" target="_blank">Anatolii Alexeevitch Karatsuba</a> proved that the multiplication of two n-digit numbers can be computed with n ^ lg(3) multiplications with an ingenious divide and conquer approach.</p>
<h2>Overview</h2>
<p>Basically Karatsuba stated that if we have to multiply two n-digit numbers x and y, this can be done with the following operations, assuming that B is the base of and m &lt; n.</p>
<p>First both numbers x and y can be represented as x1,x2 and y1,y2 with the following formula.</p>
<pre lang="PHP">
x = x1 * B^m + x2 
y = y1 * B^m + y2 
</pre>
<p>Obviously now xy will become as the following product.</p>
<pre lang="PHP">
xy = (x1 * B^m + x2)(y1 * B^m + y2) =>

a = x1 * y1
b = x1 * y2 + x2 * y1
c = x2 * y2
</pre>
<p>Finally xy will become:</p>
<pre lang="PHP">
xy = a * B^2m + b * B^m + c
</pre>
<p>However a, b and c can be computed at least with four multiplication, which isn’t a big optimization. That is why Karatsuba came up with the brilliant idea to calculate b with the following formula:</p>
<pre lang="PHP">
b = (x1 + x2)(y1 + y2) - a - c
</pre>
<p>That make use of only three multiplications to get xy.</p>
<p>Let’s see this formula by example. </p>
<pre lang="PHP">
47 x 78

x = 47
x = 4 * 10 + 7

x1 = 4
x2 = 7

y = 78
y = 7 * 10 + 8

y1 = 7
y2 = 8

a = x1 * y1 = 4 * 7 = 28
c = x2 * y2 = 7 * 8 = 56
b = (x1 + x2)(y1 + y2) - a - c = 11 * 15 - 28 - 56
</pre>
<p>Now the thing is that 11 * 15 it’s again a multiplication between 2-digit numbers, but fortunately we can apply the same rules two them. This makes the algorithm of Karatsuba a perfect example of the “divide and conquer” algorithm.</p>
<h2>Implementation</h2>
<h3>Standard Multiplication</h3>
<p>Typically the standard implementation of multiplication of n-digit numbers require n<sup>2</sup> multiplications as you can see from the following <a href="/category/php/" title="PHP on stoimen.com">PHP</a> implementation.</p>
<pre lang="PHP">
$x = array(1,2,3,4);
$y = array(5,6,7,8);

function multiply($x, $y)
{	
	$len_x = count($x);
	$len_y = count($y);
	$half_x = ceil($len_x / 2);
	$half_y = ceil($len_y / 2);
	$base = 10;

	// bottom of the recursion
	if ($len_x == 1 && $len_y == 1) {
		return $x[0] * $y[0];
	}
	
	$x_chunks = array_chunk($x, $half_x);
	$y_chunks = array_chunk($y, $half_y);
	
	// predefine aliases
	$x1 = $x_chunks[0];
	$x2 = $x_chunks[1];
	$y1 = $y_chunks[0];
	$y2 = $y_chunks[1];
	
	return  multiply($x1, $y1) * pow($base, $half_x * 2) 					// a
		 	+ (multiply($x1, $y2) + multiply($x2, $y1)) * pow($base, $half_x) 	// b
		 	+ multiply($x2, $y2);							// c
}

// 7 006 652
echo multiply($x, $y);
</pre>
<h3>Karatsuba Multiplication</h3>
<p>Karatsuba replaces two of the multiplications &#8211; this of x1 * y2 + x2 * y1 with only one &#8211; (x1 + x2)(y1 + y2) and this makes the algorithm faster.</p>
<pre lang="PHP">
$x = array(1,2,3,4);
$y = array(5,6,7,8);

function karatsuba($x, $y) 
{
	$len_x = count($x);
	$len_y = count($y);
	
	// bottom of the recursion
	if ($len_x == 1 && $len_y == 1) {
		return $x[0] * $y[0];
	} 
	if ($len_x == 1 || $len_y == 1) {
		$t1 = implode('', $x);
		$t2 = implode('', $y);
		return (int)$t1 * $t2;
	}
	
	$a = array_chunk($x, ceil($len_x/2));
	$b = array_chunk($y, ceil($len_y/2));
	
	$deg = floor($len_x/2);
	
	$x1 = $a[0];	// 1
	$x2 = $a[1];	// 2
	$y1 = $b[0];	// 1
	$y2 = $b[1];	// 2

	return  ($a = karatsuba($x1, $y1)) * pow(10, 2 * $deg)
			+ ($c = karatsuba($x2, $y2))
			+ (karatsuba(sum($x1, $x2), sum($y1, $y2)) - $a - $c) * pow(10, $deg);
}

// 7 006 652
echo karatsuba($x, $y);
</pre>
<h2>Complexity</h2>
<p>Assuming that we replace two of the multiplications with only one makes the program faster. The question is how fast. Karatsuba improves the multiplication process by replacing the initial complexity of O(n<sup>2</sup>) by O(n<sup>lg3</sup>), which as you can see on the diagram below is much faster for big n.</p>
<figure id="attachment_3141" style="width: 600px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/05/Karatsuba-Complexity.png"><img src="/wp-content/uploads/2012/05/Karatsuba-Complexity.png" alt="Karatsuba Complexity" title="Karatsuba Complexity" width="600" height="371" class="size-full wp-image-3141" srcset="/wp-content/uploads/2012/05/Karatsuba-Complexity.png 600w, /wp-content/uploads/2012/05/Karatsuba-Complexity-300x185.png 300w" sizes="(max-width: 600px) 100vw, 600px" /></a><figcaption class="wp-caption-text">O(n^2) grows much faster than O(n^lg3)</figcaption></figure>
<h2>Application</h2>
<p>It&#8217;s obvious where the Karatsuba algorithm can be used. It is very efficient when it comes to integer multiplication, but that isn’t its only advantage. It is often used for polynomial multiplications.</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2013/01/14/computer-algorithms-multiplication/" rel="bookmark" title="Computer Algorithms: Multiplication">Computer Algorithms: Multiplication </a></li>
<li><a href="/2012/11/26/computer-algorithms-strassens-matrix-multiplication/" rel="bookmark" title="Computer Algorithms: Strassen&#8217;s Matrix Multiplication">Computer Algorithms: Strassen&#8217;s Matrix Multiplication </a></li>
<li><a href="/2012/05/08/computer-algorithms-determine-if-a-number-is-prime/" rel="bookmark" title="Computer Algorithms: Determine if a Number is Prime">Computer Algorithms: Determine if a Number is Prime </a></li>
<li><a href="/2012/12/24/computer-algorithms-sorting-in-linear-time/" rel="bookmark" title="Computer Algorithms: Sorting in Linear Time">Computer Algorithms: Sorting in Linear Time </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2012/05/15/computer-algorithms-karatsuba-fast-multiplication/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
	</channel>
</rss>
