8000 log compute - taylor series by hnb22 · Pull Request #957 · mpmath/mpmath · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

log compute - taylor series #957

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

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions mpmath/libmp/libelefun.py
Original file line number Diff line number Diff line change
Expand Up @@ -694,9 +694,21 @@ def mpf_log(x, prec, rnd=round_fast):
return mpf_perturb(t, tsign, prec, rnd)
else:
wp += cancellation
# TODO: if close enough to 1, we could use Taylor series
# even in the AGM precision range, since the Taylor series
# converges rapidly

# if close enough to 1, use Taylor series
# since Taylor series converges rapidly
Comment on lines +698 to +699
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You removed AGM mention. Why? Are you know what's it about?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it's used for high precision due to its convergence properties which contrasts with taylor series depending on x.

Don't know how it would be applied to current code.

if tsign:
tfixed = (MPZ_ONE << wp) - to_fixed(x,wp)
else:
tfixed = to_fixed(x, wp) - (MPZ_ONE << wp)
threshold = (1 << wp) // 1000
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why such value?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure here, looking for feedback.

if (tfixed <= threshold):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (tfixed <= threshold):
if tfixed <= threshold:

s = log_taylor(to_fixed(x, wp), wp)
sb = s.bit_length()
rman = s << (sb)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's happens here, for example? Why mantissa corrected this way?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Constructing the mantissa from the fixed point need to be normalize it with MSB. Which is used using bit length and shifted left by this amount to get no leading zeros. Also, then constructing the exponent to input into creating a mpf. rman is constructed using sb, and to get floating point representation, we also need the working precision wp, and by exponent laws of base 2 its wp+sb.

Still learning, this is new :)

rexp = -(sb+wp)
return from_man_exp(rman, rexp, prec, rnd)

#------------------------------------------------------------------
# Another special case:
# n*log(2) is a good enough approximation
Expand Down
4 changes: 4 additions & 0 deletions mpmath/tests/test_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@ def test_log():
assert (log(-1j-1e-8).real*10**16).ae(0.5)
assert (log(1+1e-40j).real*10**80).ae(0.5)
assert (log(1j+1e-40).real*10**80).ae(0.5)
# Taylor series
assert (log(0.99999)).ae(-1.0000050000287824e-5)
assert (log(1.00001)).ae(9.9999500003988414e-6)
Comment on lines +212 to +214
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see changes.

Did you realize what's doing your code?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With default precision of 53, I tested locally for log(0.99999) and log(1.00001) and it ran through to do taylor series compute. The code checks for tfixed (distance from 1) and compares to a threshold scaled to a wp that is 0.001 in floating point?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With default precision of 53, I tested locally for log(0.99999) and log(1.00001) and it ran through to do taylor series compute.

Great, you have found values, that trigger you code path.

But results are same wrt the master (or not?). Could you argue why we need this?

The code checks for tfixed (distance from 1) and compares to a threshold scaled to a wp that is 0.001 in floating point?

Did you ask me?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Taylor series
assert (log(0.99999)).ae(-1.0000050000287824e-5)
assert (log(1.00001)).ae(9.9999500003988414e-6)
# Taylor series
assert log(0.99999).ae(-1.0000050000287824e-5)
assert log(1.00001).ae(9.9999500003988414e-6)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may not need it I guess. We wouldn't need to compute as many taylor series terms as the general case of code provided later.

Depending on the threshold, I wasn't sure what was close to 1 enough. I was looking for feedback.


# Huge
assert log(ldexp(1.234,10**20)).ae(log(2)*1e20)
assert log(ldexp(1.234,10**200)).ae(log(2)*1e200)
Expand Down
0