[goto] Large integer algorithm [one] Karatsuba multiplication

Source: Internet
Author: User

★ Intro

in the previous two, Comba multiplication was introduced, and finally it was mentioned that when the size of the input was large, the computational time required increased sharply because the time complexity of the Comba multiplication was still O (n^2). To break the limit of O (n^2) in multiplication, you need to look at multiplication from a completely different angle. In the following multiplication algorithm, it is necessary to use the polynomial base expression f (x) and G (x) of the two large integers, x and Y.

Make f (x) = a * x + b,g (x) = c * x + d,h (x) = f (x) * g (x). The x here is equivalent to a base, such as a decimal, 123456 can be expressed as 123 * 100 + 456, then x is 100.

★karatsuba Multiplication Principle

Since the amount of computation increases with n^2 when the input size n increases, it would be easier to solve these smaller problems by considering splitting a larger problem into several smaller problems.

For x and y product z = x * y, you can split both X and y into two segments: the left and right halves of X are the left and right halves of a and b,y, respectively, C and D.

Now consider the product h (x) = f (x) * g (x):

H (x) = (A * x + b) * (c * x + D)

= A * c * (x^2) + (A * d + b * C) * x + b * d

As can be seen, the calculation of H (x), the need to calculate 4 half-size multiplication, 3 additions, multiplied by x or multiplied by x^2 can be achieved by the shift, all the addition and displacement of the common O (n) calculation.

Set T (n) is the total number of operations required to multiply two n-bit integers, the recursive equation is:

T (N) = 4 * T (N/2) + O (n) when n > 1

T (n) = O (1) When n = 1

Solve this recursive equation, get T (n) = O (n^2), that is, time complexity and comba multiplication is the same, there is no improvement. To reduce the complexity of the calculation, you must reduce the number of times the multiplication is calculated.

Note that A * d + b * C can be represented by a * C and b * D: (A + B) * (C + D)-A * c-b * d.

Primitive = (A + b) * (C + D)-A * c-b * d

= A * C + A * d + b * C + b * d-a *c-b *d

= A * D + b * C

Above the conversion, the calculation of a * d + b * C can be done by two addition of a multiplication, so that the total number of multiplication is reduced to 3 times, the new recursive equation is listed as follows:

T (N) = 3 * T (N/2) + O (n) when n > 1

T (n) = O (1) When n = 1

The recursive equation gets t (n) = O (n^log3), note that the log here is based on the base 2, the approximate computation, the time complexity is: T (n) = O (n^1.585), than the Comba multiplication O (n^2) smaller.

The above is the principle of calculating multiplication using the method of divide and conquer. The above algorithm, presented by Anatolii Alexeevitch Karatsuba in 1960 and published in 1962, is also known as Karatsuba multiplication.

★ Realize Ideas

The principle is clear, now tidy up the idea:

1. Split Input:

Calculate the base of the split: B = MIN (x->used, y->used)/2

The x0,y0 stores the lower halves of X and Y, respectively, and X1,y1 stores the high halves of X and Y, respectively.

2. Calculate Three products:

x0y0 = x0 * y0//recursive call multiplication bn_mul_bn

x1y1 = x1 * Y1

T1 = x0 + x1

x0 = y0 + y1

T1 = T1 * x0

3. Calculate the intermediate:

x0 = x0y0 + x1y1

T1 = t1-x0

4. Calculate the final product:

T1 = T1 * (2^ (n * B))//shift left B digit

X1y1 = X1y1 * (2^ (2 * B))//Shift left 2 * B digits

T1 = x0y0 + T1

z = t1 + x1y1//FINAL result

★ Achieve

          According to the above idea, the implementation code of the Karatsuba multiplication is as follows:

static int Bn_mul_karatsuba (Bignum *z, const bignum *x, const bignum *y) {int ret;    size_t I, B;    Register Bn_digit *pa, *PB, *px, *py;     Bignum x0[1], x1[1], y0[1], y1[1], t1[1], x0y0[1], x1y1[1];    B = Bn_min (x->used, y->used);     B >>= 1;    Bn_check (Bn_init_size (x0, B));    Bn_check (Bn_init_size (x1, x->used-b));    Bn_check (Bn_init_size (y0, B));    Bn_check (Bn_init_size (y1, y->used-b));    Bn_check (bn_init_size (T1, B << 1));    Bn_check (Bn_init_size (x0y0, B << 1));     Bn_check (Bn_init_size (x1y1, B << 1));    x0->used = y0->used = B;    x1->used = x->used-b;     y1->used = y->used-b;    PX = x->dp;    PY = y->dp;    PA = x0->dp;     PB = y0->dp;        for (i = 0; i < B; i++) {*pa++ = *px++;    *pb++ = *py++;    } PA = x1->dp;     PB = y1->dp;     for (i = B; i < x->used; i++) *pa++ = *px++;     for (i = B; i < y->used; i++) *pb++ = *py++; Bn_clamp (x0);     Bn_clamp (y0);    Bn_check (Bn_mul_bn (x0y0, x0, y0));     Bn_check (Bn_mul_bn (x1y1, x1, y1));    Bn_check (bn_add_abs (T1, x0, x1));    Bn_check (Bn_add_abs (x0, y0, y1));     Bn_check (bn_mul_bn (T1, x0, T1));    Bn_check (Bn_add_abs (x0, x0y0, x1y1));     Bn_check (Bn_sub_abs (t1, T1, x0));    Bn_check (bn_lshd (t1, B));     Bn_check (Bn_lshd (x1y1, B << 1));    Bn_check (Bn_add_abs (T1, x0y0, T1)); Bn_check (Bn_add_abs (z, T1, x1y1));    Clean:bn_free (x0);    Bn_free (x1);    Bn_free (y0);    Bn_free (y1);    Bn_free (t1);    Bn_free (X0Y0);     Bn_free (X1Y1); return ret;}

  

The above code requires a lot of temporary bignum variables, but since we know the size of each bignum from the beginning, we use the Bn_init_size function to initialize and assign the specified digits to avoid re-allocating the memory later, saving time.

The algorithm begins by splitting the input x and y into two halves, using three loops. In order to improve efficiency, the Register keyword is added to the front of the pointer to imply that the variables are placed in the CPU registers as much as possible during execution to speed up the variable access speed.

Multiplication is a recursive call to the BN_MUL_BN function, this is the symbolic number multiplication calculation function, later, when the recursive call to a critical point, the multiplication of the calculation will call the Comba method directly to calculate, instead of always using Karatsuba recursion. The function prototypes of BN_MUL_BN are: int bn_mul_bn (bignum *z, const bignum *x, const bignum *y);

It is important to note that each calculation operation (addition, subtraction, multiplication, and shift) is likely to go wrong during execution, so the Bn_check macro must be added for error checking, and once the function call goes wrong, the memory cleanup operation is performed behind clean.

★ Split Point

Although the single-precision multiplication required by the Karatsuba multiplication is less than the Comba method, there is also an O (n)-level overhead to solve a set of equations for calculating the middle term and merging the final result, which makes the Karatsuba Multiplication can take more time to calculate when it is necessary to handle a small number of inputs. Therefore, in the actual operation, the recursive calculation to a certain size, you should use the Comba method to calculate. In the BN_MUL_BN function, the partition point size is bn_digit (when the word length is three bit) or two (when the length of the Bn_digit Word is a), when the size of the input is less than the split point, you should use the Comba method to calculate the multiplication, only if the two number of rules modulus greater than or equal to the split point is calculated recursively using the Karatsuba method.

★ Summary

The Karatsuba algorithm is a relatively simple recursive multiplication, splitting the input into 2 parts, but for a larger number, you can split the input into 3 parts or even 4 parts. Split into 3-part ticks, you can use Toom-cook 3-way multiplication and reduce complexity to O (n^1.465). Split into 4 ticks, using Toom-cook 4-way multiplication, the complexity is further reduced to O (n^1.404). For larger numbers, it can be split into 100 segments, using a fast Fourier transform, which is nearly linear in complexity and approximately O (n^1.149). As you can see, the larger the segmentation, the less time complexity, but the intermediate items to be computed and the process of merging the final result will be more complex, the overhead will increase, so the split point goes up, for public key encryption, the temporary use of not too large integers, so the use of Karatsuba is appropriate, do not have to get more complex recursive multiplication.

The next article builds the multiplication of signed numbers using the Comba method and the Karatsuba method.

"Back to this series of catalogs"

Copyright notice
Original blog post, reproduced must contain this statement, to keep this article complete, and in the form of hyperlinks annotated author Starrybird and this article original address: http://www.cnblogs.com/starrybird/p/4445566.html

[goto] Large integer algorithm [one] Karatsuba multiplication

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.