-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
atan function #41
Comments
PHP's In your observation, is the problem with the series not being precise or ext-decimal not calculating it very well? |
Hi, Wow!, that was a very fast reply. Thanks. I'm trying to build a PHP complex library with arbitrary precision based on this extension. I do not know yet where is the problem. The difference between using the standard function and the new one is:
Maybe I have found this paper: I will read it although I d not know if it is valid for arbitrary precision. |
Hi, more feedback. I was able to increase the precision using
It's better (7 decimals) but still worse than the standard PHP I have been trying to find more info. This page contains a lot of info about the function: I found some And also a GO implementation here: It seems they use alternative methods in order to try to avoid calculating the same coefficients and use a pre-calculated number or maybe even a different method to approximate functions using polynomials (Remez algorithm). It seems Taylor series is only good for small numbers. Some interesting links in: So, I think I have to use a different algorithm and calculate those coefficients depending on the precision you want. I think with this library: |
This paper explains al alternative way to calculate it: And some python examples: |
It seems there is another C library for arbitrary precision that supports transcendental functions: exp, log, pow, sin, cos, tan, asin, acos, atan, atan2 https://bellard.org/libbf/ @rtheunissen do you thing is it possible to link that library to this extension and add support for those transcendental functions easily? |
I have found an implementation: https://github.com/darlinghq/darling-bc/blob/master/bc/libmath.b#L176-L241 I think it could be the one used by the underlying package used by the other PHP arbitrary precision package: https://www.php.net/manual/es/book.bc.php |
I have an implementation in Fermat, which is now adding support for ext-decimal. A fast, arbitrary precision implementation of atan is not trivial. There are good ways to do it quickly, but only if you can limit precision. This is further complicated by the fact that precision is used in ext-decimal instead of scale. The continued fractions, taylor series, etc. that will calculate atan all work on scale (since they guarantee accuracy of total decimal positions, not significant positions). I am absolutely willing to help on algorithmic implementations of these however. The best option is likely @josecelano's suggestion of an existing arbitrary precision C library. In all honesty, I desperately want to merge the efforts of ext-decimal and Fermat, but I'm not sure that's possible so long as Decimal uses precision instead of scale. Fermat definitely goes beyond the scope of Decimal however, as it covers statistical functions. The ext-stats PECL extension is no longer maintained, so this is actually a large missing aspect of math within PHP, but I'm unsure of the best approach to merging the effort between that, my own library, and ext-decimal. |
For context, the implementation of arcsin()/asin() first actually makes atan very easy: <?php
$atan = asin( $x / ( 1 + sqrt(pow($x, 2)) ) ); To implement asin() as pseudo-code using Decimal objects in userland, it would look something like this: <?php
use Decimal\Decimal;
// NOTE: Precision/sigfigs are very hard to do with trig/transcendental functions
// use scale instead.
function asin(string|int|float $x, int $scale): Decimal
{
$prevAnswer = new Decimal($x, $scale);
$answer = $prevAnswer;
// This example has a hard-coded escape hatch at 15 loops, but this could be dropped
$count = 0;
$leadingZeros = new Decimal('0.'.str_pad('1', $scale, '0', STR_PAD_LEFT), $scale+2);
do {
$answer = $answer->sub(
$answer->sin()->sub($x)->div($answer->cos())
);
$diff = $answer->sub($prevAnswer)->abs();
$prevAnswer = $answer->toFixed($scale);
$increaseScale = ($diff->compareTo($leadingZeros) == 1);
$count++;
} while ($increaseScale && $count < 15);
return $answer;
} Doing the arc functions without having the normal trig functions is... kind of silly. I think this feature may be unresolveable with the way mpdec does its calculations. It likely gets a lot of its speed through its method of using precision instead of scale, but scale is almost required to do any sensible transcendental function implementations. |
Hi,
I'm trying to find a way to implement atan PHP function with arbitrary precision, but I can't find any implementation.
It seems you can use the Maclaurin Series:
But I can not get even the basic PHP
atan
function precision.Thanks.
The text was updated successfully, but these errors were encountered: