|
|
(One intermediate revision by one other user not shown) |
Line 1: |
Line 1: |
| In [[mathematics]] and [[computer programming]], '''exponentiating by squaring''' is a general method for fast computation of large [[positive integer]] powers of a [[number]], or, more generally of an element of a [[ring (mathematics)|ring]], like a [[polynomial]] or a [[square matrix]]. Some variants are commonly referred to as '''square-and-multiply''' algorithms or '''binary exponentiation'''. These can be of quite general use, for example in [[modular arithmetic]] or powering of matrices.
| | Centering the profile - Many of us need to keep our profile in the middle of the website. Be taught more on a related article by clicking [http://avvocato-a-roma.info/blogs/how-to-pimp-out-a-myspace-profile-using-myspace-layouts/ www.facebook.com/lunchdates]. It looks great. The rule for that is obtainable in several twitter codes internet sites. You... <br><br>Most of us wish that we could operate our page so that it looks good. Some people have special requirements. We should keep quantity of facts private, just for few friends, but do not learn how to do this. Myspace requirements help us in personalizing the account. If you hate to be taught new information about [http://izumicon.info/news/myspace-graphics-make-the-profile-fun-to-use-2/ Myspace Graphics Make The Profile Fun To Use | Izumi Co], there are many online libraries you might investigate. I would like to tell about few to you of these limitations. If you want to be taught further about [http://6times.biz/?p=5077 http://careerbuilder.com/jobs/company/c8d5pp692vgnm428tfs/its-just-lunch/], we recommend lots of resources people can pursue. <br><br>Centering the profile - Many of us wish to keep our profile in the heart of the website. It looks great. The code for that is available in many twitter rules web sites. You must duplicate the code and paste it in about me part of your account. Save yourself it and refresh your profile. Your report will be the middle. <br><br>Hide the contact table - What if you do not want to be called by others? You"ll have that freedom today. After hiding your contact dining table, you"ll have the ability to contact the others, however they can"t contact you. This saves you from lot of spam messages and [https://Www.Gov.uk/search?q=spam+profiles spam profiles]. The rule for that is quite simple to work with and you also can take it off when you need. <br><br>Image Codes - In this code, you are able to distribute your own photographs. Publish your image on any free image uploading internet site. Copy the URL of picture in-the code box and copy the code in your account. as soon as you start your report, your image will get downloaded. <br><br>Hide myspace comments - Many of us receive highly personal [http://Search.Un.org/search?ie=utf8&site=un_org&output=xml_no_dtd&client=UN_Website_en&num=10&lr=lang_en&proxystylesheet=UN_Website_en&oe=utf8&q=comments&Submit=Go comments]. We don"t want others to look at them. In profile all responses are visible. Using the signal for Hide myspace comments, you are able to cover your comments. No body will be able to see them. <br><br>Remove If you don"t wish to receive comments from everyone - put in a remark link, what should you do? That signal comes handy for that. Make use of this rule and no body could review you. <br><br>Myspace codes provide people lot of freedom to play with our myspace profile. We are in need of perhaps not be hopeless at all. With so many codes, we can design our account the way we want. We are no longer at mercy of others..<br><br>If you loved this post and you would like to receive more info with regards to health insurance prices ([http://efficaciouslose24.postbit.com web page]) kindly visit our site. |
| This method is also used for exponentiation in [[group (mathematics)|groups]]. For groups for which [[Abelian group#Notation|additive notation]] is commonly used, like [[elliptic curve]]s used in [[cryptography]], this method is also referred to as '''double-and-add'''.
| |
| | |
| ==Basic method==
| |
| | |
| The method is based on the observation that, for a positive integer ''n'', we have
| |
| :<math> x^n= | |
| \begin{cases}
| |
| x \, ( x^{2})^{\frac{n - 1}{2}}, & \mbox{if } n \mbox{ is odd} \\
| |
| (x^{2})^{\frac{n}{2}} , & \mbox{if } n \mbox{ is even}.
| |
| \end{cases}
| |
| </math>
| |
| | |
| This may be easily implemented into the following [[recursion|recursive algorithm]]:
| |
| '''Function''' <u>exp-by-squaring</u>(''x'',''n'')
| |
| '''if''' ''n''<0 '''then return''' <u>exp-by-squaring</u>(1/''x'', -''n'');
| |
| '''else if''' ''n''=0 '''then return''' 1;
| |
| '''else if''' ''n''=1 '''then return''' ''x'';
| |
| '''else if''' ''n'' is even '''then return''' <u>exp-by-squaring</u>(''x''<sup>2</sup>, ''n''/2);
| |
| '''else if''' ''n'' is odd '''then return''' ''x'' * <u>exp-by-squaring</u>(''x''<sup>2</sup>, (''n''-1)/2).
| |
| | |
| A brief analysis shows that such an algorithm uses O(log<sub>2</sub>''n'') squarings and O(log<sub>2</sub>''n'') multiplications. For n > about 4 this is computationally more efficient than naively multiplying the base with itself repeatedly.
| |
| | |
| ==2<sup>k</sup>-ary method==
| |
| This algorithm calculates the value of x<sup>n</sup> after expanding the exponent in base 2<sup>k</sup>. It was first proposed by [[Brauer]] in 1939. In the algorithm below we make use of the following function f(0) = (k,0) and f(m) = (s,u) where m = u·2<sup>s</sup>
| |
| with ''u'' odd.
| |
| | |
| Algorithm:
| |
| | |
| ;Input: An element x of G, a parameter k > 0, a non-negative integer {{math|1=''n'' = (''n''<sub>''l''−1</sub>, ''n''<sub>''l''−2</sub>, ..., ''n''<sub>0</sub>)<sub>2<sup>''k''</sup></sub>}} and the precomputed values <math style="vertical-align:baseline;">x^3, x^5, ... , x^{2^k-1}</math>.
| |
| | |
| ;Output: The element x<sup>n</sup> in ''G''
| |
| | |
| 1. y := 1; i := l-1
| |
| 2. '''while''' i>=0 do
| |
| 3. (s,u) := f(n<sub>i</sub>)
| |
| 4. '''for''' j:=1 '''to''' k-s '''do'''
| |
| 5. y := y<sup>2</sup>
| |
| 6. y := y*x<sup>u</sup>
| |
| 7. '''for''' j:=1 '''to''' s '''do'''
| |
| 8. y := y<sup>2</sup>
| |
| 9. i := i-1
| |
| 10. '''return''' y
| |
| | |
| For optimal efficiency, ''k'' should be the smallest integer satisfying <ref name="frey">Cohen, H., Frey, G. (editors): Handbook of elliptic and hyperelliptic curve cryptography. Discrete Math.Appl., Chapman & Hall/CRC (2006)</ref>
| |
| | |
| :<math>\lg(n) < \frac{k(k+1) \cdot 2^{2k}}{2^{k+1} - k - 2} + 1.</math>
| |
| | |
| ==Sliding window method==
| |
| This method is an efficient variant of the 2<sup>k</sup>-ary method. For example, to calculate the exponent 398 which has binary expansion (110 001 110)<sub>2</sub>, we take a window of length 3 using the 2<sup>k</sup>-ary method algorithm we calculate 1,x<sup>3</sup>,x<sup>6</sup>,x<sup>12</sup>,x<sup>24</sup>,x<sup>48</sup>,x<sup>49</sup>,x<sup>98</sup>,x<sup>99</sup>,x<sup>198</sup>,x<sup>199</sup>,x<sup>398</sup>.
| |
| But, we can also compute 1,x<sup>3</sup>,x<sup>6</sup>,x<sup>12</sup>,x<sup>24</sup>,x<sup>48</sup>,x<sup>96</sup>,x<sup>192</sup>,x<sup>199</sup>,
| |
| x<sup>398</sup> which saves one multiplication and amounts to evaluating (110 001 110)n<sub>2</sub>
| |
| | |
| Here is the general algorithm:
| |
| | |
| Algorithm:
| |
| | |
| ;Input:An element ''x'' of ''G'',a non negative integer {{math|1=''n''=(''n''<sub>l</sub>,''n''<sub>l-1</sub>,...,''n''<sub>0</sub>)<sub>2</sub>}}, a parameter k>0 and the pre-computed values <math style="vertical-align:baseline;">x^3, x^5, ... ,x^{2^k-1}</math>.
| |
| | |
| ;Output: The element ''x<sup>n</sup>'' ∈ ''G''
| |
| | |
| Algorithm:
| |
| | |
| 1. y := 1; i := l-1
| |
| 2. '''while''' i > -1 '''do'''
| |
| 3. '''if''' n<sub>i</sub>=0 '''then''' y:=y<sup>2</sup>' i:=i-1
| |
| 4. '''else'''
| |
| 5. s:=max{i-k+1,0}
| |
| 6. '''while''' n<sub>s</sub>=0 '''do''' s:=s+1 <ref>In this line, the loop finds the longest string of length less than or equal to 'k' which ends in a non zero value. And not all odd powers of 2 up to <math style="vertical-align:baseline;">x^{2^k-1}</math> need be computed and only those specifically involved in the computation need be considered.</ref>
| |
| 7. '''for''' h:=1 '''to''' i-s+1 '''do''' y:=y<sup>2</sup>
| |
| 8. u:=(n<sub>i</sub>,n<sub>i-1</sub>,....,n<sub>s</sub>)<sub>2</sub>
| |
| 9. y:=y*x<sup>u</sup>
| |
| 10. i:=s-1
| |
| 11. '''return''' y
| |
| | |
| ==Montgomery's ladder technique==
| |
| Many algorithms for exponentiation do not provide defence against [[side-channel attack]]s. Namely, an attacker observing the sequence of squarings and multiplications can (partially) recover the exponent involved in the computation. This is a problem if the exponent should remain secret, as with many [[Public-key cryptography|public-key cryptosystems]]. A technique called [[Peter Montgomery (mathematician)|Montgomery's]] Ladder<ref name="ladder">Montgomery, P. L. "Speeding the Pollard and Elliptic Curve Methods of Factorization." Math. Comput. 48, 243-264, 1987.</ref> addresses this concern.
| |
| | |
| Given the [[binary expansion]] of a positive, non-zero integer n=(n<sub>k-1</sub>...n<sub>0</sub>)<sub>2</sub> with n<sub>k-1</sub>=1 we can compute x<sup>n</sup> as follows:
| |
| x<sub>1</sub>=x; x<sub>2</sub>=x<sup>2</sup>
| |
| for i=k-2 to 0 do
| |
| If n<sub>i</sub>=0 then
| |
| x<sub>2</sub>=x<sub>1</sub>*x<sub>2</sub>; x<sub>1</sub>=x<sub>1</sub><sup>2</sup>
| |
| else
| |
| x<sub>1</sub>=x<sub>1</sub>*x<sub>2</sub>; x<sub>2</sub>=x<sub>2</sub><sup>2</sup>
| |
| return x<sub>1</sub>
| |
| | |
| The algorithm performs a fixed sequence of operations ([[up to]] log n): a multiplication and squaring takes place for each bit in the exponent, regardless of the bit's specific value.
| |
| | |
| ==Fixed base exponent==
| |
| There are several methods which can be employed to calculate x<sup>n</sup> when the base is fixed and the exponent varies. As one can see, [[precomputation]]s play a key role in these algorithms.
| |
| | |
| ===Yao's method===
| |
| Yao's method is orthogonal to the 2<sup>k</sup>-ary method where the exponent is expanded in radix b=2<sup>k</sup> and the computation is as performed in the algorithm above. Let "n", "n<sub>i</sub>", "b", and "b<sub>i</sub>" be integers.
| |
| | |
| Let the exponent "n" be written as
| |
| :<math> n = \sum_{i=0}^{w-1} n_ib_i</math> where <math> 0 \leqslant n_i < h</math> for all <math>i \in [0,w-1] </math>
| |
| | |
| Let x<sub>i</sub> = x<sup>b<sub>i</sub></sup>. Then the algorithm uses the equality
| |
| :<math> x^n = \prod_{i=0}^{w-1} {x_i}^{n_i} = \prod_{j=1}^{h-1}{\bigg[\prod_{n_i=j} x_i\bigg]}^j </math>
| |
| | |
| Given the element 'x' of G, and the exponent 'n' written in the above form, along with the pre computed values x<sup>b<sub>0</sub></sup>....x<sup>b<sub>w-1</sub></sup> the element x<sup>n</sup> is calculated using the algorithm below
| |
| {{verify source|date=April 2013}}
| |
| <tt>
| |
| #y=1,u=1 and j=h-1
| |
| #while j > 0 do
| |
| # for i=0 to w-1 do
| |
| ##if n<sub>i</sub>=j then u=u*x<sup>b<sub>i</sub></sup>
| |
| # y=y*u
| |
| # j=j-1
| |
| # return y
| |
| </tt>
| |
| If we set h=2<sup>k</sup> and b<sub>i</sub> = h<sup>i</sup> then the n<sub>i</sub> 's are simply the digits of n in base h. Yao's method collects in u first those x<sub>i</sub> which appear to the highest power h-1; in the next round those with power h-2 are collected in u as well etc. The variable y is multiplied h-1 times with the initial u, h-2 times with the next highest powers etc.
| |
| The algorithm uses w+h-2 multiplications and w+1 elements must be stored to compute x<sup>n</sup> (see <ref name=frey />).
| |
| | |
| ===Euclidean method===
| |
| The Euclidean method was first introduced in ''Efficient exponentiation using precomputation and vector addition chains'' by P.D Rooij.
| |
| | |
| This method for computing <math>x^n</math> in group {{math|'''G'''}}, where <math>n</math> is a natural integer, whose algorithm is given below, is using the following equality recursively:
| |
| : <math>{x_0}^{n_0} \cdot {x_1}^{n_1} = {\left( x_0 \cdot {x_1}^{q} \right)}^{n_0} \cdot {x_1}^{n_1 \mod {n_0}}</math>, where <math>q = \left\lfloor {n_1} / {n_0} \right\rfloor</math>
| |
| : (in other words an Euclidian division of the exponent {{math|''n''<sub>1</sub>}} by {{math|''n''<sub>0</sub>}} is used to return a quotient {{mvar|q}} and a rest <math>n_0</math>).
| |
| | |
| Given the base element <math>x</math> in group {{math|'''G'''}}, and the exponent <math>n</math> written as in Yao's method, the element <math>x^n</math> is calculated using <math>l</math> precomputed values <math>x^{b_0}, ..., x^{b_{l_i}}</math> and then the algorithm below.
| |
| | |
| '''Begin loop'''
| |
| Find <math>M \in \left[ 0, l - 1 \right]</math>, such that <math>\forall i \in \left[ 0, l - 1 \right], {n_M} \ge {n_i}</math>;
| |
| Find <math>N \in \left( \left[ 0, l - 1 \right] - M \right)</math>, such that <math>\forall i \in \left( \left[ 0, l - 1 \right] - M \right), {n_N} \ge {n_i}</math>;
| |
| '''Break loop''' if <math>{n_N} = 0</math>;
| |
| '''Let''' <math>q = \left\lfloor {n_M} / {n_N} \right\rfloor</math>, and then '''let''' <math>{n_N} = \left( {n_M} \mod {n_N} \right)</math>;
| |
| Compute recursively <math>{x_M}^q</math>, and then '''let''' <math>{x_N} = {x_N} \cdot {x_M}^q</math>;
| |
| '''End loop''';
| |
| '''Return''' <math>x^n = {x_M}^{n_M}</math>.
| |
| | |
| The algorithm first finds the largest value amongst the {{math|''n''<sub>''i''</sub>}} and then the supremum within the set of {{math|{{(}} ''n''<sub>''i''</sub> \ ''i'' ≠ ''M'' {{)}}}}.
| |
| Then it raises {{math|''x''<sub>''M''</sub>}} to the power {{mvar|q}}, multiplies this value with {{math|''x''<sub>''N''</sub>}}, and then assigns {{math|''x''<sub>''N''</sub>}} the result of this computation and {{math|''n''<sub>''M''</sub>}} the value {{math|''n''<sub>''M''</sub>}} modulo {{math|''n''<sub>''N''</sub>}}.
| |
| | |
| ==Further applications==
| |
| The same idea allows fast computation of large [[Modular exponentiation|exponents modulo]] a number. Especially in [[cryptography]], it is useful to compute powers in a [[Ring (mathematics)|ring]] of [[modular arithmetic|integers modulo ''q'']]. It can also be used to compute integer powers in a [[group (mathematics)|group]], using the rule
| |
| | |
| :Power(''x'', −''n'') = (Power(''x'', ''n''))<sup>−1</sup>.
| |
| | |
| The method works in every [[semigroup]] and is often used to compute powers of [[matrix (math)|matrices]],
| |
| | |
| For example, the evaluation of
| |
| | |
| :13789<sup>722341</sup> (mod 2345)
| |
| | |
| would take a very long time and lots of storage space if the naïve method were used: compute 13789<sup>722341</sup> then take the [[remainder]] when divided by 2345. Even using a more effective method will take a long time: square 13789, take the remainder when divided by 2345, multiply the [[result]] by 13789, and so on. This will take 722340 modular multiplications.
| |
| | |
| Applying above ''exp-by-squaring'' algorithm, with "*" interpreted as ''x''*''y'' = ''xy'' mod 2345 (that is a multiplication followed by a division with remainder) leads to only 27 multiplications and divisions of integers which may all be stored in a single machine word.
| |
| | |
| ==Example implementations==
| |
| ===Computation by powers of 2===
| |
| This is a non-recursive implementation of the above algorithm in [[Ruby (programming language)|Ruby]].
| |
| | |
| In most [[static typing|statically typed]] languages, <tt>result=1</tt> must be replaced with code assigning an [[identity matrix]] of the same size as <tt>x</tt> to <tt>result</tt> to get a matrix exponentiating algorithm. In Ruby, thanks to coercion, <tt>result</tt> is automatically upgraded to the appropriate type, so this function works with matrices as well as with integers and floats. Note that n=n-1 is redundant when n=n/2 implicitly rounds towards zero, as lower level languages would do.
| |
| n[0] is the rightmost bit of the binary representation of n, so if it is 1, the number is odd, if it is zero, the number is even.
| |
| | |
| <source lang="ruby">
| |
| def power(x,n)
| |
| result = 1
| |
| while n.nonzero?
| |
| if n[0].nonzero?
| |
| result *= x
| |
| n -= 1
| |
| end
| |
| x *= x
| |
| n /= 2
| |
| end
| |
| return result
| |
| end
| |
| </source>
| |
| | |
| ====Runtime example: compute 3<sup>10</sup>====
| |
| parameter x = 3
| |
| parameter n = 10
| |
| result := 1
| |
|
| |
| '''Iteration 1'''
| |
| n = 10 -> n is even
| |
| x := x<sup>2</sup> = 3<sup>2</sup> = 9
| |
| n := n / 2 = 5
| |
|
| |
| '''Iteration 2'''
| |
| n = 5 -> n is odd
| |
| -> result := result * x = 1 * x = 1 * 3<sup>2</sup> = 9
| |
| n := n - 1 = 4
| |
| x := x<sup>2</sup> = 9<sup>2</sup> = 3<sup>4</sup> = 81
| |
| n := n / 2 = 2
| |
|
| |
| '''Iteration 3'''
| |
| n = 2 -> n is even
| |
| x := x<sup>2</sup> = 81<sup>2</sup> = 3<sup>8</sup> = 6561
| |
| n := n / 2 = 1
| |
|
| |
| '''Iteration 4'''
| |
| n = 1 -> n is odd
| |
| -> result := result * x = 3<sup>2</sup> * 3<sup>8</sup> = 3<sup>10</sup> = 9 * 6561 = 59049
| |
| n := n - 1 = 0
| |
|
| |
| return result
| |
| | |
| ====Runtime example: compute 3<sup>10</sup>====
| |
| result := 3
| |
| bin := "1010"
| |
|
| |
| '''Iteration for digit 2:'''
| |
| result := result<sup>2</sup> = 3<sup>2</sup> = 9
| |
| 1'''0'''10<sub>bin</sub> - Digit equals "0"
| |
|
| |
| '''Iteration for digit 3:'''
| |
| result := result<sup>2</sup> = (3<sup>2</sup>)<sup>2</sup> = 3<sup>4</sup> = 81
| |
| 10'''1'''0<sub>bin</sub> - Digit equals "1" --> result := result*3 = (3<sup>2</sup>)<sup>2</sup>*3 = 3<sup>5</sup> = 243
| |
|
| |
| '''Iteration for digit 4:'''
| |
| result := result<sup>2</sup> = ((3<sup>2</sup>)<sup>2</sup>*3)<sup>2</sup> = 3<sup>10</sup> = 59049
| |
| 101'''0'''<sub>bin</sub> - Digit equals "0"
| |
|
| |
| return result
| |
| | |
| JavaScript-Demonstration: http://home.mnet-online.de/wzwz.de/temp/ebs/en.htm
| |
| | |
| ===Calculation of products of powers===
| |
| Exponentiation by squaring may also be used to calculate the product of 2 or more powers.
| |
| If the underlying group or semigroup is [[commutative]] then it is often possible to reduce the
| |
| number of multiplication by computing the product simultaneously.
| |
| | |
| ====Example====
| |
| The formula a<sup>7</sup>×b<sup>5</sup> may be calculated within 3 steps:
| |
| :((a)<span style="color:red;"><sup>2</sup>×</span>a)<span style="color:red;"><sup>2</sup>×</span>a (four multiplications for calculating a<sup>7</sup>)
| |
| :((b)<span style="color:red;"><sup>2</sup></span>)<span style="color:red;"><sup>2</sup>×</span>b (three multiplications for calculating b<sup>5</sup>)
| |
| : (a<sup>7</sup>)<span style="color:red;">×</span>(b<sup>5</sup>) (one multiplication to calculate the product of the two)
| |
| so one gets eight multiplications in total.
| |
| | |
| A faster solution is to calculate both powers simultaneously:
| |
| :((a<span style="color:red;">×</span>b)<span style="color:red;"><sup>2</sup>×</span>a)<span style="color:red;"><sup>2</sup>×</span>a<span style="color:red;">×</span>b
| |
| which needs only 6 multiplications in total. Note that a×b is calculated twice, the result could be stored after the first calculation which reduces the count of multiplication to 5.
| |
| | |
| Example with numbers:
| |
| :2<sup>7</sup>×3<sup>5</sup> = ((2×3)<sup>2</sup>×2)<sup>2</sup>×2×3 = (6<sup>2</sup>×2)<sup>2</sup>×6 = 72<sup>2</sup>×6 = 31,104
| |
| | |
| Calculating the powers simultaneously instead of calculating them separately always reduces the
| |
| count of multiplications if at least two of the exponents are greater than 1.
| |
| | |
| ====Using transformation====
| |
| The example above a<sup>7</sup>×b<sup>5</sup> may also be calculated with only 5
| |
| multiplications if the expression is transformed before calculation:
| |
| | |
| a<sup>7</sup>×b<sup>5</sup> = a<sup>2</sup>×(ab)<sup>5</sup> with ab := a×b
| |
| <dl>
| |
| <dd>ab := a<span style="color:red;">×</span>b (one multiplication)</dd>
| |
| <dd>a<sup>2</sup>×(ab)<sup>5</sup> = ((ab)<span style="color:red;"><sup>2</sup>×</span>a)<span style="color:red;"><sup>2</sup>×</span>ab (four multiplications)</dd>
| |
| </dl>
| |
| | |
| Generalization of transformation shows the following scheme:<br>
| |
| For calculating a<sup>A</sup>×b<sup>B</sup>×...×m<sup>M</sup>×n<sup>N</sup><br>
| |
| 1st: define ab := a×b, abc = ab×c, ...<br>
| |
| 2nd: calculate the transformed expression a<sup>A−B</sup>×ab<sup>B−C</sup>×...×abc..m<sup>M−N</sup>×abc..mn<sup>N</sup>
| |
| | |
| Transformation before calculation often reduces the count of multiplications
| |
| but in some cases it also increases the count (see the last one of the examples below),
| |
| so it may be a good idea to check the count of multiplications before using the transformed expression for calculation.
| |
| | |
| ====Examples====
| |
| For the following expressions the count of multiplications is shown for calculating each power separately,
| |
| calculating them simultaneously without transformation and calculating them simultaneously after transformation.
| |
| | |
| Example: a<sup>7</sup>×b<sup>5</sup>×c<sup>3</sup><br>
| |
| separate: [((a)<span style="color:red;"><sup>2</sup>×</span>a)<span style="color:red;"><sup>2</sup>×</span>a] <span style="color:red;">×</span> [((b)<span style="color:red;"><sup>2</sup></span>)<span style="color:red;"><sup>2</sup>×</span>b] <span style="color:red;">×</span> [(c)<span style="color:red;"><sup>2</sup>×</span>c] ( '''11''' multiplications )<br>
| |
| simultaneous: ((a<span style="color:red;">×</span>b)<span style="color:red;"><sup>2</sup>×</span>a<span style="color:red;">×</span>c)<span style="color:red;"><sup>2</sup>×</span>a<span style="color:red;">×</span>b<span style="color:red;">×</span>c ( '''8''' multiplications )<br>
| |
| transformation: a := 2 ab := a<span style="color:red;">×</span>b abc := ab<span style="color:red;">×</span>c ( 2 multiplications )<br>
| |
| calculation after that: (a<span style="color:red;">×</span>ab<span style="color:red;">×</span>abc)<span style="color:red;"><sup>2</sup>×</span>abc ( 4 multiplications ⇒ '''6''' in total )
| |
| | |
| Example: a<sup>5</sup>×b<sup>5</sup>×c<sup>3</sup><br>
| |
| separate: [((a)<span style="color:red;"><sup>2</sup></span>)<span style="color:red;"><sup>2</sup>×</span>a] <span style="color:red;">×</span> [((b)<span style="color:red;"><sup>2</sup></span>)<span style="color:red;"><sup>2</sup>×</span>b] <span style="color:red;">×</span> [(c)<span style="color:red;"><sup>2</sup>×</span>c] ( '''10''' multiplications )<br>
| |
| simultaneous: ((a<span style="color:red;">×</span>b)<span style="color:red;"><sup>2</sup>×</span>c)<span style="color:red;"><sup>2</sup>×</span>a<span style="color:red;">×</span>b<span style="color:red;">×</span>c ( '''7''' multiplications )<br>
| |
| transformation: a := 2 ab := a<span style="color:red;">×</span>b abc := ab<span style="color:red;">×</span>c ( 2 multiplications )<br>
| |
| calculation after that: (ab<span style="color:red;">×</span>abc)<span style="color:red;"><sup>2</sup>×</span>abc ( 3 multiplications ⇒ '''5''' in total )
| |
| | |
| Example: a<sup>7</sup>×b<sup>4</sup>×c<sup>1</sup><br>
| |
| separate: [((a)<span style="color:red;"><sup>2</sup>×</span>a)<span style="color:red;"><sup>2</sup>×</span>a] <span style="color:red;">×</span> [((b)<span style="color:red;"><sup>2</sup></span>)<span style="color:red;"><sup>2</sup></span>] <span style="color:red;">×</span> [c] ( '''8''' multiplications )<br>
| |
| simultaneous: ((a<span style="color:red;">×</span>b)<span style="color:red;"><sup>2</sup>×</span>a)<span style="color:red;"><sup>2</sup>×</span>a<span style="color:red;">×</span>c ( '''6''' multiplications )<br>
| |
| transformation: a := 2 ab := a<span style="color:red;">×</span>b abc := ab<span style="color:red;">×</span>c ( 2 multiplications )<br>
| |
| calculation after that: (a<span style="color:red;">×</span>ab)<span style="color:red;"><sup>2</sup>×</span>a<span style="color:red;">×</span>ab<span style="color:red;">×</span>abc ( 5 multiplications ⇒ '''7''' in total )
| |
| | |
| ==Signed-digit recoding==
| |
| In certain computations it may be more efficient to allow negative coefficients and hence use the inverse of the base, provided inversion in G is ' fast' or has been precomputed. For example, when computing x<sup>2<sup>k</sup>−1</sup> the binary method requires k−1 multiplications and k−1 squarings . However one could perform k squarings to get x<sup>2<sup>k</sup></sup> and then multiply by x<sup>−1</sup> to obtain x<sup>2<sup>k</sup>−1</sup>.
| |
| | |
| To this end we define the [[signed-digit representation]] of an integer <math>n</math> in radix <math>b</math> as
| |
| :<math>n=\sum_{i=0}^{l-1}n_ib^i \text{ with } |n_i|<b</math>
| |
| | |
| 'Signed Binary Representation' corresponds to the particular choice <math>b=2</math> and <math>n_i \in \{-1,0,1\}</math>. It is denoted by <math>(n_{l-1}\dots n_0)_s</math>. There are several methods for computing this representation. The representation is not unique, for example take <math>n=478</math>. Two distinct signed-binary representations are given by <math>(10\bar 1 1100\bar 1 10)_s</math> and <math>(100\bar 1 1000\bar 1 0)_s</math>, where <math>\bar 1</math> is used to denote <math>-1</math>. Since the binary method computes a multiplication for every non-zero entry in the base 2 representation of <math>n</math>, we are interested in finding the signed-binary representation with the smallest number of non-zero entries, that is, the one with ''minimal'' [[Hamming weight]]. One method of doing this is to compute the representation in [[non-adjacent form]], or NAF for short, which is one that satisfies <math>n_in_{i+1}=0\text{ for all }i\geqslant 0</math> and denoted by <math>(n_{l-1}\dots n_0)_{\text{NAF}}</math>. For example the NAF representation of 478 is equal to <math>(1000\bar 1 000\bar 1 0)_{\text{NAF}}</math>. This representation always has minimal Hamming weight. A simple algorithm to compute the NAF representation of a given integer <math>n=(n_ln_{l-1}\dots n_0)_2</math> with <math>n_l=n_{l-1}=0</math> is the following:
| |
| | |
| #<math>c_0=0</math>
| |
| #for <math>i=0</math> to <math>l-1</math> do
| |
| #<math>c_{i+1}=\left\lfloor\frac{1}{2}(c_i+n_i+n_{i+1})\right\rfloor</math>
| |
| #<math>n_i'=c_i+n_i-2c_{i+1}</math>
| |
| #return <math>(n_{l-1}'\dots n_0')_{\text{NAF}}</math>
| |
| | |
| Another algorithm by Koyama and Tsuruoka does not require the condition that <math>n_i=n_{i+1}=0</math>; it still minimizes the Hamming weight.
| |
| | |
| ==Alternatives and generalizations==
| |
| {{main|Addition-chain exponentiation}}
| |
| Exponentiation by squaring can be viewed as a suboptimal [[addition-chain exponentiation]] algorithm: it computes the exponent via an [[addition chain]] consisting of repeated exponent doublings (squarings) and/or incrementing exponents by ''one'' (multiplying by ''x'') only. More generally, if one allows ''any'' previously computed exponents to be summed (by multiplying those powers of ''x''), one can sometimes perform the exponentiation using fewer multiplications (but typically using more memory). The smallest power where this occurs is for ''n''=15:
| |
| | |
| :<math>a^{15} = x \times (x \times [x \times x^2]^2)^2 \!</math> (squaring, 6 multiplies)
| |
| :<math>a^{15} = x^3 \times ([x^3]^2)^2 \!</math> (optimal addition chain, 5 multiplies if ''x''<sup>3</sup> is re-used)
| |
| | |
| In general, finding the ''optimal'' addition chain for a given exponent is a hard problem, for which no efficient algorithms are known, so optimal chains are typically only used for small exponents (e.g. in [[compiler]]s where the chains for small powers have been pre-tabulated). However, there are a number of [[heuristic]] algorithms that, while not being optimal, have fewer multiplications than exponentiation by squaring at the cost of additional bookkeeping work and memory usage. Regardless, the number of multiplications never grows more slowly than [[Big-O notation|Θ]](log ''n''), so these algorithms only improve asymptotically upon exponentiation by squaring by a constant factor at best.
| |
| | |
| ==See also==
| |
| *[[Modular exponentiation]]
| |
| *[[Vectorial addition chain]]
| |
| *[[Montgomery reduction]]
| |
| *[[Non-adjacent form]]
| |
| *[[Addition chain]]
| |
| | |
| ==Notes==
| |
| {{Reflist}}
| |
| | |
| [[Category:Exponentials]]
| |
| [[Category:Computer arithmetic algorithms]]
| |
| [[Category:Computer arithmetic]]
| |