Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.7k
gh-69639: add mixed-mode rules for complex arithmetic (C-like)#124829
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
gh-69639: add mixed-mode rules for complex arithmetic (C-like)#124829
Uh oh!
There was an error while loading.Please reload this page.
Conversation
"Generally, mixed-mode arithmetic combining real and complex variables shouldbe performed directly, not by first coercing the real to complex, lest the signof zero be rendered uninformative; the same goes for combinations of pureimaginary quantities with complex variables." (c) Kahan, W: Branch cuts forcomplex elementary functions.This patch implements mixed-mode arithmetic rules, combining real andcomplex variables as specified by C standards since C99 (in particular,there is no special version for the true division with real lhsoperand). Most C compilers implementing C99+ Annex G have only thesespecial rules (without support for imaginary type, which is going to bedeprecated in C2y).
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
This comment was marked as resolved.
This comment was marked as resolved.
serhiy-storchaka left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
LGTM in general. Very LGTM! I only left a few suggestions for style.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
* more tests for multiplication* rename to _Py_convert_int_to_double* rename to real_to_float/complex* slightly optimize code
skirpichev commentedOct 2, 2024
@serhiy-storchaka, what do you think on fixing I also worry that this is a half-way solution: this neither fixesall eval(repr) round-trip issues or allows to useany analytical identity from textbook, e.g.: >>>-0.0+1j1j>>> z=complex(-0.0,2)>>>1j*(cmath.log(1-1j*z)- cmath.log(1+1j*z))/2(1.5707963267948966+0.5493061443340549j)>>> cmath.atan(z)(-1.5707963267948966+0.5493061443340549j) Proper fix seems to be only something likeskirpichev#1. Does it look complicated for you? (Note, that arithmetic methods on the complex type are mostly unchanged wrt the current pr.) |
skirpichev commentedOct 2, 2024
I also was thinking about using additional C-API helper functions like |
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
serhiy-storchaka commentedOct 2, 2024
I think that the idea of special handling of mixed complex-real arithmetic is much easier to "sell" than the idea of the imaginary number class. And it solves a half of problems. It will help to convince in necessarily to support pure imaginaries. Let's eat the elephant piece by piece.
I was surprised you did not include it. What does C99+ say about it? It looks natural and is useful in some cases, so I would implement it even if the C standard omits it.
It makes sense to me. The status of functions like Of course, the changes in arithmetic and the new C API (even if it is private) should be documented in many places. |
skirpichev commentedOct 2, 2024
Andthat is a problem.
It seems, there is no such special version in the C standard. Not sure why. And such case miss in implementations, e.g. clang: On another hand, GSL or MPC libraries implement such case.
Ok, I'll add this with naming scheme like in your pr.
New arithmetic rules documented in stdtypes.rst, C API stuff will go to Doc/c-api/complex.rst. Did I miss something else? |
serhiy-storchaka commentedOct 2, 2024
In Doc/reference/expressions.rst: "If either argument is a complex number, the other is converted to complex". There may be other leftovers. You missed a What's New entry and |
picnixz left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
One last missing modification and LGTM! Thanks for your patience Sergey!
Uh oh!
There was an error while loading.Please reload this page.
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
skirpichev commentedNov 2, 2024
@serhiy-storchaka, are you ok with current wording in docs? |
serhiy-storchaka left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
LGTM. 👍
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Co-authored-by: Sergey B Kirpichev <skirpichev@gmail.com>
…USE WEB-EDITOR...I'LL NEVER USE WEB-EDITOR...
…ythonGH-124829)"Generally, mixed-mode arithmetic combining real and complex variables shouldbe performed directly, not by first coercing the real to complex, lest the signof zero be rendered uninformative; the same goes for combinations of pureimaginary quantities with complex variables." (c) Kahan, W: Branch cuts forcomplex elementary functions.This patch implements mixed-mode arithmetic rules, combining real andcomplex variables as specified by C standards since C99 (in particular,there is no special version for the true division with real lhsoperand). Most C compilers implementing C99+ Annex G have only thesespecial rules (without support for imaginary type, which is going to bedeprecated in C2y).
f0d3f10 intopython:mainUh oh!
There was an error while loading.Please reload this page.
skirpichev commentedNov 27, 2024
Thanks to all reviewers, especially Serhiy! What's next,@serhiy-storchaka? This pr, as per description, address#69639 only partially. It's still easy to smash sign of zero or make some component to be nan, e.g.: >>>-0.0+1j1j>>>float('inf')*1j(nan+infj)>>> z=complex(-0.0,2)>>>import cmath>>> cmath.atan(z)(-1.5707963267948966+0.5493061443340549j)>>>1j*(cmath.log(1-1j*z)- cmath.log(1+1j*z))/2(1.5707963267948966+0.5493061443340549j) and we still have funny integer zeros in repr: >>>complex(-0.0,1)(-0+1j) Probably, it doesn't make sense to change repr alone. And I think that theprevious discussion showed - this set of problems can be solved only with new imaginary type. Should I prepare a PEP draft, would you like to sponsor (or be PEP co-author) such idea? Or it's better to introduce this first on the d.p.o/ideas? PS: |
…ythonGH-124829)"Generally, mixed-mode arithmetic combining real and complex variables shouldbe performed directly, not by first coercing the real to complex, lest the signof zero be rendered uninformative; the same goes for combinations of pureimaginary quantities with complex variables." (c) Kahan, W: Branch cuts forcomplex elementary functions.This patch implements mixed-mode arithmetic rules, combining real andcomplex variables as specified by C standards since C99 (in particular,there is no special version for the true division with real lhsoperand). Most C compilers implementing C99+ Annex G have only thesespecial rules (without support for imaginary type, which is going to bedeprecated in C2y).
…ythonGH-124829)"Generally, mixed-mode arithmetic combining real and complex variables shouldbe performed directly, not by first coercing the real to complex, lest the signof zero be rendered uninformative; the same goes for combinations of pureimaginary quantities with complex variables." (c) Kahan, W: Branch cuts forcomplex elementary functions.This patch implements mixed-mode arithmetic rules, combining real andcomplex variables as specified by C standards since C99 (in particular,there is no special version for the true division with real lhsoperand). Most C compilers implementing C99+ Annex G have only thesespecial rules (without support for imaginary type, which is going to bedeprecated in C2y).
…ythonGH-124829)"Generally, mixed-mode arithmetic combining real and complex variables shouldbe performed directly, not by first coercing the real to complex, lest the signof zero be rendered uninformative; the same goes for combinations of pureimaginary quantities with complex variables." (c) Kahan, W: Branch cuts forcomplex elementary functions.This patch implements mixed-mode arithmetic rules, combining real andcomplex variables as specified by C standards since C99 (in particular,there is no special version for the true division with real lhsoperand). Most C compilers implementing C99+ Annex G have only thesespecial rules (without support for imaginary type, which is going to bedeprecated in C2y).
…ythonGH-124829)"Generally, mixed-mode arithmetic combining real and complex variables shouldbe performed directly, not by first coercing the real to complex, lest the signof zero be rendered uninformative; the same goes for combinations of pureimaginary quantities with complex variables." (c) Kahan, W: Branch cuts forcomplex elementary functions.This patch implements mixed-mode arithmetic rules, combining real andcomplex variables as specified by C standards since C99 (in particular,there is no special version for the true division with real lhsoperand). Most C compilers implementing C99+ Annex G have only thesespecial rules (without support for imaginary type, which is going to bedeprecated in C2y).
vstinner commentedJan 13, 2025
This change adds 6 private functions and documents them:
I would prefer to move these functions to the internal C API, or to make them public. I dislike adding private functions (functions with a name prefixed by |
skirpichev commentedJan 14, 2025
@vstinner, these functions follows existing convention for
I don't think it's a good idea. These functions are extensively used in the cmath module and outside of the CPython it happens too.
This does make sense for me. We could just drop |
vstinner commentedJan 14, 2025
Previous discussions about |
vstinner commentedJan 14, 2025
I would prefer to rename Note:
If you agree with the idea of adding a public C API, you can open a new issue in this project (cpython) first. |
skirpichev commentedJan 14, 2025
FYI:#128813 |
…ythonGH-124829)"Generally, mixed-mode arithmetic combining real and complex variables shouldbe performed directly, not by first coercing the real to complex, lest the signof zero be rendered uninformative; the same goes for combinations of pureimaginary quantities with complex variables." (c) Kahan, W: Branch cuts forcomplex elementary functions.This patch implements mixed-mode arithmetic rules, combining real andcomplex variables as specified by C standards since C99 (in particular,there is no special version for the true division with real lhsoperand). Most C compilers implementing C99+ Annex G have only thesespecial rules (without support for imaginary type, which is going to bedeprecated in C2y).
…ythonGH-124829)"Generally, mixed-mode arithmetic combining real and complex variables shouldbe performed directly, not by first coercing the real to complex, lest the signof zero be rendered uninformative; the same goes for combinations of pureimaginary quantities with complex variables." (c) Kahan, W: Branch cuts forcomplex elementary functions.This patch implements mixed-mode arithmetic rules, combining real andcomplex variables as specified by C standards since C99 (in particular,there is no special version for the true division with real lhsoperand). Most C compilers implementing C99+ Annex G have only thesespecial rules (without support for imaginary type, which is going to bedeprecated in C2y).
Uh oh!
There was an error while loading.Please reload this page.
"Generally, mixed-mode arithmetic combining real and complex variables should be performed directly, not by first coercing the real to complex, lest the sign of zero be rendered uninformative; the same goes for combinations of pure imaginary quantities with complex variables." (c) Kahan, W: Branch cuts for complex elementary functions.
This patch implements mixed-mode arithmetic rules, combining real and complex variables as specified by C standards since C99. Most C compilers implementing C99+ Annex G have only these special rules (without support for imaginary type, which is going to be deprecated in C2y).
New rules allow to use complex arithmetic for implementation of mathematical functions without "corner cases" for special numbers (like signed zero or infinities). Well, at least it works now for more cases;)
Examples:
That doesn't work (requires support for imaginary type):
Notes for reviewers
Maybe it worth add missing (as noted in the commit message) case for the true division (i.e.x/(u + vj)==(x*u + (-x*v)j)/(u**2 + v**2)).repr(complex(-0.0, 1)), which currently prints funny negative integer zero; seethis commit. Probably this doesn't make sense alone../python -m timeit -s 'c=1+1j;d=1.2' 'c*d') I got a measurable performance boost for mixed arithmetic (~10-12%, except for_Py_dc_quot()case) and a performance degradation for complex arithmetic (~4-5%).📚 Documentation preview 📚:https://cpython-previews--124829.org.readthedocs.build/