Remove an invalid fuzz compiler arg
[gh-bc.git] / manuals / algorithms.md
blobce27bf026b696f881e9d2c1bb4eb65240b7721e7
1 # Algorithms
3 This `bc` uses the math algorithms below:
5 ### Addition
7 This `bc` uses brute force addition, which is linear (`O(n)`) in the number of
8 digits.
10 ### Subtraction
12 This `bc` uses brute force subtraction, which is linear (`O(n)`) in the number
13 of digits.
15 ### Multiplication
17 This `bc` uses two algorithms: [Karatsuba][1] and brute force.
19 Karatsuba is used for "large" numbers. ("Large" numbers are defined as any
20 number with `BC_NUM_KARATSUBA_LEN` digits or larger. `BC_NUM_KARATSUBA_LEN` has
21 a sane default, but may be configured by the user.) Karatsuba, as implemented in
22 this `bc`, is superlinear but subpolynomial (bounded by `O(n^log_2(3))`).
24 Brute force multiplication is used below `BC_NUM_KARATSUBA_LEN` digits. It is
25 polynomial (`O(n^2)`), but since Karatsuba requires both more intermediate
26 values (which translate to memory allocations) and a few more additions, there
27 is a "break even" point in the number of digits where brute force multiplication
28 is faster than Karatsuba. There is a script (`$ROOT/scripts/karatsuba.py`) that
29 will find the break even point on a particular machine.
31 ***WARNING: The Karatsuba script requires Python 3.***
33 ### Division
35 This `bc` uses Algorithm D ([long division][2]). Long division is polynomial
36 (`O(n^2)`), but unlike Karatsuba, any division "divide and conquer" algorithm
37 reaches its "break even" point with significantly larger numbers. "Fast"
38 algorithms become less attractive with division as this operation typically
39 reduces the problem size.
41 While the implementation of long division may appear to use the subtractive
42 chunking method, it only uses subtraction to find a quotient digit. It avoids
43 unnecessary work by aligning digits prior to performing subtraction and finding
44 a starting guess for the quotient.
46 Subtraction was used instead of multiplication for two reasons:
48 1.      Division and subtraction can share code (one of the less important goals of
49         this `bc` is small code).
50 2.      It minimizes algorithmic complexity.
52 Using multiplication would make division have the even worse algorithmic
53 complexity of `O(n^(2*log_2(3)))` (best case) and `O(n^3)` (worst case).
55 ### Power
57 This `bc` implements [Exponentiation by Squaring][3], which (via Karatsuba) has
58 a complexity of `O((n*log(n))^log_2(3))` which is favorable to the
59 `O((n*log(n))^2)` without Karatsuba.
61 ### Square Root
63 This `bc` implements the fast algorithm [Newton's Method][4] (also known as the
64 Newton-Raphson Method, or the [Babylonian Method][5]) to perform the square root
65 operation.
67 Its complexity is `O(log(n)*n^2)` as it requires one division per iteration, and
68 it doubles the amount of correct digits per iteration.
70 ### Sine and Cosine (`bc` Math Library Only)
72 This `bc` uses the series
74 ```
75 x - x^3/3! + x^5/5! - x^7/7! + ...
76 ```
78 to calculate `sin(x)` and `cos(x)`. It also uses the relation
80 ```
81 cos(x) = sin(x + pi/2)
82 ```
84 to calculate `cos(x)`. It has a complexity of `O(n^3)`.
86 **Note**: this series has a tendency to *occasionally* produce an error of 1
87 [ULP][6]. (It is an unfortunate side effect of the algorithm, and there isn't
88 any way around it; [this article][7] explains why calculating sine and cosine,
89 and the other transcendental functions below, within less than 1 ULP is nearly
90 impossible and unnecessary.) Therefore, I recommend that users do their
91 calculations with the precision (`scale`) set to at least 1 greater than is
92 needed.
94 ### Exponentiation (`bc` Math Library Only)
96 This `bc` uses the series
98 ```
99 1 + x + x^2/2! + x^3/3! + ...
102 to calculate `e^x`. Since this only works when `x` is small, it uses
105 e^x = (e^(x/2))^2
108 to reduce `x`.
110 It has a complexity of `O(n^3)`.
112 **Note**: this series can also produce errors of 1 ULP, so I recommend users do
113 their calculations with the precision (`scale`) set to at least 1 greater than
114 is needed.
116 ### Natural Logarithm (`bc` Math Library Only)
118 This `bc` uses the series
121 a + a^3/3 + a^5/5 + ...
124 (where `a` is equal to `(x - 1)/(x + 1)`) to calculate `ln(x)` when `x` is small
125 and uses the relation
128 ln(x^2) = 2 * ln(x)
131 to sufficiently reduce `x`.
133 It has a complexity of `O(n^3)`.
135 **Note**: this series can also produce errors of 1 ULP, so I recommend users do
136 their calculations with the precision (`scale`) set to at least 1 greater than
137 is needed.
139 ### Arctangent (`bc` Math Library Only)
141 This `bc` uses the series
144 x - x^3/3 + x^5/5 - x^7/7 + ...
147 to calculate `atan(x)` for small `x` and the relation
150 atan(x) = atan(c) + atan((x - c)/(1 + x * c))
153 to reduce `x` to small enough. It has a complexity of `O(n^3)`.
155 **Note**: this series can also produce errors of 1 ULP, so I recommend users do
156 their calculations with the precision (`scale`) set to at least 1 greater than
157 is needed.
159 ### Bessel (`bc` Math Library Only)
161 This `bc` uses the series
164 x^n/(2^n * n!) * (1 - x^2 * 2 * 1! * (n + 1)) + x^4/(2^4 * 2! * (n + 1) * (n + 2)) - ...
167 to calculate the bessel function (integer order only).
169 It also uses the relation
172 j(-n,x) = (-1)^n * j(n,x)
175 to calculate the bessel when `x < 0`, It has a complexity of `O(n^3)`.
177 **Note**: this series can also produce errors of 1 ULP, so I recommend users do
178 their calculations with the precision (`scale`) set to at least 1 greater than
179 is needed.
181 ### Modular Exponentiation
183 This `dc` uses the [Memory-efficient method][8] to compute modular
184 exponentiation. The complexity is `O(e*n^2)`, which may initially seem
185 inefficient, but `n` is kept small by maintaining small numbers. In practice, it
186 is extremely fast.
188 ### Non-Integer Exponentiation (`bc` Math Library 2 Only)
190 This is implemented in the function `p(x,y)`.
192 The algorithm used is to use the formula `e(y*l(x))`.
194 It has a complexity of `O(n^3)` because both `e()` and `l()` do.
196 However, there are details to this algorithm, described by the author,
197 TediusTimmy, in GitHub issue [#69][12].
199 First, check if the exponent is 0. If it is, return 1 at the appropriate
200 `scale`.
202 Next, check if the number is 0. If so, check if the exponent is greater than
203 zero; if it is, return 0. If the exponent is less than 0, error (with a divide
204 by 0) because that is undefined.
206 Next, check if the exponent is actually an integer, and if it is, use the
207 exponentiation operator.
209 At the `z=0` line is the start of the meat of the new code.
211 `z` is set to zero as a flag and as a value. What I mean by that will be clear
212 later.
214 Then we check if the number is less than 0. If it is, we negate the exponent
215 (and the integer version of the exponent, which we calculated earlier to check
216 if it was an integer). We also save the number in `z`; being non-zero is a flag
217 for later and a value to be used. Then we store the reciprocal of the number in
218 itself.
220 All of the above paragraph will not make sense unless you remember the
221 relationship `l(x) == -l(1/x)`; we negated the exponent, which is equivalent to
222 the negative sign in that relationship, and we took the reciprocal of the
223 number, which is equivalent to the reciprocal in the relationship.
225 But what if the number is negative? We ignore that for now because we eventually
226 call `l(x)`, which will raise an error if `x` is negative.
228 Now, we can keep going.
230 If at this point, the exponent is negative, we need to use the original formula
231 (`e(y * l(x))`) and return that result because the result will go to zero
232 anyway.
234 But if we did *not* return, we know the exponent is *not* negative, so we can
235 get clever.
237 We then compute the integral portion of the power by computing the number to
238 power of the integral portion of the exponent.
240 Then we have the most clever trick: we add the length of that integer power (and
241 a little extra) to the `scale`. Why? Because this will ensure that the next part
242 is calculated to at least as many digits as should be in the integer *plus* any
243 extra `scale` that was wanted.
245 Then we check `z`, which, if it is not zero, is the original value of the
246 number. If it is not zero, we need to take the take the reciprocal *again*
247 because now we have the correct `scale`. And we *also* have to calculate the
248 integer portion of the power again.
250 Then we need to calculate the fractional portion of the number. We do this by
251 using the original formula, but we instead of calculating `e(y * l(x))`, we
252 calculate `e((y - a) * l(x))`, where `a` is the integer portion of `y`. It's
253 easy to see that `y - a` will be just the fractional portion of `y` (the
254 exponent), so this makes sense.
256 But then we *multiply* it into the integer portion of the power. Why? Because
257 remember: we're dealing with an exponent and a power; the relationship is
258 `x^(y+z) == (x^y)*(x^z)`.
260 So we multiply it into the integer portion of the power.
262 Finally, we set the result to the `scale`.
264 ### Rounding (`bc` Math Library 2 Only)
266 This is implemented in the function `r(x,p)`.
268 The algorithm is a simple method to check if rounding away from zero is
269 necessary, and if so, adds `1e10^p`.
271 It has a complexity of `O(n)` because of add.
273 ### Ceiling (`bc` Math Library 2 Only)
275 This is implemented in the function `ceil(x,p)`.
277 The algorithm is a simple add of one less decimal place than `p`.
279 It has a complexity of `O(n)` because of add.
281 ### Factorial (`bc` Math Library 2 Only)
283 This is implemented in the function `f(n)`.
285 The algorithm is a simple multiplication loop.
287 It has a complexity of `O(n^3)` because of linear amount of `O(n^2)`
288 multiplications.
290 ### Permutations (`bc` Math Library 2 Only)
292 This is implemented in the function `perm(n,k)`.
294 The algorithm is to use the formula `n!/(n-k)!`.
296 It has a complexity of `O(n^3)` because of the division and factorials.
298 ### Combinations (`bc` Math Library 2 Only)
300 This is implemented in the function `comb(n,r)`.
302 The algorithm is to use the formula `n!/r!*(n-r)!`.
304 It has a complexity of `O(n^3)` because of the division and factorials.
306 ### Logarithm of Any Base (`bc` Math Library 2 Only)
308 This is implemented in the function `log(x,b)`.
310 The algorithm is to use the formula `l(x)/l(b)` with double the `scale` because
311 there is no good way of knowing how many digits of precision are needed when
312 switching bases.
314 It has a complexity of `O(n^3)` because of the division and `l()`.
316 ### Logarithm of Base 2 (`bc` Math Library 2 Only)
318 This is implemented in the function `l2(x)`.
320 This is a convenience wrapper around `log(x,2)`.
322 ### Logarithm of Base 10 (`bc` Math Library 2 Only)
324 This is implemented in the function `l10(x)`.
326 This is a convenience wrapper around `log(x,10)`.
328 ### Root (`bc` Math Library 2 Only)
330 This is implemented in the function `root(x,n)`.
332 The algorithm is [Newton's method][9]. The initial guess is calculated as
333 `10^ceil(length(x)/n)`.
335 Like square root, its complexity is `O(log(n)*n^2)` as it requires one division
336 per iteration, and it doubles the amount of correct digits per iteration.
338 ### Cube Root (`bc` Math Library 2 Only)
340 This is implemented in the function `cbrt(x)`.
342 This is a convenience wrapper around `root(x,3)`.
344 ### Greatest Common Divisor (`bc` Math Library 2 Only)
346 This is implemented in the function `gcd(a,b)`.
348 The algorithm is an iterative version of the [Euclidean Algorithm][10].
350 It has a complexity of `O(n^4)` because it has a linear number of divisions.
352 This function ensures that `a` is always bigger than `b` before starting the
353 algorithm.
355 ### Least Common Multiple (`bc` Math Library 2 Only)
357 This is implemented in the function `lcm(a,b)`.
359 The algorithm uses the formula `a*b/gcd(a,b)`.
361 It has a complexity of `O(n^4)` because of `gcd()`.
363 ### Pi (`bc` Math Library 2 Only)
365 This is implemented in the function `pi(s)`.
367 The algorithm uses the formula `4*a(1)`.
369 It has a complexity of `O(n^3)` because of arctangent.
371 ### Tangent (`bc` Math Library 2 Only)
373 This is implemented in the function `t(x)`.
375 The algorithm uses the formula `s(x)/c(x)`.
377 It has a complexity of `O(n^3)` because of sine, cosine, and division.
379 ### Atan2 (`bc` Math Library 2 Only)
381 This is implemented in the function `a2(y,x)`.
383 The algorithm uses the [standard formulas][11].
385 It has a complexity of `O(n^3)` because of arctangent.
387 [1]: https://en.wikipedia.org/wiki/Karatsuba_algorithm
388 [2]: https://en.wikipedia.org/wiki/Long_division
389 [3]: https://en.wikipedia.org/wiki/Exponentiation_by_squaring
390 [4]: https://en.wikipedia.org/wiki/Newton%27s_method#Square_root_of_a_number
391 [5]: https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method
392 [6]: https://en.wikipedia.org/wiki/Unit_in_the_last_place
393 [7]: https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT
394 [8]: https://en.wikipedia.org/wiki/Modular_exponentiation#Memory-efficient_method
395 [9]: https://en.wikipedia.org/wiki/Root-finding_algorithms#Newton's_method_(and_similar_derivative-based_methods)
396 [10]: https://en.wikipedia.org/wiki/Euclidean_algorithm
397 [11]: https://en.wikipedia.org/wiki/Atan2#Definition_and_computation
398 [12]: https://github.com/gavinhoward/bc/issues/69