{
  "__type": "IngestedDoc",
  "__tag": 4010,
  "_content": {},
  "_ordered_sections": [],
  "item_file": null,
  "item_line": null,
  "item_type": null,
  "aliases": [],
  "example_section_data": {
    "__type": "Section",
    "__tag": 4015,
    "children": [],
    "title": [],
    "level": 0,
    "target": null
  },
  "see_also": [],
  "signature": null,
  "references": null,
  "qa": "reference:c-api:coremath",
  "arbitrary": [
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "This library contains most math-related C99 functionality, which can be used on platforms where C99 is not well supported. The core math functions have the same API as the C99 ones, except for the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "npy_*"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " prefix."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "The available functions are defined in "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "<numpy/npy_math.h>"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " - please refer to this header when in doubt."
            }
          ]
        },
        {
          "__type": "Admonition",
          "__tag": 4056,
          "kind": "note",
          "base_type": "note",
          "children": [
            {
              "__type": "AdmonitionTitle",
              "__tag": 4055,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "note "
                }
              ]
            },
            {
              "__type": "Paragraph",
              "__tag": 4045,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "An effort is underway to make "
                },
                {
                  "__type": "InlineCode",
                  "__tag": 4051,
                  "value": "npymath"
                },
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": " smaller (since C99 compatibility of compilers has improved over time) and more easily vendorable or usable as a header-only dependency. That will avoid problems with shipping a static library built with a compiler which may not match the compiler used by a downstream package or end user. See "
                },
                {
                  "__type": "Link",
                  "__tag": 4049,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "gh-20880"
                    }
                  ],
                  "url": "https://github.com/numpy/numpy/issues/20880",
                  "title": ""
                },
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": " for details."
                }
              ]
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "NumPy core math library"
        }
      ],
      "level": 0,
      "target": null
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Floating point classification"
        }
      ],
      "level": 1,
      "target": null
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "The following math constants are available in "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "npy_math.h"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ". Single and extended precision are also available by adding the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "f"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " and "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "l"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " suffixes respectively."
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Useful math constants"
        }
      ],
      "level": 1,
      "target": null
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Those can be useful for precise floating point comparison."
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Low-level floating point manipulation"
        }
      ],
      "level": 1,
      "target": null
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "C99-like complex functions have been added. Those can be used if you wish to implement portable C extensions. Since NumPy 2.0 we use C99 complex types as the underlying type:"
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": "typedef double _Complex npy_cdouble;\ntypedef float _Complex npy_cfloat;\ntypedef long double _Complex npy_clongdouble;",
          "execution_status": null
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "MSVC does not support the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "_Complex"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " type itself, but has added support for the C99 "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "complex.h"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " header by providing its own implementation. Thus, under MSVC, the equivalent MSVC types will be used:"
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": "typedef _Dcomplex npy_cdouble;\ntypedef _Fcomplex npy_cfloat;\ntypedef _Lcomplex npy_clongdouble;",
          "execution_status": null
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Because MSVC still does not support C99 syntax for initializing a complex number, you need to restrict to C90-compatible syntax, e.g.:"
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": "/* a = 1 + 2i \\*/\nnpy_complex a = npy_cpack(1, 2);\nnpy_complex b;\n\nb = npy_log(a);",
          "execution_status": null
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "A few utilities have also been added in "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "numpy/npy_math.h"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", in order to retrieve or set the real or the imaginary part of a complex number:"
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": "npy_cdouble c;\nnpy_csetreal(&c, 1.0);\nnpy_csetimag(&c, 0.0);\nprintf(\"%d + %di\\n\", npy_creal(c), npy_cimag(c));",
          "execution_status": null
        },
        {
          "__type": "Admonition",
          "__tag": 4056,
          "kind": "versionchanged",
          "base_type": "neutral",
          "children": [
            {
              "__type": "AdmonitionTitle",
              "__tag": 4055,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "versionchanged 2.0.0"
                }
              ]
            },
            {
              "__type": "Paragraph",
              "__tag": 4045,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "The underlying C types for all of numpy's complex types have been changed to use C99 complex types. Up until now the following was being used to represent complex types:"
                }
              ]
            },
            {
              "__type": "Code",
              "__tag": 4050,
              "value": "typedef struct { double real, imag; } npy_cdouble;\ntypedef struct { float real, imag; } npy_cfloat;\ntypedef struct {npy_longdouble real, imag;} npy_clongdouble;",
              "execution_status": null
            },
            {
              "__type": "Paragraph",
              "__tag": 4045,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "Using the "
                },
                {
                  "__type": "InlineCode",
                  "__tag": 4051,
                  "value": "struct"
                },
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": " representation ensured that complex numbers could be used on all platforms, even the ones without support for built-in complex types. It also meant that a static library had to be shipped together with NumPy to provide a C99 compatibility layer for downstream packages to use. In recent years however, support for native complex types has been improved immensely, with MSVC adding built-in support for the "
                },
                {
                  "__type": "InlineCode",
                  "__tag": 4051,
                  "value": "complex.h"
                },
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": " header in 2019."
                }
              ]
            },
            {
              "__type": "Paragraph",
              "__tag": 4045,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "To ease cross-version compatibility, macros that use the new set APIs have been added."
                }
              ]
            },
            {
              "__type": "Code",
              "__tag": 4050,
              "value": "#define NPY_CSETREAL(z, r) npy_csetreal(z, r)\n#define NPY_CSETIMAG(z, i) npy_csetimag(z, i)",
              "execution_status": null
            },
            {
              "__type": "Paragraph",
              "__tag": 4045,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "A compatibility layer is also provided in "
                },
                {
                  "__type": "InlineCode",
                  "__tag": 4051,
                  "value": "numpy/npy_2_complexcompat.h"
                },
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": ". It checks whether the macros exist, and falls back to the 1.x syntax in case they don't."
                }
              ]
            },
            {
              "__type": "Code",
              "__tag": 4050,
              "value": "#include <numpy/npy_math.h>\n\n#ifndef NPY_CSETREALF\n#define NPY_CSETREALF(c, r) (c)->real = (r)\n#endif\n#ifndef NPY_CSETIMAGF\n#define NPY_CSETIMAGF(c, i) (c)->imag = (i)\n#endif",
              "execution_status": null
            },
            {
              "__type": "Paragraph",
              "__tag": 4045,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "We suggest all downstream packages that need this functionality to copy-paste the compatibility layer code into their own sources and use that, so that they can continue to support both NumPy 1.x and 2.x without issues. Note also that the "
                },
                {
                  "__type": "InlineCode",
                  "__tag": 4051,
                  "value": "complex.h"
                },
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": " header is included in "
                },
                {
                  "__type": "InlineCode",
                  "__tag": 4051,
                  "value": "numpy/npy_common.h"
                },
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": ", which makes "
                },
                {
                  "__type": "InlineCode",
                  "__tag": 4051,
                  "value": "complex"
                },
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": " a reserved keyword."
                }
              ]
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Support for complex numbers"
        }
      ],
      "level": 1,
      "target": "complex-numbers"
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "To use the core math library that NumPy ships as a static library in your own Python extension, you need to add the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "npymath"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " compile and link options to your extension. The exact steps to take will depend on the build system you are using. The generic steps to take are:"
            }
          ]
        },
        {
          "__type": "BulletList",
          "__tag": 4053,
          "ordered": true,
          "start": 1,
          "children": [
            {
              "__type": "ListItem",
              "__tag": 4054,
              "children": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "Add the numpy include directory (= the value of "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "np.get_include()"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": ") to    your include directories,"
                    }
                  ]
                }
              ]
            },
            {
              "__type": "ListItem",
              "__tag": 4054,
              "children": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "The "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "npymath"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": " static library resides in the "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "lib"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": " directory right next    to numpy's include directory (i.e., "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "pathlib.Path(np.get_include()) / '..'    / 'lib'"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "). Add that to your library search directories,"
                    }
                  ]
                }
              ]
            },
            {
              "__type": "ListItem",
              "__tag": 4054,
              "children": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "Link with "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "libnpymath"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": " and "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "libm"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "."
                    }
                  ]
                }
              ]
            }
          ]
        },
        {
          "__type": "Admonition",
          "__tag": 4056,
          "kind": "note",
          "base_type": "note",
          "children": [
            {
              "__type": "AdmonitionTitle",
              "__tag": 4055,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "note "
                }
              ]
            },
            {
              "__type": "Paragraph",
              "__tag": 4045,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "Keep in mind that when you are cross compiling, you must use the "
                },
                {
                  "__type": "InlineCode",
                  "__tag": 4051,
                  "value": "numpy"
                },
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": " for the platform you are building for, not the native one for the build machine. Otherwise you pick up a static library built for the wrong architecture."
                }
              ]
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "When you build with "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "numpy.distutils"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " (deprecated), then use this in your "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "setup.py"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ":"
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> from numpy.distutils.misc_util import get_info\n>>> info = get_info('npymath')\n>>> _ = config.add_extension('foo', sources=['foo.c'], extra_info=info)",
              "execution_status": null
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "In other words, the usage of "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "info"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " is exactly the same as when using "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "blas_info"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " and co."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "When you are building with "
            },
            {
              "__type": "Link",
              "__tag": 4049,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "Meson"
                }
              ],
              "url": "https://mesonbuild.com",
              "title": ""
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", use      "
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": "# Note that this will get easier in the future, when Meson has\n# support for numpy built in; most of this can then be replaced\n# by `dependency('numpy')`.\nincdir_numpy = run_command(py3,\n  [\n    '-c',\n    'import os; os.chdir(\"..\"); import numpy; print(numpy.get_include())'\n  ],\n  check: true\n).stdout().strip()\n\ninc_np = include_directories(incdir_numpy)\n\ncc = meson.get_compiler('c')\nnpymath_path = incdir_numpy / '..' / 'lib'\nnpymath_lib = cc.find_library('npymath', dirs: npymath_path)\n\npy3.extension_module('module_name',\n  ...\n  include_directories: inc_np,\n  dependencies: [npymath_lib],",
          "execution_status": null
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Linking against the core math library in an extension"
        }
      ],
      "level": 1,
      "target": "linking-npymath"
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "The header file "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "<numpy/halffloat.h>"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " provides functions to work with IEEE 754-2008 16-bit floating point values. While this format is not typically used for numerical computations, it is useful for storing values which require floating point but do not need much precision. It can also be used as an educational tool to understand the nature of floating point round-off error."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Like for other types, NumPy includes a typedef npy_half for the 16 bit float.  Unlike for most of the other types, you cannot use this as a normal type in C, since it is a typedef for npy_uint16.  For example, 1.0 looks like 0x3c00 to C, and if you do an equality comparison between the different signed zeros, you will get -0.0 != 0.0 (0x8000 != 0x0000), which is incorrect."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "For these reasons, NumPy provides an API to work with npy_half values accessible by including "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "<numpy/halffloat.h>"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " and linking to "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "npymath"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ". For functions that are not provided directly, such as the arithmetic operations, the preferred method is to convert to float or double and back again, as in the following example."
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": "npy_half sum(int n, npy_half *array) {\n    float ret = 0;\n    while(n--) {\n        ret += npy_half_to_float(*array++);\n    }\n    return npy_float_to_half(ret);\n}",
          "execution_status": null
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "External Links:"
            }
          ]
        },
        {
          "__type": "BulletList",
          "__tag": 4053,
          "ordered": false,
          "start": 1,
          "children": [
            {
              "__type": "ListItem",
              "__tag": 4054,
              "children": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "InlineRole",
                      "__tag": 4003,
                      "value": "754-2008 IEEE Standard for Floating-Point Arithmetic",
                      "domain": null,
                      "role": null,
                      "inventory": null
                    }
                  ]
                }
              ]
            },
            {
              "__type": "ListItem",
              "__tag": 4054,
              "children": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "InlineRole",
                      "__tag": 4003,
                      "value": "Half-precision Float Wikipedia Article",
                      "domain": null,
                      "role": null,
                      "inventory": null
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "."
                    }
                  ]
                }
              ]
            },
            {
              "__type": "ListItem",
              "__tag": 4054,
              "children": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "InlineRole",
                      "__tag": 4003,
                      "value": "OpenGL Half Float Pixel Support",
                      "domain": null,
                      "role": null,
                      "inventory": null
                    }
                  ]
                }
              ]
            },
            {
              "__type": "ListItem",
              "__tag": 4054,
              "children": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "InlineRole",
                      "__tag": 4003,
                      "value": "The OpenEXR image format",
                      "domain": null,
                      "role": null,
                      "inventory": null
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "."
                    }
                  ]
                }
              ]
            }
          ]
        },
        {
          "__type": "Unimplemented",
          "__tag": 4018,
          "placeholder": "target",
          "value": "__ https://ieeexplore.ieee.org/document/4610935/"
        },
        {
          "__type": "Unimplemented",
          "__tag": 4018,
          "placeholder": "target",
          "value": "__ https://en.wikipedia.org/wiki/Half-precision_floating-point_format"
        },
        {
          "__type": "Unimplemented",
          "__tag": 4018,
          "placeholder": "target",
          "value": "__ https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_half_float_pixel.txt"
        },
        {
          "__type": "Unimplemented",
          "__tag": 4018,
          "placeholder": "target",
          "value": "__ https://www.openexr.com/about.html"
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Half-precision functions"
        }
      ],
      "level": 1,
      "target": null
    }
  ],
  "local_refs": []
}