Skip to content

Commit adf9794

Browse files
authored
Merge pull request numpy#24362 from lysnikolaou/complex-types-docs
DOC: Add release notes for complex types changes in 2.x
2 parents a2bfa54 + 5d8fead commit adf9794

File tree

2 files changed

+109
-5
lines changed

2 files changed

+109
-5
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
Complex types - Underlying type changes
2+
---------------------------------------
3+
4+
* The underlying C types for all of numpy's complex types have been changed to
5+
use C99 complex types.
6+
7+
* While this change does not affect the memory layout of complex types, it
8+
changes the API to be used, in order to directly retrieve or write the real or
9+
complex part of the complex number, since direct field access (as in ``c.real``
10+
or ``c.imag``) is no longer an option. You can now use utilities provided in
11+
``numpy/npy_math.h`` to do these operations, like this:
12+
13+
.. code-block:: c
14+
15+
npy_cdouble c;
16+
npy_csetreal(&c, 1.0);
17+
npy_csetimag(&c, 0.0);
18+
printf("%d + %di\n", npy_creal(c), npy_cimag(c));
19+
20+
* To ease cross-version compatibility, equivalent macros and a compatibility
21+
layer have been added which can be used by downstream packages to continue
22+
to support both NumPy 1.x and 2.x. See :ref:`complex-numbers` for more info.
23+
24+
* ``numpy/npy_common.h`` now includes ``complex.h``, which means that ``complex``
25+
is now a reserved keyword.

doc/source/reference/c-api/coremath.rst

Lines changed: 84 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -213,13 +213,33 @@ Those can be useful for precise floating point comparison.
213213
214214
.. versionadded:: 1.15.0
215215
216-
Complex functions
217-
~~~~~~~~~~~~~~~~~
216+
.. _complex-numbers:
217+
218+
Support for complex numbers
219+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
218220
219221
C99-like complex functions have been added. Those can be used if you wish to
220-
implement portable C extensions. Since we still support platforms without C99
221-
complex type (most importantly Windows, where MSVC doesn't support C99 complex
222-
types as of Nov 2022), you need to restrict to C90-compatible syntax, e.g.:
222+
implement portable C extensions. Since NumPy 2.0 we use C99 complex types as
223+
the underlying type:
224+
225+
.. code-block:: c
226+
227+
typedef double _Complex npy_cdouble;
228+
typedef float _Complex npy_cfloat;
229+
typedef long double _Complex npy_clongdouble;
230+
231+
MSVC does not support the ``_Complex`` type itself, but has added support for
232+
the C99 ``complex.h`` header by providing its own implementation. Thus, under
233+
MSVC, the equivalent MSVC types will be used:
234+
235+
.. code-block:: c
236+
237+
typedef _Dcomplex npy_cdouble;
238+
typedef _Fcomplex npy_cfloat;
239+
typedef _Lcomplex npy_clongdouble;
240+
241+
Because MSVC still does not support C99 syntax for initializing a complex
242+
number, you need to restrict to C90-compatible syntax, e.g.:
223243

224244
.. code-block:: c
225245
@@ -229,6 +249,65 @@ types as of Nov 2022), you need to restrict to C90-compatible syntax, e.g.:
229249
230250
b = npy_log(a);
231251
252+
A few utilities have also been added in
253+
``numpy/npy_math.h``, in order to retrieve or set the real or the imaginary
254+
part of a complex number:
255+
256+
.. code-block:: c
257+
258+
npy_cdouble c;
259+
npy_csetreal(&c, 1.0);
260+
npy_csetimag(&c, 0.0);
261+
printf("%d + %di\n", npy_creal(c), npy_cimag(c));
262+
263+
.. versionchanged:: 2.0.0
264+
265+
The underlying C types for all of numpy's complex types have been changed to
266+
use C99 complex types. Up until now the following was being used to represent
267+
complex types:
268+
269+
.. code-block:: c
270+
271+
typedef struct { double real, imag; } npy_cdouble;
272+
typedef struct { float real, imag; } npy_cfloat;
273+
typedef struct {npy_longdouble real, imag;} npy_clongdouble;
274+
275+
Using the ``struct`` representation ensured that complex numbers could be used
276+
on all platforms, even the ones without support for built-in complex types. It
277+
also meant that a static library had to be shipped together with NumPy to
278+
provide a C99 compatibility layer for downstream packages to use. In recent
279+
years however, support for native complex types has been improved immensely,
280+
with MSVC adding built-in support for the ``complex.h`` header in 2019.
281+
282+
To ease cross-version compatibility, macros that use the new set APIs have
283+
been added.
284+
285+
.. code-block:: c
286+
287+
#define NPY_CSETREAL(z, r) npy_csetreal(z, r)
288+
#define NPY_CSETIMAG(z, i) npy_csetimag(z, i)
289+
290+
A compatibility layer is also provided in ``numpy/npy_2_complexcompat.h``. It
291+
checks whether the macros exist, and falls back to the 1.x syntax in case they
292+
don't.
293+
294+
.. code-block:: c
295+
296+
#include <numpy/npy_math.h>
297+
298+
#ifndef NPY_CSETREALF
299+
#define NPY_CSETREALF(c, r) (c)->real = (r)
300+
#endif
301+
#ifndef NPY_CSETIMAGF
302+
#define NPY_CSETIMAGF(c, i) (c)->imag = (i)
303+
#endif
304+
305+
We suggest all downstream packages that need this functionality to copy-paste
306+
the compatibility layer code into their own sources and use that, so that
307+
they can continue to support both NumPy 1.x and 2.x without issues. Note also
308+
that the ``complex.h`` header is included in ``numpy/npy_common.h``, which
309+
makes ``complex`` a reserved keyword.
310+
232311
.. _linking-npymath:
233312

234313
Linking against the core math library in an extension

0 commit comments

Comments
 (0)