@@ -38,61 +38,56 @@ Python) in such system is a complex number with zero real component.
3838
3939Unfortunately, this doesn't work well, if components of the complex number are
4040floating-point numbers, used as model of the *extended * real line. Such as
41- ones, specified by the IEC 60559 standard, which beyond normal
42- (finite and nonzero) numbers has special values like signed zero, infinities
43- and nans. Lets take simple examples with multiplication (where
44- :math: ` \rightarrow ` denotes type coersion and :math: ` \Rightarrow ` is
45- substitution of :math: ` 0.0 +i` for :math: `i `):
41+ ones, specified by the IEC 60559 standard, which beyond normal (finite and
42+ nonzero) numbers has special values like signed zero, infinities and nans.
43+ Lets take simple examples with multiplication in Python-like pseudocode (where
44+ `` ~> `` denotes type coersion and `` ~= `` is substitution of `` complex(0, y) ``
45+ for `` yj ` `):
4646
47- .. math ::
48- :label: ex-mul1
47+ .. code :: python
48+
49+ 2.0 * (inf+ 3j ) ~ > complex (2 , 0 ) * complex (inf, 3 )
50+ == complex (2.0 * inf - 0.0 * 3.0 , 2.0 * 3.0 + 0.0 * inf)
51+ == complex (inf, nan)
4952
50- 2.0 \times (\infty + 3.0 i) & \rightarrow (2.0 + 0.0 i) \times (\infty + 3.0 i) \\
51- & = (2.0 \times\infty - 0.0 \times 3.0 ) + i(0.0 \times\infty + 2.0 \times 3.0 ) \\
52- & = \infty + i\mathrm {nan}
53+ .. code :: python
5354
54- .. math ::
55- :label: ex-mul2
55+ 2j * (inf+ 3j ) ~= complex (0 , 2 ) * complex (inf, 3 )
56+ == complex (0.0 * inf - 2.0 * 3.0 , 2.0 * inf + 0.0 * 3.0 )
57+ == complex (nan, inf)
5658
57- 2.0 i \times (\infty + 3.0 i) & \Rightarrow (0.0 + 2.0 i) \times (\infty + 3.0 i) \\
58- & = (0.0 \times\infty - 2.0 \times 3.0 ) + i (0.0 \times 3.0 + 2.0 \times\infty ) \\
59- & = \mathrm {nan} + i\infty
59+ .. code :: python
6060
61- .. math ::
62- :label: ex-mul3
61+ 2j * complex (- 0.0 , 3 ) ~= complex (0 , 2 ) * complex (- 0.0 , 3 )
62+ == complex (- 0.0 * 0.0 - 2.0 * 3.0 , - 2.0 * 0.0 + 0.0 * 3.0 )
63+ == complex (- 6.0 , 0.0 )
6364
64- 2.0 i \times (-0.0 + 3.0 i) & \Rightarrow (0.0 + 2.0 i) \times (-0.0 + 3.0 i) \\
65- & = (-0.0 \times 0.0 - 2.0 \times 3.0 ) + i (-2.0 \times 0.0 + 0.0 \times 3.0 ) \\
66- & = -6.0 + i 0.0
6765
6866 Users with some mathematical background instead would expect, that ``x+yj ``
69- notation in the Python is just usual rectangular form for a complex number
70- with components ``x `` (real) and ``y `` (imaginary) and that above examples
71- will work, following rules of elementary algebra (with assumption that
72- :math: `i` is a symbol such that :math: `i^ 2 =- 1 `):
67+ notation in the Python is equal to `` complex(x, y) `` and is just the usual
68+ rectangular form for a complex number with components ``x `` (real) and ``y ``
69+ (imaginary) and that above examples will work, following rules of elementary
70+ algebra (with assumption that `` 1j**2 `` is `` -1 ` `):
7371
74- .. math ::
72+ .. code :: python
7573
76- 2.0 \times ( \infty + 3.0 i) & = 2.0 \times\infty + i 2.0 \times 3.0 = \infty + i 6.0 \\
77- 2.0 i \times ( \infty + 3.0 i) & = -2.0 \times 3.0 + i 2.0 \times\infty = - 6.0 + i \infty \\
78- 2.0 i \times (-0.0 + 3.0 i) & = -2.0 \times 3.0 - i 2.0 \times 0.0 = - 6.0 - i 0.0 \\
74+ 2.0 * (inf + 3 j ) == complex ( 2.0 * inf, 2.0 * 3.0 ) == complex (inf, 6 )
75+ 2 j * (inf + 3 j ) == complex ( - 2.0 * 3.0 , 2.0 * inf) == complex ( - 6 , inf)
76+ 2 j * complex (- 0.0 , 3 ) == complex ( - 2.0 * 3.0 , - 2.0 * 0.0 ) == complex ( - 6 , - 0.0 )
7977
8078
8179 Same affects addition (or subtraction):
8280
83- .. math ::
84- :label: ex-add1
81+ .. code :: python
82+
83+ 2.0 - 0j ~= 2.0 - complex (0 , 0 ) ~ > complex (2.0 , 0 ) - complex (0 , 0 )
84+ == complex (2.0 - 0.0 , 0.0 - 0.0 ) == complex (2 , 0 )
8585
86- 2.0 - 0.0 i & \rightarrow (2.0 + 0.0 i) - 0.0 i \\
87- & \Rightarrow (2.0 + 0.0 i) - (0.0 + 0.0 i) \\
88- & = 2.0 + 0.0 i
86+ .. code :: python
8987
90- .. math ::
91- :label: ex-add 2
88+ - 0.0 + 2 j ~= - 0.0 + complex ( 0 , 2 ) ~ > complex ( - 0.0 , 0 ) + complex ( 0 , 2 )
89+ == complex ( - 0.0 + 0.0 , 0.0 + 2.0 ) == complex ( 0 , 2 )
9290
93- -0.0 + 2.0 i & \rightarrow (-0.0 + 0.0 i) + 2.0 i \\
94- & \Rightarrow (-0.0 + 0.0 i) + (0.0 + 2.0 i) \\
95- & = 0.0 + 2.0 i
9691
9792 Simplistic approach for complex arithmetic is underlying reason for numerous
9893and reccuring issues in the CPython bugtracker (here is an incomplete list:
@@ -136,10 +131,10 @@ it's less useful to end users.
136131
137132A more modern approach [2 ]_, reflecting advances in the IEC standard for real
138133floating-point arithmetic, instead avoid coersion of reals to complexes
139- (:math: ` \rightarrow ` ) and use a separate data type (imaginary) to represent
140- the imaginary unit, *ignoring it's real component in arithmetic * (i.e. no
141- implicit cast ( :math: ` \Rightarrow ` ) to a complex number with zero real part).
142- The `` cmath.asin() `` would be implemented with this approach simply by:
134+ (`` ~> `` ) and use a separate data type (imaginary) to represent the imaginary
135+ unit, *ignoring it's real component in arithmetic * (i.e. no implicit cast
136+ (`` ~= `` ) to a complex number with zero real part). The `` cmath.asin() `` would
137+ be implemented with this approach simply by:
143138
144139.. code :: python
145140
@@ -158,8 +153,8 @@ Though it's more important, that in the IEC floating-point arithmetic results
158153here are uniquely determined by usual mathematical formulae.
159154
160155For a first step, :cpython-pr: `124829 ` added in the CPython 3.14 mixed-mode
161- rules for complex arithmetic, combining real and complex operands. So,
162- examples like :eq: ` ex-mul1 ` or :eq: ` ex-add1 ` now are working correctly:
156+ rules for complex arithmetic, combining real and complex operands. So, some
157+ examples from above now are working correctly:
163158
164159.. code :: pycon
165160
@@ -170,8 +165,8 @@ examples like :eq:`ex-mul1` or :eq:`ex-add1` now are working correctly:
170165 (2-0j)
171166
172167
173- Unfortunately, this is only a half-way solution. To fix the rest of above
174- examples we need a separate type for pure-imaginary complex numbers.
168+ Unfortunately, this is only a half-way solution. To fix the rest of examples
169+ we need a separate type for pure-imaginary complex numbers.
175170
176171
177172Rationale
0 commit comments