Implement BigMath.erf(x, prec) and BigMath.erfc(x, prec) #357
+186
−0
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Followup of #336
Calculates erf and erfc in Taylor series or in asymptotic expansion.
Taylor series for small x and Asymptotic expansion for large x
Asymptotic expansion is generally faster, but has some restriction.
So first try asymptotic expansion and then fallback to Taylor series.
Asymptotic expansion
See https://en.wikipedia.org/wiki/Error_function#Asymptotic_expansion
For example: Asymptotic expansion can calculate
erfc(10)in maximum 42 digits.erfc_with_asymptotic_expansion(10) = 0.208848758376254475700078629495778861156082e-44BigMath.erf(10, 50)can be calculated as1 - BigMath.send(:_erfc_asymptotic, BigDecimal(10), 50 - 44)On the other hand, calculating
BigMath.erf(10, 100)as1 - BigMath.send(:_erfc_asymptotic, BigDecimal(10), 100 - 44)fails because maximum digits forerfc(10)is 42 but this calculation requires more digits.In this case, we need to fallbacks to Taylor series.
Example benchmark:
Taylor series
Use Taylor series of
exp(x**2)*erf(x).Precision management is easier than normal Taylor series of
erf(x).Faster calculation
Calculating Taylor series of
erf(large_x)is slow.It can be calculated faster by two steps of Taylor series calculation.
Example benchmark: