aleaxit / gmpy

General Multi-Precision arithmetic for Python 2.6+/3+ (GMP, MPIR, MPFR, MPC)
https://gmpy2.readthedocs.io/en/latest/
GNU Lesser General Public License v3.0
521 stars 86 forks source link

Support mixed-mode arithmetic rules for mpc & real types? #520

Open skirpichev opened 1 month ago

skirpichev commented 1 month ago

The MPC has special routines to do arithmetic with operands of different types (i.e. mpc_t and mpfr_t), but gmpy2 don't use this stuff (for example, mpc_mul_fr()).

I think we should. Such arithmetic fix some analytical identities, that are broken in gmpy2 now. Consider asinh:

>>> import gmpy2
>>> z = gmpy2.mpc(-0.0, 2)
>>> gmpy2.asinh(z)
mpc('-1.3169578969248168+1.5707963267948966j')
>>> gmpy2.log(z + gmpy2.sqrt(1 + z*z))  # wrong real part, from other side of the branch cut
mpc('1.3169578969248166+1.5707963267948966j')

Also, I would expect some performance boost.

See also https://github.com/python/cpython/pull/124829

casevh commented 1 month ago

This is a good idea. I've started work on it.

skirpichev commented 1 month ago

Maybe it's wise to wait for a fate of above CPython PR. Note that special rules for real arguments can't save all identities, e.g. for atan: https://github.com/python/cpython/pull/124829#issuecomment-2387555557

Proper solution would be using also C99 Annex G imaginary-like type. But this one will be not closed under arithmetic operations (i.e. 1j*1j->-1.0). I'm thinking on a different approach (which might work for mpc too): https://github.com/python/cpython/pull/124829#discussion_r1788881051