A word of warning.
Jun. 22nd, 2004 09:43 pmYou can't make multiplying together a big heap of bignums big-O faster by reordering the order in which you do the multiplies, unless you use a big-O-fast multiply. The cost of multiplying together a_1 ... a_n will be roughly
O(\sum_{i < j} log(a_i)log(a_j))
no matter what you try.
Suppose we want to find abc, and we do it by calculating (ab)c. Finding ab using naive multiplication will take time proportional to log(a)log(b), and then finding (ab)c will take log(ab)log(c). Total time
log(a) log(b) + log(ab)log(c) = log(a)log(b) + (log(a) + log(b))log(c)
= log(a) log(b) + log(a)log(c) + log(b)log(c)
Clearly, this is the same time as you'd get if you found it by calculating a(bc) or (ac)b.
To prove the general case by induction: partition the sequence A into two non-empty subsequences, X = x_0 .. x_m and Y = y_0 ... y_n, such that the final multiply we do is (\Pi X) (\Pi Y). The cost of finding (\Pi X) is \sum_{i < j} log(x_i)log(x_j) and similarly for (\Pi Y). Then the cost of the final multiply is log(\Pi X)log(\Pi Y) = (\sum log(x_i))(\sum log(y_j)) = \sum log(x_i) log(y_j) . In other words, the total cost of finding \Pi A by this method is the sum of the pairwise products of the logs of the numbers inside X and Y, plus the sum of the pairwise products of the logs of the numbers across X and Y - ie, the sum of the pairwise products of the logs of all numbers in A.
This is probably a well known result in bignum math, but I only worked this out after about two hard days trying such a strategy while labouring under a fatal misconception...
Update However, it turns out that gmp uses big-O-faster multiplication once numbers get to above 30 limbs or so (ie about 1000 bits). So it is worth trying to arrange for the numbers you multiply to be about the same size as each other - just not nearly as much worth it as I thought...
no subject
Date: 2004-06-22 03:23 pm (UTC)no subject
Date: 2004-06-22 08:06 pm (UTC)(OTOH since I'd written it top-down, inlining wouldn't have helped anyway.)
no subject
Date: 2004-06-22 07:41 pm (UTC)I'd just like to point out that you can do stuff like
Σi < j log(ai)log(aj)
on the web these days.
no subject
Date: 2004-06-23 12:30 am (UTC)no subject
Date: 2004-06-22 11:52 pm (UTC)no subject
Date: 2004-06-23 03:19 pm (UTC)Well, yes, obviously...
Date: 2004-06-23 03:43 pm (UTC)log(a1) * log(a2) +
(log(a1) + log(a2)) * log(a3) +
... +
(log(a1) + log(a2) + ... + log(an-1)) * log(an)
I don't readily see something that suggests permuting the ai terms would change the sum.
What I'm trying to say is by what line of thought did you guess that permuting the numbers might help? Your thought might apply in some other context.
Re: Well, yes, obviously...
Date: 2004-06-29 05:52 am (UTC)Consider the classic dynamic programming example of reordering matrix multiplication for potentially enormous speedups (eg http://www.ics.uci.edu/~dan/class/161/notes/6/Dynamic.html) - that's where a strategy like this works.